From ea3509eea41983b5ef77f7c96fc3bd265c24d56f Mon Sep 17 00:00:00 2001 From: agnesthealien Date: Tue, 17 Mar 2026 01:16:49 -0400 Subject: [PATCH] first --- .codeclimate.yml | 12 + .codecov.yml | 1 + .erb-lint.yml | 45 + .gitattributes | 6 + .gitignore | 127 + .gitpod.yml | 21 + .hound.yml | 9 + .jshintignore | 4 + .jshintrc | 1 + .phrase.yml | 164 + .rubocop.yml | 310 + .ruby-version | 1 + .simplecov | 10 + ACKNOWLEDGMENTS.md | 27 + CONTRIBUTING.md | 63 + Capfile | 4 + Gemfile | 186 + Gemfile.lock | 781 + LICENSE | 339 + README.md | 46 + Rakefile | 9 + SECURITY.md | 14 + app/controllers/abuse_reports_controller.rb | 38 + .../admin/activities_controller.rb | 11 + .../admin/admin_invitations_controller.rb | 61 + .../admin/admin_users_controller.rb | 237 + app/controllers/admin/api_controller.rb | 71 + app/controllers/admin/banners_controller.rb | 82 + app/controllers/admin/base_controller.rb | 3 + .../admin/blacklisted_emails_controller.rb | 40 + app/controllers/admin/passwords_controller.rb | 7 + app/controllers/admin/sessions_controller.rb | 14 + app/controllers/admin/settings_controller.rb | 24 + app/controllers/admin/skins_controller.rb | 98 + app/controllers/admin/spam_controller.rb | 36 + .../admin/user_creations_controller.rb | 101 + app/controllers/admin_posts_controller.rb | 101 + app/controllers/admins_controller.rb | 4 + app/controllers/api/v2/base_controller.rb | 63 + .../api/v2/bookmarks_controller.rb | 229 + app/controllers/api/v2/works_controller.rb | 225 + app/controllers/application_controller.rb | 564 + app/controllers/archive_faqs_controller.rb | 195 + app/controllers/autocomplete_controller.rb | 224 + app/controllers/blocked/users_controller.rb | 89 + app/controllers/bookmarks_controller.rb | 397 + .../challenge/gift_exchange_controller.rb | 109 + .../challenge/prompt_meme_controller.rb | 80 + .../challenge_assignments_controller.rb | 243 + .../challenge_claims_controller.rb | 148 + .../challenge_requests_controller.rb | 41 + .../challenge_signups_controller.rb | 389 + app/controllers/challenges_controller.rb | 68 + app/controllers/chapters_controller.rb | 295 + .../collection_items_controller.rb | 229 + .../collection_participants_controller.rb | 135 + .../collection_profile_controller.rb | 13 + app/controllers/collections_controller.rb | 214 + app/controllers/comments_controller.rb | 700 + app/controllers/concerns/tag_wrangling.rb | 14 + app/controllers/creatorships_controller.rb | 72 + app/controllers/downloads_controller.rb | 72 + app/controllers/errors_controller.rb | 16 + .../external_authors_controller.rb | 104 + app/controllers/external_works_controller.rb | 69 + app/controllers/fandoms_controller.rb | 56 + app/controllers/favorite_tags_controller.rb | 52 + app/controllers/feedbacks_controller.rb | 48 + app/controllers/gifts_controller.rb | 61 + app/controllers/hit_count_controller.rb | 31 + app/controllers/home_controller.rb | 87 + app/controllers/inbox_controller.rb | 75 + app/controllers/invitations_controller.rb | 93 + app/controllers/invite_requests_controller.rb | 124 + app/controllers/known_issues_controller.rb | 58 + app/controllers/kudos_controller.rb | 94 + app/controllers/languages_controller.rb | 53 + app/controllers/locales_controller.rb | 55 + app/controllers/media_controller.rb | 25 + app/controllers/menu_controller.rb | 23 + app/controllers/muted/users_controller.rb | 89 + .../opendoors/external_authors_controller.rb | 78 + app/controllers/opendoors/tools_controller.rb | 61 + app/controllers/orphans_controller.rb | 90 + app/controllers/owned_tag_sets_controller.rb | 239 + app/controllers/people_controller.rb | 33 + .../potential_matches_controller.rb | 146 + app/controllers/preferences_controller.rb | 72 + app/controllers/profile_controller.rb | 45 + app/controllers/prompts_controller.rb | 211 + app/controllers/pseuds_controller.rb | 143 + app/controllers/questions_controller.rb | 38 + app/controllers/readings_controller.rb | 70 + app/controllers/redirect_controller.rb | 29 + app/controllers/related_works_controller.rb | 96 + app/controllers/serial_works_controller.rb | 25 + app/controllers/series_controller.rb | 157 + app/controllers/skins_controller.rb | 223 + app/controllers/stats_controller.rb | 130 + app/controllers/statuses_controller.rb | 112 + app/controllers/subscriptions_controller.rb | 97 + .../tag_set_associations_controller.rb | 77 + .../tag_set_nominations_controller.rb | 371 + app/controllers/tag_wranglers_controller.rb | 112 + app/controllers/tag_wranglings_controller.rb | 108 + app/controllers/tags_controller.rb | 427 + app/controllers/troubleshooting_controller.rb | 197 + app/controllers/unsorted_tags_controller.rb | 31 + .../user_invite_requests_controller.rb | 86 + app/controllers/users/passwords_controller.rb | 54 + .../users/registrations_controller.rb | 98 + app/controllers/users/sessions_controller.rb | 36 + app/controllers/users_controller.rb | 418 + app/controllers/works_controller.rb | 984 + .../wrangling_guidelines_controller.rb | 82 + app/decorators/bookmarkable_decorator.rb | 75 + app/decorators/comment_decorator.rb | 68 + app/decorators/homepage.rb | 70 + app/decorators/pseud_decorator.rb | 126 + app/helpers/admin_helper.rb | 54 + app/helpers/admin_post_helper.rb | 8 + app/helpers/advanced_search_helper.rb | 16 + app/helpers/application_helper.rb | 654 + app/helpers/block_helper.rb | 46 + app/helpers/bookmarks_helper.rb | 130 + app/helpers/challenge_helper.rb | 48 + app/helpers/collections_helper.rb | 138 + app/helpers/comments_helper.rb | 404 + app/helpers/date_helper.rb | 36 + app/helpers/exports_helper.rb | 17 + app/helpers/external_authors_helper.rb | 26 + app/helpers/home_helper.rb | 114 + app/helpers/inbox_helper.rb | 20 + app/helpers/invitations_helper.rb | 26 + app/helpers/kudos_helper.rb | 52 + app/helpers/language_helper.rb | 39 + app/helpers/mailer_helper.rb | 311 + app/helpers/mute_helper.rb | 42 + app/helpers/number_helper.rb | 17 + app/helpers/orphans_helper.rb | 15 + app/helpers/pagination_helper.rb | 66 + app/helpers/prompt_restrictions_helper.rb | 76 + app/helpers/pseuds_helper.rb | 51 + app/helpers/search_helper.rb | 64 + app/helpers/series_helper.rb | 83 + app/helpers/share_helper.rb | 78 + app/helpers/skin_cache_helper.rb | 28 + app/helpers/skins_helper.rb | 88 + app/helpers/statuses_helper.rb | 3 + app/helpers/tag_sets_helper.rb | 105 + app/helpers/tag_type_helper.rb | 42 + app/helpers/tags_helper.rb | 355 + app/helpers/translation_helper.rb | 42 + app/helpers/user_invite_requests_helper.rb | 14 + app/helpers/users_helper.rb | 192 + app/helpers/validation_helper.rb | 181 + app/helpers/works_helper.rb | 232 + app/helpers/wrangling_helper.rb | 14 + app/jobs/application_job.rb | 14 + app/jobs/application_mailer_job.rb | 34 + app/jobs/async_indexer_job.rb | 15 + app/jobs/hit_count_update_job.rb | 44 + app/jobs/instance_method_job.rb | 10 + app/jobs/invite_from_queue_job.rb | 13 + app/jobs/readings_job.rb | 37 + app/jobs/redis_hash_job.rb | 16 + app/jobs/redis_job_spawner.rb | 25 + app/jobs/redis_set_job.rb | 76 + app/jobs/report_attachment_job.rb | 7 + app/jobs/resanitize_batch_job.rb | 44 + app/jobs/stat_counter_job.rb | 19 + app/jobs/tag_count_update_job.rb | 24 + app/jobs/tag_method_job.rb | 15 + app/mailers/README.md | 3 + app/mailers/admin_mailer.rb | 35 + app/mailers/application_mailer.rb | 7 + app/mailers/archive_devise_mailer.rb | 42 + app/mailers/collection_mailer.rb | 16 + app/mailers/comment_mailer.rb | 112 + app/mailers/kudo_mailer.rb | 27 + .../tag_wrangling_supervisor_mailer.rb | 12 + app/mailers/tos_update_mailer.rb | 11 + app/mailers/user_mailer.rb | 417 + app/models/abuse_report.rb | 214 + app/models/admin.rb | 43 + app/models/admin_activity.rb | 25 + app/models/admin_banner.rb | 28 + app/models/admin_blacklisted_email.rb | 38 + app/models/admin_post.rb | 140 + app/models/admin_post_tag.rb | 21 + app/models/admin_post_tagging.rb | 4 + app/models/admin_setting.rb | 102 + app/models/api_key.rb | 8 + app/models/application_record.rb | 18 + app/models/archive_faq.rb | 32 + app/models/archive_warning.rb | 31 + app/models/banned.rb | 5 + app/models/block.rb | 27 + app/models/bookmark.rb | 216 + app/models/category.rb | 7 + app/models/challenge_assignment.rb | 498 + app/models/challenge_claim.rb | 155 + app/models/challenge_models/gift_exchange.rb | 81 + app/models/challenge_models/prompt_meme.rb | 49 + app/models/challenge_signup.rb | 202 + app/models/challenge_signup_summary.rb | 151 + app/models/chapter.rb | 209 + app/models/character.rb | 32 + app/models/collection.rb | 464 + app/models/collection_item.rb | 275 + app/models/collection_participant.rb | 57 + app/models/collection_preference.rb | 15 + app/models/collection_profile.rb | 24 + app/models/comment.rb | 555 + app/models/common_tagging.rb | 96 + app/models/concerns/async_with_active_job.rb | 17 + app/models/concerns/async_with_resque.rb | 53 + app/models/concerns/creatable.rb | 228 + app/models/concerns/filterable.rb | 106 + app/models/concerns/globalized.rb | 13 + app/models/concerns/justifiable.rb | 70 + .../concerns/password_resets_limitable.rb | 46 + app/models/concerns/taggable.rb | 163 + app/models/concerns/user_loggable.rb | 61 + app/models/concerns/wrangleable.rb | 19 + app/models/creatorship.rb | 292 + app/models/download.rb | 140 + app/models/download_writer.rb | 176 + app/models/external_author.rb | 178 + app/models/external_author_name.rb | 34 + app/models/external_creatorship.rb | 26 + app/models/external_work.rb | 126 + app/models/fandom.rb | 50 + app/models/fannish_next_of_kin.rb | 10 + app/models/favorite_tag.rb | 46 + app/models/feedback.rb | 91 + .../feedback_reporters/abuse_reporter.rb | 42 + .../feedback_reporters/feedback_reporter.rb | 79 + .../feedback_reporters/support_reporter.rb | 45 + app/models/filter_count.rb | 141 + app/models/filter_tagging.rb | 30 + app/models/filter_updater.rb | 212 + app/models/freeform.rb | 37 + app/models/gift.rb | 75 + app/models/inbox_comment.rb | 43 + app/models/indexing/cache_master.rb | 63 + app/models/indexing/index_queue.rb | 92 + app/models/indexing/scheduled_reindex_job.rb | 18 + app/models/inherited_meta_tag_updater.rb | 81 + app/models/invitation.rb | 106 + app/models/invite_request.rb | 60 + app/models/known_issue.rb | 20 + app/models/kudo.rb | 105 + app/models/language.rb | 28 + app/models/last_wrangling_activity.rb | 3 + app/models/locale.rb | 28 + app/models/log_item.rb | 17 + app/models/media.rb | 36 + app/models/meta_tagging.rb | 55 + app/models/moderated_work.rb | 71 + app/models/mute.rb | 35 + app/models/offer.rb | 7 + app/models/opendoors.rb | 5 + app/models/potential_match.rb | 284 + app/models/potential_match_builder.rb | 56 + app/models/potential_match_settings.rb | 41 + .../potential_matcher_constrained.rb | 127 + .../potential_matcher_progress.rb | 87 + .../potential_matcher_unconstrained.rb | 67 + app/models/potential_matcher/prompt_batch.rb | 85 + .../potential_matcher/prompt_tag_type_info.rb | 109 + app/models/preference.rb | 48 + app/models/profile.rb | 16 + app/models/prompt.rb | 297 + app/models/prompt_restriction.rb | 124 + app/models/pseud.rb | 455 + app/models/question.rb | 33 + app/models/rating.rb | 24 + app/models/reading.rb | 52 + app/models/redis_hit_counter.rb | 131 + app/models/redis_mail_queue.rb | 104 + app/models/related_work.rb | 61 + app/models/relationship.rb | 43 + app/models/request.rb | 7 + app/models/role.rb | 11 + app/models/roles_user.rb | 38 + app/models/scheduled_tag_job.rb | 10 + app/models/search/async_indexer.rb | 68 + app/models/search/bookmark_indexer.rb | 113 + app/models/search/bookmark_query.rb | 364 + app/models/search/bookmark_search_form.rb | 200 + app/models/search/bookmarkable_indexer.rb | 37 + app/models/search/bookmarkable_query.rb | 287 + .../bookmarked_external_work_indexer.rb | 5 + .../search/bookmarked_series_indexer.rb | 5 + app/models/search/bookmarked_work_indexer.rb | 18 + app/models/search/index_sweeper.rb | 111 + app/models/search/indexer.rb | 228 + app/models/search/pseud_indexer.rb | 128 + app/models/search/pseud_query.rb | 62 + app/models/search/pseud_search_form.rb | 40 + app/models/search/query.rb | 272 + app/models/search/query_cleaner.rb | 103 + app/models/search/query_facet.rb | 2 + app/models/search/query_result.rb | 130 + app/models/search/search_counts.rb | 126 + app/models/search/stat_counter_indexer.rb | 65 + app/models/search/tag_indexer.rb | 90 + app/models/search/tag_query.rb | 161 + app/models/search/tag_search_form.rb | 78 + app/models/search/taggable_query.rb | 82 + app/models/search/user_indexer.rb | 79 + app/models/search/user_query.rb | 59 + app/models/search/work_creator_indexer.rb | 47 + app/models/search/work_indexer.rb | 135 + app/models/search/work_query.rb | 370 + app/models/search/work_search_form.rb | 228 + app/models/search_range.rb | 118 + app/models/serial_work.rb | 50 + app/models/series.rb | 315 + app/models/skin.rb | 602 + app/models/skin_parent.rb | 77 + app/models/spam_report.rb | 75 + app/models/stat_counter.rb | 14 + app/models/status.rb | 5 + app/models/story_parser.rb | 981 + app/models/subscription.rb | 55 + app/models/tag.rb | 1254 ++ app/models/tagging.rb | 45 + app/models/tagset_models/cast_nomination.rb | 43 + .../tagset_models/character_nomination.rb | 5 + app/models/tagset_models/fandom_nomination.rb | 34 + .../tagset_models/freeform_nomination.rb | 5 + app/models/tagset_models/owned_set_tagging.rb | 6 + app/models/tagset_models/owned_tag_set.rb | 279 + .../tagset_models/relationship_nomination.rb | 5 + app/models/tagset_models/set_tagging.rb | 6 + app/models/tagset_models/tag_nomination.rb | 183 + app/models/tagset_models/tag_set.rb | 297 + .../tagset_models/tag_set_association.rb | 132 + .../tagset_models/tag_set_nomination.rb | 102 + app/models/tagset_models/tag_set_ownership.rb | 4 + app/models/unsorted_tag.rb | 3 + app/models/user.rb | 626 + app/models/user_invite_request.rb | 34 + app/models/user_manager.rb | 134 + app/models/work.rb | 1324 ++ app/models/work_original_creator.rb | 23 + app/models/work_skin.rb | 52 + app/models/wrangling_assignment.rb | 9 + app/models/wrangling_guideline.rb | 11 + app/policies/admin_activity_policy.rb | 9 + app/policies/admin_banner_policy.rb | 16 + .../admin_blacklisted_email_policy.rb | 8 + app/policies/admin_post_policy.rb | 13 + app/policies/admin_setting_policy.rb | 47 + app/policies/api_key_policy.rb | 14 + app/policies/application_policy.rb | 59 + app/policies/archive_faq_policy.rb | 24 + app/policies/block_policy.rb | 5 + app/policies/bookmark_policy.rb | 2 + app/policies/comment_policy.rb | 68 + app/policies/external_work_policy.rb | 5 + app/policies/inbox_comment_policy.rb | 7 + app/policies/invitation_policy.rb | 7 + app/policies/invite_request_policy.rb | 10 + app/policies/known_issue_policy.rb | 16 + app/policies/language_policy.rb | 35 + app/policies/locale_policy.rb | 12 + app/policies/moderated_work_policy.rb | 9 + app/policies/mute_policy.rb | 5 + app/policies/profile_policy.rb | 10 + app/policies/pseud_policy.rb | 25 + app/policies/series_policy.rb | 2 + app/policies/skin_policy.rb | 21 + app/policies/user_creation_policy.rb | 23 + app/policies/user_manager_policy.rb | 18 + app/policies/user_policy.rb | 90 + app/policies/work_policy.rb | 28 + app/policies/wrangling_policy.rb | 25 + app/sweepers/collection_sweeper.rb | 61 + app/sweepers/feed_sweeper.rb | 35 + app/sweepers/pseud_sweeper.rb | 43 + app/sweepers/tag_set_sweeper.rb | 40 + app/validators/at_most_validator.rb | 17 + app/validators/attachment_validator.rb | 24 + app/validators/email_blacklist_validator.rb | 10 + app/validators/email_format_validator.rb | 30 + app/validators/not_blocked_validator.rb | 25 + .../not_forbidden_name_validator.rb | 9 + app/validators/url_active_validator.rb | 27 + app/validators/url_format_validator.rb | 20 + app/views/abuse_reports/new.html.erb | 17 + app/views/admin/_admin_nav.html.erb | 41 + app/views/admin/_admin_options.html.erb | 74 + app/views/admin/_header.html.erb | 82 + app/views/admin/activities/index.html.erb | 41 + app/views/admin/activities/show.html.erb | 33 + .../admin/admin_invitations/find.html.erb | 30 + .../admin/admin_invitations/index.html.erb | 76 + .../admin/admin_invitations/new.html.erb | 16 + .../_user_creations_summary.html.erb | 21 + .../admin/admin_users/_user_form.html.erb | 25 + .../admin/admin_users/_user_history.html.erb | 51 + .../admin/admin_users/_user_listing.html.erb | 8 + .../admin/admin_users/_user_table.html.erb | 33 + .../admin/admin_users/bulk_search.html.erb | 46 + .../confirm_delete_user_creations.html.erb | 17 + .../admin/admin_users/creations.html.erb | 24 + app/views/admin/admin_users/index.html.erb | 78 + app/views/admin/admin_users/show.html.erb | 144 + app/views/admin/api/_api_key_form.html.erb | 39 + app/views/admin/api/_navigation.html.erb | 4 + app/views/admin/api/edit.html.erb | 13 + app/views/admin/api/index.html.erb | 54 + app/views/admin/api/new.html.erb | 13 + app/views/admin/banners/_banner.html.erb | 7 + app/views/admin/banners/_banner_form.html.erb | 55 + app/views/admin/banners/_navigation.html.erb | 12 + .../admin/banners/confirm_delete.html.erb | 16 + app/views/admin/banners/edit.html.erb | 13 + app/views/admin/banners/index.html.erb | 40 + app/views/admin/banners/new.html.erb | 13 + app/views/admin/banners/show.html.erb | 13 + .../admin/blacklisted_emails/index.html.erb | 62 + .../admin/mailer/password_change.html.erb | 13 + .../admin/mailer/password_change.text.erb | 13 + .../reset_password_instructions.html.erb | 7 + .../reset_password_instructions.text.erb | 12 + app/views/admin/passwords/edit.html.erb | 26 + app/views/admin/passwords/new.html.erb | 15 + .../admin/sessions/confirm_logout.html.erb | 8 + app/views/admin/sessions/new.html.erb | 17 + app/views/admin/settings/index.html.erb | 107 + app/views/admin/skins/_navigation.html.erb | 6 + app/views/admin/skins/index.html.erb | 71 + app/views/admin/skins/index_approved.html.erb | 100 + app/views/admin/skins/index_rejected.html.erb | 51 + app/views/admin/spam/index.html.erb | 88 + .../confirm_remove_pseud.html.erb | 30 + .../admin_mailer/send_spam_alert.html.erb | 20 + .../admin_mailer/send_spam_alert.text.erb | 14 + .../set_password_notification.html.erb | 8 + .../set_password_notification.text.erb | 12 + app/views/admin_posts/_admin_index.html.erb | 27 + app/views/admin_posts/_admin_post.html.erb | 39 + .../admin_posts/_admin_post_form.html.erb | 105 + app/views/admin_posts/_filters.html.erb | 8 + app/views/admin_posts/_sidebar.html.erb | 8 + app/views/admin_posts/edit.html.erb | 11 + app/views/admin_posts/index.html.erb | 43 + app/views/admin_posts/index.rss.builder | 19 + app/views/admin_posts/new.html.erb | 11 + app/views/admin_posts/show.html.erb | 55 + app/views/admins/index.html.erb | 29 + app/views/archive_faqs/_admin_index.html.erb | 37 + .../archive_faqs/_archive_faq_form.html.erb | 61 + .../archive_faqs/_archive_faq_order.html.erb | 33 + .../_archive_faq_questions_order.html.erb | 33 + app/views/archive_faqs/_faq_index.html.erb | 86 + app/views/archive_faqs/_filters.html.erb | 10 + .../_question_answer_fields.html.erb | 67 + .../archive_faqs/confirm_delete.html.erb | 11 + app/views/archive_faqs/edit.html.erb | 14 + app/views/archive_faqs/index.html.erb | 5 + app/views/archive_faqs/manage.html.erb | 11 + app/views/archive_faqs/new.html.erb | 13 + app/views/archive_faqs/show.html.erb | 58 + .../users/_blocked_user_blurb.html.erb | 9 + .../blocked/users/confirm_block.html.erb | 31 + .../blocked/users/confirm_unblock.html.erb | 21 + app/views/blocked/users/index.html.erb | 52 + app/views/bookmarks/_bookmark_blurb.html.erb | 47 + .../bookmarks/_bookmark_blurb_short.html.erb | 43 + app/views/bookmarks/_bookmark_form.html.erb | 110 + .../bookmarks/_bookmark_item_module.html.erb | 8 + .../_bookmark_owner_navigation.html.erb | 12 + .../bookmarks/_bookmark_user_module.html.erb | 60 + .../bookmarks/_bookmarkable_blurb.html.erb | 54 + app/views/bookmarks/_bookmarklet.html.erb | 1 + app/views/bookmarks/_bookmarks.html.erb | 21 + .../bookmarks/_external_work_fields.html.erb | 119 + app/views/bookmarks/_filters.html.erb | 154 + app/views/bookmarks/_search_form.html.erb | 121 + .../bookmarks/bookmark_form_dynamic.js.erb | 22 + app/views/bookmarks/confirm_delete.html.erb | 17 + app/views/bookmarks/edit.html.erb | 22 + app/views/bookmarks/index.html.erb | 71 + app/views/bookmarks/new.html.erb | 9 + app/views/bookmarks/search.html.erb | 12 + app/views/bookmarks/search_results.html.erb | 35 + app/views/bookmarks/share.html.erb | 1 + app/views/bookmarks/show.html.erb | 23 + .../gift_exchange/_challenge_main.html.erb | 1 + .../gift_exchange/_challenge_meta.html.erb | 1 + .../_challenge_navigation_maintainer.html.erb | 6 + .../_challenge_navigation_user.html.erb | 1 + .../_challenge_requests.html.erb | 1 + .../gift_exchange/_challenge_sidebar.html.erb | 46 + .../gift_exchange/_challenge_signups.html.erb | 64 + .../_challenge_signups_summary.html.erb | 42 + .../_gift_exchange_form.html.erb | 57 + .../gift_exchange/confirm_delete.html.erb | 6 + .../challenge/gift_exchange/edit.html.erb | 2 + .../challenge/gift_exchange/new.html.erb | 1 + .../prompt_meme/_challenge_main.html.erb | 1 + .../prompt_meme/_challenge_meta.html.erb | 4 + .../_challenge_navigation_maintainer.html.erb | 6 + .../_challenge_navigation_user.html.erb | 1 + .../prompt_meme/_challenge_requests.html.erb | 1 + .../prompt_meme/_challenge_sidebar.html.erb | 28 + .../prompt_meme/_challenge_signups.html.erb | 11 + .../prompt_meme/_prompt_meme_form.html.erb | 52 + .../prompt_meme/confirm_delete.html.erb | 6 + app/views/challenge/prompt_meme/edit.html.erb | 1 + .../challenge/prompt_meme/manage.html.erb | 0 app/views/challenge/prompt_meme/new.html.erb | 1 + app/views/challenge/prompt_meme/show.html.erb | 0 .../_challenge_form_confirm_delete.html.erb | 14 + .../shared/_challenge_form_delete.html.erb | 8 + .../_challenge_form_instructions.html.erb | 44 + .../shared/_challenge_form_schedule.html.erb | 50 + .../challenge/shared/_challenge_meta.html.erb | 74 + .../_challenge_navigation_user.html.erb | 40 + .../shared/_challenge_requests.html.erb | 40 + .../shared/_challenge_signups.html.erb | 31 + .../_assignment_blurb.html.erb | 70 + .../_maintainer_index.html.erb | 82 + .../_maintainer_index_defaulted.html.erb | 22 + .../_maintainer_index_fulfilled.html.erb | 6 + .../_maintainer_index_unfulfilled.html.erb | 47 + .../_user_index.html.erb | 20 + .../confirm_purge.html.erb | 19 + .../challenge_assignments/index.html.erb | 5 + app/views/challenge_assignments/show.html.erb | 46 + .../_maintainer_index.html.erb | 36 + .../_unposted_claim_blurb.html.erb | 59 + .../challenge_claims/_user_index.html.erb | 34 + app/views/challenge_claims/index.html.erb | 5 + app/views/challenge_requests/index.html.erb | 5 + .../challenge_signups/_show_offers.html.erb | 24 + .../challenge_signups/_show_requests.html.erb | 24 + .../_signup_controls.html.erb | 48 + .../challenge_signups/_signup_form.html.erb | 83 + .../_signup_form_general_information.html.erb | 21 + .../challenge_signups/confirm_delete.html.erb | 17 + app/views/challenge_signups/edit.html.erb | 10 + app/views/challenge_signups/index.html.erb | 30 + app/views/challenge_signups/index.xls.erb | 7 + app/views/challenge_signups/new.html.erb | 10 + app/views/challenge_signups/show.html.erb | 13 + app/views/challenge_signups/summary.html.erb | 13 + app/views/chapters/_chapter.html.erb | 85 + app/views/chapters/_chapter_form.html.erb | 101 + .../chapters/_chapter_management.html.erb | 11 + app/views/chapters/_hidden_fields.html.erb | 24 + app/views/chapters/confirm_delete.html.erb | 12 + app/views/chapters/edit.html.erb | 28 + app/views/chapters/manage.html.erb | 78 + app/views/chapters/new.html.erb | 14 + app/views/chapters/preview.html.erb | 47 + app/views/chapters/show.html.erb | 69 + .../collectibles/_collectible_form.html.erb | 17 + .../_collection_item_controls.html.erb | 75 + .../_collection_item_form.html.erb | 42 + .../collection_items/_item_fields.html.erb | 62 + app/views/collection_items/index.html.erb | 50 + app/views/collection_items/new.html.erb | 12 + .../item_added_notification.html.erb | 21 + .../item_added_notification.text.erb | 18 + .../_add_participants_form.html.erb | 10 + .../_participant_form.html.erb | 19 + .../collection_participants/index.html.erb | 10 + .../collection_profile/_navigation.html.erb | 14 + app/views/collection_profile/show.html.erb | 112 + .../collections/_bookmarks_module.html.erb | 17 + .../_challenge_collections.html.erb | 12 + .../_challenge_list_top_navigation.html.erb | 7 + .../collections/_collection_blurb.html.erb | 87 + .../_collection_form_delete.html.erb | 6 + .../_collection_profile_navigation.html.erb | 14 + app/views/collections/_filters.html.erb | 151 + app/views/collections/_form.html.erb | 250 + app/views/collections/_header.html.erb | 45 + app/views/collections/_sidebar.html.erb | 54 + app/views/collections/_works_module.html.erb | 17 + app/views/collections/confirm_delete.html.erb | 11 + app/views/collections/edit.html.erb | 13 + app/views/collections/index.html.erb | 71 + .../collections/list_challenges.html.erb | 10 + .../collections/list_ge_challenges.html.erb | 10 + .../collections/list_pm_challenges.html.erb | 10 + app/views/collections/new.html.erb | 23 + app/views/collections/show.html.erb | 20 + .../_comment_notification_footer.html.erb | 12 + .../_comment_notification_footer.text.erb | 6 + ...ent_notification_footer_for_other.html.erb | 40 + ...ent_notification_footer_for_other.text.erb | 14 + ...mment_notification_footer_for_tag.html.erb | 18 + ...mment_notification_footer_for_tag.text.erb | 4 + .../comment_notification.html.erb | 13 + .../comment_notification.text.erb | 11 + .../comment_reply_notification.html.erb | 22 + .../comment_reply_notification.text.erb | 20 + .../comment_reply_sent_notification.html.erb | 22 + .../comment_reply_sent_notification.text.erb | 20 + .../comment_sent_notification.html.erb | 14 + .../comment_sent_notification.text.erb | 12 + .../edited_comment_notification.html.erb | 16 + .../edited_comment_notification.text.erb | 11 + ...edited_comment_reply_notification.html.erb | 22 + ...edited_comment_reply_notification.text.erb | 20 + .../_comment_abbreviated_list.html.erb | 15 + app/views/comments/_comment_actions.html.erb | 76 + app/views/comments/_comment_form.html.erb | 113 + app/views/comments/_comment_thread.html.erb | 23 + app/views/comments/_commentable.html.erb | 159 + app/views/comments/_confirm_delete.html.erb | 5 + app/views/comments/_single_comment.html.erb | 78 + app/views/comments/add_comment_reply.js.erb | 5 + .../comments/cancel_comment_delete.js.erb | 5 + app/views/comments/cancel_comment_edit.js.erb | 11 + .../comments/cancel_comment_reply.js.erb | 5 + app/views/comments/delete_comment.js.erb | 5 + app/views/comments/edit.html.erb | 21 + app/views/comments/edit.js.erb | 8 + app/views/comments/hide_comments.js.erb | 7 + app/views/comments/index.html.erb | 10 + app/views/comments/new.html.erb | 17 + app/views/comments/review.js.erb | 10 + app/views/comments/show.html.erb | 7 + app/views/comments/show_comments.js.erb | 11 + app/views/comments/unreviewed.html.erb | 31 + app/views/comments/update.js.erb | 11 + app/views/creatorships/show.html.erb | 63 + .../downloads/_download_afterword.html.erb | 32 + .../downloads/_download_chapter.html.erb | 39 + .../downloads/_download_preface.html.erb | 92 + app/views/downloads/show.html.erb | 17 + app/views/errors/403.html.erb | 3 + app/views/errors/404.html.erb | 8 + app/views/errors/422.html.erb | 3 + app/views/errors/500.html.erb | 3 + app/views/errors/auth_error.html.erb | 2 + app/views/errors/timeout_error.html.erb | 3 + .../_external_author_blurb.html.erb | 19 + .../_external_author_description.html.erb | 35 + .../_external_author_form.html.erb | 38 + .../_external_author_name.html.erb | 9 + .../_external_author_navigation.html.erb | 16 + app/views/external_authors/claim.html.erb | 121 + app/views/external_authors/edit.html.erb | 6 + app/views/external_authors/index.html.erb | 52 + app/views/external_works/_blurb.html.erb | 57 + .../external_works/_work_module.html.erb | 57 + app/views/external_works/edit.html.erb | 56 + app/views/external_works/fetch.js.erb | 20 + app/views/external_works/index.html.erb | 23 + app/views/external_works/new.html.erb | 2 + app/views/external_works/show.html.erb | 6 + app/views/fandoms/index.html.erb | 61 + app/views/fandoms/show.html.erb | 31 + app/views/fandoms/unassigned.html.erb | 62 + app/views/favorite_tags/_form.html.erb | 13 + app/views/feedbacks/new.html.erb | 99 + app/views/gifts/_gift_blurb.html.erb | 10 + app/views/gifts/_gift_search.html.erb | 10 + app/views/gifts/index.html.erb | 42 + app/views/hit_count/_include.html.erb | 19 + app/views/home/_content.html.erb | 21 + app/views/home/_dmca.html.erb | 188 + app/views/home/_fandoms.html.erb | 11 + app/views/home/_inbox_module.html.erb | 41 + app/views/home/_intro_module.html.erb | 40 + app/views/home/_news_module.html.erb | 35 + app/views/home/_privacy.html.erb | 236 + app/views/home/_tos.html.erb | 26 + app/views/home/_tos_navigation.html.erb | 6 + app/views/home/about.html.erb | 15 + app/views/home/content.html.erb | 20 + app/views/home/diversity_statement.html.erb | 47 + app/views/home/dmca.html.erb | 4 + app/views/home/donate.html.erb | 9 + app/views/home/first_login_help.html.erb | 155 + app/views/home/index.html.erb | 57 + app/views/home/lost_cookie.html.erb | 5 + app/views/home/privacy.html.erb | 20 + app/views/home/site_map.html.erb | 65 + app/views/home/site_pages.html.erb | 41 + app/views/home/tos.html.erb | 25 + app/views/home/tos_faq.html.erb | 1247 ++ app/views/home/unicorn_test.html.erb | 3 + app/views/inbox/_approve_button.html.erb | 7 + app/views/inbox/_delete_form.html.erb | 6 + .../inbox/_inbox_comment_contents.html.erb | 31 + app/views/inbox/_read_form.html.erb | 6 + app/views/inbox/_reply_button.html.erb | 4 + app/views/inbox/reply.js.erb | 9 + app/views/inbox/show.html.erb | 189 + app/views/invitations/_invitation.html.erb | 35 + .../invitations/_user_invitations.html.erb | 42 + .../_user_invitations_navigation.html.erb | 7 + app/views/invitations/index.html.erb | 46 + app/views/invitations/manage.html.erb | 31 + app/views/invitations/show.html.erb | 9 + .../invite_requests/_index_closed.html.erb | 18 + .../invite_requests/_index_open.html.erb | 38 + .../invite_requests/_invitation.html.erb | 28 + .../invite_requests/_invite_request.html.erb | 14 + .../invite_requests/_no_invitation.html.erb | 3 + app/views/invite_requests/index.html.erb | 6 + app/views/invite_requests/manage.html.erb | 66 + app/views/invite_requests/show.html.erb | 11 + app/views/invite_requests/show.js.erb | 14 + app/views/invite_requests/status.html.erb | 30 + app/views/known_issues/_admin_index.html.erb | 32 + .../known_issues/_known_issues_form.html.erb | 37 + app/views/known_issues/edit.html.erb | 14 + app/views/known_issues/index.html.erb | 20 + app/views/known_issues/new.html.erb | 11 + app/views/known_issues/show.html.erb | 23 + .../batch_kudo_notification.html.erb | 26 + .../batch_kudo_notification.text.erb | 28 + app/views/kudos/_kudos.html.erb | 21 + app/views/kudos/create.js.erb | 2 + app/views/kudos/index.html.erb | 22 + app/views/kudos/index.js.erb | 2 + app/views/languages/_form.html.erb | 51 + app/views/languages/edit.html.erb | 3 + app/views/languages/index.html.erb | 43 + app/views/languages/new.html.erb | 3 + app/views/layouts/_banner.html.erb | 24 + app/views/layouts/_footer.html.erb | 57 + app/views/layouts/_header.html.erb | 78 + app/views/layouts/_includes.html.erb | 11 + app/views/layouts/_javascripts.html.erb | 114 + app/views/layouts/_proxy_notice.html.erb | 35 + app/views/layouts/_tos_prompt.html.erb | 77 + app/views/layouts/application.html.erb | 57 + app/views/layouts/barebones.html.erb | 29 + app/views/layouts/home.html.erb | 47 + app/views/layouts/mailer.html.erb | 126 + app/views/layouts/mailer.text.erb | 25 + app/views/layouts/session.html.erb | 53 + app/views/locales/_locale_form.html.erb | 32 + app/views/locales/_navigation.html.erb | 4 + app/views/locales/edit.html.erb | 13 + app/views/locales/index.html.erb | 40 + app/views/locales/new.html.erb | 13 + app/views/media/index.html.erb | 28 + app/views/menu/_menu_about.html.erb | 8 + app/views/menu/_menu_browse.html.erb | 7 + app/views/menu/_menu_fandoms.html.erb | 11 + app/views/menu/_menu_othersites.html.erb | 8 + app/views/menu/_menu_search.html.erb | 6 + app/views/menu/about.html.erb | 4 + app/views/menu/browse.html.erb | 4 + app/views/menu/fandoms.html.erb | 4 + app/views/menu/search.html.erb | 4 + app/views/muted/_muted_items_notice.html.erb | 3 + .../muted/users/_muted_user_blurb.html.erb | 9 + app/views/muted/users/confirm_mute.html.erb | 34 + app/views/muted/users/confirm_unmute.html.erb | 19 + app/views/muted/users/index.html.erb | 55 + .../opendoors/external_authors/index.html.erb | 50 + .../opendoors/external_authors/show.html.erb | 3 + .../tools/_tools_navigation.html.erb | 14 + app/views/opendoors/tools/index.html.erb | 46 + app/views/orphans/_choose_pseud.html.erb | 8 + app/views/orphans/_orphan_pseud.html.erb | 43 + app/views/orphans/_orphan_series.html.erb | 24 + app/views/orphans/_orphan_user.html.erb | 33 + app/views/orphans/_orphan_work.html.erb | 43 + app/views/orphans/index.html.erb | 17 + app/views/orphans/new.html.erb | 6 + .../_internal_tag_set_fields.html.erb | 30 + app/views/owned_tag_sets/_navigation.html.erb | 26 + .../_show_fandoms_by_media.html.erb | 47 + .../_show_tag_set_associations.html.erb | 15 + .../_show_tag_set_tags.html.erb | 70 + .../_show_tags_alpha_listbox.html.erb | 36 + .../_show_tags_by_alpha.html.erb | 9 + .../_show_tags_in_single_list.html.erb | 12 + .../_tag_set_association_fields.html.erb | 18 + .../_tag_set_associations_remove.html.erb | 12 + .../owned_tag_sets/_tag_set_blurb.html.erb | 49 + .../owned_tag_sets/_tag_set_form.html.erb | 73 + .../_tag_set_form_management.html.erb | 63 + app/views/owned_tag_sets/batch_load.html.erb | 30 + .../owned_tag_sets/confirm_delete.html.erb | 12 + app/views/owned_tag_sets/edit.html.erb | 7 + app/views/owned_tag_sets/index.html.erb | 54 + app/views/owned_tag_sets/new.html.erb | 6 + app/views/owned_tag_sets/show.html.erb | 65 + .../owned_tag_sets/show_options.html.erb | 24 + app/views/owned_tag_sets/wrangle.html.erb | 4 + app/views/people/_author_blurb.html.erb | 25 + app/views/people/_search_form.html.erb | 27 + app/views/people/index.html.erb | 22 + app/views/people/search.html.erb | 19 + .../_potential_match_settings_form.html.erb | 52 + .../_assignment_with_request.html.erb | 36 + .../potential_matches/_assignments.html.erb | 32 + .../potential_matches/_in_progress.html.erb | 16 + .../_invalid_signups.html.erb | 15 + .../_match_navigation.html.erb | 29 + .../_no_match_required.html.erb | 8 + .../_no_potential_givers.html.erb | 30 + .../_no_potential_recipients.html.erb | 24 + .../_potential_matches.html.erb | 71 + app/views/potential_matches/index.html.erb | 46 + .../list_potential_matches.html.erb | 0 app/views/potential_matches/show.html.erb | 31 + app/views/preferences/index.html.erb | 156 + app/views/profile/pseuds.js.erb | 2 + app/views/profile/show.html.erb | 46 + .../_prompt_restriction_form.html.erb | 90 + app/views/prompts/_prompt_blurb.html.erb | 96 + app/views/prompts/_prompt_controls.html.erb | 56 + app/views/prompts/_prompt_form.html.erb | 114 + .../prompts/_prompt_form_tag_options.html.erb | 117 + app/views/prompts/_prompt_navigation.html.erb | 10 + app/views/prompts/edit.html.erb | 18 + app/views/prompts/index.html.erb | 9 + app/views/prompts/new.html.erb | 16 + app/views/prompts/show.html.erb | 13 + app/views/pseuds/_byline.html.erb | 90 + app/views/pseuds/_pseud_blurb.html.erb | 45 + app/views/pseuds/_pseud_module.html.erb | 22 + app/views/pseuds/_pseuds_form.html.erb | 72 + app/views/pseuds/delete_preview.html.erb | 26 + app/views/pseuds/edit.html.erb | 18 + app/views/pseuds/index.html.erb | 26 + app/views/pseuds/new.html.erb | 14 + app/views/pseuds/show.html.erb | 14 + app/views/questions/manage.html.erb | 41 + app/views/readings/_reading_blurb.html.erb | 64 + app/views/readings/index.html.erb | 40 + app/views/redirect/show.html.erb | 18 + app/views/related_works/_approve.html.erb | 18 + app/views/related_works/_remove.html.erb | 18 + app/views/related_works/index.html.erb | 156 + app/views/related_works/show.html.erb | 13 + app/views/series/_series_blurb.html.erb | 7 + app/views/series/_series_module.html.erb | 52 + app/views/series/_series_navigation.html.erb | 22 + app/views/series/_series_order.html.erb | 35 + app/views/series/confirm_delete.html.erb | 11 + app/views/series/edit.html.erb | 82 + app/views/series/index.html.erb | 28 + app/views/series/manage.html.erb | 10 + app/views/series/new.html.erb | 22 + app/views/series/show.html.erb | 102 + app/views/share/_embed_link_bookmark.html.erb | 4 + app/views/share/_embed_link_header.html.erb | 10 + app/views/share/_embed_link_work.html.erb | 2 + app/views/share/_embed_meta.html.erb | 19 + app/views/share/_embed_meta_bookmark.erb | 10 + app/views/share/_share.html.erb | 29 + app/views/shared/_search_nav.html.erb | 6 + app/views/skins/_form.html.erb | 99 + app/views/skins/_header.html.erb | 42 + app/views/skins/_revert_skin_form.html.erb | 10 + app/views/skins/_skin_actions.html.erb | 25 + app/views/skins/_skin_module.html.erb | 28 + app/views/skins/_skin_navigation.html.erb | 36 + app/views/skins/_skin_parent_fields.html.erb | 11 + app/views/skins/_skin_style_block.html.erb | 4 + .../skins/_skin_type_navigation.html.erb | 14 + app/views/skins/_update_skin_form.html.erb | 10 + app/views/skins/_wizard_form.html.erb | 132 + app/views/skins/confirm_delete.html.erb | 13 + app/views/skins/edit.html.erb | 17 + app/views/skins/index.html.erb | 33 + app/views/skins/new.html.erb | 21 + app/views/skins/new_wizard.html.erb | 22 + app/views/skins/show.html.erb | 94 + app/views/stats/_navigation.html.erb | 4 + app/views/stats/index.html.erb | 105 + app/views/stats/no_stats.html.erb | 3 + app/views/statuses/edit.html.erb | 42 + app/views/statuses/index.html.erb | 34 + app/views/statuses/new.html.erb | 42 + app/views/statuses/show.html.erb | 23 + app/views/statuses/timeline.html.erb | 29 + app/views/subscriptions/_form.html.erb | 14 + .../subscriptions/confirm_delete_all.erb | 23 + app/views/subscriptions/index.html.erb | 76 + app/views/tag_set_associations/index.html.erb | 48 + .../_nomination_form.html.erb | 70 + .../tag_set_nominations/_review.html.erb | 78 + .../tag_set_nominations/_review_cast.html.erb | 25 + .../_review_fandoms.html.erb | 20 + .../_review_individual_nom.html.erb | 41 + .../_review_thead.html.erb | 10 + .../_show_by_tag_type.html.erb | 16 + .../_show_tag_status.html.erb | 2 + .../_tag_nominations.html.erb | 31 + .../_tag_nominations_by_fandom.html.erb | 39 + .../confirm_delete.html.erb | 12 + .../confirm_destroy_multiple.html.erb | 12 + app/views/tag_set_nominations/edit.html.erb | 18 + app/views/tag_set_nominations/index.html.erb | 11 + app/views/tag_set_nominations/new.html.erb | 1 + app/views/tag_set_nominations/show.html.erb | 104 + app/views/tag_wranglers/index.html.erb | 101 + app/views/tag_wranglers/show.html.erb | 70 + ...gler_username_change_notification.html.erb | 10 + ...gler_username_change_notification.text.erb | 8 + .../_wrangler_dashboard.html.erb | 62 + app/views/tag_wranglings/index.html.erb | 159 + app/views/tags/_search_form.html.erb | 85 + app/views/tags/edit.html.erb | 235 + app/views/tags/feed.atom.builder | 17 + app/views/tags/index.html.erb | 48 + app/views/tags/new.html.erb | 47 + app/views/tags/search.html.erb | 18 + app/views/tags/show.html.erb | 143 + app/views/tags/show_hidden.js.erb | 12 + app/views/tags/wrangle.html.erb | 177 + .../tos_update_notification.html.erb | 16 + .../tos_update_notification.text.erb | 16 + app/views/troubleshooting/show.html.erb | 31 + app/views/unsorted_tags/index.html.erb | 43 + app/views/user_invite_requests/index.html.erb | 43 + app/views/user_invite_requests/new.html.erb | 26 + app/views/user_mailer/_work_info.html.erb | 24 + app/views/user_mailer/_work_info.text.erb | 22 + app/views/user_mailer/abuse_report.html.erb | 38 + app/views/user_mailer/abuse_report.text.erb | 33 + .../admin_deleted_work_notification.html.erb | 11 + .../admin_deleted_work_notification.text.erb | 11 + .../admin_hidden_work_notification.html.erb | 22 + .../admin_hidden_work_notification.text.erb | 20 + .../admin_spam_work_notification.html.erb | 9 + .../admin_spam_work_notification.text.erb | 9 + ...nymous_or_unrevealed_notification.html.erb | 26 + ...nymous_or_unrevealed_notification.text.erb | 26 + ..._added_to_collection_notification.html.erb | 16 + ..._added_to_collection_notification.text.erb | 15 + .../batch_subscription_notification.html.erb | 77 + .../batch_subscription_notification.text.erb | 40 + ...challenge_assignment_notification.html.erb | 93 + ...challenge_assignment_notification.text.erb | 71 + app/views/user_mailer/change_email.html.erb | 14 + app/views/user_mailer/change_email.text.erb | 14 + .../user_mailer/change_username.html.erb | 22 + .../user_mailer/change_username.text.erb | 22 + .../user_mailer/claim_notification.html.erb | 41 + .../user_mailer/claim_notification.text.erb | 34 + .../collection_notification.html.erb | 12 + .../collection_notification.text.erb | 8 + .../creatorship_notification.html.erb | 26 + .../creatorship_notification.text.erb | 16 + ...reatorship_notification_archivist.html.erb | 27 + ...reatorship_notification_archivist.text.erb | 18 + .../user_mailer/creatorship_request.html.erb | 20 + .../user_mailer/creatorship_request.text.erb | 14 + .../delete_signup_notification.text.erb | 0 .../delete_work_notification.html.erb | 10 + .../delete_work_notification.text.erb | 13 + app/views/user_mailer/feedback.html.erb | 24 + app/views/user_mailer/feedback.text.erb | 24 + .../invalid_signup_notification.html.erb | 19 + .../invalid_signup_notification.text.erb | 16 + app/views/user_mailer/invitation.html.erb | 29 + app/views/user_mailer/invitation.text.erb | 17 + .../user_mailer/invitation_to_claim.html.erb | 40 + .../user_mailer/invitation_to_claim.text.erb | 38 + .../invite_increase_notification.html.erb | 10 + .../invite_increase_notification.text.erb | 8 + .../invite_request_declined.html.erb | 10 + .../invite_request_declined.text.erb | 12 + ...nvited_to_collection_notification.html.erb | 10 + ...nvited_to_collection_notification.text.erb | 12 + ...ial_match_generation_notification.html.erb | 13 + ...ial_match_generation_notification.text.erb | 11 + .../prompter_notification.html.erb | 29 + .../prompter_notification.text.erb | 14 + .../recipient_notification.html.erb | 26 + .../recipient_notification.text.erb | 17 + .../related_work_notification.html.erb | 18 + .../related_work_notification.text.erb | 15 + .../user_mailer/signup_notification.html.erb | 12 + .../user_mailer/signup_notification.text.erb | 16 + .../users/_admin_change_username.html.erb | 29 + app/views/users/_contents.html.erb | 144 + .../users/_edit_header_navigation.html.erb | 7 + .../users/_edit_user_navigation.html.erb | 7 + app/views/users/_header.html.erb | 15 + app/views/users/_header_navigation.html.erb | 25 + app/views/users/_sidebar.html.erb | 66 + app/views/users/change_email.html.erb | 47 + app/views/users/change_password.html.erb | 33 + app/views/users/change_username.html.erb | 55 + app/views/users/confirm_change_email.html.erb | 24 + app/views/users/confirmation.html.erb | 21 + app/views/users/delete_confirmation.html.erb | 4 + app/views/users/delete_preview.html.erb | 74 + app/views/users/edit.html.erb | 48 + app/views/users/end_banner.js.erb | 1 + app/views/users/end_first_login.js.erb | 2 + .../mailer/confirmation_instructions.html.erb | 11 + .../mailer/confirmation_instructions.text.erb | 11 + .../users/mailer/password_change.html.erb | 15 + .../users/mailer/password_change.text.erb | 15 + .../reset_password_instructions.html.erb | 7 + .../reset_password_instructions.text.erb | 12 + app/views/users/passwords/edit.html.erb | 28 + app/views/users/passwords/new.html.erb | 15 + app/views/users/registrations/_legal.html.erb | 33 + .../users/registrations/_passwd.html.erb | 44 + app/views/users/registrations/new.html.erb | 29 + app/views/users/sessions/_greeting.html.erb | 60 + app/views/users/sessions/_login.html.erb | 3 + app/views/users/sessions/_passwd.html.erb | 14 + .../users/sessions/_passwd_small.html.erb | 29 + .../users/sessions/confirm_logout.html.erb | 8 + app/views/users/sessions/new.html.erb | 43 + app/views/users/show.html.erb | 37 + app/views/works/_adult.html.erb | 29 + app/views/works/_collection_filters.html.erb | 57 + app/views/works/_filters.html.erb | 199 + app/views/works/_hidden_fields.html.erb | 55 + app/views/works/_meta.html.erb | 117 + app/views/works/_mystery_blurb.html.erb | 11 + app/views/works/_notes_form.html.erb | 40 + app/views/works/_search_box.html.erb | 10 + app/views/works/_search_form.html.erb | 212 + app/views/works/_standard_form.html.erb | 378 + .../works/_work_abbreviated_list.html.erb | 17 + .../works/_work_approved_children.html.erb | 15 + app/views/works/_work_blurb.html.erb | 22 + app/views/works/_work_endnotes.html.erb | 6 + .../_work_form_associations_language.html.erb | 11 + app/views/works/_work_form_pseuds.html.erb | 23 + app/views/works/_work_form_tags.html.erb | 120 + app/views/works/_work_header.html.erb | 55 + .../works/_work_header_navigation.html.erb | 122 + app/views/works/_work_header_notes.html.erb | 79 + app/views/works/_work_module.html.erb | 121 + app/views/works/_work_series_links.html.erb | 10 + app/views/works/_work_unrevealed_notice.erb | 12 + app/views/works/collected.html.erb | 43 + app/views/works/confirm_delete.html.erb | 19 + .../works/confirm_delete_multiple.html.erb | 26 + app/views/works/drafts.html.erb | 24 + app/views/works/edit.html.erb | 36 + app/views/works/edit_multiple.html.erb | 105 + app/views/works/edit_tags.html.erb | 46 + app/views/works/import.html.erb | 19 + app/views/works/index.html.erb | 65 + app/views/works/navigate.html.erb | 8 + app/views/works/new.html.erb | 24 + app/views/works/new_import.html.erb | 206 + app/views/works/preview.html.erb | 73 + app/views/works/preview_tags.html.erb | 46 + app/views/works/search.html.erb | 11 + app/views/works/search_results.html.erb | 36 + app/views/works/share.html.erb | 1 + app/views/works/show.html.erb | 76 + app/views/works/show_multiple.html.erb | 67 + .../_admin_index.html.erb | 29 + .../_wrangling_guideline_form.html.erb | 43 + .../_wrangling_guideline_order.html.erb | 33 + app/views/wrangling_guidelines/edit.html.erb | 11 + app/views/wrangling_guidelines/index.html.erb | 19 + .../wrangling_guidelines/manage.html.erb | 11 + app/views/wrangling_guidelines/new.html.erb | 11 + app/views/wrangling_guidelines/show.html.erb | 22 + bin/brakeman | 7 + bin/bundle | 3 + bin/rails | 4 + bin/rake | 4 + bin/reload_elastic | 8 + bin/rubocop | 8 + bin/setup | 37 + bin/update | 29 + config.ru | 17 + config/application.rb | 153 + config/boot.rb | 3 + config/brakeman.yml | 4 + config/cable.yml | 10 + config/config.yml | 773 + config/cucumber.yml | 11 + config/database.example | 45 + config/deploy.rb | 140 + config/deploy/production.rb | 56 + config/deploy/staging.rb | 41 + config/docker/Dockerfile | 24 + config/docker/local.yml | 2 + config/docker/redis.yml | 18 + config/environment.rb | 5 + config/environments/production.rb | 119 + config/environments/staging.rb | 80 + config/environments/test.rb | 74 + config/gh-actions/database.yml | 11 + config/gh-actions/local.yml | 2 + config/gh-actions/redis.yml | 12 + config/i18n-tasks.yml | 277 + .../active_record_log_subscriber.rb | 16 + .../initializers/active_record_query_trace.rb | 5 + .../active_record_schema_ignore_tables.rb | 4 + .../application_controller_renderer.rb | 8 + config/initializers/archive_config/locale.rb | 16 + .../archive_config/settings_for_admin.rb | 8 + config/initializers/assets.rb | 7 + config/initializers/backtrace_silencers.rb | 8 + .../initializers/content_security_policy.rb | 25 + config/initializers/cookies_serializer.rb | 5 + config/initializers/cors.rb | 16 + config/initializers/departure.rb | 10 + config/initializers/devise.rb | 272 + .../initializers/filter_parameter_logging.rb | 13 + .../gem-plugin_config/acts_as_commentable.rb | 3 + .../gem-plugin_config/elasticsearch.rb | 1 + .../gem-plugin_config/escape_utils_config.rb | 16 + config/initializers/gem-plugin_config/pagy.rb | 10 + .../gem-plugin_config/permit_yo_config.rb | 34 + .../initializers/gem-plugin_config/redis.rb | 35 + .../initializers/gem-plugin_config/resque.rb | 14 + .../gem-plugin_config/sanitizer_config.rb | 71 + .../initializers/gem-plugin_config/webmock.rb | 6 + .../gem-plugin_config/will_paginate_config.rb | 2 + config/initializers/inflections.rb | 17 + config/initializers/mime_types.rb | 9 + .../initializers/monkeypatches/akismetor.rb | 10 + .../monkeypatches/deliver_after_commit.rb | 9 + .../monkeypatches/fix_phraseapp.rb | 16 + .../monkeypatches/mailers_controller.rb | 11 + .../override_default_form_field_sizes.rb | 24 + .../textarea_convert_html_to_newlines.rb | 51 + .../monkeypatches/translate_string.rb | 78 + config/initializers/permissions_policy.rb | 13 + .../phraseapp_in_context_editor.rb | 31 + config/initializers/rack_attack.rb | 127 + config/initializers/rollout_init.rb | 1 + config/initializers/sentry.rb | 29 + config/initializers/session_store.rb | 18 + config/initializers/wrap_parameters.rb | 14 + config/locales/README.md | 17 + config/locales/controllers/en.yml | 283 + config/locales/devise/en.yml | 73 + config/locales/helpers/en.yml | 54 + config/locales/mailers/en.yml | 700 + config/locales/mailers/en.yml.save | 678 + config/locales/models/en.yml | 293 + config/locales/phrase-exports/README.md | 1 + config/locales/phrase-exports/af.yml | 6 + config/locales/phrase-exports/ar.yml | 547 + config/locales/phrase-exports/bg.yml | 527 + config/locales/phrase-exports/bn.yml | 518 + config/locales/phrase-exports/ca.yml | 628 + config/locales/phrase-exports/cs.yml | 632 + config/locales/phrase-exports/cy.yml | 672 + config/locales/phrase-exports/da.yml | 616 + config/locales/phrase-exports/de.yml | 644 + config/locales/phrase-exports/el.yml | 663 + config/locales/phrase-exports/es.yml | 623 + config/locales/phrase-exports/fa.yml | 533 + config/locales/phrase-exports/fi.yml | 598 + config/locales/phrase-exports/fil.yml | 2 + config/locales/phrase-exports/fr.yml | 672 + config/locales/phrase-exports/he.yml | 471 + config/locales/phrase-exports/hi.yml | 532 + config/locales/phrase-exports/hr.yml | 631 + config/locales/phrase-exports/hu.yml | 534 + config/locales/phrase-exports/id.yml | 630 + config/locales/phrase-exports/it.yml | 662 + config/locales/phrase-exports/ja.yml | 404 + config/locales/phrase-exports/ko.yml | 490 + config/locales/phrase-exports/lt.yml | 2 + config/locales/phrase-exports/lv.yml | 288 + config/locales/phrase-exports/mk.yml | 2 + config/locales/phrase-exports/mr.yml | 533 + config/locales/phrase-exports/ms.yml | 615 + config/locales/phrase-exports/nb.yml | 620 + config/locales/phrase-exports/nl.yml | 563 + config/locales/phrase-exports/pl.yml | 554 + config/locales/phrase-exports/pt-BR.yml | 1197 ++ config/locales/phrase-exports/pt-PT.yml | 539 + config/locales/phrase-exports/ro.yml | 672 + config/locales/phrase-exports/ru.yml | 640 + config/locales/phrase-exports/scr.yml | 518 + config/locales/phrase-exports/sk.yml | 2 + config/locales/phrase-exports/sl.yml | 647 + config/locales/phrase-exports/sv.yml | 617 + config/locales/phrase-exports/th.yml | 459 + config/locales/phrase-exports/tr.yml | 520 + config/locales/phrase-exports/uk.yml | 667 + config/locales/phrase-exports/vi.yml | 613 + config/locales/phrase-exports/zh-CN.yml | 360 + config/locales/rails-i18n/locale/fil.yml | 202 + config/locales/rails-i18n/locale/mr.yml | 207 + .../locales/rails-i18n/pluralization/fil.rb | 3 + config/locales/rails-i18n/pluralization/hr.rb | 41 + config/locales/rails-i18n/pluralization/mr.rb | 3 + config/locales/validators/en.yml | 8 + config/locales/views/en.yml | 2565 +++ config/locales/views/ru.yml | 6 + config/locales/views/uk.yml | 6 + config/locales/views/zh-CN.yml | 6 + config/redis-cucumber.conf.example | 14 + config/redis.example | 24 + config/resque_schedule.yml | 117 + config/routes.rb | 718 + config/s3.example | 4 + config/schedule.rb | 65 + config/schedule_production.rb | 16 + config/servers.yml | 76 + config/storage.yml | 17 + docker-compose-example.yml | 106 + entrypoints/sc-entrypoint.sh | 11 + entrypoints/worker-entrypoint.sh | 11 + factories/abuse_reports.rb | 10 + factories/admin.rb | 36 + factories/admin_banner.rb | 13 + factories/admin_blacklisted_email.rb | 7 + factories/admin_post.rb | 10 + factories/api_key.rb | 8 + factories/archive_faqs.rb | 18 + factories/bookmarks.rb | 19 + factories/challenge_claims.rb | 5 + factories/challenges.rb | 54 + factories/chapters.rb | 24 + factories/collections.rb | 60 + factories/comments.rb | 37 + factories/fannish_next_of_kin.rb | 9 + factories/favorite_tags.rb | 8 + factories/feedback.rb | 10 + factories/gift.rb | 10 + factories/invitations.rb | 13 + factories/known_issues.rb | 8 + factories/kudos.rb | 6 + factories/language.rb | 8 + factories/last_wrangling_activity.rb | 7 + factories/locales.rb | 17 + factories/prompt.rb | 11 + factories/prompt_restriction.rb | 6 + factories/pseuds.rb | 8 + factories/readings.rb | 14 + factories/related_works.rb | 9 + factories/serial_work.rb | 7 + factories/series.rb | 27 + factories/skins.rb | 30 + factories/subscriptions.rb | 10 + factories/tags.rb | 143 + factories/user_invite_requests.rb | 10 + factories/users.rb | 52 + factories/work_original_creators.rb | 6 + factories/works.rb | 67 + factories/wrangling_assignments.rb | 8 + factories/wrangling_guideline.rb | 17 + features/admins/admin_email_blacklist.feature | 95 + features/admins/admin_invitations.feature | 520 + features/admins/admin_languages.feature | 52 + features/admins/admin_locales.feature | 25 + features/admins/admin_post_faqs.feature | 198 + features/admins/admin_post_issues.feature | 53 + features/admins/admin_post_news.feature | 279 + features/admins/admin_reorder_faq.feature | 19 + .../admin_reorder_faq_questions.feature | 28 + features/admins/admin_settings.feature | 169 + features/admins/admin_skins.feature | 151 + features/admins/admin_spam.feature | 74 + features/admins/admin_tasks.feature | 12 + features/admins/admin_works.feature | 641 + features/admins/authenticate_admins.feature | 163 + .../admins/users/admin_abuse_users.feature | 242 + .../admins/users/admin_find_users.feature | 160 + features/admins/users/admin_fnok.feature | 124 + .../admins/users/admin_manage_users.feature | 130 + features/bookmarks/bookmark_browse.feature | 25 + features/bookmarks/bookmark_create.feature | 460 + features/bookmarks/bookmark_external.feature | 212 + features/bookmarks/bookmark_filter.feature | 19 + features/bookmarks/bookmark_indexing.feature | 167 + features/bookmarks/bookmark_privacy.feature | 200 + features/bookmarks/bookmark_search.feature | 257 + features/bookmarks/bookmark_share.feature | 48 + .../bookmarks/delete_bookmarkable.feature | 84 + .../collectible_closed_collection.feature | 25 + .../collectible_moderated_collection.feature | 47 + .../collectible_multiple_collections.feature | 59 + .../collectible_open_collection.feature | 89 + .../collections/collection_anonymity.feature | 625 + .../collections/collection_browse.feature | 181 + .../collections/collection_create.feature | 226 + .../collections/collection_dashboard.feature | 81 + .../collections/collection_invite.feature | 107 + .../collections/collection_navigation.feature | 138 + .../collection_notification.feature | 144 + .../collection_participants.feature | 77 + .../comments_and_kudos/add_comment.feature | 316 + .../comments_and_kudos/admin_info.feature | 51 + .../comment_blocking.feature | 113 + .../comment_moderation.feature | 331 + .../comments_adminposts.feature | 142 + .../comments_delete.feature | 96 + .../comments_pagination.feature | 36 + .../comments_redirect.feature | 119 + .../frozen_comments.feature | 47 + .../guest_comment_replies.feature | 70 + .../comments_and_kudos/guest_comments.feature | 45 + .../hidden_comments.feature | 88 + .../comments_and_kudos/hidden_works.feature | 78 + .../image_safety_mode.feature | 68 + features/comments_and_kudos/inbox.feature | 167 + features/comments_and_kudos/kudos.feature | 261 + .../kudos_pagination.feature | 67 + .../official_comments.feature | 34 + .../comments_and_kudos/spam_comments.feature | 196 + features/fixtures/icon.bmp | Bin 0 -> 10650 bytes features/fixtures/icon.gif | Bin 0 -> 2387 bytes features/fixtures/icon.jpg | Bin 0 -> 5865 bytes features/fixtures/icon.png | Bin 0 -> 4311 bytes features/fixtures/skin_test_preview.png | Bin 0 -> 3688 bytes .../challenge_giftexchange.feature | 718 + .../challenge_giftexchange_tagsets.feature | 69 + .../gift_exchanges/challenge_yuletide.feature | 636 + .../notification_emails.feature | 164 + .../gift_exchanges/potential_matches.feature | 360 + .../gift_exchanges/signup_summary.feature | 41 + features/importing/archivist.feature | 392 + .../importing/archivist_creatorships.feature | 83 + features/importing/work_import.feature | 367 + features/importing/work_import_da.feature | 73 + features/importing/work_import_dw.feature | 170 + features/importing/work_import_errors.feature | 26 + features/importing/work_import_ffn.feature | 25 + features/importing/work_import_lj.feature | 172 + features/other_a/abuse_report.feature | 77 + features/other_a/accept_header.feature | 10 + features/other_a/autocomplete.feature | 262 + features/other_a/banner_general.feature | 142 + features/other_a/banner_login.feature | 70 + features/other_a/gift.feature | 458 + features/other_a/help.feature | 42 + features/other_a/hit_counts.feature | 112 + features/other_a/homepage.feature | 34 + features/other_a/invite_queue.feature | 183 + features/other_a/invite_request.feature | 189 + features/other_a/invite_use.feature | 50 + features/other_a/languages.feature | 53 + features/other_a/media.feature | 131 + features/other_a/orphan_account.feature | 69 + features/other_a/orphan_pseud.feature | 104 + features/other_a/orphan_series.feature | 81 + features/other_a/orphan_work.feature | 162 + features/other_a/page_title.feature | 73 + features/other_a/parser.feature | 126 + features/other_a/preferences_edit.feature | 337 + .../other_a/preferences_edit_more.feature | 73 + features/other_a/profile_edit.feature | 229 + features/other_a/pseud_dashboard.feature | 107 + features/other_a/pseud_delete.feature | 209 + features/other_a/pseuds.feature | 330 + .../other_a/pseuds_special_characters.feature | 162 + features/other_a/reading.feature | 303 + features/other_b/errors.feature | 11 + features/other_b/fandoms.feature | 47 + features/other_b/icon.feature | 54 + features/other_b/sanitizer.feature | 66 + features/other_b/series.feature | 346 + features/other_b/series_lock.feature | 67 + features/other_b/series_order.feature | 70 + features/other_b/skin.feature | 352 + features/other_b/skin_public.feature | 120 + features/other_b/skin_wizard.feature | 105 + features/other_b/stats.feature | 89 + features/other_b/subscriptions.feature | 370 + .../other_b/subscriptions_fandoms.feature | 83 + features/other_b/support.feature | 87 + .../challenge_promptmeme_setup.feature | 490 + ...challenge_promptmeme_posting_fills.feature | 561 + .../challenge_promptmeme_springkink.feature | 81 + .../challenge_promptmeme_claims.feature | 456 + .../challenge_promptmeme_deletion.feature | 215 + features/search/exceeding_maximum.feature | 46 + features/search/filters.feature | 354 + features/search/people_search.feature | 130 + features/search/works_anonymous.feature | 59 + features/search/works_collected.feature | 48 + features/search/works_info.feature | 145 + features/search/works_restricted.feature | 47 + features/search/works_stats.feature | 233 + features/search/works_tags.feature | 304 + features/step_definitions/admin_steps.rb | 579 + features/step_definitions/archivist_steps.rb | 103 + .../step_definitions/autocomplete_steps.rb | 256 + features/step_definitions/banner_steps.rb | 158 + features/step_definitions/block_steps.rb | 41 + features/step_definitions/bookmark_steps.rb | 457 + .../challege_gift_exchange_steps.rb | 405 + .../challenge_promptmeme_steps.rb | 557 + features/step_definitions/challenge_steps.rb | 298 + .../challenge_yuletide_steps.rb | 24 + features/step_definitions/collection_steps.rb | 306 + features/step_definitions/comment_steps.rb | 406 + .../step_definitions/email_custom_steps.rb | 139 + features/step_definitions/email_steps.rb | 105 + .../step_definitions/external_work_steps.rb | 101 + features/step_definitions/generic_steps.rb | 306 + features/step_definitions/gift_steps.rb | 43 + features/step_definitions/icon_steps.rb | 61 + features/step_definitions/invite_steps.rb | 192 + features/step_definitions/kudos_steps.rb | 48 + features/step_definitions/mute_steps.rb | 41 + features/step_definitions/orphan_steps.rb | 70 + features/step_definitions/page_title_steps.rb | 11 + features/step_definitions/pickle_steps.rb | 100 + .../step_definitions/potential_match_steps.rb | 182 + .../step_definitions/preferences_steps.rb | 147 + features/step_definitions/profile_steps.rb | 85 + features/step_definitions/pseud_steps.rb | 39 + features/step_definitions/rake_steps.rb | 14 + features/step_definitions/reading_steps.rb | 13 + .../redis_mail_queue_steps.rb | 15 + .../step_definitions/request_header_steps.rb | 14 + features/step_definitions/search_steps.rb | 31 + features/step_definitions/series_steps.rb | 156 + features/step_definitions/share_steps.rb | 6 + features/step_definitions/skin_steps.rb | 282 + .../step_definitions/subscription_steps.rb | 34 + features/step_definitions/support_steps.rb | 18 + features/step_definitions/tag_set_steps.rb | 241 + features/step_definitions/tag_steps.rb | 492 + features/step_definitions/user_steps.rb | 351 + features/step_definitions/web_steps.rb | 289 + .../step_definitions/work_deletion_steps.rb | 11 + .../step_definitions/work_download_steps.rb | 37 + .../step_definitions/work_import_steps.rb | 136 + .../step_definitions/work_related_steps.rb | 206 + .../step_definitions/work_search_steps.rb | 514 + features/step_definitions/work_steps.rb | 813 + features/support/capybara.rb | 78 + features/support/elapsed_time.rb | 6 + features/support/email.rb | 25 + features/support/env.rb | 76 + features/support/formatter.rb | 51 + features/support/hooks.rb | 79 + features/support/minitest.rb | 3 + features/support/paths.rb | 311 + features/support/pickle.rb | 26 + features/support/user.rb | 33 + features/support/vcr.rb | 46 + features/support/wait_for_ajax.rb | 11 + features/support/webmock.rb | 1 + features/tag_sets/tag_set.feature | 175 + .../tag_sets/tag_set_associations.feature | 123 + features/tag_sets/tag_set_batch_load.feature | 67 + features/tag_sets/tag_set_delete.feature | 17 + features/tag_sets/tag_set_nominations.feature | 340 + .../brand_new_fandoms.feature | 114 + .../tags_and_wrangling/favorite_tags.feature | 39 + features/tags_and_wrangling/tag_cloud.feature | 110 + .../tags_and_wrangling/tag_comment.feature | 216 + .../tags_and_wrangling/tag_search.feature | 250 + .../tags_and_wrangling/tag_wrangling.feature | 383 + .../tag_wrangling_admin.feature | 172 + .../tag_wrangling_characters.feature | 168 + .../tag_wrangling_fandoms.feature | 215 + .../tag_wrangling_freeforms.feature | 130 + .../tag_wrangling_media.feature | 208 + .../tag_wrangling_more.feature | 396 + .../tag_wrangling_relationships.feature | 277 + .../tag_wrangling_special.feature | 182 + .../tag_wrangling_unsorted.feature | 106 + .../wrangling_guidelines.feature | 52 + features/users/authenticate_users.feature | 337 + features/users/blocking.feature | 137 + features/users/muting.feature | 154 + features/users/password_compatibility.feature | 39 + features/users/suspensions.feature | 17 + features/users/user_create.feature | 86 + features/users/user_dashboard.feature | 275 + features/users/user_delete.feature | 119 + features/users/user_rename.feature | 293 + features/works/chapter_edit.feature | 620 + features/works/work_browse.feature | 186 + features/works/work_create.feature | 427 + features/works/work_dates_edit.feature | 85 + features/works/work_delete.feature | 214 + features/works/work_download.feature | 422 + features/works/work_drafts.feature | 189 + features/works/work_edit.feature | 320 + features/works/work_edit_multiple.feature | 271 + features/works/work_edit_tags.feature | 86 + features/works/work_languages.feature | 58 + features/works/work_lock.feature | 91 + features/works/work_notes.feature | 25 + features/works/work_related.feature | 786 + features/works/work_share.feature | 85 + features/works/work_view.feature | 82 + lib/ EXAMPLE_MODULE.rb.example | 23 + lib/acts_as_commentable/comment_methods.rb | 150 + lib/acts_as_commentable/commentable.rb | 17 + lib/acts_as_commentable/commentable_entity.rb | 100 + lib/autocomplete_source.rb | 323 + ...backwards_compatible_password_decryptor.rb | 45 + lib/bookmark_count_caching.rb | 15 + lib/bookmarkable.rb | 28 + lib/challenge_core.rb | 102 + lib/collectible.rb | 150 + lib/creation_notifier.rb | 102 + lib/css_cleaner.rb | 289 + lib/devise_failure_message_options.rb | 21 + lib/html_cleaner.rb | 160 + lib/otw_sanitize/embed_sanitizer.rb | 205 + lib/otw_sanitize/media_sanitizer.rb | 126 + lib/otw_sanitize/user_class_sanitizer.rb | 47 + lib/pagination_list_link_renderer.rb | 62 + lib/paragraph_maker.rb | 280 + lib/redis_scanning.rb | 11 + lib/redis_test_setup.rb | 20 + lib/responder.rb | 21 + lib/searchable.rb | 65 + lib/skin_wizard.rb | 367 + lib/sortable_list.rb | 14 + lib/string_cleaner.rb | 12 + lib/tasks/admin_tasks.rake | 32 + lib/tasks/after_tasks.rake | 583 + lib/tasks/creatorships.rake | 44 + lib/tasks/cucumber.rake | 76 + lib/tasks/database_seed.rake | 21 + lib/tasks/defaults.rake | 8 + lib/tasks/deploy_tasks.rake | 16 + lib/tasks/language_tasks.rake | 19 + lib/tasks/load_autocomplete_data.rake | 122 + lib/tasks/memcached.rake | 15 + lib/tasks/notifications.rake | 31 + lib/tasks/opendoors.rake | 44 + lib/tasks/resanitize.rake | 40 + lib/tasks/resque.rake | 58 + lib/tasks/search.rake | 119 + lib/tasks/skin_tasks.rake | 193 + lib/tasks/spam_report.rake | 7 + lib/tasks/tag_tasks.rake | 178 + lib/tasks/work_tasks.rake | 55 + lib/url_formatter.rb | 67 + lib/word_counter.rb | 37 + lib/work_chapter_count_caching.rb | 15 + lib/works_owner.rb | 52 + lib/zoho_auth_client.rb | 50 + lib/zoho_resource_client.rb | 96 + multi-master.info | 0 node.lock | 0 nodes | 1 + public/.htaccess | 40 + public/403.html | 150 + public/406-unsupported-browser.html | 149 + public/445.html | 149 + public/500.html | 150 + public/502.html | 152 + public/503.html | 151 + public/507.html | 151 + public/OTW_Membership_Donation_Form.pdf | Bin 0 -> 89154 bytes .../apple-touch-icon-114x114-precomposed.png | Bin 0 -> 4750 bytes public/apple-touch-icon-114x114.png | Bin 0 -> 4750 bytes .../apple-touch-icon-120x120-precomposed.png | Bin 0 -> 4928 bytes public/apple-touch-icon-120x120.png | Bin 0 -> 2039 bytes .../apple-touch-icon-144x144-precomposed.png | Bin 0 -> 6048 bytes public/apple-touch-icon-144x144.png | Bin 0 -> 2465 bytes .../apple-touch-icon-152x152-precomposed.png | Bin 0 -> 6459 bytes public/apple-touch-icon-152x152.png | Bin 0 -> 2596 bytes .../apple-touch-icon-167x167-precomposed.png | Bin 0 -> 7071 bytes .../apple-touch-icon-180x180-precomposed.png | Bin 0 -> 8144 bytes public/apple-touch-icon-180x180.png | Bin 0 -> 3302 bytes public/apple-touch-icon-57x57-precomposed.png | Bin 0 -> 2103 bytes public/apple-touch-icon-57x57.png | Bin 0 -> 2103 bytes public/apple-touch-icon-72x72-precomposed.png | Bin 0 -> 3771 bytes public/apple-touch-icon-72x72.png | Bin 0 -> 3771 bytes public/apple-touch-icon-76x76-precomposed.png | Bin 0 -> 2925 bytes public/apple-touch-icon-76x76.png | Bin 0 -> 1442 bytes public/apple-touch-icon-precomposed.png | Bin 0 -> 6048 bytes public/apple-touch-icon.png | Bin 0 -> 2465 bytes public/apple-touch-icon120x120.png | Bin 0 -> 2039 bytes public/apple-touch-icon152x152.png | Bin 0 -> 2596 bytes public/apple-touch-icon76x76.png | Bin 0 -> 1442 bytes public/dispatch.cgi | 10 + public/dispatch.fcgi | 24 + public/dispatch.rb | 10 + public/favicon.ico | Bin 0 -> 15406 bytes .../help/add-collectible-to-collection.html | 18 + public/help/add-work-to-assignment.html | 15 + public/help/additional-tags-help.html | 6 + public/help/backdating-help.html | 16 + .../help/bookmark-filters-exclude-tags.html | 25 + .../help/bookmark-filters-include-tags.html | 29 + .../help/bookmark-search-bookmarker-tag.html | 5 + .../bookmark-search-date-bookmarked-help.html | 18 + .../bookmark-search-date-updated-help.html | 18 + public/help/bookmark-search-notes-help.html | 3 + public/help/bookmark-search-rec-help.html | 3 + public/help/bookmark-search-results-help.html | 3 + public/help/bookmark-search-text-help.html | 18 + public/help/bookmark-search-type-help.html | 7 + public/help/bookmark-search-work-tag.html | 5 + public/help/bookmark-symbols-key.html | 11 + public/help/categories-help.html | 21 + public/help/challenge-any.html | 28 + public/help/challenge-assignments.html | 32 + public/help/challenge-category-tags.html | 64 + .../help/challenge-include-optional-tags.html | 28 + .../help/challenge-matching-assignments.html | 89 + public/help/challenge-matching.html | 26 + public/help/challenge-optional-tags-user.html | 8 + public/help/challenge-optional-tags.html | 18 + public/help/challenge-pinch-hitter.html | 6 + public/help/challenge-requests-summary.html | 8 + public/help/chapter-title.html | 3 + public/help/characters-help.html | 6 + public/help/choosing-series.html | 11 + public/help/collection-closed.html | 7 + public/help/collection-moderated.html | 18 + public/help/collection-name.html | 9 + public/help/collection-preferences.html | 32 + public/help/comment-preferences.html | 14 + public/help/comments-moderated.html | 2 + public/help/csv-download.html | 1 + public/help/display-preferences.html | 24 + public/help/encoding-help.html | 6 + public/help/fandom-help.html | 5 + public/help/fr/choosing-series.html | 5 + public/help/html-help.html | 87 + public/help/icon-alt-text.html | 10 + public/help/languages-help.html | 4 + public/help/locale-preferences.html | 8 + public/help/misc-preferences.html | 13 + public/help/parent-works-help.html | 10 + public/help/people-search-all-fields.html | 20 + public/help/privacy-preferences.html | 41 + ...estriction-character-and-relationship.html | 48 + public/help/prompt-restriction-tag-set.html | 26 + public/help/pseud-icon-comment.html | 1 + public/help/rating-help.html | 26 + public/help/recipients.html | 10 + public/help/registered-users.html | 6 + public/help/relationships-help.html | 11 + public/help/required-field.html | 3 + public/help/rte-help.html | 48 + public/help/skins-approval.html | 11 + public/help/skins-basics.html | 14 + public/help/skins-conditions.html | 92 + public/help/skins-creating.html | 204 + public/help/skins-parents.html | 25 + public/help/skins-wizard-accent-color.html | 2 + public/help/skins-wizard-font-size.html | 2 + public/help/skins-wizard-font.html | 3 + public/help/skins-wizard-vertical-gap.html | 3 + public/help/symbols-key.html | 65 + public/help/tag-search-results-help.html | 5 + public/help/tag-search-text-help.html | 43 + public/help/tagset-about.html | 32 + public/help/tagset-batch-load.html | 24 + public/help/tagset-fandom-for-child.html | 7 + public/help/tagset-nominated-tags.html | 13 + public/help/tagset-tag-associations.html | 18 + public/help/translation-link.html | 7 + public/help/warning-help.html | 72 + public/help/who-can-comment-on-this-work.html | 10 + public/help/work-filters-exclude-tags.html | 25 + public/help/work-filters-include-tags.html | 29 + public/help/work-import.html | 45 + public/help/work-search-crossover-help.html | 9 + public/help/work-search-date-help.html | 27 + public/help/work-search-language-help.html | 3 + public/help/work-search-numerical-help.html | 14 + public/help/work-search-results-help.html | 3 + public/help/work-search-tags-help.html | 41 + public/help/work-search-text-help.html | 36 + public/help/work-skins.html | 41 + public/help/work_title_format.html | 15 + public/images/OTWLogo.png | Bin 0 -> 5747 bytes public/images/ao3_logos/ao3-502.png | Bin 0 -> 37560 bytes .../ao3_logos/logo-glitter-hat-noisemaker.gif | Bin 0 -> 47051 bytes public/images/ao3_logos/logo-rails3.png | Bin 0 -> 8601 bytes public/images/ao3_logos/logo-ruby.png | Bin 0 -> 33700 bytes public/images/ao3_logos/logo-stroke.png | Bin 0 -> 5936 bytes public/images/ao3_logos/logo.png | Bin 0 -> 116074 bytes public/images/ao3_logos/logo_42.png | Bin 0 -> 116074 bytes public/images/ao3_logos/sadface.png | Bin 0 -> 16618 bytes public/images/arrow-down.gif | Bin 0 -> 454 bytes public/images/arrow-down.png | Bin 0 -> 112 bytes public/images/arrow-right.gif | Bin 0 -> 70 bytes public/images/arrow-right.png | Bin 0 -> 112 bytes public/images/arrow-up.gif | Bin 0 -> 454 bytes public/images/arrow-up.png | Bin 0 -> 110 bytes public/images/beta-flag.png | Bin 0 -> 4078 bytes public/images/envelope_icon.gif | Bin 0 -> 259 bytes public/images/feed-icon-14x14.png | Bin 0 -> 661 bytes public/images/imageset.png | Bin 0 -> 93690 bytes public/images/indicator.gif | Bin 0 -> 3897 bytes public/images/key-square-1.png | Bin 0 -> 2140 bytes public/images/key-square-2.png | Bin 0 -> 2121 bytes public/images/key-square-3.png | Bin 0 -> 2079 bytes public/images/key-square-4.png | Bin 0 -> 2075 bytes public/images/legacy/beta-flag-legacy.png | Bin 0 -> 10817 bytes public/images/legacy/button-gradient.png | Bin 0 -> 178 bytes public/images/legacy/ccc-fff.png | Bin 0 -> 128 bytes public/images/legacy/drop-shadow-light.gif | Bin 0 -> 7047 bytes public/images/legacy/fffef9-ccc.png | Bin 0 -> 139 bytes public/images/legacy/header-red.png | Bin 0 -> 1035 bytes public/images/legacy/headergradient.png | Bin 0 -> 209 bytes public/images/legacy/kudos-legacy.png | Bin 0 -> 116074 bytes public/images/legacy/login-gradient-2.png | Bin 0 -> 172 bytes public/images/legacy/logo-stroke-legacy.gif | Bin 0 -> 4216 bytes public/images/legacy/openid.png | Bin 0 -> 723 bytes public/images/lockblack.png | Bin 0 -> 2965 bytes public/images/lockblue.png | Bin 0 -> 2951 bytes public/images/lockred.png | Bin 0 -> 2951 bytes public/images/logo-stroke.png | Bin 0 -> 5936 bytes public/images/logo.png | Bin 0 -> 116074 bytes public/images/logo_42.png | Bin 0 -> 116074 bytes public/images/mailer/logo.png | Bin 0 -> 116074 bytes public/images/mailer/mailer-banner-corner.gif | Bin 0 -> 1226 bytes public/images/mailer/mailer-logo-bottom.gif | Bin 0 -> 3722 bytes .../iconsets/default/bookmark-hidden.png | Bin 0 -> 801 bytes .../iconsets/default/bookmark-private.png | Bin 0 -> 554 bytes .../iconsets/default/bookmark-public.png | Bin 0 -> 708 bytes .../skins/iconsets/default/bookmark-rec.png | Bin 0 -> 804 bytes .../iconsets/default/category-femslash.png | Bin 0 -> 1231 bytes .../skins/iconsets/default/category-gen.png | Bin 0 -> 1188 bytes .../skins/iconsets/default/category-het.png | Bin 0 -> 1130 bytes .../skins/iconsets/default/category-multi.png | Bin 0 -> 415 bytes .../skins/iconsets/default/category-none.png | Bin 0 -> 246 bytes .../skins/iconsets/default/category-other.png | Bin 0 -> 1002 bytes .../skins/iconsets/default/category-slash.png | Bin 0 -> 1050 bytes .../skins/iconsets/default/complete-no.png | Bin 0 -> 1089 bytes .../skins/iconsets/default/complete-yes.png | Bin 0 -> 776 bytes .../skins/iconsets/default/icon-template.png | Bin 0 -> 53082 bytes .../skins/iconsets/default/icon_admin.jpeg | Bin 0 -> 2998 bytes .../iconsets/default/icon_collection-s.png | Bin 0 -> 2796 bytes .../iconsets/default/icon_collection.png | Bin 0 -> 5882 bytes .../skins/iconsets/default/icon_mystery.png | Bin 0 -> 1263 bytes .../skins/iconsets/default/icon_skins.png | Bin 0 -> 4444 bytes .../skins/iconsets/default/icon_tag.png | Bin 0 -> 2779 bytes .../iconsets/default/icon_transparent.gif | Bin 0 -> 156 bytes .../skins/iconsets/default/icon_user.png | Bin 0 -> 4625 bytes .../images/skins/iconsets/default/kudos.png | Bin 0 -> 116074 bytes .../skins/iconsets/default/logo-stroke.png | Bin 0 -> 7439 bytes .../iconsets/default/rating-explicit.png | Bin 0 -> 715 bytes .../default/rating-general-audience.png | Bin 0 -> 954 bytes .../skins/iconsets/default/rating-mature.png | Bin 0 -> 1021 bytes .../iconsets/default/rating-notrated.png | Bin 0 -> 246 bytes .../iconsets/default/rating-teen-orange.png | Bin 0 -> 647 bytes .../skins/iconsets/default/rating-teen.png | Bin 0 -> 643 bytes public/images/skins/iconsets/default/rss.png | Bin 0 -> 1699 bytes .../iconsets/default/warning-choosenotto.png | Bin 0 -> 1164 bytes .../skins/iconsets/default/warning-death.png | Bin 0 -> 586 bytes .../default/warning-external-work.png | Bin 0 -> 1364 bytes .../skins/iconsets/default/warning-no.png | Bin 0 -> 246 bytes .../iconsets/default/warning-underage.png | Bin 0 -> 1321 bytes .../skins/iconsets/default/warning-yes.png | Bin 0 -> 572 bytes .../default_large/bookmark-hidden.png | Bin 0 -> 1037 bytes .../default_large/bookmark-private.png | Bin 0 -> 717 bytes .../default_large/bookmark-public.png | Bin 0 -> 2134 bytes .../iconsets/default_large/bookmark-rec.png | Bin 0 -> 2299 bytes .../default_large/category-femslash.png | Bin 0 -> 1982 bytes .../iconsets/default_large/category-gen.png | Bin 0 -> 2372 bytes .../iconsets/default_large/category-het.png | Bin 0 -> 1754 bytes .../iconsets/default_large/category-multi.png | Bin 0 -> 327 bytes .../iconsets/default_large/category-none.png | Bin 0 -> 199 bytes .../iconsets/default_large/category-other.png | Bin 0 -> 358 bytes .../iconsets/default_large/category-slash.png | Bin 0 -> 1918 bytes .../iconsets/default_large/complete-no.png | Bin 0 -> 2314 bytes .../iconsets/default_large/complete-yes.png | Bin 0 -> 1209 bytes .../iconsets/default_large/external-work.png | Bin 0 -> 3615 bytes .../default_large/icon_collection.png | Bin 0 -> 5882 bytes .../iconsets/default_large/icon_mystery.png | Bin 0 -> 2664 bytes .../skins/iconsets/default_large/icon_tag.png | Bin 0 -> 2779 bytes .../iconsets/default_large/icon_user.png | Bin 0 -> 4625 bytes .../default_large/rating-explicit.png | Bin 0 -> 847 bytes .../default_large/rating-general-audience.png | Bin 0 -> 1503 bytes .../iconsets/default_large/rating-mature.png | Bin 0 -> 1605 bytes .../iconsets/default_large/rating-na.png | Bin 0 -> 2709 bytes .../default_large/rating-notrated.png | Bin 0 -> 199 bytes .../default_large/rating-teen-orange.png | Bin 0 -> 720 bytes .../iconsets/default_large/rating-teen.png | Bin 0 -> 704 bytes .../default_large/warning-choosenotto.png | Bin 0 -> 2709 bytes .../default_large/warning-eschewed.png | Bin 0 -> 1087 bytes .../iconsets/default_large/warning-no.png | Bin 0 -> 199 bytes .../iconsets/default_large/warning-none.png | Bin 0 -> 199 bytes .../iconsets/default_large/warning-yes.png | Bin 0 -> 794 bytes .../iconsets/default_large/warnings-death.png | Bin 0 -> 1367 bytes .../iconsets/default_large/warnings-na.png | Bin 0 -> 1495 bytes .../default_large/warnings-noncon.png | Bin 0 -> 3178 bytes .../default_large/warnings-underage.png | Bin 0 -> 3107 bytes .../default_large/warnings-violence.png | Bin 0 -> 3466 bytes .../skins/iconsets/legacy/bookmark-hidden.png | Bin 0 -> 1037 bytes .../iconsets/legacy/bookmark-private.png | Bin 0 -> 717 bytes .../skins/iconsets/legacy/bookmark-public.png | Bin 0 -> 2134 bytes .../skins/iconsets/legacy/bookmark-rec.png | Bin 0 -> 2299 bytes .../iconsets/legacy/category-femslash-s.png | Bin 0 -> 1231 bytes .../skins/iconsets/legacy/category-gen-s.png | Bin 0 -> 1188 bytes .../skins/iconsets/legacy/category-het-s.png | Bin 0 -> 1130 bytes .../iconsets/legacy/category-multi-s.png | Bin 0 -> 415 bytes .../skins/iconsets/legacy/category-none-s.png | Bin 0 -> 246 bytes .../iconsets/legacy/category-other-s.png | Bin 0 -> 1002 bytes .../iconsets/legacy/category-slash-s.png | Bin 0 -> 1050 bytes .../skins/iconsets/legacy/complete-no-s.png | Bin 0 -> 1089 bytes .../skins/iconsets/legacy/complete-yes-s.png | Bin 0 -> 776 bytes .../skins/iconsets/legacy/icon_admin.jpeg | Bin 0 -> 2998 bytes .../iconsets/legacy/icon_collection-s.png | Bin 0 -> 2726 bytes .../skins/iconsets/legacy/icon_collection.png | Bin 0 -> 5882 bytes .../skins/iconsets/legacy/icon_mystery-s.png | Bin 0 -> 1263 bytes .../skins/iconsets/legacy/icon_mystery.png | Bin 0 -> 2664 bytes .../skins/iconsets/legacy/icon_skins.png | Bin 0 -> 4444 bytes .../images/skins/iconsets/legacy/icon_tag.png | Bin 0 -> 2779 bytes .../skins/iconsets/legacy/icon_user.png | Bin 0 -> 4625 bytes public/images/skins/iconsets/legacy/kudos.png | Bin 0 -> 1517 bytes .../iconsets/legacy/rating-explicit-s.png | Bin 0 -> 715 bytes .../legacy/rating-general-audience-s.png | Bin 0 -> 954 bytes .../skins/iconsets/legacy/rating-mature-s.png | Bin 0 -> 1021 bytes .../iconsets/legacy/rating-notrated-s.png | Bin 0 -> 246 bytes .../iconsets/legacy/rating-teen-orange-s.png | Bin 0 -> 647 bytes .../skins/iconsets/legacy/rating-teen-s.png | Bin 0 -> 643 bytes public/images/skins/iconsets/legacy/rss.png | Bin 0 -> 1699 bytes .../iconsets/legacy/warning-choosenotto-s.png | Bin 0 -> 1164 bytes .../legacy/warning-external-work-s.png | Bin 0 -> 1364 bytes .../skins/iconsets/legacy/warning-no-s.png | Bin 0 -> 246 bytes .../skins/iconsets/legacy/warning-yes-s.png | Bin 0 -> 572 bytes .../iconsets/legacy/warnings-death-s.png | Bin 0 -> 586 bytes .../iconsets/legacy/warnings-underage-s.png | Bin 0 -> 1321 bytes .../low_vision/lvb-bookmark-public-s.png | Bin 0 -> 1104 bytes .../low_vision/lvb-bookmark-public.png | Bin 0 -> 717 bytes .../low_vision/lvb-bookmark-rec-s.png | Bin 0 -> 497 bytes .../iconsets/low_vision/lvb-bookmark-rec.png | Bin 0 -> 460 bytes .../low_vision/lvb-category-femslash-s.png | Bin 0 -> 447 bytes .../low_vision/lvb-category-femslash.png | Bin 0 -> 423 bytes .../low_vision/lvb-category-gen-s.png | Bin 0 -> 555 bytes .../iconsets/low_vision/lvb-category-gen.png | Bin 0 -> 508 bytes .../low_vision/lvb-category-het-s.png | Bin 0 -> 491 bytes .../iconsets/low_vision/lvb-category-het.png | Bin 0 -> 445 bytes .../low_vision/lvb-category-multi-s.png | Bin 0 -> 649 bytes .../low_vision/lvb-category-multi.png | Bin 0 -> 440 bytes .../low_vision/lvb-category-other-s.png | Bin 0 -> 674 bytes .../low_vision/lvb-category-other.png | Bin 0 -> 546 bytes .../low_vision/lvb-category-slash-s.png | Bin 0 -> 508 bytes .../low_vision/lvb-category-slash.png | Bin 0 -> 436 bytes .../iconsets/low_vision/lvb-collections.png | Bin 0 -> 330 bytes .../iconsets/low_vision/lvb-complete-no-s.png | Bin 0 -> 425 bytes .../iconsets/low_vision/lvb-complete-no.png | Bin 0 -> 398 bytes .../low_vision/lvb-complete-yes-s.png | Bin 0 -> 584 bytes .../iconsets/low_vision/lvb-complete-yes.png | Bin 0 -> 552 bytes .../low_vision/lvb-external-work-s.png | Bin 0 -> 598 bytes .../iconsets/low_vision/lvb-external-work.png | Bin 0 -> 498 bytes .../iconsets/low_vision/lvb-mystery-s.png | Bin 0 -> 312 bytes .../skins/iconsets/low_vision/lvb-mystery.png | Bin 0 -> 327 bytes .../low_vision/lvb-rating-explicit-s.png | Bin 0 -> 317 bytes .../low_vision/lvb-rating-explicit.png | Bin 0 -> 259 bytes .../lvb-rating-general-audience-s.png | Bin 0 -> 365 bytes .../lvb-rating-general-audience.png | Bin 0 -> 366 bytes .../low_vision/lvb-rating-mature-s.png | Bin 0 -> 404 bytes .../iconsets/low_vision/lvb-rating-mature.png | Bin 0 -> 337 bytes .../low_vision/lvb-rating-notrated-s.png | Bin 0 -> 125 bytes .../low_vision/lvb-rating-notrated.png | Bin 0 -> 174 bytes .../iconsets/low_vision/lvb-rating-teen-s.png | Bin 0 -> 271 bytes .../iconsets/low_vision/lvb-rating-teen.png | Bin 0 -> 198 bytes .../low_vision/lvb-warning-choosenotto-s.png | Bin 0 -> 414 bytes .../low_vision/lvb-warning-choosenotto.png | Bin 0 -> 372 bytes .../low_vision/lvb-warning-eschewed-s.png | Bin 0 -> 313 bytes .../low_vision/lvb-warning-eschewed.png | Bin 0 -> 341 bytes .../iconsets/low_vision/lvb-warning-no-s.png | Bin 0 -> 125 bytes .../iconsets/low_vision/lvb-warning-no.png | Bin 0 -> 174 bytes .../iconsets/low_vision/lvb-warning-yes-s.png | Bin 0 -> 247 bytes .../iconsets/low_vision/lvb-warning-yes.png | Bin 0 -> 242 bytes .../low_vision/lvy-bookmark-public-s.png | Bin 0 -> 1123 bytes .../low_vision/lvy-bookmark-public.png | Bin 0 -> 712 bytes .../low_vision/lvy-bookmark-rec-s.png | Bin 0 -> 502 bytes .../iconsets/low_vision/lvy-bookmark-rec.png | Bin 0 -> 454 bytes .../low_vision/lvy-category-femslash-s.png | Bin 0 -> 451 bytes .../low_vision/lvy-category-femslash.png | Bin 0 -> 402 bytes .../low_vision/lvy-category-gen-s.png | Bin 0 -> 555 bytes .../iconsets/low_vision/lvy-category-gen.png | Bin 0 -> 487 bytes .../low_vision/lvy-category-het-s.png | Bin 0 -> 496 bytes .../iconsets/low_vision/lvy-category-het.png | Bin 0 -> 424 bytes .../low_vision/lvy-category-multi-s.png | Bin 0 -> 641 bytes .../low_vision/lvy-category-multi.png | Bin 0 -> 444 bytes .../low_vision/lvy-category-other-s.png | Bin 0 -> 675 bytes .../low_vision/lvy-category-other.png | Bin 0 -> 525 bytes .../low_vision/lvy-category-slash-s.png | Bin 0 -> 514 bytes .../low_vision/lvy-category-slash.png | Bin 0 -> 415 bytes .../iconsets/low_vision/lvy-collections.png | Bin 0 -> 330 bytes .../iconsets/low_vision/lvy-complete-no-s.png | Bin 0 -> 439 bytes .../iconsets/low_vision/lvy-complete-no.png | Bin 0 -> 403 bytes .../low_vision/lvy-complete-yes-s.png | Bin 0 -> 618 bytes .../iconsets/low_vision/lvy-complete-yes.png | Bin 0 -> 552 bytes .../low_vision/lvy-external-work-s.png | Bin 0 -> 607 bytes .../iconsets/low_vision/lvy-external-work.png | Bin 0 -> 477 bytes .../iconsets/low_vision/lvy-mystery-s.png | Bin 0 -> 324 bytes .../skins/iconsets/low_vision/lvy-mystery.png | Bin 0 -> 325 bytes .../low_vision/lvy-rating-explicit-s.png | Bin 0 -> 322 bytes .../low_vision/lvy-rating-explicit.png | Bin 0 -> 259 bytes .../lvy-rating-general-audience-s.png | Bin 0 -> 378 bytes .../lvy-rating-general-audience.png | Bin 0 -> 367 bytes .../low_vision/lvy-rating-mature-s.png | Bin 0 -> 403 bytes .../iconsets/low_vision/lvy-rating-mature.png | Bin 0 -> 337 bytes .../low_vision/lvy-rating-notrated-s.png | Bin 0 -> 126 bytes .../low_vision/lvy-rating-notrated.png | Bin 0 -> 174 bytes .../iconsets/low_vision/lvy-rating-teen-s.png | Bin 0 -> 275 bytes .../iconsets/low_vision/lvy-rating-teen.png | Bin 0 -> 201 bytes .../low_vision/lvy-warning-choosenotto-s.png | Bin 0 -> 431 bytes .../low_vision/lvy-warning-choosenotto.png | Bin 0 -> 377 bytes .../low_vision/lvy-warning-eschewed-s.png | Bin 0 -> 319 bytes .../low_vision/lvy-warning-eschewed.png | Bin 0 -> 341 bytes .../iconsets/low_vision/lvy-warning-no-s.png | Bin 0 -> 126 bytes .../iconsets/low_vision/lvy-warning-no.png | Bin 0 -> 174 bytes .../iconsets/low_vision/lvy-warning-yes-s.png | Bin 0 -> 251 bytes .../iconsets/low_vision/lvy-warning-yes.png | Bin 0 -> 243 bytes .../icon-template-invert-mono.png | Bin 0 -> 31527 bytes .../template-grids/icon-template-invert.png | Bin 0 -> 53145 bytes .../template-grids/icon-template-mono.png | Bin 0 -> 30927 bytes .../iconsets/template-grids/icon-template.png | Bin 0 -> 51991 bytes public/images/skins/objects/blank-stamp.png | Bin 0 -> 8273 bytes public/images/skins/objects/coffee-cup.png | Bin 0 -> 76981 bytes .../skins/objects/glitter-pens-l-b-matte.png | Bin 0 -> 145944 bytes .../skins/objects/glitter-pens-l-bmatte.png | Bin 0 -> 164496 bytes public/images/skins/objects/glitter-pens.png | Bin 0 -> 139811 bytes public/images/skins/objects/track-bike.png | Bin 0 -> 5833 bytes .../skins/previews/basic_formatting.png | Bin 0 -> 238726 bytes public/images/skins/previews/default.png | Bin 0 -> 266268 bytes public/images/skins/previews/plaintext.png | Bin 0 -> 52090 bytes .../skins/textures/tiles/aaaaa-readme.txt | 21 + .../skins/textures/tiles/black-denim.jpg | Bin 0 -> 68501 bytes .../textures/tiles/black-illo-breeze.gif | Bin 0 -> 33690 bytes .../skins/textures/tiles/black-metal-grid.jpg | Bin 0 -> 50803 bytes .../skins/textures/tiles/black-noise.jpg | Bin 0 -> 4459 bytes .../skins/textures/tiles/black-scribble-x.png | Bin 0 -> 21938 bytes .../skins/textures/tiles/black-stripe.gif | Bin 0 -> 56 bytes .../tiles/black-wallpaper-charcoal.gif | Bin 0 -> 10149 bytes .../skins/textures/tiles/black-zebra-fur.jpg | Bin 0 -> 38097 bytes .../skins/textures/tiles/blue-denim-1.jpg | Bin 0 -> 52474 bytes .../skins/textures/tiles/blue-denim.jpg | Bin 0 -> 43632 bytes .../skins/textures/tiles/blue-geometric.jpg | Bin 0 -> 2753 bytes .../textures/tiles/blue-heartflowers.jpg | Bin 0 -> 66663 bytes .../skins/textures/tiles/blue-illo-ravens.gif | Bin 0 -> 115743 bytes .../skins/textures/tiles/blue-illo-waves.gif | Bin 0 -> 289613 bytes .../skins/textures/tiles/blue-lotus.gif | Bin 0 -> 65780 bytes .../skins/textures/tiles/blue-metal-grid.jpg | Bin 0 -> 24353 bytes .../skins/textures/tiles/brown-canvas.jpg | Bin 0 -> 53224 bytes .../skins/textures/tiles/brown-corkboard.jpg | Bin 0 -> 105064 bytes .../textures/tiles/brown-fine-cardboard.jpg | Bin 0 -> 27685 bytes .../skins/textures/tiles/brown-grunge.jpg | Bin 0 -> 16066 bytes .../textures/tiles/brown-handmade-paper.jpg | Bin 0 -> 33337 bytes .../skins/textures/tiles/brown-hessian.jpg | Bin 0 -> 58626 bytes .../textures/tiles/brown-illo-octo-redux.gif | Bin 0 -> 103650 bytes .../skins/textures/tiles/brown-linen.jpg | Bin 0 -> 44975 bytes .../textures/tiles/brown-manila-card.jpg | Bin 0 -> 30334 bytes .../skins/textures/tiles/brown-metal-grid.jpg | Bin 0 -> 30296 bytes .../textures/tiles/brown-planks-nails.jpg | Bin 0 -> 40881 bytes .../skins/textures/tiles/brown-twill.jpg | Bin 0 -> 51133 bytes .../textures/tiles/brown-winchester-walls.gif | Bin 0 -> 7817 bytes .../skins/textures/tiles/green-leather.jpg | Bin 0 -> 36776 bytes .../skins/textures/tiles/grey-argyle.jpg | Bin 0 -> 40335 bytes .../skins/textures/tiles/grey-bookswirl.jpg | Bin 0 -> 45313 bytes .../skins/textures/tiles/grey-canvas.jpg | Bin 0 -> 34166 bytes .../skins/textures/tiles/grey-corrogated.jpg | Bin 0 -> 20628 bytes .../skins/textures/tiles/grey-illo-skulls.gif | Bin 0 -> 39172 bytes .../skins/textures/tiles/grey-shiplap.jpg | Bin 0 -> 57856 bytes .../skins/textures/tiles/henna-leather.jpg | Bin 0 -> 73213 bytes .../skins/textures/tiles/multi-chevrons-x.png | Bin 0 -> 12528 bytes .../skins/textures/tiles/multi-chevrons-y.png | Bin 0 -> 13082 bytes .../tiles/multi-illo-autumn-butterflies.gif | Bin 0 -> 76413 bytes .../tiles/pink-illo-panda-madness.gif | Bin 0 -> 31915 bytes .../textures/tiles/purple-wood-desktop.jpg | Bin 0 -> 39917 bytes .../images/skins/textures/tiles/red-ao3.png | Bin 0 -> 12995 bytes .../images/skins/textures/tiles/red-brick.jpg | Bin 0 -> 35521 bytes .../textures/tiles/red-illo-45-caliber.gif | Bin 0 -> 103105 bytes .../tiles/red-illo-dead-revolutionaries.gif | Bin 0 -> 167410 bytes .../textures/tiles/red-illo-hold-fast.gif | Bin 0 -> 110082 bytes .../textures/tiles/red-illo-indian-summer.gif | Bin 0 -> 76406 bytes .../textures/tiles/red-illo-overlyRosie.gif | Bin 0 -> 46985 bytes .../skins/textures/tiles/red-illo-rafters.gif | Bin 0 -> 23059 bytes .../tiles/red-illo-vintage-scarlet.gif | Bin 0 -> 93867 bytes .../skins/textures/tiles/transp-dot.gif | Bin 0 -> 70 bytes .../tiles/transp-notebook-spiral-x.png | Bin 0 -> 50183 bytes .../tiles/transp-notebook-spiral-y.png | Bin 0 -> 48117 bytes .../textures/tiles/white-cartridge-paper.jpg | Bin 0 -> 31825 bytes .../textures/tiles/white-graph-paper.jpg | Bin 0 -> 62301 bytes .../textures/tiles/white-handmade-paper.jpg | Bin 0 -> 39122 bytes .../textures/tiles/white-lined-paper.jpg | Bin 0 -> 52940 bytes .../skins/textures/tiles/white-lined.jpg | Bin 0 -> 3014 bytes .../skins/textures/tiles/yellow-leaves.jpg | Bin 0 -> 76306 bytes .../skins/textures/tiles/yellow-postit.jpg | Bin 0 -> 3699 bytes .../textures/tiles/yellow-thick-card.jpg | Bin 0 -> 31086 bytes .../tiles/yellow-watercolour-paper.jpg | Bin 0 -> 31186 bytes public/images/unused/bluesymbol.png | Bin 0 -> 508 bytes public/images/unused/drag.png | Bin 0 -> 360 bytes public/images/unused/indicator.gif | Bin 0 -> 3897 bytes public/images/unused/rails.png | Bin 0 -> 6447 bytes public/images/unused/skin_preview_none.png | Bin 0 -> 7515 bytes public/images/unused/spinner.gif | Bin 0 -> 1456 bytes public/images/unused/wig.png | Bin 0 -> 5873 bytes public/javascripts/ao3modal.js | 342 + public/javascripts/ao3modal.min.js | 1 + public/javascripts/application.js | 641 + .../bootstrap/bootstrap-dropdown.js | 186 + .../bootstrap/bootstrap-dropdown.min.js | 1 + public/javascripts/filters.js | 79 + public/javascripts/filters.min.js | 1 + public/javascripts/jquery-shuffle.js | 15 + .../javascripts/jquery-ui-timepicker-addon.js | 19 + public/javascripts/jquery-ui.js | 14850 ++++++++++++++ public/javascripts/jquery-ui.min.js | 6 + public/javascripts/jquery.js | 9555 +++++++++ public/javascripts/jquery.livequery.min.js | 8 + public/javascripts/jquery.min.js | 4 + public/javascripts/jquery.qtip.min.js | 3 + public/javascripts/jquery.scrollTo.js | 210 + public/javascripts/jquery.scrollTo.min.js | 7 + public/javascripts/jquery.timeago.js | 193 + public/javascripts/jquery.timeago.min.js | 1 + public/javascripts/jquery.tokeninput.js | 1016 + public/javascripts/jquery.tokeninput.min.js | 1 + public/javascripts/jquery.trap.min.js | 8 + public/javascripts/js.cookie.min.js | 8 + .../javascripts/livevalidation_standalone.js | 924 + public/javascripts/mce_editor.js | 121 + public/javascripts/mce_editor.min.js | 1 + public/javascripts/rails.js | 534 + public/javascripts/select_all.js | 46 + .../javascripts/tinymce/jquery.tinymce.min.js | 91 + public/javascripts/tinymce/langs/readme.md | 3 + public/javascripts/tinymce/license.txt | 504 + .../tinymce/plugins/advlist/plugin.min.js | 9 + .../tinymce/plugins/anchor/plugin.min.js | 9 + .../tinymce/plugins/autolink/plugin.min.js | 9 + .../tinymce/plugins/autoresize/plugin.min.js | 9 + .../tinymce/plugins/autosave/plugin.min.js | 9 + .../tinymce/plugins/bbcode/plugin.min.js | 9 + .../tinymce/plugins/charmap/plugin.min.js | 9 + .../tinymce/plugins/code/plugin.min.js | 9 + .../tinymce/plugins/codesample/plugin.min.js | 9 + .../tinymce/plugins/colorpicker/plugin.min.js | 9 + .../tinymce/plugins/contextmenu/plugin.min.js | 9 + .../plugins/directionality/plugin.min.js | 9 + .../tinymce/plugins/emoticons/js/emojis.js | 9015 +++++++++ .../plugins/emoticons/js/emojis.min.js | 2 + .../tinymce/plugins/emoticons/plugin.min.js | 9 + .../tinymce/plugins/fullpage/plugin.min.js | 9 + .../tinymce/plugins/fullscreen/plugin.min.js | 9 + .../tinymce/plugins/help/plugin.min.js | 9 + .../tinymce/plugins/hr/plugin.min.js | 9 + .../tinymce/plugins/image/plugin.min.js | 9 + .../tinymce/plugins/imagetools/plugin.min.js | 9 + .../tinymce/plugins/importcss/plugin.min.js | 9 + .../plugins/insertdatetime/plugin.min.js | 9 + .../plugins/legacyoutput/plugin.min.js | 9 + .../tinymce/plugins/link/plugin.min.js | 9 + .../tinymce/plugins/lists/plugin.min.js | 9 + .../tinymce/plugins/media/plugin.min.js | 9 + .../tinymce/plugins/nonbreaking/plugin.min.js | 9 + .../tinymce/plugins/noneditable/plugin.min.js | 9 + .../tinymce/plugins/pagebreak/plugin.min.js | 9 + .../tinymce/plugins/paste/plugin.min.js | 9 + .../tinymce/plugins/preview/plugin.min.js | 9 + .../tinymce/plugins/print/plugin.min.js | 9 + .../tinymce/plugins/quickbars/plugin.min.js | 9 + .../tinymce/plugins/save/plugin.min.js | 9 + .../plugins/searchreplace/plugin.min.js | 9 + .../plugins/spellchecker/plugin.min.js | 9 + .../tinymce/plugins/tabfocus/plugin.min.js | 9 + .../tinymce/plugins/table/plugin.min.js | 9 + .../tinymce/plugins/template/plugin.min.js | 9 + .../tinymce/plugins/textcolor/plugin.min.js | 9 + .../tinymce/plugins/textpattern/plugin.min.js | 9 + .../tinymce/plugins/toc/plugin.min.js | 9 + .../plugins/visualblocks/plugin.min.js | 9 + .../tinymce/plugins/visualchars/plugin.min.js | 9 + .../tinymce/plugins/wordcount/plugin.min.js | 9 + .../skins/content/dark/content.min.css | 7 + .../skins/content/default/content.min.css | 7 + .../skins/content/document/content.min.css | 7 + .../skins/content/writer/content.min.css | 7 + .../ui/oxide-dark/content.inline.min.css | 7 + .../skins/ui/oxide-dark/content.min.css | 7 + .../ui/oxide-dark/content.mobile.min.css | 7 + .../ui/oxide-dark/fonts/tinymce-mobile.woff | Bin 0 -> 4624 bytes .../tinymce/skins/ui/oxide-dark/skin.min.css | 7 + .../skins/ui/oxide-dark/skin.mobile.min.css | 7 + .../skins/ui/oxide/content.inline.min.css | 7 + .../tinymce/skins/ui/oxide/content.min.css | 7 + .../skins/ui/oxide/content.mobile.min.css | 7 + .../skins/ui/oxide/fonts/tinymce-mobile.woff | Bin 0 -> 4624 bytes .../tinymce/skins/ui/oxide/skin.min.css | 7 + .../skins/ui/oxide/skin.mobile.min.css | 7 + .../tinymce/themes/mobile/theme.min.js | 9 + .../tinymce/themes/silver/theme.min.js | 9 + public/javascripts/tinymce/tinymce.min.js | 9 + public/nomaintenance.html | 150 + public/otw-logobox-transparent.png | Bin 0 -> 9702 bytes public/robots.private.txt | 5 + public/robots.public.txt | 40 + public/status/24_hour.html | 36 + public/status/3_hour.html | 36 + public/status/index.html | 184 + public/status/jquery-ui.css | 1186 ++ public/status/simple_status.html | 64 + public/stylesheets/.gitkeep | 0 public/stylesheets/README.md | 23 + public/stylesheets/ebooks.css | 45 + public/stylesheets/forms-backup.css | 1023 + .../stylesheets/masters/dark_mode/README.md | 54 + .../masters/dark_mode/dark_mode_midsize_.css | 23 + .../dark_mode/dark_mode_site_screen_.css | 789 + .../masters/low_vision_default/README.md | 37 + .../low_vision_default_site_screen_.css | 193 + public/stylesheets/masters/reversi/README.md | 10 + .../masters/reversi/reversi_site_screen_.css | 383 + public/stylesheets/masters/snow/README.md | 14 + .../masters/snow/snow_site_screen_.css | 56 + .../stylesheets/masters/snow_blue/README.md | 13 + .../snow_blue/snow_blue_site_screen_.css | 65 + public/stylesheets/sandbox.css | 113 + public/stylesheets/site/2.0/01-core.css | 59 + public/stylesheets/site/2.0/02-elements.css | 256 + .../stylesheets/site/2.0/03-region-header.css | 295 + .../site/2.0/04-region-dashboard.css | 60 + .../stylesheets/site/2.0/05-region-main.css | 57 + .../stylesheets/site/2.0/06-region-footer.css | 77 + .../stylesheets/site/2.0/07-interactions.css | 707 + public/stylesheets/site/2.0/08-actions.css | 225 + .../stylesheets/site/2.0/09-roles-states.css | 99 + .../stylesheets/site/2.0/10-types-groups.css | 260 + .../stylesheets/site/2.0/11-group-listbox.css | 95 + public/stylesheets/site/2.0/12-group-meta.css | 101 + .../stylesheets/site/2.0/13-group-blurb.css | 438 + .../stylesheets/site/2.0/14-group-preface.css | 71 + .../site/2.0/15-group-comments.css | 114 + .../stylesheets/site/2.0/16-zone-system.css | 444 + public/stylesheets/site/2.0/17-zone-home.css | 100 + .../site/2.0/18-zone-searchbrowse.css | 260 + public/stylesheets/site/2.0/19-zone-tags.css | 53 + .../site/2.0/20-zone-translation.css | 10 + public/stylesheets/site/2.0/21-userstuff.css | 207 + .../site/2.0/22-system-messages.css | 282 + .../site/2.0/23-role-translator.css | 4 + public/stylesheets/site/2.0/24-role-admin.css | 50 + .../stylesheets/site/2.0/25-media-midsize.css | 123 + .../stylesheets/site/2.0/26-media-narrow.css | 293 + .../stylesheets/site/2.0/27-media-aural.css | 76 + .../stylesheets/site/2.0/28-media-print.css | 66 + .../site/2.0/29-role-ie8_or_lower.css | 157 + public/stylesheets/site/2.0/30-role-ie5.css | 258 + public/stylesheets/site/2.0/31-role-ie6.css | 258 + public/stylesheets/site/2.0/32-role-ie7.css | 79 + public/stylesheets/site/2.0/preview.png | Bin 0 -> 147343 bytes public/stylesheets/site/preview.png | Bin 0 -> 147343 bytes .../site/user_skins_to_load/README.txt | 26 + public/stylesheets/tiny_mce_custom.css | 3 + .../work_skins/basic_formatting.css | 55 + rubocop/cop/README.md | 121 + rubocop/cop/cucumber/regex_step_name.rb | 51 + rubocop/cop/i18n/default_translation.rb | 34 + rubocop/cop/i18n/deprecated_helper.rb | 33 + .../cop/i18n/deprecated_translation_key.rb | 47 + rubocop/cop/i18n/html_safe_translation.rb | 39 + .../migration/large_table_schema_update.rb | 61 + rubocop/rubocop.rb | 5 + script/create_admin.rb | 77 + script/docker/init.cmd | 16 + script/docker/init.sh | 23 + script/ensure_required_tags.rb | 30 + script/get_user_data.rb | 214 + script/gh-actions/configure_database.sh | 4 + script/gh-actions/multiple_redis.sh | 8 + script/lock_admin.rb | 48 + script/reset_database-prod.sh | 27 + script/reset_database.sh | 24 + script/unlock_admin.rb | 46 + .../admin/activities_controller_spec.rb | 71 + .../admin_invitations_controller_spec.rb | 121 + .../admin/admin_users_controller_spec.rb | 784 + spec/controllers/admin/api_controller_spec.rb | 470 + .../admin/banners_controller_spec.rb | 134 + .../blacklisted_emails_controller_spec.rb | 68 + .../admin/settings_controller_spec.rb | 166 + .../admin/skins_controller_spec.rb | 289 + .../controllers/admin/spam_controller_spec.rb | 107 + .../admin/user_creations_controller_spec.rb | 279 + .../admin_posts_controller_spec.rb | 350 + spec/controllers/api/api_helper.rb | 70 + .../api/v2/api_authorization_spec.rb | 33 + .../api/v2/api_base_controller_spec.rb | 67 + spec/controllers/api/v2/api_bookmarks_spec.rb | 191 + .../api/v2/api_works_search_spec.rb | 98 + spec/controllers/api/v2/api_works_spec.rb | 552 + .../archive_faqs_controller_spec.rb | 388 + .../autocomplete_controller_spec.rb | 13 + .../blocked/users_controller_spec.rb | 185 + spec/controllers/bookmarks_controller_spec.rb | 397 + .../challenge_assignments_controller_spec.rb | 455 + .../challenge_claims_controller_spec.rb | 157 + .../challenge_signups_controller_spec.rb | 275 + .../controllers/challenges_controller_spec.rb | 52 + spec/controllers/chapters_controller_spec.rb | 1266 ++ .../collection_items_controller_spec.rb | 635 + ...collection_participants_controller_spec.rb | 449 + .../collection_profile_controller_spec.rb | 21 + .../collections_controller_spec.rb | 95 + spec/controllers/comments/blocking_spec.rb | 243 + .../comments/comment_moderation_spec.rb | 507 + .../comments/comments_controller_spec.rb | 497 + .../comments/default_rails_actions_spec.rb | 1023 + spec/controllers/comments/freeze_spec.rb | 1067 ++ spec/controllers/comments/hide_spec.rb | 694 + spec/controllers/comments/reply_spec.rb | 288 + .../creatorships_controller_spec.rb | 109 + spec/controllers/errors_controller_spec.rb | 47 + .../external_authors_controller_spec.rb | 414 + .../external_works_controller_spec.rb | 90 + spec/controllers/fandoms_controller_spec.rb | 22 + spec/controllers/feedbacks_controller_spec.rb | 120 + .../gift_exchange_controller_spec.rb | 123 + spec/controllers/gifts_controller_spec.rb | 42 + spec/controllers/hit_count_controller_spec.rb | 58 + spec/controllers/inbox_controller_spec.rb | 357 + .../invitations_controller_spec.rb | 232 + .../invite_requests_controller_spec.rb | 347 + .../known_issues_controller_spec.rb | 187 + spec/controllers/kudos_controller_spec.rb | 251 + spec/controllers/languages_controller_spec.rb | 312 + spec/controllers/locales_controller_spec.rb | 278 + .../muted/users_controller_spec.rb | 185 + .../opendoors/tools_controller_spec.rb | 107 + spec/controllers/orphans_controller_spec.rb | 409 + .../owned_tag_sets_controller_spec.rb | 339 + spec/controllers/people_controller_spec.rb | 12 + spec/controllers/profile_controller_spec.rb | 23 + .../prompt_meme_controller_spec.rb | 117 + spec/controllers/prompts_controller_spec.rb | 265 + spec/controllers/pseuds_controller_spec.rb | 276 + spec/controllers/questions_controller_spec.rb | 71 + spec/controllers/readings_controller_spec.rb | 207 + .../related_works_controller_spec.rb | 141 + .../serial_works_controller_spec.rb | 31 + spec/controllers/series_controller_spec.rb | 201 + spec/controllers/skins_controller_spec.rb | 204 + .../subscriptions_controller_spec.rb | 94 + .../tag_set_associations_controller_spec.rb | 138 + .../tag_set_nominations_controller_spec.rb | 1669 ++ .../tag_wranglers_controller_spec.rb | 307 + .../tag_wranglings_controller_spec.rb | 110 + spec/controllers/tags_controller_spec.rb | 774 + .../troubleshooting_controller_spec.rb | 230 + .../unsorted_tags_controller_spec.rb | 63 + .../users/registrations_controller_spec.rb | 113 + spec/controllers/users_controller_spec.rb | 304 + .../works/default_rails_actions_spec.rb | 940 + spec/controllers/works/drafts_spec.rb | 153 + spec/controllers/works/importing_spec.rb | 131 + spec/controllers/works/mark_for_later_spec.rb | 37 + .../works/multiple_actions_spec.rb | 432 + .../works/remove_user_cocreatorship_spec.rb | 43 + spec/controllers/works/updating_tags_spec.rb | 60 + .../works/works_controller_spec.rb | 27 + .../wrangling_guidelines_controller_spec.rb | 351 + spec/helpers/admin_helper_spec.rb | 23 + spec/helpers/admin_post_helper_spec.rb | 19 + spec/helpers/application_helper_spec.rb | 388 + spec/helpers/bookmarks_helper_spec.rb | 329 + spec/helpers/comments_helper_spec.rb | 125 + spec/helpers/date_helper_spec.rb | 18 + spec/helpers/exports_helper_spec.rb | 28 + spec/helpers/home_helper_spec.rb | 13 + spec/helpers/inbox_helper_spec.rb | 35 + spec/helpers/mailer_helper_spec.rb | 166 + spec/helpers/share_helper_spec.rb | 101 + spec/helpers/skins_helper_spec.rb | 77 + spec/helpers/tag_sets_helper_spec.rb | 214 + spec/helpers/tag_type_helper_spec.rb | 28 + .../user_invite_requests_helper_spec.rb | 25 + spec/helpers/validation_helper_spec.rb | 92 + spec/helpers/works_helper_spec.rb | 99 + spec/jobs/hit_count_update_job_spec.rb | 72 + spec/jobs/report_attachment_job_spec.rb | 25 + spec/lib/autocomplete_source_spec.rb | 177 + spec/lib/collectible_spec.rb | 170 + spec/lib/css_cleaner_spec.rb | 242 + spec/lib/html_cleaner_spec.rb | 1249 ++ spec/lib/i18n/i18n_tasks_spec.rb | 34 + spec/lib/i18n/pluralization_spec.rb | 35 + spec/lib/otw_sanitize/media_sanitizer_spec.rb | 191 + spec/lib/paragraph_maker_spec.rb | 27 + spec/lib/string_cleaner_spec.rb | 31 + spec/lib/tasks/admin_tasks.rake_spec.rb | 46 + spec/lib/tasks/after_tasks.rake_spec.rb | 688 + spec/lib/tasks/creatorships.rake_spec.rb | 127 + spec/lib/tasks/database_seed.rake_spec.rb | 16 + spec/lib/tasks/defaults.rake_spec.rb | 10 + spec/lib/tasks/notifications.rake_spec.rb | 30 + spec/lib/tasks/opendoors.rake_spec.rb | 70 + spec/lib/tasks/resanitize.rake_spec.rb | 123 + spec/lib/tasks/resque.rake_spec.rb | 59 + spec/lib/tasks/search_tasks.rake_spec.rb | 104 + spec/lib/tasks/skin_tasks.rake_spec.rb | 35 + spec/lib/tasks/tag_tasks.rake_spec.rb | 222 + spec/lib/tasks/work_tasks.rake_spec.rb | 166 + spec/lib/url_formatter_spec.rb | 110 + spec/lib/word_counter_spec.rb | 93 + spec/lib/works_owner_spec.rb | 230 + spec/lib/zoho_auth_client_spec.rb | 58 + spec/lib/zoho_resource_client_spec.rb | 169 + spec/mailers/admin_mailer_spec.rb | 175 + spec/mailers/archive_devise_mailer_spec.rb | 175 + spec/mailers/collection_mailer_spec.rb | 12 + spec/mailers/comment_mailer_spec.rb | 966 + spec/mailers/kudo_mailer_spec.rb | 80 + .../tag_wrangling_supervisor_mailer_spec.rb | 36 + spec/mailers/tos_update_mailer_spec.rb | 38 + spec/mailers/user_mailer_spec.rb | 1354 ++ spec/models/abuse_report_spec.rb | 557 + spec/models/admin_activity_spec.rb | 36 + spec/models/admin_blacklisted_email_spec.rb | 66 + spec/models/admin_post_spec.rb | 49 + spec/models/admin_setting_spec.rb | 32 + spec/models/admin_spec.rb | 131 + spec/models/archive_faq_spec.rb | 31 + spec/models/bookmark_spec.rb | 49 + spec/models/challenge_assignment_spec.rb | 167 + spec/models/challenge_claim_spec.rb | 15 + spec/models/chapter_spec.rb | 113 + spec/models/collection_item_spec.rb | 94 + spec/models/collection_spec.rb | 116 + spec/models/comment_spec.rb | 771 + spec/models/concerns/filterable_spec.rb | 211 + spec/models/concerns/justifiable_spec.rb | 140 + .../password_resets_limitable_spec.rb | 189 + spec/models/concerns/wrangleable_spec.rb | 73 + spec/models/creatorship_spec.rb | 34 + spec/models/download_spec.rb | 221 + spec/models/external_author_spec.rb | 49 + spec/models/external_work_spec.rb | 61 + spec/models/favorite_tag_spec.rb | 49 + .../feedback_reporters/abuse_reporter_spec.rb | 113 + .../feedback_reporter_spec.rb | 103 + .../support_reporter_spec.rb | 157 + spec/models/feedback_spec.rb | 103 + spec/models/filter_count_spec.rb | 74 + spec/models/gift_exchange_spec.rb | 45 + spec/models/gift_spec.rb | 12 + spec/models/indexing/cache_master_spec.rb | 37 + spec/models/indexing/index_queue_spec.rb | 77 + spec/models/invitation_spec.rb | 115 + spec/models/invite_request_spec.rb | 72 + spec/models/kudo_spec.rb | 76 + spec/models/language_spec.rb | 51 + spec/models/locale_spec.rb | 16 + spec/models/moderated_work_spec.rb | 22 + spec/models/owned_tag_set_spec.rb | 128 + spec/models/potential_match_spec.rb | 30 + spec/models/preference_spec.rb | 43 + spec/models/prompt_spec.rb | 47 + spec/models/pseud_spec.rb | 126 + spec/models/reading_spec.rb | 34 + spec/models/redis_hit_counter_spec.rb | 128 + spec/models/roles_user_spec.rb | 22 + spec/models/search/async_indexer_spec.rb | 76 + spec/models/search/bookmark_indexer_spec.rb | 16 + spec/models/search/bookmark_query_spec.rb | 151 + ...mark_search_form_exclusion_filters_spec.rb | 104 + .../search/bookmark_search_form_spec.rb | 510 + spec/models/search/bookmarkable_query_spec.rb | 74 + .../search/bookmarked_work_indexer_spec.rb | 15 + spec/models/search/homepage_decorator_spec.rb | 64 + spec/models/search/index_sweeper_spec.rb | 156 + spec/models/search/pseud_decorator_spec.rb | 145 + spec/models/search/pseud_indexer_spec.rb | 16 + spec/models/search/pseud_query_spec.rb | 92 + spec/models/search/pseud_search_form_spec.rb | 186 + spec/models/search/query_cleaner_spec.rb | 76 + spec/models/search/query_spec.rb | 37 + .../search/stat_counter_indexer_spec.rb | 68 + spec/models/search/tag_query_spec.rb | 256 + .../models/search/tag_query_wrangling_spec.rb | 111 + .../search/work_creator_indexer_spec.rb | 15 + spec/models/search/work_indexer_spec.rb | 41 + spec/models/search/work_query_spec.rb | 291 + ...work_search_form_exclusion_filters_spec.rb | 167 + spec/models/search/work_search_form_spec.rb | 634 + spec/models/serial_work_spec.rb | 29 + spec/models/series_spec.rb | 113 + spec/models/skin_parent_spec.rb | 77 + spec/models/skin_spec.rb | 400 + spec/models/spam_report_spec.rb | 58 + spec/models/stat_counter_spec.rb | 14 + spec/models/story_parser_spec.rb | 350 + spec/models/subscription_spec.rb | 118 + spec/models/tag_set_nomination_spec.rb | 17 + spec/models/tag_spec.rb | 627 + spec/models/tag_wrangling_spec.rb | 657 + .../tagset_models/tag_nomination_spec.rb | 66 + spec/models/unsorted_tag_spec.rb | 20 + spec/models/user_manager_spec.rb | 74 + spec/models/user_spec.rb | 390 + spec/models/work_original_creator_spec.rb | 40 + spec/models/work_spec.rb | 692 + .../requests/blocked_users_n_plus_one_spec.rb | 40 + spec/requests/bookmarks_n_plus_one_spec.rb | 53 + .../collection_items_n_plus_one_spec.rb | 37 + spec/requests/comments_n_plus_one_spec.rb | 112 + spec/requests/muted_users_n_plus_one_spec.rb | 40 + spec/requests/people_n_plus_one_spec.rb | 51 + spec/requests/pseuds_n_plus_one_spec.rb | 35 + spec/requests/rack_attack_spec.rb | 193 + spec/requests/security_headers_spec.rb | 14 + spec/requests/skins_n_plus_one_spec.rb | 97 + spec/requests/works_n_plus_one_spec.rb | 143 + spec/requests/works_show_request_spec.rb | 77 + .../cop/cucumber/regex_step_name_spec.rb | 69 + .../cop/i18n/default_translation_spec.rb | 37 + .../cop/i18n/deprecated_helper_spec.rb | 33 + .../i18n/deprecated_translation_key_spec.rb | 34 + .../cop/i18n/html_safe_translation_spec.rb | 73 + .../large_table_schema_update_spec.rb | 53 + spec/rubocop_spec_helper.rb | 20 + spec/spec_helper.rb | 206 + .../fixtures/opendoors_import_url_mapping.csv | 3 + spec/support/i18n_newlines_tasks.rb | 16 + spec/support/login_macros.rb | 24 + spec/support/matchers/add_to_reindex_queue.rb | 44 + spec/support/matchers/be_valid_verbose.rb | 15 + .../matchers/have_html_part_content.rb | 14 + .../matchers/have_text_part_content.rb | 14 + spec/support/redirect_expectation_helper.rb | 72 + .../shared_examples/access_shared_examples.rb | 82 + .../shared_examples/mailer_shared_examples.rb | 64 + spec/support/task_example_group.rb | 28 + spec/support/zoho_client_spec_helper.rb | 17 + test/fixtures/admin_settings.yml | 23 + test/fixtures/admins.yml | 73 + test/fixtures/archive_faq_translations.yml | 8 + test/fixtures/archive_faqs.yml | 8 + test/fixtures/bookmarks.yml | 629 + test/fixtures/chapters.yml | 15992 ++++++++++++++++ test/fixtures/collection_items.yml | 37 + test/fixtures/collection_participants.yml | 56 + test/fixtures/collection_preferences.yml | 45 + test/fixtures/collection_profiles.yml | 1378 ++ test/fixtures/collections.yml | 54 + test/fixtures/comments.yml | 918 + test/fixtures/common_taggings.yml | 757 + test/fixtures/creatorships.yml | 2537 +++ test/fixtures/external_works.yml | 31 + test/fixtures/gifts.yml | 9 + test/fixtures/inbox_comments.yml | 297 + test/fixtures/languages.yml | 55 + test/fixtures/locales.yml | 85 + test/fixtures/preferences.yml | 705 + test/fixtures/profiles.yml | 225 + test/fixtures/pseuds.yml | 407 + test/fixtures/question_translations.yml | 17 + test/fixtures/questions.yml | 19 + test/fixtures/related_works.yml | 19 + test/fixtures/roles.yml | 22 + test/fixtures/roles_users.yml | 39 + test/fixtures/serial_works.yml | 120 + test/fixtures/series.yml | 86 + test/fixtures/stat_counters.yml | 36 + test/fixtures/taggings.yml | 6241 ++++++ test/fixtures/tags.yml | 5799 ++++++ test/fixtures/users.yml | 467 + test/fixtures/works.yml | 2182 +++ .../previews/application_mailer_preview.rb | 18 + .../previews/archive_devise_mailer_preview.rb | 27 + .../previews/comment_mailer_preview.rb | 171 + test/mailers/previews/kudo_mailer_preview.rb | 12 + ...tag_wrangling_supervisor_mailer_preview.rb | 6 + .../previews/tos_update_mailer_preview.rb | 8 + test/mailers/previews/user_mailer_preview.rb | 339 + 2471 files changed, 283565 insertions(+) create mode 100755 .codeclimate.yml create mode 100755 .codecov.yml create mode 100755 .erb-lint.yml create mode 100755 .gitattributes create mode 100644 .gitignore create mode 100755 .gitpod.yml create mode 100755 .hound.yml create mode 100755 .jshintignore create mode 100755 .jshintrc create mode 100755 .phrase.yml create mode 100755 .rubocop.yml create mode 100755 .ruby-version create mode 100755 .simplecov create mode 100755 ACKNOWLEDGMENTS.md create mode 100755 CONTRIBUTING.md create mode 100755 Capfile create mode 100755 Gemfile create mode 100755 Gemfile.lock create mode 100755 LICENSE create mode 100755 README.md create mode 100755 Rakefile create mode 100755 SECURITY.md create mode 100755 app/controllers/abuse_reports_controller.rb create mode 100755 app/controllers/admin/activities_controller.rb create mode 100755 app/controllers/admin/admin_invitations_controller.rb create mode 100755 app/controllers/admin/admin_users_controller.rb create mode 100755 app/controllers/admin/api_controller.rb create mode 100755 app/controllers/admin/banners_controller.rb create mode 100755 app/controllers/admin/base_controller.rb create mode 100755 app/controllers/admin/blacklisted_emails_controller.rb create mode 100755 app/controllers/admin/passwords_controller.rb create mode 100755 app/controllers/admin/sessions_controller.rb create mode 100755 app/controllers/admin/settings_controller.rb create mode 100755 app/controllers/admin/skins_controller.rb create mode 100755 app/controllers/admin/spam_controller.rb create mode 100755 app/controllers/admin/user_creations_controller.rb create mode 100755 app/controllers/admin_posts_controller.rb create mode 100755 app/controllers/admins_controller.rb create mode 100755 app/controllers/api/v2/base_controller.rb create mode 100755 app/controllers/api/v2/bookmarks_controller.rb create mode 100755 app/controllers/api/v2/works_controller.rb create mode 100755 app/controllers/application_controller.rb create mode 100755 app/controllers/archive_faqs_controller.rb create mode 100755 app/controllers/autocomplete_controller.rb create mode 100755 app/controllers/blocked/users_controller.rb create mode 100755 app/controllers/bookmarks_controller.rb create mode 100755 app/controllers/challenge/gift_exchange_controller.rb create mode 100755 app/controllers/challenge/prompt_meme_controller.rb create mode 100755 app/controllers/challenge_assignments_controller.rb create mode 100755 app/controllers/challenge_claims_controller.rb create mode 100755 app/controllers/challenge_requests_controller.rb create mode 100755 app/controllers/challenge_signups_controller.rb create mode 100755 app/controllers/challenges_controller.rb create mode 100755 app/controllers/chapters_controller.rb create mode 100755 app/controllers/collection_items_controller.rb create mode 100755 app/controllers/collection_participants_controller.rb create mode 100755 app/controllers/collection_profile_controller.rb create mode 100755 app/controllers/collections_controller.rb create mode 100755 app/controllers/comments_controller.rb create mode 100755 app/controllers/concerns/tag_wrangling.rb create mode 100755 app/controllers/creatorships_controller.rb create mode 100755 app/controllers/downloads_controller.rb create mode 100755 app/controllers/errors_controller.rb create mode 100755 app/controllers/external_authors_controller.rb create mode 100755 app/controllers/external_works_controller.rb create mode 100755 app/controllers/fandoms_controller.rb create mode 100755 app/controllers/favorite_tags_controller.rb create mode 100755 app/controllers/feedbacks_controller.rb create mode 100755 app/controllers/gifts_controller.rb create mode 100755 app/controllers/hit_count_controller.rb create mode 100755 app/controllers/home_controller.rb create mode 100755 app/controllers/inbox_controller.rb create mode 100755 app/controllers/invitations_controller.rb create mode 100755 app/controllers/invite_requests_controller.rb create mode 100755 app/controllers/known_issues_controller.rb create mode 100755 app/controllers/kudos_controller.rb create mode 100755 app/controllers/languages_controller.rb create mode 100755 app/controllers/locales_controller.rb create mode 100755 app/controllers/media_controller.rb create mode 100755 app/controllers/menu_controller.rb create mode 100755 app/controllers/muted/users_controller.rb create mode 100755 app/controllers/opendoors/external_authors_controller.rb create mode 100755 app/controllers/opendoors/tools_controller.rb create mode 100755 app/controllers/orphans_controller.rb create mode 100755 app/controllers/owned_tag_sets_controller.rb create mode 100755 app/controllers/people_controller.rb create mode 100755 app/controllers/potential_matches_controller.rb create mode 100755 app/controllers/preferences_controller.rb create mode 100755 app/controllers/profile_controller.rb create mode 100755 app/controllers/prompts_controller.rb create mode 100755 app/controllers/pseuds_controller.rb create mode 100755 app/controllers/questions_controller.rb create mode 100755 app/controllers/readings_controller.rb create mode 100755 app/controllers/redirect_controller.rb create mode 100755 app/controllers/related_works_controller.rb create mode 100755 app/controllers/serial_works_controller.rb create mode 100755 app/controllers/series_controller.rb create mode 100755 app/controllers/skins_controller.rb create mode 100755 app/controllers/stats_controller.rb create mode 100644 app/controllers/statuses_controller.rb create mode 100755 app/controllers/subscriptions_controller.rb create mode 100755 app/controllers/tag_set_associations_controller.rb create mode 100755 app/controllers/tag_set_nominations_controller.rb create mode 100755 app/controllers/tag_wranglers_controller.rb create mode 100755 app/controllers/tag_wranglings_controller.rb create mode 100755 app/controllers/tags_controller.rb create mode 100755 app/controllers/troubleshooting_controller.rb create mode 100755 app/controllers/unsorted_tags_controller.rb create mode 100755 app/controllers/user_invite_requests_controller.rb create mode 100755 app/controllers/users/passwords_controller.rb create mode 100755 app/controllers/users/registrations_controller.rb create mode 100755 app/controllers/users/sessions_controller.rb create mode 100755 app/controllers/users_controller.rb create mode 100755 app/controllers/works_controller.rb create mode 100755 app/controllers/wrangling_guidelines_controller.rb create mode 100755 app/decorators/bookmarkable_decorator.rb create mode 100755 app/decorators/comment_decorator.rb create mode 100755 app/decorators/homepage.rb create mode 100755 app/decorators/pseud_decorator.rb create mode 100755 app/helpers/admin_helper.rb create mode 100755 app/helpers/admin_post_helper.rb create mode 100755 app/helpers/advanced_search_helper.rb create mode 100755 app/helpers/application_helper.rb create mode 100755 app/helpers/block_helper.rb create mode 100755 app/helpers/bookmarks_helper.rb create mode 100755 app/helpers/challenge_helper.rb create mode 100755 app/helpers/collections_helper.rb create mode 100755 app/helpers/comments_helper.rb create mode 100755 app/helpers/date_helper.rb create mode 100755 app/helpers/exports_helper.rb create mode 100755 app/helpers/external_authors_helper.rb create mode 100755 app/helpers/home_helper.rb create mode 100755 app/helpers/inbox_helper.rb create mode 100755 app/helpers/invitations_helper.rb create mode 100755 app/helpers/kudos_helper.rb create mode 100755 app/helpers/language_helper.rb create mode 100755 app/helpers/mailer_helper.rb create mode 100755 app/helpers/mute_helper.rb create mode 100755 app/helpers/number_helper.rb create mode 100755 app/helpers/orphans_helper.rb create mode 100755 app/helpers/pagination_helper.rb create mode 100755 app/helpers/prompt_restrictions_helper.rb create mode 100755 app/helpers/pseuds_helper.rb create mode 100755 app/helpers/search_helper.rb create mode 100755 app/helpers/series_helper.rb create mode 100755 app/helpers/share_helper.rb create mode 100755 app/helpers/skin_cache_helper.rb create mode 100755 app/helpers/skins_helper.rb create mode 100644 app/helpers/statuses_helper.rb create mode 100755 app/helpers/tag_sets_helper.rb create mode 100755 app/helpers/tag_type_helper.rb create mode 100755 app/helpers/tags_helper.rb create mode 100755 app/helpers/translation_helper.rb create mode 100755 app/helpers/user_invite_requests_helper.rb create mode 100755 app/helpers/users_helper.rb create mode 100755 app/helpers/validation_helper.rb create mode 100755 app/helpers/works_helper.rb create mode 100755 app/helpers/wrangling_helper.rb create mode 100755 app/jobs/application_job.rb create mode 100755 app/jobs/application_mailer_job.rb create mode 100755 app/jobs/async_indexer_job.rb create mode 100755 app/jobs/hit_count_update_job.rb create mode 100755 app/jobs/instance_method_job.rb create mode 100755 app/jobs/invite_from_queue_job.rb create mode 100755 app/jobs/readings_job.rb create mode 100755 app/jobs/redis_hash_job.rb create mode 100755 app/jobs/redis_job_spawner.rb create mode 100755 app/jobs/redis_set_job.rb create mode 100755 app/jobs/report_attachment_job.rb create mode 100755 app/jobs/resanitize_batch_job.rb create mode 100755 app/jobs/stat_counter_job.rb create mode 100755 app/jobs/tag_count_update_job.rb create mode 100755 app/jobs/tag_method_job.rb create mode 100755 app/mailers/README.md create mode 100755 app/mailers/admin_mailer.rb create mode 100755 app/mailers/application_mailer.rb create mode 100755 app/mailers/archive_devise_mailer.rb create mode 100755 app/mailers/collection_mailer.rb create mode 100755 app/mailers/comment_mailer.rb create mode 100755 app/mailers/kudo_mailer.rb create mode 100755 app/mailers/tag_wrangling_supervisor_mailer.rb create mode 100755 app/mailers/tos_update_mailer.rb create mode 100755 app/mailers/user_mailer.rb create mode 100755 app/models/abuse_report.rb create mode 100755 app/models/admin.rb create mode 100755 app/models/admin_activity.rb create mode 100755 app/models/admin_banner.rb create mode 100755 app/models/admin_blacklisted_email.rb create mode 100755 app/models/admin_post.rb create mode 100755 app/models/admin_post_tag.rb create mode 100755 app/models/admin_post_tagging.rb create mode 100755 app/models/admin_setting.rb create mode 100755 app/models/api_key.rb create mode 100755 app/models/application_record.rb create mode 100755 app/models/archive_faq.rb create mode 100755 app/models/archive_warning.rb create mode 100755 app/models/banned.rb create mode 100755 app/models/block.rb create mode 100755 app/models/bookmark.rb create mode 100755 app/models/category.rb create mode 100755 app/models/challenge_assignment.rb create mode 100755 app/models/challenge_claim.rb create mode 100755 app/models/challenge_models/gift_exchange.rb create mode 100755 app/models/challenge_models/prompt_meme.rb create mode 100755 app/models/challenge_signup.rb create mode 100755 app/models/challenge_signup_summary.rb create mode 100755 app/models/chapter.rb create mode 100755 app/models/character.rb create mode 100755 app/models/collection.rb create mode 100755 app/models/collection_item.rb create mode 100755 app/models/collection_participant.rb create mode 100755 app/models/collection_preference.rb create mode 100755 app/models/collection_profile.rb create mode 100755 app/models/comment.rb create mode 100755 app/models/common_tagging.rb create mode 100755 app/models/concerns/async_with_active_job.rb create mode 100755 app/models/concerns/async_with_resque.rb create mode 100755 app/models/concerns/creatable.rb create mode 100755 app/models/concerns/filterable.rb create mode 100755 app/models/concerns/globalized.rb create mode 100755 app/models/concerns/justifiable.rb create mode 100755 app/models/concerns/password_resets_limitable.rb create mode 100755 app/models/concerns/taggable.rb create mode 100755 app/models/concerns/user_loggable.rb create mode 100755 app/models/concerns/wrangleable.rb create mode 100755 app/models/creatorship.rb create mode 100755 app/models/download.rb create mode 100755 app/models/download_writer.rb create mode 100755 app/models/external_author.rb create mode 100755 app/models/external_author_name.rb create mode 100755 app/models/external_creatorship.rb create mode 100755 app/models/external_work.rb create mode 100755 app/models/fandom.rb create mode 100755 app/models/fannish_next_of_kin.rb create mode 100755 app/models/favorite_tag.rb create mode 100755 app/models/feedback.rb create mode 100755 app/models/feedback_reporters/abuse_reporter.rb create mode 100755 app/models/feedback_reporters/feedback_reporter.rb create mode 100755 app/models/feedback_reporters/support_reporter.rb create mode 100755 app/models/filter_count.rb create mode 100755 app/models/filter_tagging.rb create mode 100755 app/models/filter_updater.rb create mode 100755 app/models/freeform.rb create mode 100755 app/models/gift.rb create mode 100755 app/models/inbox_comment.rb create mode 100755 app/models/indexing/cache_master.rb create mode 100755 app/models/indexing/index_queue.rb create mode 100755 app/models/indexing/scheduled_reindex_job.rb create mode 100755 app/models/inherited_meta_tag_updater.rb create mode 100755 app/models/invitation.rb create mode 100755 app/models/invite_request.rb create mode 100755 app/models/known_issue.rb create mode 100755 app/models/kudo.rb create mode 100755 app/models/language.rb create mode 100755 app/models/last_wrangling_activity.rb create mode 100755 app/models/locale.rb create mode 100755 app/models/log_item.rb create mode 100755 app/models/media.rb create mode 100755 app/models/meta_tagging.rb create mode 100755 app/models/moderated_work.rb create mode 100755 app/models/mute.rb create mode 100755 app/models/offer.rb create mode 100755 app/models/opendoors.rb create mode 100755 app/models/potential_match.rb create mode 100755 app/models/potential_match_builder.rb create mode 100755 app/models/potential_match_settings.rb create mode 100755 app/models/potential_matcher/potential_matcher_constrained.rb create mode 100755 app/models/potential_matcher/potential_matcher_progress.rb create mode 100755 app/models/potential_matcher/potential_matcher_unconstrained.rb create mode 100755 app/models/potential_matcher/prompt_batch.rb create mode 100755 app/models/potential_matcher/prompt_tag_type_info.rb create mode 100755 app/models/preference.rb create mode 100755 app/models/profile.rb create mode 100755 app/models/prompt.rb create mode 100755 app/models/prompt_restriction.rb create mode 100755 app/models/pseud.rb create mode 100755 app/models/question.rb create mode 100755 app/models/rating.rb create mode 100755 app/models/reading.rb create mode 100755 app/models/redis_hit_counter.rb create mode 100755 app/models/redis_mail_queue.rb create mode 100755 app/models/related_work.rb create mode 100755 app/models/relationship.rb create mode 100755 app/models/request.rb create mode 100755 app/models/role.rb create mode 100755 app/models/roles_user.rb create mode 100755 app/models/scheduled_tag_job.rb create mode 100755 app/models/search/async_indexer.rb create mode 100755 app/models/search/bookmark_indexer.rb create mode 100755 app/models/search/bookmark_query.rb create mode 100755 app/models/search/bookmark_search_form.rb create mode 100755 app/models/search/bookmarkable_indexer.rb create mode 100755 app/models/search/bookmarkable_query.rb create mode 100755 app/models/search/bookmarked_external_work_indexer.rb create mode 100755 app/models/search/bookmarked_series_indexer.rb create mode 100755 app/models/search/bookmarked_work_indexer.rb create mode 100755 app/models/search/index_sweeper.rb create mode 100755 app/models/search/indexer.rb create mode 100755 app/models/search/pseud_indexer.rb create mode 100755 app/models/search/pseud_query.rb create mode 100755 app/models/search/pseud_search_form.rb create mode 100755 app/models/search/query.rb create mode 100755 app/models/search/query_cleaner.rb create mode 100755 app/models/search/query_facet.rb create mode 100755 app/models/search/query_result.rb create mode 100755 app/models/search/search_counts.rb create mode 100755 app/models/search/stat_counter_indexer.rb create mode 100755 app/models/search/tag_indexer.rb create mode 100755 app/models/search/tag_query.rb create mode 100755 app/models/search/tag_search_form.rb create mode 100755 app/models/search/taggable_query.rb create mode 100755 app/models/search/user_indexer.rb create mode 100755 app/models/search/user_query.rb create mode 100755 app/models/search/work_creator_indexer.rb create mode 100755 app/models/search/work_indexer.rb create mode 100755 app/models/search/work_query.rb create mode 100755 app/models/search/work_search_form.rb create mode 100755 app/models/search_range.rb create mode 100755 app/models/serial_work.rb create mode 100755 app/models/series.rb create mode 100755 app/models/skin.rb create mode 100755 app/models/skin_parent.rb create mode 100755 app/models/spam_report.rb create mode 100755 app/models/stat_counter.rb create mode 100644 app/models/status.rb create mode 100755 app/models/story_parser.rb create mode 100755 app/models/subscription.rb create mode 100755 app/models/tag.rb create mode 100755 app/models/tagging.rb create mode 100755 app/models/tagset_models/cast_nomination.rb create mode 100755 app/models/tagset_models/character_nomination.rb create mode 100755 app/models/tagset_models/fandom_nomination.rb create mode 100755 app/models/tagset_models/freeform_nomination.rb create mode 100755 app/models/tagset_models/owned_set_tagging.rb create mode 100755 app/models/tagset_models/owned_tag_set.rb create mode 100755 app/models/tagset_models/relationship_nomination.rb create mode 100755 app/models/tagset_models/set_tagging.rb create mode 100755 app/models/tagset_models/tag_nomination.rb create mode 100755 app/models/tagset_models/tag_set.rb create mode 100755 app/models/tagset_models/tag_set_association.rb create mode 100755 app/models/tagset_models/tag_set_nomination.rb create mode 100755 app/models/tagset_models/tag_set_ownership.rb create mode 100755 app/models/unsorted_tag.rb create mode 100755 app/models/user.rb create mode 100755 app/models/user_invite_request.rb create mode 100755 app/models/user_manager.rb create mode 100755 app/models/work.rb create mode 100755 app/models/work_original_creator.rb create mode 100755 app/models/work_skin.rb create mode 100755 app/models/wrangling_assignment.rb create mode 100755 app/models/wrangling_guideline.rb create mode 100755 app/policies/admin_activity_policy.rb create mode 100755 app/policies/admin_banner_policy.rb create mode 100755 app/policies/admin_blacklisted_email_policy.rb create mode 100755 app/policies/admin_post_policy.rb create mode 100755 app/policies/admin_setting_policy.rb create mode 100755 app/policies/api_key_policy.rb create mode 100755 app/policies/application_policy.rb create mode 100755 app/policies/archive_faq_policy.rb create mode 100755 app/policies/block_policy.rb create mode 100755 app/policies/bookmark_policy.rb create mode 100755 app/policies/comment_policy.rb create mode 100755 app/policies/external_work_policy.rb create mode 100755 app/policies/inbox_comment_policy.rb create mode 100755 app/policies/invitation_policy.rb create mode 100755 app/policies/invite_request_policy.rb create mode 100755 app/policies/known_issue_policy.rb create mode 100755 app/policies/language_policy.rb create mode 100755 app/policies/locale_policy.rb create mode 100755 app/policies/moderated_work_policy.rb create mode 100755 app/policies/mute_policy.rb create mode 100755 app/policies/profile_policy.rb create mode 100755 app/policies/pseud_policy.rb create mode 100755 app/policies/series_policy.rb create mode 100755 app/policies/skin_policy.rb create mode 100755 app/policies/user_creation_policy.rb create mode 100755 app/policies/user_manager_policy.rb create mode 100755 app/policies/user_policy.rb create mode 100755 app/policies/work_policy.rb create mode 100755 app/policies/wrangling_policy.rb create mode 100755 app/sweepers/collection_sweeper.rb create mode 100755 app/sweepers/feed_sweeper.rb create mode 100755 app/sweepers/pseud_sweeper.rb create mode 100755 app/sweepers/tag_set_sweeper.rb create mode 100755 app/validators/at_most_validator.rb create mode 100755 app/validators/attachment_validator.rb create mode 100755 app/validators/email_blacklist_validator.rb create mode 100755 app/validators/email_format_validator.rb create mode 100755 app/validators/not_blocked_validator.rb create mode 100755 app/validators/not_forbidden_name_validator.rb create mode 100755 app/validators/url_active_validator.rb create mode 100755 app/validators/url_format_validator.rb create mode 100755 app/views/abuse_reports/new.html.erb create mode 100755 app/views/admin/_admin_nav.html.erb create mode 100755 app/views/admin/_admin_options.html.erb create mode 100755 app/views/admin/_header.html.erb create mode 100755 app/views/admin/activities/index.html.erb create mode 100755 app/views/admin/activities/show.html.erb create mode 100755 app/views/admin/admin_invitations/find.html.erb create mode 100755 app/views/admin/admin_invitations/index.html.erb create mode 100755 app/views/admin/admin_invitations/new.html.erb create mode 100755 app/views/admin/admin_users/_user_creations_summary.html.erb create mode 100755 app/views/admin/admin_users/_user_form.html.erb create mode 100755 app/views/admin/admin_users/_user_history.html.erb create mode 100755 app/views/admin/admin_users/_user_listing.html.erb create mode 100755 app/views/admin/admin_users/_user_table.html.erb create mode 100755 app/views/admin/admin_users/bulk_search.html.erb create mode 100755 app/views/admin/admin_users/confirm_delete_user_creations.html.erb create mode 100755 app/views/admin/admin_users/creations.html.erb create mode 100755 app/views/admin/admin_users/index.html.erb create mode 100755 app/views/admin/admin_users/show.html.erb create mode 100755 app/views/admin/api/_api_key_form.html.erb create mode 100755 app/views/admin/api/_navigation.html.erb create mode 100755 app/views/admin/api/edit.html.erb create mode 100755 app/views/admin/api/index.html.erb create mode 100755 app/views/admin/api/new.html.erb create mode 100755 app/views/admin/banners/_banner.html.erb create mode 100755 app/views/admin/banners/_banner_form.html.erb create mode 100755 app/views/admin/banners/_navigation.html.erb create mode 100755 app/views/admin/banners/confirm_delete.html.erb create mode 100755 app/views/admin/banners/edit.html.erb create mode 100755 app/views/admin/banners/index.html.erb create mode 100755 app/views/admin/banners/new.html.erb create mode 100755 app/views/admin/banners/show.html.erb create mode 100755 app/views/admin/blacklisted_emails/index.html.erb create mode 100755 app/views/admin/mailer/password_change.html.erb create mode 100755 app/views/admin/mailer/password_change.text.erb create mode 100755 app/views/admin/mailer/reset_password_instructions.html.erb create mode 100755 app/views/admin/mailer/reset_password_instructions.text.erb create mode 100755 app/views/admin/passwords/edit.html.erb create mode 100755 app/views/admin/passwords/new.html.erb create mode 100755 app/views/admin/sessions/confirm_logout.html.erb create mode 100755 app/views/admin/sessions/new.html.erb create mode 100755 app/views/admin/settings/index.html.erb create mode 100755 app/views/admin/skins/_navigation.html.erb create mode 100755 app/views/admin/skins/index.html.erb create mode 100755 app/views/admin/skins/index_approved.html.erb create mode 100755 app/views/admin/skins/index_rejected.html.erb create mode 100755 app/views/admin/spam/index.html.erb create mode 100755 app/views/admin/user_creations/confirm_remove_pseud.html.erb create mode 100755 app/views/admin_mailer/send_spam_alert.html.erb create mode 100755 app/views/admin_mailer/send_spam_alert.text.erb create mode 100755 app/views/admin_mailer/set_password_notification.html.erb create mode 100755 app/views/admin_mailer/set_password_notification.text.erb create mode 100755 app/views/admin_posts/_admin_index.html.erb create mode 100755 app/views/admin_posts/_admin_post.html.erb create mode 100755 app/views/admin_posts/_admin_post_form.html.erb create mode 100755 app/views/admin_posts/_filters.html.erb create mode 100755 app/views/admin_posts/_sidebar.html.erb create mode 100755 app/views/admin_posts/edit.html.erb create mode 100755 app/views/admin_posts/index.html.erb create mode 100755 app/views/admin_posts/index.rss.builder create mode 100755 app/views/admin_posts/new.html.erb create mode 100755 app/views/admin_posts/show.html.erb create mode 100755 app/views/admins/index.html.erb create mode 100755 app/views/archive_faqs/_admin_index.html.erb create mode 100755 app/views/archive_faqs/_archive_faq_form.html.erb create mode 100755 app/views/archive_faqs/_archive_faq_order.html.erb create mode 100755 app/views/archive_faqs/_archive_faq_questions_order.html.erb create mode 100755 app/views/archive_faqs/_faq_index.html.erb create mode 100755 app/views/archive_faqs/_filters.html.erb create mode 100755 app/views/archive_faqs/_question_answer_fields.html.erb create mode 100755 app/views/archive_faqs/confirm_delete.html.erb create mode 100755 app/views/archive_faqs/edit.html.erb create mode 100755 app/views/archive_faqs/index.html.erb create mode 100755 app/views/archive_faqs/manage.html.erb create mode 100755 app/views/archive_faqs/new.html.erb create mode 100755 app/views/archive_faqs/show.html.erb create mode 100755 app/views/blocked/users/_blocked_user_blurb.html.erb create mode 100755 app/views/blocked/users/confirm_block.html.erb create mode 100755 app/views/blocked/users/confirm_unblock.html.erb create mode 100755 app/views/blocked/users/index.html.erb create mode 100755 app/views/bookmarks/_bookmark_blurb.html.erb create mode 100755 app/views/bookmarks/_bookmark_blurb_short.html.erb create mode 100755 app/views/bookmarks/_bookmark_form.html.erb create mode 100755 app/views/bookmarks/_bookmark_item_module.html.erb create mode 100755 app/views/bookmarks/_bookmark_owner_navigation.html.erb create mode 100755 app/views/bookmarks/_bookmark_user_module.html.erb create mode 100755 app/views/bookmarks/_bookmarkable_blurb.html.erb create mode 100755 app/views/bookmarks/_bookmarklet.html.erb create mode 100755 app/views/bookmarks/_bookmarks.html.erb create mode 100755 app/views/bookmarks/_external_work_fields.html.erb create mode 100755 app/views/bookmarks/_filters.html.erb create mode 100755 app/views/bookmarks/_search_form.html.erb create mode 100755 app/views/bookmarks/bookmark_form_dynamic.js.erb create mode 100755 app/views/bookmarks/confirm_delete.html.erb create mode 100755 app/views/bookmarks/edit.html.erb create mode 100755 app/views/bookmarks/index.html.erb create mode 100755 app/views/bookmarks/new.html.erb create mode 100755 app/views/bookmarks/search.html.erb create mode 100755 app/views/bookmarks/search_results.html.erb create mode 100755 app/views/bookmarks/share.html.erb create mode 100755 app/views/bookmarks/show.html.erb create mode 100755 app/views/challenge/gift_exchange/_challenge_main.html.erb create mode 100755 app/views/challenge/gift_exchange/_challenge_meta.html.erb create mode 100755 app/views/challenge/gift_exchange/_challenge_navigation_maintainer.html.erb create mode 100755 app/views/challenge/gift_exchange/_challenge_navigation_user.html.erb create mode 100755 app/views/challenge/gift_exchange/_challenge_requests.html.erb create mode 100755 app/views/challenge/gift_exchange/_challenge_sidebar.html.erb create mode 100755 app/views/challenge/gift_exchange/_challenge_signups.html.erb create mode 100755 app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb create mode 100755 app/views/challenge/gift_exchange/_gift_exchange_form.html.erb create mode 100755 app/views/challenge/gift_exchange/confirm_delete.html.erb create mode 100755 app/views/challenge/gift_exchange/edit.html.erb create mode 100755 app/views/challenge/gift_exchange/new.html.erb create mode 100755 app/views/challenge/prompt_meme/_challenge_main.html.erb create mode 100755 app/views/challenge/prompt_meme/_challenge_meta.html.erb create mode 100755 app/views/challenge/prompt_meme/_challenge_navigation_maintainer.html.erb create mode 100755 app/views/challenge/prompt_meme/_challenge_navigation_user.html.erb create mode 100755 app/views/challenge/prompt_meme/_challenge_requests.html.erb create mode 100755 app/views/challenge/prompt_meme/_challenge_sidebar.html.erb create mode 100755 app/views/challenge/prompt_meme/_challenge_signups.html.erb create mode 100755 app/views/challenge/prompt_meme/_prompt_meme_form.html.erb create mode 100755 app/views/challenge/prompt_meme/confirm_delete.html.erb create mode 100755 app/views/challenge/prompt_meme/edit.html.erb create mode 100755 app/views/challenge/prompt_meme/manage.html.erb create mode 100755 app/views/challenge/prompt_meme/new.html.erb create mode 100755 app/views/challenge/prompt_meme/show.html.erb create mode 100755 app/views/challenge/shared/_challenge_form_confirm_delete.html.erb create mode 100755 app/views/challenge/shared/_challenge_form_delete.html.erb create mode 100755 app/views/challenge/shared/_challenge_form_instructions.html.erb create mode 100755 app/views/challenge/shared/_challenge_form_schedule.html.erb create mode 100755 app/views/challenge/shared/_challenge_meta.html.erb create mode 100755 app/views/challenge/shared/_challenge_navigation_user.html.erb create mode 100755 app/views/challenge/shared/_challenge_requests.html.erb create mode 100755 app/views/challenge/shared/_challenge_signups.html.erb create mode 100755 app/views/challenge_assignments/_assignment_blurb.html.erb create mode 100755 app/views/challenge_assignments/_maintainer_index.html.erb create mode 100755 app/views/challenge_assignments/_maintainer_index_defaulted.html.erb create mode 100755 app/views/challenge_assignments/_maintainer_index_fulfilled.html.erb create mode 100755 app/views/challenge_assignments/_maintainer_index_unfulfilled.html.erb create mode 100755 app/views/challenge_assignments/_user_index.html.erb create mode 100755 app/views/challenge_assignments/confirm_purge.html.erb create mode 100755 app/views/challenge_assignments/index.html.erb create mode 100755 app/views/challenge_assignments/show.html.erb create mode 100755 app/views/challenge_claims/_maintainer_index.html.erb create mode 100755 app/views/challenge_claims/_unposted_claim_blurb.html.erb create mode 100755 app/views/challenge_claims/_user_index.html.erb create mode 100755 app/views/challenge_claims/index.html.erb create mode 100755 app/views/challenge_requests/index.html.erb create mode 100755 app/views/challenge_signups/_show_offers.html.erb create mode 100755 app/views/challenge_signups/_show_requests.html.erb create mode 100755 app/views/challenge_signups/_signup_controls.html.erb create mode 100755 app/views/challenge_signups/_signup_form.html.erb create mode 100755 app/views/challenge_signups/_signup_form_general_information.html.erb create mode 100755 app/views/challenge_signups/confirm_delete.html.erb create mode 100755 app/views/challenge_signups/edit.html.erb create mode 100755 app/views/challenge_signups/index.html.erb create mode 100755 app/views/challenge_signups/index.xls.erb create mode 100755 app/views/challenge_signups/new.html.erb create mode 100755 app/views/challenge_signups/show.html.erb create mode 100755 app/views/challenge_signups/summary.html.erb create mode 100755 app/views/chapters/_chapter.html.erb create mode 100755 app/views/chapters/_chapter_form.html.erb create mode 100755 app/views/chapters/_chapter_management.html.erb create mode 100755 app/views/chapters/_hidden_fields.html.erb create mode 100755 app/views/chapters/confirm_delete.html.erb create mode 100755 app/views/chapters/edit.html.erb create mode 100755 app/views/chapters/manage.html.erb create mode 100755 app/views/chapters/new.html.erb create mode 100755 app/views/chapters/preview.html.erb create mode 100755 app/views/chapters/show.html.erb create mode 100755 app/views/collectibles/_collectible_form.html.erb create mode 100755 app/views/collection_items/_collection_item_controls.html.erb create mode 100755 app/views/collection_items/_collection_item_form.html.erb create mode 100755 app/views/collection_items/_item_fields.html.erb create mode 100755 app/views/collection_items/index.html.erb create mode 100755 app/views/collection_items/new.html.erb create mode 100755 app/views/collection_mailer/item_added_notification.html.erb create mode 100755 app/views/collection_mailer/item_added_notification.text.erb create mode 100755 app/views/collection_participants/_add_participants_form.html.erb create mode 100755 app/views/collection_participants/_participant_form.html.erb create mode 100755 app/views/collection_participants/index.html.erb create mode 100755 app/views/collection_profile/_navigation.html.erb create mode 100755 app/views/collection_profile/show.html.erb create mode 100755 app/views/collections/_bookmarks_module.html.erb create mode 100755 app/views/collections/_challenge_collections.html.erb create mode 100755 app/views/collections/_challenge_list_top_navigation.html.erb create mode 100755 app/views/collections/_collection_blurb.html.erb create mode 100755 app/views/collections/_collection_form_delete.html.erb create mode 100755 app/views/collections/_collection_profile_navigation.html.erb create mode 100755 app/views/collections/_filters.html.erb create mode 100755 app/views/collections/_form.html.erb create mode 100755 app/views/collections/_header.html.erb create mode 100755 app/views/collections/_sidebar.html.erb create mode 100755 app/views/collections/_works_module.html.erb create mode 100755 app/views/collections/confirm_delete.html.erb create mode 100755 app/views/collections/edit.html.erb create mode 100755 app/views/collections/index.html.erb create mode 100755 app/views/collections/list_challenges.html.erb create mode 100755 app/views/collections/list_ge_challenges.html.erb create mode 100755 app/views/collections/list_pm_challenges.html.erb create mode 100755 app/views/collections/new.html.erb create mode 100755 app/views/collections/show.html.erb create mode 100755 app/views/comment_mailer/_comment_notification_footer.html.erb create mode 100755 app/views/comment_mailer/_comment_notification_footer.text.erb create mode 100755 app/views/comment_mailer/_comment_notification_footer_for_other.html.erb create mode 100755 app/views/comment_mailer/_comment_notification_footer_for_other.text.erb create mode 100755 app/views/comment_mailer/_comment_notification_footer_for_tag.html.erb create mode 100755 app/views/comment_mailer/_comment_notification_footer_for_tag.text.erb create mode 100755 app/views/comment_mailer/comment_notification.html.erb create mode 100755 app/views/comment_mailer/comment_notification.text.erb create mode 100755 app/views/comment_mailer/comment_reply_notification.html.erb create mode 100755 app/views/comment_mailer/comment_reply_notification.text.erb create mode 100755 app/views/comment_mailer/comment_reply_sent_notification.html.erb create mode 100755 app/views/comment_mailer/comment_reply_sent_notification.text.erb create mode 100755 app/views/comment_mailer/comment_sent_notification.html.erb create mode 100755 app/views/comment_mailer/comment_sent_notification.text.erb create mode 100755 app/views/comment_mailer/edited_comment_notification.html.erb create mode 100755 app/views/comment_mailer/edited_comment_notification.text.erb create mode 100755 app/views/comment_mailer/edited_comment_reply_notification.html.erb create mode 100755 app/views/comment_mailer/edited_comment_reply_notification.text.erb create mode 100755 app/views/comments/_comment_abbreviated_list.html.erb create mode 100755 app/views/comments/_comment_actions.html.erb create mode 100755 app/views/comments/_comment_form.html.erb create mode 100755 app/views/comments/_comment_thread.html.erb create mode 100755 app/views/comments/_commentable.html.erb create mode 100755 app/views/comments/_confirm_delete.html.erb create mode 100755 app/views/comments/_single_comment.html.erb create mode 100755 app/views/comments/add_comment_reply.js.erb create mode 100755 app/views/comments/cancel_comment_delete.js.erb create mode 100755 app/views/comments/cancel_comment_edit.js.erb create mode 100755 app/views/comments/cancel_comment_reply.js.erb create mode 100755 app/views/comments/delete_comment.js.erb create mode 100755 app/views/comments/edit.html.erb create mode 100755 app/views/comments/edit.js.erb create mode 100755 app/views/comments/hide_comments.js.erb create mode 100755 app/views/comments/index.html.erb create mode 100755 app/views/comments/new.html.erb create mode 100755 app/views/comments/review.js.erb create mode 100755 app/views/comments/show.html.erb create mode 100755 app/views/comments/show_comments.js.erb create mode 100755 app/views/comments/unreviewed.html.erb create mode 100755 app/views/comments/update.js.erb create mode 100755 app/views/creatorships/show.html.erb create mode 100755 app/views/downloads/_download_afterword.html.erb create mode 100755 app/views/downloads/_download_chapter.html.erb create mode 100755 app/views/downloads/_download_preface.html.erb create mode 100755 app/views/downloads/show.html.erb create mode 100755 app/views/errors/403.html.erb create mode 100755 app/views/errors/404.html.erb create mode 100755 app/views/errors/422.html.erb create mode 100755 app/views/errors/500.html.erb create mode 100755 app/views/errors/auth_error.html.erb create mode 100755 app/views/errors/timeout_error.html.erb create mode 100755 app/views/external_authors/_external_author_blurb.html.erb create mode 100755 app/views/external_authors/_external_author_description.html.erb create mode 100755 app/views/external_authors/_external_author_form.html.erb create mode 100755 app/views/external_authors/_external_author_name.html.erb create mode 100755 app/views/external_authors/_external_author_navigation.html.erb create mode 100755 app/views/external_authors/claim.html.erb create mode 100755 app/views/external_authors/edit.html.erb create mode 100755 app/views/external_authors/index.html.erb create mode 100755 app/views/external_works/_blurb.html.erb create mode 100755 app/views/external_works/_work_module.html.erb create mode 100755 app/views/external_works/edit.html.erb create mode 100755 app/views/external_works/fetch.js.erb create mode 100755 app/views/external_works/index.html.erb create mode 100755 app/views/external_works/new.html.erb create mode 100755 app/views/external_works/show.html.erb create mode 100755 app/views/fandoms/index.html.erb create mode 100755 app/views/fandoms/show.html.erb create mode 100755 app/views/fandoms/unassigned.html.erb create mode 100755 app/views/favorite_tags/_form.html.erb create mode 100755 app/views/feedbacks/new.html.erb create mode 100755 app/views/gifts/_gift_blurb.html.erb create mode 100755 app/views/gifts/_gift_search.html.erb create mode 100755 app/views/gifts/index.html.erb create mode 100755 app/views/hit_count/_include.html.erb create mode 100755 app/views/home/_content.html.erb create mode 100755 app/views/home/_dmca.html.erb create mode 100755 app/views/home/_fandoms.html.erb create mode 100755 app/views/home/_inbox_module.html.erb create mode 100755 app/views/home/_intro_module.html.erb create mode 100755 app/views/home/_news_module.html.erb create mode 100755 app/views/home/_privacy.html.erb create mode 100755 app/views/home/_tos.html.erb create mode 100755 app/views/home/_tos_navigation.html.erb create mode 100755 app/views/home/about.html.erb create mode 100755 app/views/home/content.html.erb create mode 100755 app/views/home/diversity_statement.html.erb create mode 100755 app/views/home/dmca.html.erb create mode 100755 app/views/home/donate.html.erb create mode 100755 app/views/home/first_login_help.html.erb create mode 100755 app/views/home/index.html.erb create mode 100755 app/views/home/lost_cookie.html.erb create mode 100755 app/views/home/privacy.html.erb create mode 100755 app/views/home/site_map.html.erb create mode 100755 app/views/home/site_pages.html.erb create mode 100755 app/views/home/tos.html.erb create mode 100755 app/views/home/tos_faq.html.erb create mode 100755 app/views/home/unicorn_test.html.erb create mode 100755 app/views/inbox/_approve_button.html.erb create mode 100755 app/views/inbox/_delete_form.html.erb create mode 100755 app/views/inbox/_inbox_comment_contents.html.erb create mode 100755 app/views/inbox/_read_form.html.erb create mode 100755 app/views/inbox/_reply_button.html.erb create mode 100755 app/views/inbox/reply.js.erb create mode 100755 app/views/inbox/show.html.erb create mode 100755 app/views/invitations/_invitation.html.erb create mode 100755 app/views/invitations/_user_invitations.html.erb create mode 100755 app/views/invitations/_user_invitations_navigation.html.erb create mode 100755 app/views/invitations/index.html.erb create mode 100755 app/views/invitations/manage.html.erb create mode 100755 app/views/invitations/show.html.erb create mode 100755 app/views/invite_requests/_index_closed.html.erb create mode 100755 app/views/invite_requests/_index_open.html.erb create mode 100755 app/views/invite_requests/_invitation.html.erb create mode 100755 app/views/invite_requests/_invite_request.html.erb create mode 100755 app/views/invite_requests/_no_invitation.html.erb create mode 100755 app/views/invite_requests/index.html.erb create mode 100755 app/views/invite_requests/manage.html.erb create mode 100755 app/views/invite_requests/show.html.erb create mode 100755 app/views/invite_requests/show.js.erb create mode 100755 app/views/invite_requests/status.html.erb create mode 100755 app/views/known_issues/_admin_index.html.erb create mode 100755 app/views/known_issues/_known_issues_form.html.erb create mode 100755 app/views/known_issues/edit.html.erb create mode 100755 app/views/known_issues/index.html.erb create mode 100755 app/views/known_issues/new.html.erb create mode 100755 app/views/known_issues/show.html.erb create mode 100755 app/views/kudo_mailer/batch_kudo_notification.html.erb create mode 100755 app/views/kudo_mailer/batch_kudo_notification.text.erb create mode 100755 app/views/kudos/_kudos.html.erb create mode 100755 app/views/kudos/create.js.erb create mode 100755 app/views/kudos/index.html.erb create mode 100755 app/views/kudos/index.js.erb create mode 100755 app/views/languages/_form.html.erb create mode 100755 app/views/languages/edit.html.erb create mode 100755 app/views/languages/index.html.erb create mode 100755 app/views/languages/new.html.erb create mode 100755 app/views/layouts/_banner.html.erb create mode 100755 app/views/layouts/_footer.html.erb create mode 100755 app/views/layouts/_header.html.erb create mode 100755 app/views/layouts/_includes.html.erb create mode 100755 app/views/layouts/_javascripts.html.erb create mode 100755 app/views/layouts/_proxy_notice.html.erb create mode 100755 app/views/layouts/_tos_prompt.html.erb create mode 100755 app/views/layouts/application.html.erb create mode 100755 app/views/layouts/barebones.html.erb create mode 100755 app/views/layouts/home.html.erb create mode 100755 app/views/layouts/mailer.html.erb create mode 100755 app/views/layouts/mailer.text.erb create mode 100755 app/views/layouts/session.html.erb create mode 100755 app/views/locales/_locale_form.html.erb create mode 100755 app/views/locales/_navigation.html.erb create mode 100755 app/views/locales/edit.html.erb create mode 100755 app/views/locales/index.html.erb create mode 100755 app/views/locales/new.html.erb create mode 100755 app/views/media/index.html.erb create mode 100755 app/views/menu/_menu_about.html.erb create mode 100755 app/views/menu/_menu_browse.html.erb create mode 100755 app/views/menu/_menu_fandoms.html.erb create mode 100644 app/views/menu/_menu_othersites.html.erb create mode 100755 app/views/menu/_menu_search.html.erb create mode 100755 app/views/menu/about.html.erb create mode 100755 app/views/menu/browse.html.erb create mode 100755 app/views/menu/fandoms.html.erb create mode 100755 app/views/menu/search.html.erb create mode 100755 app/views/muted/_muted_items_notice.html.erb create mode 100755 app/views/muted/users/_muted_user_blurb.html.erb create mode 100755 app/views/muted/users/confirm_mute.html.erb create mode 100755 app/views/muted/users/confirm_unmute.html.erb create mode 100755 app/views/muted/users/index.html.erb create mode 100755 app/views/opendoors/external_authors/index.html.erb create mode 100755 app/views/opendoors/external_authors/show.html.erb create mode 100755 app/views/opendoors/tools/_tools_navigation.html.erb create mode 100755 app/views/opendoors/tools/index.html.erb create mode 100755 app/views/orphans/_choose_pseud.html.erb create mode 100755 app/views/orphans/_orphan_pseud.html.erb create mode 100755 app/views/orphans/_orphan_series.html.erb create mode 100755 app/views/orphans/_orphan_user.html.erb create mode 100755 app/views/orphans/_orphan_work.html.erb create mode 100755 app/views/orphans/index.html.erb create mode 100755 app/views/orphans/new.html.erb create mode 100755 app/views/owned_tag_sets/_internal_tag_set_fields.html.erb create mode 100755 app/views/owned_tag_sets/_navigation.html.erb create mode 100755 app/views/owned_tag_sets/_show_fandoms_by_media.html.erb create mode 100755 app/views/owned_tag_sets/_show_tag_set_associations.html.erb create mode 100755 app/views/owned_tag_sets/_show_tag_set_tags.html.erb create mode 100755 app/views/owned_tag_sets/_show_tags_alpha_listbox.html.erb create mode 100755 app/views/owned_tag_sets/_show_tags_by_alpha.html.erb create mode 100755 app/views/owned_tag_sets/_show_tags_in_single_list.html.erb create mode 100755 app/views/owned_tag_sets/_tag_set_association_fields.html.erb create mode 100755 app/views/owned_tag_sets/_tag_set_associations_remove.html.erb create mode 100755 app/views/owned_tag_sets/_tag_set_blurb.html.erb create mode 100755 app/views/owned_tag_sets/_tag_set_form.html.erb create mode 100755 app/views/owned_tag_sets/_tag_set_form_management.html.erb create mode 100755 app/views/owned_tag_sets/batch_load.html.erb create mode 100755 app/views/owned_tag_sets/confirm_delete.html.erb create mode 100755 app/views/owned_tag_sets/edit.html.erb create mode 100755 app/views/owned_tag_sets/index.html.erb create mode 100755 app/views/owned_tag_sets/new.html.erb create mode 100755 app/views/owned_tag_sets/show.html.erb create mode 100755 app/views/owned_tag_sets/show_options.html.erb create mode 100755 app/views/owned_tag_sets/wrangle.html.erb create mode 100755 app/views/people/_author_blurb.html.erb create mode 100755 app/views/people/_search_form.html.erb create mode 100755 app/views/people/index.html.erb create mode 100755 app/views/people/search.html.erb create mode 100755 app/views/potential_match_settings/_potential_match_settings_form.html.erb create mode 100755 app/views/potential_matches/_assignment_with_request.html.erb create mode 100755 app/views/potential_matches/_assignments.html.erb create mode 100755 app/views/potential_matches/_in_progress.html.erb create mode 100755 app/views/potential_matches/_invalid_signups.html.erb create mode 100755 app/views/potential_matches/_match_navigation.html.erb create mode 100755 app/views/potential_matches/_no_match_required.html.erb create mode 100755 app/views/potential_matches/_no_potential_givers.html.erb create mode 100755 app/views/potential_matches/_no_potential_recipients.html.erb create mode 100755 app/views/potential_matches/_potential_matches.html.erb create mode 100755 app/views/potential_matches/index.html.erb create mode 100755 app/views/potential_matches/list_potential_matches.html.erb create mode 100755 app/views/potential_matches/show.html.erb create mode 100755 app/views/preferences/index.html.erb create mode 100755 app/views/profile/pseuds.js.erb create mode 100755 app/views/profile/show.html.erb create mode 100755 app/views/prompt_restrictions/_prompt_restriction_form.html.erb create mode 100755 app/views/prompts/_prompt_blurb.html.erb create mode 100755 app/views/prompts/_prompt_controls.html.erb create mode 100755 app/views/prompts/_prompt_form.html.erb create mode 100755 app/views/prompts/_prompt_form_tag_options.html.erb create mode 100755 app/views/prompts/_prompt_navigation.html.erb create mode 100755 app/views/prompts/edit.html.erb create mode 100755 app/views/prompts/index.html.erb create mode 100755 app/views/prompts/new.html.erb create mode 100755 app/views/prompts/show.html.erb create mode 100755 app/views/pseuds/_byline.html.erb create mode 100755 app/views/pseuds/_pseud_blurb.html.erb create mode 100755 app/views/pseuds/_pseud_module.html.erb create mode 100755 app/views/pseuds/_pseuds_form.html.erb create mode 100755 app/views/pseuds/delete_preview.html.erb create mode 100755 app/views/pseuds/edit.html.erb create mode 100755 app/views/pseuds/index.html.erb create mode 100755 app/views/pseuds/new.html.erb create mode 100755 app/views/pseuds/show.html.erb create mode 100755 app/views/questions/manage.html.erb create mode 100755 app/views/readings/_reading_blurb.html.erb create mode 100755 app/views/readings/index.html.erb create mode 100755 app/views/redirect/show.html.erb create mode 100755 app/views/related_works/_approve.html.erb create mode 100755 app/views/related_works/_remove.html.erb create mode 100755 app/views/related_works/index.html.erb create mode 100755 app/views/related_works/show.html.erb create mode 100755 app/views/series/_series_blurb.html.erb create mode 100755 app/views/series/_series_module.html.erb create mode 100755 app/views/series/_series_navigation.html.erb create mode 100755 app/views/series/_series_order.html.erb create mode 100755 app/views/series/confirm_delete.html.erb create mode 100755 app/views/series/edit.html.erb create mode 100755 app/views/series/index.html.erb create mode 100755 app/views/series/manage.html.erb create mode 100755 app/views/series/new.html.erb create mode 100755 app/views/series/show.html.erb create mode 100755 app/views/share/_embed_link_bookmark.html.erb create mode 100755 app/views/share/_embed_link_header.html.erb create mode 100755 app/views/share/_embed_link_work.html.erb create mode 100755 app/views/share/_embed_meta.html.erb create mode 100755 app/views/share/_embed_meta_bookmark.erb create mode 100755 app/views/share/_share.html.erb create mode 100755 app/views/shared/_search_nav.html.erb create mode 100755 app/views/skins/_form.html.erb create mode 100755 app/views/skins/_header.html.erb create mode 100755 app/views/skins/_revert_skin_form.html.erb create mode 100755 app/views/skins/_skin_actions.html.erb create mode 100755 app/views/skins/_skin_module.html.erb create mode 100755 app/views/skins/_skin_navigation.html.erb create mode 100755 app/views/skins/_skin_parent_fields.html.erb create mode 100755 app/views/skins/_skin_style_block.html.erb create mode 100755 app/views/skins/_skin_type_navigation.html.erb create mode 100755 app/views/skins/_update_skin_form.html.erb create mode 100755 app/views/skins/_wizard_form.html.erb create mode 100755 app/views/skins/confirm_delete.html.erb create mode 100755 app/views/skins/edit.html.erb create mode 100755 app/views/skins/index.html.erb create mode 100755 app/views/skins/new.html.erb create mode 100755 app/views/skins/new_wizard.html.erb create mode 100755 app/views/skins/show.html.erb create mode 100755 app/views/stats/_navigation.html.erb create mode 100755 app/views/stats/index.html.erb create mode 100755 app/views/stats/no_stats.html.erb create mode 100644 app/views/statuses/edit.html.erb create mode 100644 app/views/statuses/index.html.erb create mode 100644 app/views/statuses/new.html.erb create mode 100644 app/views/statuses/show.html.erb create mode 100644 app/views/statuses/timeline.html.erb create mode 100755 app/views/subscriptions/_form.html.erb create mode 100755 app/views/subscriptions/confirm_delete_all.erb create mode 100755 app/views/subscriptions/index.html.erb create mode 100755 app/views/tag_set_associations/index.html.erb create mode 100755 app/views/tag_set_nominations/_nomination_form.html.erb create mode 100755 app/views/tag_set_nominations/_review.html.erb create mode 100755 app/views/tag_set_nominations/_review_cast.html.erb create mode 100755 app/views/tag_set_nominations/_review_fandoms.html.erb create mode 100755 app/views/tag_set_nominations/_review_individual_nom.html.erb create mode 100755 app/views/tag_set_nominations/_review_thead.html.erb create mode 100755 app/views/tag_set_nominations/_show_by_tag_type.html.erb create mode 100755 app/views/tag_set_nominations/_show_tag_status.html.erb create mode 100755 app/views/tag_set_nominations/_tag_nominations.html.erb create mode 100755 app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb create mode 100755 app/views/tag_set_nominations/confirm_delete.html.erb create mode 100755 app/views/tag_set_nominations/confirm_destroy_multiple.html.erb create mode 100755 app/views/tag_set_nominations/edit.html.erb create mode 100755 app/views/tag_set_nominations/index.html.erb create mode 100755 app/views/tag_set_nominations/new.html.erb create mode 100755 app/views/tag_set_nominations/show.html.erb create mode 100755 app/views/tag_wranglers/index.html.erb create mode 100755 app/views/tag_wranglers/show.html.erb create mode 100755 app/views/tag_wrangling_supervisor_mailer/wrangler_username_change_notification.html.erb create mode 100755 app/views/tag_wrangling_supervisor_mailer/wrangler_username_change_notification.text.erb create mode 100755 app/views/tag_wranglings/_wrangler_dashboard.html.erb create mode 100755 app/views/tag_wranglings/index.html.erb create mode 100755 app/views/tags/_search_form.html.erb create mode 100755 app/views/tags/edit.html.erb create mode 100755 app/views/tags/feed.atom.builder create mode 100755 app/views/tags/index.html.erb create mode 100755 app/views/tags/new.html.erb create mode 100755 app/views/tags/search.html.erb create mode 100755 app/views/tags/show.html.erb create mode 100755 app/views/tags/show_hidden.js.erb create mode 100755 app/views/tags/wrangle.html.erb create mode 100755 app/views/tos_update_mailer/tos_update_notification.html.erb create mode 100755 app/views/tos_update_mailer/tos_update_notification.text.erb create mode 100755 app/views/troubleshooting/show.html.erb create mode 100755 app/views/unsorted_tags/index.html.erb create mode 100755 app/views/user_invite_requests/index.html.erb create mode 100755 app/views/user_invite_requests/new.html.erb create mode 100755 app/views/user_mailer/_work_info.html.erb create mode 100755 app/views/user_mailer/_work_info.text.erb create mode 100755 app/views/user_mailer/abuse_report.html.erb create mode 100755 app/views/user_mailer/abuse_report.text.erb create mode 100755 app/views/user_mailer/admin_deleted_work_notification.html.erb create mode 100755 app/views/user_mailer/admin_deleted_work_notification.text.erb create mode 100755 app/views/user_mailer/admin_hidden_work_notification.html.erb create mode 100755 app/views/user_mailer/admin_hidden_work_notification.text.erb create mode 100755 app/views/user_mailer/admin_spam_work_notification.html.erb create mode 100755 app/views/user_mailer/admin_spam_work_notification.text.erb create mode 100755 app/views/user_mailer/anonymous_or_unrevealed_notification.html.erb create mode 100755 app/views/user_mailer/anonymous_or_unrevealed_notification.text.erb create mode 100755 app/views/user_mailer/archivist_added_to_collection_notification.html.erb create mode 100755 app/views/user_mailer/archivist_added_to_collection_notification.text.erb create mode 100755 app/views/user_mailer/batch_subscription_notification.html.erb create mode 100755 app/views/user_mailer/batch_subscription_notification.text.erb create mode 100755 app/views/user_mailer/challenge_assignment_notification.html.erb create mode 100755 app/views/user_mailer/challenge_assignment_notification.text.erb create mode 100755 app/views/user_mailer/change_email.html.erb create mode 100755 app/views/user_mailer/change_email.text.erb create mode 100755 app/views/user_mailer/change_username.html.erb create mode 100755 app/views/user_mailer/change_username.text.erb create mode 100755 app/views/user_mailer/claim_notification.html.erb create mode 100755 app/views/user_mailer/claim_notification.text.erb create mode 100755 app/views/user_mailer/collection_notification.html.erb create mode 100755 app/views/user_mailer/collection_notification.text.erb create mode 100755 app/views/user_mailer/creatorship_notification.html.erb create mode 100755 app/views/user_mailer/creatorship_notification.text.erb create mode 100755 app/views/user_mailer/creatorship_notification_archivist.html.erb create mode 100755 app/views/user_mailer/creatorship_notification_archivist.text.erb create mode 100755 app/views/user_mailer/creatorship_request.html.erb create mode 100755 app/views/user_mailer/creatorship_request.text.erb create mode 100755 app/views/user_mailer/delete_signup_notification.text.erb create mode 100755 app/views/user_mailer/delete_work_notification.html.erb create mode 100755 app/views/user_mailer/delete_work_notification.text.erb create mode 100755 app/views/user_mailer/feedback.html.erb create mode 100755 app/views/user_mailer/feedback.text.erb create mode 100755 app/views/user_mailer/invalid_signup_notification.html.erb create mode 100755 app/views/user_mailer/invalid_signup_notification.text.erb create mode 100755 app/views/user_mailer/invitation.html.erb create mode 100755 app/views/user_mailer/invitation.text.erb create mode 100755 app/views/user_mailer/invitation_to_claim.html.erb create mode 100755 app/views/user_mailer/invitation_to_claim.text.erb create mode 100755 app/views/user_mailer/invite_increase_notification.html.erb create mode 100755 app/views/user_mailer/invite_increase_notification.text.erb create mode 100755 app/views/user_mailer/invite_request_declined.html.erb create mode 100755 app/views/user_mailer/invite_request_declined.text.erb create mode 100755 app/views/user_mailer/invited_to_collection_notification.html.erb create mode 100755 app/views/user_mailer/invited_to_collection_notification.text.erb create mode 100755 app/views/user_mailer/potential_match_generation_notification.html.erb create mode 100755 app/views/user_mailer/potential_match_generation_notification.text.erb create mode 100755 app/views/user_mailer/prompter_notification.html.erb create mode 100755 app/views/user_mailer/prompter_notification.text.erb create mode 100755 app/views/user_mailer/recipient_notification.html.erb create mode 100755 app/views/user_mailer/recipient_notification.text.erb create mode 100755 app/views/user_mailer/related_work_notification.html.erb create mode 100755 app/views/user_mailer/related_work_notification.text.erb create mode 100755 app/views/user_mailer/signup_notification.html.erb create mode 100755 app/views/user_mailer/signup_notification.text.erb create mode 100755 app/views/users/_admin_change_username.html.erb create mode 100755 app/views/users/_contents.html.erb create mode 100755 app/views/users/_edit_header_navigation.html.erb create mode 100755 app/views/users/_edit_user_navigation.html.erb create mode 100755 app/views/users/_header.html.erb create mode 100755 app/views/users/_header_navigation.html.erb create mode 100755 app/views/users/_sidebar.html.erb create mode 100755 app/views/users/change_email.html.erb create mode 100755 app/views/users/change_password.html.erb create mode 100755 app/views/users/change_username.html.erb create mode 100755 app/views/users/confirm_change_email.html.erb create mode 100755 app/views/users/confirmation.html.erb create mode 100755 app/views/users/delete_confirmation.html.erb create mode 100755 app/views/users/delete_preview.html.erb create mode 100755 app/views/users/edit.html.erb create mode 100755 app/views/users/end_banner.js.erb create mode 100755 app/views/users/end_first_login.js.erb create mode 100755 app/views/users/mailer/confirmation_instructions.html.erb create mode 100755 app/views/users/mailer/confirmation_instructions.text.erb create mode 100755 app/views/users/mailer/password_change.html.erb create mode 100755 app/views/users/mailer/password_change.text.erb create mode 100755 app/views/users/mailer/reset_password_instructions.html.erb create mode 100755 app/views/users/mailer/reset_password_instructions.text.erb create mode 100755 app/views/users/passwords/edit.html.erb create mode 100755 app/views/users/passwords/new.html.erb create mode 100755 app/views/users/registrations/_legal.html.erb create mode 100755 app/views/users/registrations/_passwd.html.erb create mode 100755 app/views/users/registrations/new.html.erb create mode 100755 app/views/users/sessions/_greeting.html.erb create mode 100755 app/views/users/sessions/_login.html.erb create mode 100755 app/views/users/sessions/_passwd.html.erb create mode 100755 app/views/users/sessions/_passwd_small.html.erb create mode 100755 app/views/users/sessions/confirm_logout.html.erb create mode 100755 app/views/users/sessions/new.html.erb create mode 100755 app/views/users/show.html.erb create mode 100755 app/views/works/_adult.html.erb create mode 100755 app/views/works/_collection_filters.html.erb create mode 100755 app/views/works/_filters.html.erb create mode 100755 app/views/works/_hidden_fields.html.erb create mode 100755 app/views/works/_meta.html.erb create mode 100755 app/views/works/_mystery_blurb.html.erb create mode 100755 app/views/works/_notes_form.html.erb create mode 100755 app/views/works/_search_box.html.erb create mode 100755 app/views/works/_search_form.html.erb create mode 100755 app/views/works/_standard_form.html.erb create mode 100755 app/views/works/_work_abbreviated_list.html.erb create mode 100755 app/views/works/_work_approved_children.html.erb create mode 100755 app/views/works/_work_blurb.html.erb create mode 100755 app/views/works/_work_endnotes.html.erb create mode 100755 app/views/works/_work_form_associations_language.html.erb create mode 100755 app/views/works/_work_form_pseuds.html.erb create mode 100755 app/views/works/_work_form_tags.html.erb create mode 100755 app/views/works/_work_header.html.erb create mode 100755 app/views/works/_work_header_navigation.html.erb create mode 100755 app/views/works/_work_header_notes.html.erb create mode 100755 app/views/works/_work_module.html.erb create mode 100755 app/views/works/_work_series_links.html.erb create mode 100755 app/views/works/_work_unrevealed_notice.erb create mode 100755 app/views/works/collected.html.erb create mode 100755 app/views/works/confirm_delete.html.erb create mode 100755 app/views/works/confirm_delete_multiple.html.erb create mode 100755 app/views/works/drafts.html.erb create mode 100755 app/views/works/edit.html.erb create mode 100755 app/views/works/edit_multiple.html.erb create mode 100755 app/views/works/edit_tags.html.erb create mode 100755 app/views/works/import.html.erb create mode 100755 app/views/works/index.html.erb create mode 100755 app/views/works/navigate.html.erb create mode 100755 app/views/works/new.html.erb create mode 100755 app/views/works/new_import.html.erb create mode 100755 app/views/works/preview.html.erb create mode 100755 app/views/works/preview_tags.html.erb create mode 100755 app/views/works/search.html.erb create mode 100755 app/views/works/search_results.html.erb create mode 100755 app/views/works/share.html.erb create mode 100755 app/views/works/show.html.erb create mode 100755 app/views/works/show_multiple.html.erb create mode 100755 app/views/wrangling_guidelines/_admin_index.html.erb create mode 100755 app/views/wrangling_guidelines/_wrangling_guideline_form.html.erb create mode 100755 app/views/wrangling_guidelines/_wrangling_guideline_order.html.erb create mode 100755 app/views/wrangling_guidelines/edit.html.erb create mode 100755 app/views/wrangling_guidelines/index.html.erb create mode 100755 app/views/wrangling_guidelines/manage.html.erb create mode 100755 app/views/wrangling_guidelines/new.html.erb create mode 100755 app/views/wrangling_guidelines/show.html.erb create mode 100755 bin/brakeman create mode 100755 bin/bundle create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/reload_elastic create mode 100755 bin/rubocop create mode 100755 bin/setup create mode 100755 bin/update create mode 100755 config.ru create mode 100755 config/application.rb create mode 100755 config/boot.rb create mode 100755 config/brakeman.yml create mode 100755 config/cable.yml create mode 100755 config/config.yml create mode 100755 config/cucumber.yml create mode 100755 config/database.example create mode 100755 config/deploy.rb create mode 100755 config/deploy/production.rb create mode 100755 config/deploy/staging.rb create mode 100755 config/docker/Dockerfile create mode 100755 config/docker/local.yml create mode 100755 config/docker/redis.yml create mode 100755 config/environment.rb create mode 100755 config/environments/production.rb create mode 100755 config/environments/staging.rb create mode 100755 config/environments/test.rb create mode 100755 config/gh-actions/database.yml create mode 100755 config/gh-actions/local.yml create mode 100755 config/gh-actions/redis.yml create mode 100755 config/i18n-tasks.yml create mode 100755 config/initializers/active_record_log_subscriber.rb create mode 100755 config/initializers/active_record_query_trace.rb create mode 100755 config/initializers/active_record_schema_ignore_tables.rb create mode 100755 config/initializers/application_controller_renderer.rb create mode 100755 config/initializers/archive_config/locale.rb create mode 100755 config/initializers/archive_config/settings_for_admin.rb create mode 100755 config/initializers/assets.rb create mode 100755 config/initializers/backtrace_silencers.rb create mode 100755 config/initializers/content_security_policy.rb create mode 100755 config/initializers/cookies_serializer.rb create mode 100755 config/initializers/cors.rb create mode 100755 config/initializers/departure.rb create mode 100755 config/initializers/devise.rb create mode 100755 config/initializers/filter_parameter_logging.rb create mode 100755 config/initializers/gem-plugin_config/acts_as_commentable.rb create mode 100755 config/initializers/gem-plugin_config/elasticsearch.rb create mode 100755 config/initializers/gem-plugin_config/escape_utils_config.rb create mode 100755 config/initializers/gem-plugin_config/pagy.rb create mode 100755 config/initializers/gem-plugin_config/permit_yo_config.rb create mode 100755 config/initializers/gem-plugin_config/redis.rb create mode 100755 config/initializers/gem-plugin_config/resque.rb create mode 100755 config/initializers/gem-plugin_config/sanitizer_config.rb create mode 100755 config/initializers/gem-plugin_config/webmock.rb create mode 100755 config/initializers/gem-plugin_config/will_paginate_config.rb create mode 100755 config/initializers/inflections.rb create mode 100755 config/initializers/mime_types.rb create mode 100755 config/initializers/monkeypatches/akismetor.rb create mode 100755 config/initializers/monkeypatches/deliver_after_commit.rb create mode 100755 config/initializers/monkeypatches/fix_phraseapp.rb create mode 100755 config/initializers/monkeypatches/mailers_controller.rb create mode 100755 config/initializers/monkeypatches/override_default_form_field_sizes.rb create mode 100755 config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb create mode 100755 config/initializers/monkeypatches/translate_string.rb create mode 100755 config/initializers/permissions_policy.rb create mode 100755 config/initializers/phraseapp_in_context_editor.rb create mode 100755 config/initializers/rack_attack.rb create mode 100755 config/initializers/rollout_init.rb create mode 100755 config/initializers/sentry.rb create mode 100755 config/initializers/session_store.rb create mode 100755 config/initializers/wrap_parameters.rb create mode 100755 config/locales/README.md create mode 100755 config/locales/controllers/en.yml create mode 100755 config/locales/devise/en.yml create mode 100755 config/locales/helpers/en.yml create mode 100755 config/locales/mailers/en.yml create mode 100755 config/locales/mailers/en.yml.save create mode 100755 config/locales/models/en.yml create mode 100755 config/locales/phrase-exports/README.md create mode 100755 config/locales/phrase-exports/af.yml create mode 100755 config/locales/phrase-exports/ar.yml create mode 100755 config/locales/phrase-exports/bg.yml create mode 100755 config/locales/phrase-exports/bn.yml create mode 100755 config/locales/phrase-exports/ca.yml create mode 100755 config/locales/phrase-exports/cs.yml create mode 100755 config/locales/phrase-exports/cy.yml create mode 100755 config/locales/phrase-exports/da.yml create mode 100755 config/locales/phrase-exports/de.yml create mode 100755 config/locales/phrase-exports/el.yml create mode 100755 config/locales/phrase-exports/es.yml create mode 100755 config/locales/phrase-exports/fa.yml create mode 100755 config/locales/phrase-exports/fi.yml create mode 100755 config/locales/phrase-exports/fil.yml create mode 100755 config/locales/phrase-exports/fr.yml create mode 100755 config/locales/phrase-exports/he.yml create mode 100755 config/locales/phrase-exports/hi.yml create mode 100755 config/locales/phrase-exports/hr.yml create mode 100755 config/locales/phrase-exports/hu.yml create mode 100755 config/locales/phrase-exports/id.yml create mode 100755 config/locales/phrase-exports/it.yml create mode 100755 config/locales/phrase-exports/ja.yml create mode 100755 config/locales/phrase-exports/ko.yml create mode 100755 config/locales/phrase-exports/lt.yml create mode 100755 config/locales/phrase-exports/lv.yml create mode 100755 config/locales/phrase-exports/mk.yml create mode 100755 config/locales/phrase-exports/mr.yml create mode 100755 config/locales/phrase-exports/ms.yml create mode 100755 config/locales/phrase-exports/nb.yml create mode 100755 config/locales/phrase-exports/nl.yml create mode 100755 config/locales/phrase-exports/pl.yml create mode 100755 config/locales/phrase-exports/pt-BR.yml create mode 100755 config/locales/phrase-exports/pt-PT.yml create mode 100755 config/locales/phrase-exports/ro.yml create mode 100755 config/locales/phrase-exports/ru.yml create mode 100755 config/locales/phrase-exports/scr.yml create mode 100755 config/locales/phrase-exports/sk.yml create mode 100755 config/locales/phrase-exports/sl.yml create mode 100755 config/locales/phrase-exports/sv.yml create mode 100755 config/locales/phrase-exports/th.yml create mode 100755 config/locales/phrase-exports/tr.yml create mode 100755 config/locales/phrase-exports/uk.yml create mode 100755 config/locales/phrase-exports/vi.yml create mode 100755 config/locales/phrase-exports/zh-CN.yml create mode 100755 config/locales/rails-i18n/locale/fil.yml create mode 100755 config/locales/rails-i18n/locale/mr.yml create mode 100755 config/locales/rails-i18n/pluralization/fil.rb create mode 100755 config/locales/rails-i18n/pluralization/hr.rb create mode 100755 config/locales/rails-i18n/pluralization/mr.rb create mode 100755 config/locales/validators/en.yml create mode 100755 config/locales/views/en.yml create mode 100755 config/locales/views/ru.yml create mode 100755 config/locales/views/uk.yml create mode 100755 config/locales/views/zh-CN.yml create mode 100755 config/redis-cucumber.conf.example create mode 100755 config/redis.example create mode 100755 config/resque_schedule.yml create mode 100755 config/routes.rb create mode 100755 config/s3.example create mode 100755 config/schedule.rb create mode 100755 config/schedule_production.rb create mode 100755 config/servers.yml create mode 100755 config/storage.yml create mode 100755 docker-compose-example.yml create mode 100755 entrypoints/sc-entrypoint.sh create mode 100755 entrypoints/worker-entrypoint.sh create mode 100755 factories/abuse_reports.rb create mode 100755 factories/admin.rb create mode 100755 factories/admin_banner.rb create mode 100755 factories/admin_blacklisted_email.rb create mode 100755 factories/admin_post.rb create mode 100755 factories/api_key.rb create mode 100755 factories/archive_faqs.rb create mode 100755 factories/bookmarks.rb create mode 100755 factories/challenge_claims.rb create mode 100755 factories/challenges.rb create mode 100755 factories/chapters.rb create mode 100755 factories/collections.rb create mode 100755 factories/comments.rb create mode 100755 factories/fannish_next_of_kin.rb create mode 100755 factories/favorite_tags.rb create mode 100755 factories/feedback.rb create mode 100755 factories/gift.rb create mode 100755 factories/invitations.rb create mode 100755 factories/known_issues.rb create mode 100755 factories/kudos.rb create mode 100755 factories/language.rb create mode 100755 factories/last_wrangling_activity.rb create mode 100755 factories/locales.rb create mode 100755 factories/prompt.rb create mode 100755 factories/prompt_restriction.rb create mode 100755 factories/pseuds.rb create mode 100755 factories/readings.rb create mode 100755 factories/related_works.rb create mode 100755 factories/serial_work.rb create mode 100755 factories/series.rb create mode 100755 factories/skins.rb create mode 100755 factories/subscriptions.rb create mode 100755 factories/tags.rb create mode 100755 factories/user_invite_requests.rb create mode 100755 factories/users.rb create mode 100755 factories/work_original_creators.rb create mode 100755 factories/works.rb create mode 100755 factories/wrangling_assignments.rb create mode 100755 factories/wrangling_guideline.rb create mode 100755 features/admins/admin_email_blacklist.feature create mode 100755 features/admins/admin_invitations.feature create mode 100755 features/admins/admin_languages.feature create mode 100755 features/admins/admin_locales.feature create mode 100755 features/admins/admin_post_faqs.feature create mode 100755 features/admins/admin_post_issues.feature create mode 100755 features/admins/admin_post_news.feature create mode 100755 features/admins/admin_reorder_faq.feature create mode 100755 features/admins/admin_reorder_faq_questions.feature create mode 100755 features/admins/admin_settings.feature create mode 100755 features/admins/admin_skins.feature create mode 100755 features/admins/admin_spam.feature create mode 100755 features/admins/admin_tasks.feature create mode 100755 features/admins/admin_works.feature create mode 100755 features/admins/authenticate_admins.feature create mode 100755 features/admins/users/admin_abuse_users.feature create mode 100755 features/admins/users/admin_find_users.feature create mode 100755 features/admins/users/admin_fnok.feature create mode 100755 features/admins/users/admin_manage_users.feature create mode 100755 features/bookmarks/bookmark_browse.feature create mode 100755 features/bookmarks/bookmark_create.feature create mode 100755 features/bookmarks/bookmark_external.feature create mode 100755 features/bookmarks/bookmark_filter.feature create mode 100755 features/bookmarks/bookmark_indexing.feature create mode 100755 features/bookmarks/bookmark_privacy.feature create mode 100755 features/bookmarks/bookmark_search.feature create mode 100755 features/bookmarks/bookmark_share.feature create mode 100755 features/bookmarks/delete_bookmarkable.feature create mode 100755 features/collections/collectible_closed_collection.feature create mode 100755 features/collections/collectible_moderated_collection.feature create mode 100755 features/collections/collectible_multiple_collections.feature create mode 100755 features/collections/collectible_open_collection.feature create mode 100755 features/collections/collection_anonymity.feature create mode 100755 features/collections/collection_browse.feature create mode 100755 features/collections/collection_create.feature create mode 100755 features/collections/collection_dashboard.feature create mode 100755 features/collections/collection_invite.feature create mode 100755 features/collections/collection_navigation.feature create mode 100755 features/collections/collection_notification.feature create mode 100755 features/collections/collection_participants.feature create mode 100755 features/comments_and_kudos/add_comment.feature create mode 100755 features/comments_and_kudos/admin_info.feature create mode 100755 features/comments_and_kudos/comment_blocking.feature create mode 100755 features/comments_and_kudos/comment_moderation.feature create mode 100755 features/comments_and_kudos/comments_adminposts.feature create mode 100755 features/comments_and_kudos/comments_delete.feature create mode 100755 features/comments_and_kudos/comments_pagination.feature create mode 100755 features/comments_and_kudos/comments_redirect.feature create mode 100755 features/comments_and_kudos/frozen_comments.feature create mode 100755 features/comments_and_kudos/guest_comment_replies.feature create mode 100755 features/comments_and_kudos/guest_comments.feature create mode 100755 features/comments_and_kudos/hidden_comments.feature create mode 100755 features/comments_and_kudos/hidden_works.feature create mode 100755 features/comments_and_kudos/image_safety_mode.feature create mode 100755 features/comments_and_kudos/inbox.feature create mode 100755 features/comments_and_kudos/kudos.feature create mode 100755 features/comments_and_kudos/kudos_pagination.feature create mode 100755 features/comments_and_kudos/official_comments.feature create mode 100755 features/comments_and_kudos/spam_comments.feature create mode 100755 features/fixtures/icon.bmp create mode 100755 features/fixtures/icon.gif create mode 100755 features/fixtures/icon.jpg create mode 100755 features/fixtures/icon.png create mode 100755 features/fixtures/skin_test_preview.png create mode 100755 features/gift_exchanges/challenge_giftexchange.feature create mode 100755 features/gift_exchanges/challenge_giftexchange_tagsets.feature create mode 100755 features/gift_exchanges/challenge_yuletide.feature create mode 100755 features/gift_exchanges/notification_emails.feature create mode 100755 features/gift_exchanges/potential_matches.feature create mode 100755 features/gift_exchanges/signup_summary.feature create mode 100755 features/importing/archivist.feature create mode 100755 features/importing/archivist_creatorships.feature create mode 100755 features/importing/work_import.feature create mode 100755 features/importing/work_import_da.feature create mode 100755 features/importing/work_import_dw.feature create mode 100755 features/importing/work_import_errors.feature create mode 100755 features/importing/work_import_ffn.feature create mode 100755 features/importing/work_import_lj.feature create mode 100755 features/other_a/abuse_report.feature create mode 100755 features/other_a/accept_header.feature create mode 100755 features/other_a/autocomplete.feature create mode 100755 features/other_a/banner_general.feature create mode 100755 features/other_a/banner_login.feature create mode 100755 features/other_a/gift.feature create mode 100755 features/other_a/help.feature create mode 100755 features/other_a/hit_counts.feature create mode 100755 features/other_a/homepage.feature create mode 100755 features/other_a/invite_queue.feature create mode 100755 features/other_a/invite_request.feature create mode 100755 features/other_a/invite_use.feature create mode 100755 features/other_a/languages.feature create mode 100755 features/other_a/media.feature create mode 100755 features/other_a/orphan_account.feature create mode 100755 features/other_a/orphan_pseud.feature create mode 100755 features/other_a/orphan_series.feature create mode 100755 features/other_a/orphan_work.feature create mode 100755 features/other_a/page_title.feature create mode 100755 features/other_a/parser.feature create mode 100755 features/other_a/preferences_edit.feature create mode 100755 features/other_a/preferences_edit_more.feature create mode 100755 features/other_a/profile_edit.feature create mode 100755 features/other_a/pseud_dashboard.feature create mode 100755 features/other_a/pseud_delete.feature create mode 100755 features/other_a/pseuds.feature create mode 100755 features/other_a/pseuds_special_characters.feature create mode 100755 features/other_a/reading.feature create mode 100755 features/other_b/errors.feature create mode 100755 features/other_b/fandoms.feature create mode 100755 features/other_b/icon.feature create mode 100755 features/other_b/sanitizer.feature create mode 100755 features/other_b/series.feature create mode 100755 features/other_b/series_lock.feature create mode 100755 features/other_b/series_order.feature create mode 100755 features/other_b/skin.feature create mode 100755 features/other_b/skin_public.feature create mode 100755 features/other_b/skin_wizard.feature create mode 100755 features/other_b/stats.feature create mode 100755 features/other_b/subscriptions.feature create mode 100755 features/other_b/subscriptions_fandoms.feature create mode 100755 features/other_b/support.feature create mode 100755 features/prompt_memes_a/challenge_promptmeme_setup.feature create mode 100755 features/prompt_memes_b/challenge_promptmeme_posting_fills.feature create mode 100755 features/prompt_memes_b/challenge_promptmeme_springkink.feature create mode 100755 features/prompt_memes_c/challenge_promptmeme_claims.feature create mode 100755 features/prompt_memes_c/challenge_promptmeme_deletion.feature create mode 100755 features/search/exceeding_maximum.feature create mode 100755 features/search/filters.feature create mode 100755 features/search/people_search.feature create mode 100755 features/search/works_anonymous.feature create mode 100755 features/search/works_collected.feature create mode 100755 features/search/works_info.feature create mode 100755 features/search/works_restricted.feature create mode 100755 features/search/works_stats.feature create mode 100755 features/search/works_tags.feature create mode 100755 features/step_definitions/admin_steps.rb create mode 100755 features/step_definitions/archivist_steps.rb create mode 100755 features/step_definitions/autocomplete_steps.rb create mode 100755 features/step_definitions/banner_steps.rb create mode 100755 features/step_definitions/block_steps.rb create mode 100755 features/step_definitions/bookmark_steps.rb create mode 100755 features/step_definitions/challege_gift_exchange_steps.rb create mode 100755 features/step_definitions/challenge_promptmeme_steps.rb create mode 100755 features/step_definitions/challenge_steps.rb create mode 100755 features/step_definitions/challenge_yuletide_steps.rb create mode 100755 features/step_definitions/collection_steps.rb create mode 100755 features/step_definitions/comment_steps.rb create mode 100755 features/step_definitions/email_custom_steps.rb create mode 100755 features/step_definitions/email_steps.rb create mode 100755 features/step_definitions/external_work_steps.rb create mode 100755 features/step_definitions/generic_steps.rb create mode 100755 features/step_definitions/gift_steps.rb create mode 100755 features/step_definitions/icon_steps.rb create mode 100755 features/step_definitions/invite_steps.rb create mode 100755 features/step_definitions/kudos_steps.rb create mode 100755 features/step_definitions/mute_steps.rb create mode 100755 features/step_definitions/orphan_steps.rb create mode 100755 features/step_definitions/page_title_steps.rb create mode 100755 features/step_definitions/pickle_steps.rb create mode 100755 features/step_definitions/potential_match_steps.rb create mode 100755 features/step_definitions/preferences_steps.rb create mode 100755 features/step_definitions/profile_steps.rb create mode 100755 features/step_definitions/pseud_steps.rb create mode 100755 features/step_definitions/rake_steps.rb create mode 100755 features/step_definitions/reading_steps.rb create mode 100755 features/step_definitions/redis_mail_queue_steps.rb create mode 100755 features/step_definitions/request_header_steps.rb create mode 100755 features/step_definitions/search_steps.rb create mode 100755 features/step_definitions/series_steps.rb create mode 100755 features/step_definitions/share_steps.rb create mode 100755 features/step_definitions/skin_steps.rb create mode 100755 features/step_definitions/subscription_steps.rb create mode 100755 features/step_definitions/support_steps.rb create mode 100755 features/step_definitions/tag_set_steps.rb create mode 100755 features/step_definitions/tag_steps.rb create mode 100755 features/step_definitions/user_steps.rb create mode 100755 features/step_definitions/web_steps.rb create mode 100755 features/step_definitions/work_deletion_steps.rb create mode 100755 features/step_definitions/work_download_steps.rb create mode 100755 features/step_definitions/work_import_steps.rb create mode 100755 features/step_definitions/work_related_steps.rb create mode 100755 features/step_definitions/work_search_steps.rb create mode 100755 features/step_definitions/work_steps.rb create mode 100755 features/support/capybara.rb create mode 100755 features/support/elapsed_time.rb create mode 100755 features/support/email.rb create mode 100755 features/support/env.rb create mode 100755 features/support/formatter.rb create mode 100755 features/support/hooks.rb create mode 100755 features/support/minitest.rb create mode 100755 features/support/paths.rb create mode 100755 features/support/pickle.rb create mode 100755 features/support/user.rb create mode 100755 features/support/vcr.rb create mode 100755 features/support/wait_for_ajax.rb create mode 100755 features/support/webmock.rb create mode 100755 features/tag_sets/tag_set.feature create mode 100755 features/tag_sets/tag_set_associations.feature create mode 100755 features/tag_sets/tag_set_batch_load.feature create mode 100755 features/tag_sets/tag_set_delete.feature create mode 100755 features/tag_sets/tag_set_nominations.feature create mode 100755 features/tags_and_wrangling/brand_new_fandoms.feature create mode 100755 features/tags_and_wrangling/favorite_tags.feature create mode 100755 features/tags_and_wrangling/tag_cloud.feature create mode 100755 features/tags_and_wrangling/tag_comment.feature create mode 100755 features/tags_and_wrangling/tag_search.feature create mode 100755 features/tags_and_wrangling/tag_wrangling.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_admin.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_characters.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_fandoms.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_freeforms.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_media.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_more.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_relationships.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_special.feature create mode 100755 features/tags_and_wrangling/tag_wrangling_unsorted.feature create mode 100755 features/tags_and_wrangling/wrangling_guidelines.feature create mode 100755 features/users/authenticate_users.feature create mode 100755 features/users/blocking.feature create mode 100755 features/users/muting.feature create mode 100755 features/users/password_compatibility.feature create mode 100755 features/users/suspensions.feature create mode 100755 features/users/user_create.feature create mode 100755 features/users/user_dashboard.feature create mode 100755 features/users/user_delete.feature create mode 100755 features/users/user_rename.feature create mode 100755 features/works/chapter_edit.feature create mode 100755 features/works/work_browse.feature create mode 100755 features/works/work_create.feature create mode 100755 features/works/work_dates_edit.feature create mode 100755 features/works/work_delete.feature create mode 100755 features/works/work_download.feature create mode 100755 features/works/work_drafts.feature create mode 100755 features/works/work_edit.feature create mode 100755 features/works/work_edit_multiple.feature create mode 100755 features/works/work_edit_tags.feature create mode 100755 features/works/work_languages.feature create mode 100755 features/works/work_lock.feature create mode 100755 features/works/work_notes.feature create mode 100755 features/works/work_related.feature create mode 100755 features/works/work_share.feature create mode 100755 features/works/work_view.feature create mode 100755 lib/ EXAMPLE_MODULE.rb.example create mode 100755 lib/acts_as_commentable/comment_methods.rb create mode 100755 lib/acts_as_commentable/commentable.rb create mode 100755 lib/acts_as_commentable/commentable_entity.rb create mode 100755 lib/autocomplete_source.rb create mode 100755 lib/backwards_compatible_password_decryptor.rb create mode 100755 lib/bookmark_count_caching.rb create mode 100755 lib/bookmarkable.rb create mode 100755 lib/challenge_core.rb create mode 100755 lib/collectible.rb create mode 100755 lib/creation_notifier.rb create mode 100755 lib/css_cleaner.rb create mode 100755 lib/devise_failure_message_options.rb create mode 100755 lib/html_cleaner.rb create mode 100755 lib/otw_sanitize/embed_sanitizer.rb create mode 100755 lib/otw_sanitize/media_sanitizer.rb create mode 100755 lib/otw_sanitize/user_class_sanitizer.rb create mode 100755 lib/pagination_list_link_renderer.rb create mode 100755 lib/paragraph_maker.rb create mode 100755 lib/redis_scanning.rb create mode 100755 lib/redis_test_setup.rb create mode 100755 lib/responder.rb create mode 100755 lib/searchable.rb create mode 100755 lib/skin_wizard.rb create mode 100755 lib/sortable_list.rb create mode 100755 lib/string_cleaner.rb create mode 100755 lib/tasks/admin_tasks.rake create mode 100755 lib/tasks/after_tasks.rake create mode 100755 lib/tasks/creatorships.rake create mode 100755 lib/tasks/cucumber.rake create mode 100755 lib/tasks/database_seed.rake create mode 100755 lib/tasks/defaults.rake create mode 100755 lib/tasks/deploy_tasks.rake create mode 100755 lib/tasks/language_tasks.rake create mode 100755 lib/tasks/load_autocomplete_data.rake create mode 100755 lib/tasks/memcached.rake create mode 100755 lib/tasks/notifications.rake create mode 100755 lib/tasks/opendoors.rake create mode 100755 lib/tasks/resanitize.rake create mode 100755 lib/tasks/resque.rake create mode 100755 lib/tasks/search.rake create mode 100755 lib/tasks/skin_tasks.rake create mode 100755 lib/tasks/spam_report.rake create mode 100755 lib/tasks/tag_tasks.rake create mode 100755 lib/tasks/work_tasks.rake create mode 100755 lib/url_formatter.rb create mode 100755 lib/word_counter.rb create mode 100755 lib/work_chapter_count_caching.rb create mode 100755 lib/works_owner.rb create mode 100755 lib/zoho_auth_client.rb create mode 100755 lib/zoho_resource_client.rb create mode 100755 multi-master.info create mode 100644 node.lock create mode 100644 nodes create mode 100755 public/.htaccess create mode 100755 public/403.html create mode 100755 public/406-unsupported-browser.html create mode 100755 public/445.html create mode 100755 public/500.html create mode 100755 public/502.html create mode 100755 public/503.html create mode 100755 public/507.html create mode 100755 public/OTW_Membership_Donation_Form.pdf create mode 100755 public/apple-touch-icon-114x114-precomposed.png create mode 100755 public/apple-touch-icon-114x114.png create mode 100755 public/apple-touch-icon-120x120-precomposed.png create mode 100755 public/apple-touch-icon-120x120.png create mode 100755 public/apple-touch-icon-144x144-precomposed.png create mode 100755 public/apple-touch-icon-144x144.png create mode 100755 public/apple-touch-icon-152x152-precomposed.png create mode 100755 public/apple-touch-icon-152x152.png create mode 100755 public/apple-touch-icon-167x167-precomposed.png create mode 100755 public/apple-touch-icon-180x180-precomposed.png create mode 100755 public/apple-touch-icon-180x180.png create mode 100755 public/apple-touch-icon-57x57-precomposed.png create mode 100755 public/apple-touch-icon-57x57.png create mode 100755 public/apple-touch-icon-72x72-precomposed.png create mode 100755 public/apple-touch-icon-72x72.png create mode 100755 public/apple-touch-icon-76x76-precomposed.png create mode 100755 public/apple-touch-icon-76x76.png create mode 100755 public/apple-touch-icon-precomposed.png create mode 100755 public/apple-touch-icon.png create mode 100755 public/apple-touch-icon120x120.png create mode 100755 public/apple-touch-icon152x152.png create mode 100755 public/apple-touch-icon76x76.png create mode 100755 public/dispatch.cgi create mode 100755 public/dispatch.fcgi create mode 100755 public/dispatch.rb create mode 100644 public/favicon.ico create mode 100755 public/help/add-collectible-to-collection.html create mode 100755 public/help/add-work-to-assignment.html create mode 100755 public/help/additional-tags-help.html create mode 100755 public/help/backdating-help.html create mode 100755 public/help/bookmark-filters-exclude-tags.html create mode 100755 public/help/bookmark-filters-include-tags.html create mode 100755 public/help/bookmark-search-bookmarker-tag.html create mode 100755 public/help/bookmark-search-date-bookmarked-help.html create mode 100755 public/help/bookmark-search-date-updated-help.html create mode 100755 public/help/bookmark-search-notes-help.html create mode 100755 public/help/bookmark-search-rec-help.html create mode 100755 public/help/bookmark-search-results-help.html create mode 100755 public/help/bookmark-search-text-help.html create mode 100755 public/help/bookmark-search-type-help.html create mode 100755 public/help/bookmark-search-work-tag.html create mode 100755 public/help/bookmark-symbols-key.html create mode 100755 public/help/categories-help.html create mode 100755 public/help/challenge-any.html create mode 100755 public/help/challenge-assignments.html create mode 100755 public/help/challenge-category-tags.html create mode 100755 public/help/challenge-include-optional-tags.html create mode 100755 public/help/challenge-matching-assignments.html create mode 100755 public/help/challenge-matching.html create mode 100755 public/help/challenge-optional-tags-user.html create mode 100755 public/help/challenge-optional-tags.html create mode 100755 public/help/challenge-pinch-hitter.html create mode 100755 public/help/challenge-requests-summary.html create mode 100755 public/help/chapter-title.html create mode 100755 public/help/characters-help.html create mode 100755 public/help/choosing-series.html create mode 100755 public/help/collection-closed.html create mode 100755 public/help/collection-moderated.html create mode 100755 public/help/collection-name.html create mode 100755 public/help/collection-preferences.html create mode 100755 public/help/comment-preferences.html create mode 100755 public/help/comments-moderated.html create mode 100755 public/help/csv-download.html create mode 100755 public/help/display-preferences.html create mode 100755 public/help/encoding-help.html create mode 100755 public/help/fandom-help.html create mode 100755 public/help/fr/choosing-series.html create mode 100755 public/help/html-help.html create mode 100755 public/help/icon-alt-text.html create mode 100755 public/help/languages-help.html create mode 100755 public/help/locale-preferences.html create mode 100755 public/help/misc-preferences.html create mode 100755 public/help/parent-works-help.html create mode 100755 public/help/people-search-all-fields.html create mode 100755 public/help/privacy-preferences.html create mode 100755 public/help/prompt-restriction-character-and-relationship.html create mode 100755 public/help/prompt-restriction-tag-set.html create mode 100755 public/help/pseud-icon-comment.html create mode 100755 public/help/rating-help.html create mode 100755 public/help/recipients.html create mode 100755 public/help/registered-users.html create mode 100755 public/help/relationships-help.html create mode 100755 public/help/required-field.html create mode 100755 public/help/rte-help.html create mode 100755 public/help/skins-approval.html create mode 100755 public/help/skins-basics.html create mode 100755 public/help/skins-conditions.html create mode 100755 public/help/skins-creating.html create mode 100755 public/help/skins-parents.html create mode 100755 public/help/skins-wizard-accent-color.html create mode 100755 public/help/skins-wizard-font-size.html create mode 100755 public/help/skins-wizard-font.html create mode 100755 public/help/skins-wizard-vertical-gap.html create mode 100755 public/help/symbols-key.html create mode 100755 public/help/tag-search-results-help.html create mode 100755 public/help/tag-search-text-help.html create mode 100755 public/help/tagset-about.html create mode 100755 public/help/tagset-batch-load.html create mode 100755 public/help/tagset-fandom-for-child.html create mode 100755 public/help/tagset-nominated-tags.html create mode 100755 public/help/tagset-tag-associations.html create mode 100755 public/help/translation-link.html create mode 100755 public/help/warning-help.html create mode 100755 public/help/who-can-comment-on-this-work.html create mode 100755 public/help/work-filters-exclude-tags.html create mode 100755 public/help/work-filters-include-tags.html create mode 100755 public/help/work-import.html create mode 100755 public/help/work-search-crossover-help.html create mode 100755 public/help/work-search-date-help.html create mode 100755 public/help/work-search-language-help.html create mode 100755 public/help/work-search-numerical-help.html create mode 100755 public/help/work-search-results-help.html create mode 100755 public/help/work-search-tags-help.html create mode 100755 public/help/work-search-text-help.html create mode 100755 public/help/work-skins.html create mode 100755 public/help/work_title_format.html create mode 100755 public/images/OTWLogo.png create mode 100755 public/images/ao3_logos/ao3-502.png create mode 100755 public/images/ao3_logos/logo-glitter-hat-noisemaker.gif create mode 100755 public/images/ao3_logos/logo-rails3.png create mode 100755 public/images/ao3_logos/logo-ruby.png create mode 100755 public/images/ao3_logos/logo-stroke.png create mode 100644 public/images/ao3_logos/logo.png create mode 100644 public/images/ao3_logos/logo_42.png create mode 100755 public/images/ao3_logos/sadface.png create mode 100755 public/images/arrow-down.gif create mode 100755 public/images/arrow-down.png create mode 100755 public/images/arrow-right.gif create mode 100755 public/images/arrow-right.png create mode 100755 public/images/arrow-up.gif create mode 100755 public/images/arrow-up.png create mode 100755 public/images/beta-flag.png create mode 100755 public/images/envelope_icon.gif create mode 100755 public/images/feed-icon-14x14.png create mode 100644 public/images/imageset.png create mode 100755 public/images/indicator.gif create mode 100755 public/images/key-square-1.png create mode 100755 public/images/key-square-2.png create mode 100755 public/images/key-square-3.png create mode 100755 public/images/key-square-4.png create mode 100755 public/images/legacy/beta-flag-legacy.png create mode 100755 public/images/legacy/button-gradient.png create mode 100755 public/images/legacy/ccc-fff.png create mode 100755 public/images/legacy/drop-shadow-light.gif create mode 100755 public/images/legacy/fffef9-ccc.png create mode 100755 public/images/legacy/header-red.png create mode 100755 public/images/legacy/headergradient.png create mode 100644 public/images/legacy/kudos-legacy.png create mode 100755 public/images/legacy/login-gradient-2.png create mode 100755 public/images/legacy/logo-stroke-legacy.gif create mode 100755 public/images/legacy/openid.png create mode 100755 public/images/lockblack.png create mode 100755 public/images/lockblue.png create mode 100755 public/images/lockred.png create mode 100755 public/images/logo-stroke.png create mode 100644 public/images/logo.png create mode 100644 public/images/logo_42.png create mode 100644 public/images/mailer/logo.png create mode 100755 public/images/mailer/mailer-banner-corner.gif create mode 100755 public/images/mailer/mailer-logo-bottom.gif create mode 100755 public/images/skins/iconsets/default/bookmark-hidden.png create mode 100755 public/images/skins/iconsets/default/bookmark-private.png create mode 100755 public/images/skins/iconsets/default/bookmark-public.png create mode 100755 public/images/skins/iconsets/default/bookmark-rec.png create mode 100755 public/images/skins/iconsets/default/category-femslash.png create mode 100755 public/images/skins/iconsets/default/category-gen.png create mode 100755 public/images/skins/iconsets/default/category-het.png create mode 100755 public/images/skins/iconsets/default/category-multi.png create mode 100755 public/images/skins/iconsets/default/category-none.png create mode 100755 public/images/skins/iconsets/default/category-other.png create mode 100755 public/images/skins/iconsets/default/category-slash.png create mode 100755 public/images/skins/iconsets/default/complete-no.png create mode 100755 public/images/skins/iconsets/default/complete-yes.png create mode 100755 public/images/skins/iconsets/default/icon-template.png create mode 100755 public/images/skins/iconsets/default/icon_admin.jpeg create mode 100755 public/images/skins/iconsets/default/icon_collection-s.png create mode 100755 public/images/skins/iconsets/default/icon_collection.png create mode 100755 public/images/skins/iconsets/default/icon_mystery.png create mode 100755 public/images/skins/iconsets/default/icon_skins.png create mode 100755 public/images/skins/iconsets/default/icon_tag.png create mode 100755 public/images/skins/iconsets/default/icon_transparent.gif create mode 100755 public/images/skins/iconsets/default/icon_user.png create mode 100644 public/images/skins/iconsets/default/kudos.png create mode 100755 public/images/skins/iconsets/default/logo-stroke.png create mode 100755 public/images/skins/iconsets/default/rating-explicit.png create mode 100755 public/images/skins/iconsets/default/rating-general-audience.png create mode 100755 public/images/skins/iconsets/default/rating-mature.png create mode 100755 public/images/skins/iconsets/default/rating-notrated.png create mode 100755 public/images/skins/iconsets/default/rating-teen-orange.png create mode 100755 public/images/skins/iconsets/default/rating-teen.png create mode 100755 public/images/skins/iconsets/default/rss.png create mode 100755 public/images/skins/iconsets/default/warning-choosenotto.png create mode 100755 public/images/skins/iconsets/default/warning-death.png create mode 100755 public/images/skins/iconsets/default/warning-external-work.png create mode 100755 public/images/skins/iconsets/default/warning-no.png create mode 100755 public/images/skins/iconsets/default/warning-underage.png create mode 100755 public/images/skins/iconsets/default/warning-yes.png create mode 100755 public/images/skins/iconsets/default_large/bookmark-hidden.png create mode 100755 public/images/skins/iconsets/default_large/bookmark-private.png create mode 100755 public/images/skins/iconsets/default_large/bookmark-public.png create mode 100755 public/images/skins/iconsets/default_large/bookmark-rec.png create mode 100755 public/images/skins/iconsets/default_large/category-femslash.png create mode 100755 public/images/skins/iconsets/default_large/category-gen.png create mode 100755 public/images/skins/iconsets/default_large/category-het.png create mode 100755 public/images/skins/iconsets/default_large/category-multi.png create mode 100755 public/images/skins/iconsets/default_large/category-none.png create mode 100755 public/images/skins/iconsets/default_large/category-other.png create mode 100755 public/images/skins/iconsets/default_large/category-slash.png create mode 100755 public/images/skins/iconsets/default_large/complete-no.png create mode 100755 public/images/skins/iconsets/default_large/complete-yes.png create mode 100755 public/images/skins/iconsets/default_large/external-work.png create mode 100755 public/images/skins/iconsets/default_large/icon_collection.png create mode 100755 public/images/skins/iconsets/default_large/icon_mystery.png create mode 100755 public/images/skins/iconsets/default_large/icon_tag.png create mode 100755 public/images/skins/iconsets/default_large/icon_user.png create mode 100755 public/images/skins/iconsets/default_large/rating-explicit.png create mode 100755 public/images/skins/iconsets/default_large/rating-general-audience.png create mode 100755 public/images/skins/iconsets/default_large/rating-mature.png create mode 100755 public/images/skins/iconsets/default_large/rating-na.png create mode 100755 public/images/skins/iconsets/default_large/rating-notrated.png create mode 100755 public/images/skins/iconsets/default_large/rating-teen-orange.png create mode 100755 public/images/skins/iconsets/default_large/rating-teen.png create mode 100755 public/images/skins/iconsets/default_large/warning-choosenotto.png create mode 100755 public/images/skins/iconsets/default_large/warning-eschewed.png create mode 100755 public/images/skins/iconsets/default_large/warning-no.png create mode 100755 public/images/skins/iconsets/default_large/warning-none.png create mode 100755 public/images/skins/iconsets/default_large/warning-yes.png create mode 100755 public/images/skins/iconsets/default_large/warnings-death.png create mode 100755 public/images/skins/iconsets/default_large/warnings-na.png create mode 100755 public/images/skins/iconsets/default_large/warnings-noncon.png create mode 100755 public/images/skins/iconsets/default_large/warnings-underage.png create mode 100755 public/images/skins/iconsets/default_large/warnings-violence.png create mode 100755 public/images/skins/iconsets/legacy/bookmark-hidden.png create mode 100755 public/images/skins/iconsets/legacy/bookmark-private.png create mode 100755 public/images/skins/iconsets/legacy/bookmark-public.png create mode 100755 public/images/skins/iconsets/legacy/bookmark-rec.png create mode 100755 public/images/skins/iconsets/legacy/category-femslash-s.png create mode 100755 public/images/skins/iconsets/legacy/category-gen-s.png create mode 100755 public/images/skins/iconsets/legacy/category-het-s.png create mode 100755 public/images/skins/iconsets/legacy/category-multi-s.png create mode 100755 public/images/skins/iconsets/legacy/category-none-s.png create mode 100755 public/images/skins/iconsets/legacy/category-other-s.png create mode 100755 public/images/skins/iconsets/legacy/category-slash-s.png create mode 100755 public/images/skins/iconsets/legacy/complete-no-s.png create mode 100755 public/images/skins/iconsets/legacy/complete-yes-s.png create mode 100755 public/images/skins/iconsets/legacy/icon_admin.jpeg create mode 100755 public/images/skins/iconsets/legacy/icon_collection-s.png create mode 100755 public/images/skins/iconsets/legacy/icon_collection.png create mode 100755 public/images/skins/iconsets/legacy/icon_mystery-s.png create mode 100755 public/images/skins/iconsets/legacy/icon_mystery.png create mode 100755 public/images/skins/iconsets/legacy/icon_skins.png create mode 100755 public/images/skins/iconsets/legacy/icon_tag.png create mode 100755 public/images/skins/iconsets/legacy/icon_user.png create mode 100755 public/images/skins/iconsets/legacy/kudos.png create mode 100755 public/images/skins/iconsets/legacy/rating-explicit-s.png create mode 100755 public/images/skins/iconsets/legacy/rating-general-audience-s.png create mode 100755 public/images/skins/iconsets/legacy/rating-mature-s.png create mode 100755 public/images/skins/iconsets/legacy/rating-notrated-s.png create mode 100755 public/images/skins/iconsets/legacy/rating-teen-orange-s.png create mode 100755 public/images/skins/iconsets/legacy/rating-teen-s.png create mode 100755 public/images/skins/iconsets/legacy/rss.png create mode 100755 public/images/skins/iconsets/legacy/warning-choosenotto-s.png create mode 100755 public/images/skins/iconsets/legacy/warning-external-work-s.png create mode 100755 public/images/skins/iconsets/legacy/warning-no-s.png create mode 100755 public/images/skins/iconsets/legacy/warning-yes-s.png create mode 100755 public/images/skins/iconsets/legacy/warnings-death-s.png create mode 100755 public/images/skins/iconsets/legacy/warnings-underage-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-bookmark-public-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-bookmark-public.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-bookmark-rec-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-bookmark-rec.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-femslash-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-femslash.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-gen-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-gen.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-het-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-het.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-multi-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-multi.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-other-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-other.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-slash-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-category-slash.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-collections.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-complete-no-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-complete-no.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-complete-yes-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-complete-yes.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-external-work-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-external-work.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-mystery-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-mystery.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-explicit-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-explicit.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-general-audience-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-general-audience.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-mature-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-mature.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-notrated-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-notrated.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-teen-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-rating-teen.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-warning-choosenotto-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-warning-choosenotto.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-warning-eschewed-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-warning-eschewed.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-warning-no-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-warning-no.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-warning-yes-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvb-warning-yes.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-bookmark-public-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-bookmark-public.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-bookmark-rec-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-bookmark-rec.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-femslash-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-femslash.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-gen-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-gen.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-het-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-het.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-multi-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-multi.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-other-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-other.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-slash-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-category-slash.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-collections.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-complete-no-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-complete-no.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-complete-yes-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-complete-yes.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-external-work-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-external-work.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-mystery-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-mystery.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-explicit-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-explicit.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-general-audience-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-general-audience.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-mature-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-mature.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-notrated-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-notrated.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-teen-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-rating-teen.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-warning-choosenotto-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-warning-choosenotto.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-warning-eschewed-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-warning-eschewed.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-warning-no-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-warning-no.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-warning-yes-s.png create mode 100755 public/images/skins/iconsets/low_vision/lvy-warning-yes.png create mode 100755 public/images/skins/iconsets/template-grids/icon-template-invert-mono.png create mode 100755 public/images/skins/iconsets/template-grids/icon-template-invert.png create mode 100755 public/images/skins/iconsets/template-grids/icon-template-mono.png create mode 100755 public/images/skins/iconsets/template-grids/icon-template.png create mode 100755 public/images/skins/objects/blank-stamp.png create mode 100755 public/images/skins/objects/coffee-cup.png create mode 100755 public/images/skins/objects/glitter-pens-l-b-matte.png create mode 100755 public/images/skins/objects/glitter-pens-l-bmatte.png create mode 100755 public/images/skins/objects/glitter-pens.png create mode 100755 public/images/skins/objects/track-bike.png create mode 100755 public/images/skins/previews/basic_formatting.png create mode 100755 public/images/skins/previews/default.png create mode 100755 public/images/skins/previews/plaintext.png create mode 100755 public/images/skins/textures/tiles/aaaaa-readme.txt create mode 100755 public/images/skins/textures/tiles/black-denim.jpg create mode 100755 public/images/skins/textures/tiles/black-illo-breeze.gif create mode 100755 public/images/skins/textures/tiles/black-metal-grid.jpg create mode 100755 public/images/skins/textures/tiles/black-noise.jpg create mode 100755 public/images/skins/textures/tiles/black-scribble-x.png create mode 100755 public/images/skins/textures/tiles/black-stripe.gif create mode 100755 public/images/skins/textures/tiles/black-wallpaper-charcoal.gif create mode 100755 public/images/skins/textures/tiles/black-zebra-fur.jpg create mode 100755 public/images/skins/textures/tiles/blue-denim-1.jpg create mode 100755 public/images/skins/textures/tiles/blue-denim.jpg create mode 100755 public/images/skins/textures/tiles/blue-geometric.jpg create mode 100755 public/images/skins/textures/tiles/blue-heartflowers.jpg create mode 100755 public/images/skins/textures/tiles/blue-illo-ravens.gif create mode 100755 public/images/skins/textures/tiles/blue-illo-waves.gif create mode 100755 public/images/skins/textures/tiles/blue-lotus.gif create mode 100755 public/images/skins/textures/tiles/blue-metal-grid.jpg create mode 100755 public/images/skins/textures/tiles/brown-canvas.jpg create mode 100755 public/images/skins/textures/tiles/brown-corkboard.jpg create mode 100755 public/images/skins/textures/tiles/brown-fine-cardboard.jpg create mode 100755 public/images/skins/textures/tiles/brown-grunge.jpg create mode 100755 public/images/skins/textures/tiles/brown-handmade-paper.jpg create mode 100755 public/images/skins/textures/tiles/brown-hessian.jpg create mode 100755 public/images/skins/textures/tiles/brown-illo-octo-redux.gif create mode 100755 public/images/skins/textures/tiles/brown-linen.jpg create mode 100755 public/images/skins/textures/tiles/brown-manila-card.jpg create mode 100755 public/images/skins/textures/tiles/brown-metal-grid.jpg create mode 100755 public/images/skins/textures/tiles/brown-planks-nails.jpg create mode 100755 public/images/skins/textures/tiles/brown-twill.jpg create mode 100755 public/images/skins/textures/tiles/brown-winchester-walls.gif create mode 100755 public/images/skins/textures/tiles/green-leather.jpg create mode 100755 public/images/skins/textures/tiles/grey-argyle.jpg create mode 100755 public/images/skins/textures/tiles/grey-bookswirl.jpg create mode 100755 public/images/skins/textures/tiles/grey-canvas.jpg create mode 100755 public/images/skins/textures/tiles/grey-corrogated.jpg create mode 100755 public/images/skins/textures/tiles/grey-illo-skulls.gif create mode 100755 public/images/skins/textures/tiles/grey-shiplap.jpg create mode 100755 public/images/skins/textures/tiles/henna-leather.jpg create mode 100755 public/images/skins/textures/tiles/multi-chevrons-x.png create mode 100755 public/images/skins/textures/tiles/multi-chevrons-y.png create mode 100755 public/images/skins/textures/tiles/multi-illo-autumn-butterflies.gif create mode 100755 public/images/skins/textures/tiles/pink-illo-panda-madness.gif create mode 100755 public/images/skins/textures/tiles/purple-wood-desktop.jpg create mode 100755 public/images/skins/textures/tiles/red-ao3.png create mode 100755 public/images/skins/textures/tiles/red-brick.jpg create mode 100755 public/images/skins/textures/tiles/red-illo-45-caliber.gif create mode 100755 public/images/skins/textures/tiles/red-illo-dead-revolutionaries.gif create mode 100755 public/images/skins/textures/tiles/red-illo-hold-fast.gif create mode 100755 public/images/skins/textures/tiles/red-illo-indian-summer.gif create mode 100755 public/images/skins/textures/tiles/red-illo-overlyRosie.gif create mode 100755 public/images/skins/textures/tiles/red-illo-rafters.gif create mode 100755 public/images/skins/textures/tiles/red-illo-vintage-scarlet.gif create mode 100755 public/images/skins/textures/tiles/transp-dot.gif create mode 100755 public/images/skins/textures/tiles/transp-notebook-spiral-x.png create mode 100755 public/images/skins/textures/tiles/transp-notebook-spiral-y.png create mode 100755 public/images/skins/textures/tiles/white-cartridge-paper.jpg create mode 100755 public/images/skins/textures/tiles/white-graph-paper.jpg create mode 100755 public/images/skins/textures/tiles/white-handmade-paper.jpg create mode 100755 public/images/skins/textures/tiles/white-lined-paper.jpg create mode 100755 public/images/skins/textures/tiles/white-lined.jpg create mode 100755 public/images/skins/textures/tiles/yellow-leaves.jpg create mode 100755 public/images/skins/textures/tiles/yellow-postit.jpg create mode 100755 public/images/skins/textures/tiles/yellow-thick-card.jpg create mode 100755 public/images/skins/textures/tiles/yellow-watercolour-paper.jpg create mode 100755 public/images/unused/bluesymbol.png create mode 100755 public/images/unused/drag.png create mode 100755 public/images/unused/indicator.gif create mode 100755 public/images/unused/rails.png create mode 100755 public/images/unused/skin_preview_none.png create mode 100755 public/images/unused/spinner.gif create mode 100755 public/images/unused/wig.png create mode 100755 public/javascripts/ao3modal.js create mode 100755 public/javascripts/ao3modal.min.js create mode 100755 public/javascripts/application.js create mode 100755 public/javascripts/bootstrap/bootstrap-dropdown.js create mode 100755 public/javascripts/bootstrap/bootstrap-dropdown.min.js create mode 100755 public/javascripts/filters.js create mode 100755 public/javascripts/filters.min.js create mode 100755 public/javascripts/jquery-shuffle.js create mode 100755 public/javascripts/jquery-ui-timepicker-addon.js create mode 100755 public/javascripts/jquery-ui.js create mode 100755 public/javascripts/jquery-ui.min.js create mode 100755 public/javascripts/jquery.js create mode 100755 public/javascripts/jquery.livequery.min.js create mode 100755 public/javascripts/jquery.min.js create mode 100755 public/javascripts/jquery.qtip.min.js create mode 100755 public/javascripts/jquery.scrollTo.js create mode 100755 public/javascripts/jquery.scrollTo.min.js create mode 100755 public/javascripts/jquery.timeago.js create mode 100755 public/javascripts/jquery.timeago.min.js create mode 100755 public/javascripts/jquery.tokeninput.js create mode 100755 public/javascripts/jquery.tokeninput.min.js create mode 100755 public/javascripts/jquery.trap.min.js create mode 100755 public/javascripts/js.cookie.min.js create mode 100755 public/javascripts/livevalidation_standalone.js create mode 100755 public/javascripts/mce_editor.js create mode 100755 public/javascripts/mce_editor.min.js create mode 100755 public/javascripts/rails.js create mode 100755 public/javascripts/select_all.js create mode 100755 public/javascripts/tinymce/jquery.tinymce.min.js create mode 100755 public/javascripts/tinymce/langs/readme.md create mode 100755 public/javascripts/tinymce/license.txt create mode 100755 public/javascripts/tinymce/plugins/advlist/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/anchor/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/autolink/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/autoresize/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/autosave/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/bbcode/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/charmap/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/code/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/codesample/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/colorpicker/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/contextmenu/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/directionality/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/emoticons/js/emojis.js create mode 100755 public/javascripts/tinymce/plugins/emoticons/js/emojis.min.js create mode 100755 public/javascripts/tinymce/plugins/emoticons/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/fullpage/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/fullscreen/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/help/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/hr/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/image/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/imagetools/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/importcss/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/insertdatetime/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/legacyoutput/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/link/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/lists/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/media/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/nonbreaking/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/noneditable/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/pagebreak/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/paste/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/preview/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/print/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/quickbars/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/save/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/searchreplace/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/spellchecker/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/tabfocus/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/table/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/template/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/textcolor/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/textpattern/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/toc/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/visualblocks/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/visualchars/plugin.min.js create mode 100755 public/javascripts/tinymce/plugins/wordcount/plugin.min.js create mode 100755 public/javascripts/tinymce/skins/content/dark/content.min.css create mode 100755 public/javascripts/tinymce/skins/content/default/content.min.css create mode 100755 public/javascripts/tinymce/skins/content/document/content.min.css create mode 100755 public/javascripts/tinymce/skins/content/writer/content.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide-dark/content.inline.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide-dark/content.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide-dark/content.mobile.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide-dark/fonts/tinymce-mobile.woff create mode 100755 public/javascripts/tinymce/skins/ui/oxide-dark/skin.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide-dark/skin.mobile.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide/content.inline.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide/content.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide/content.mobile.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide/fonts/tinymce-mobile.woff create mode 100755 public/javascripts/tinymce/skins/ui/oxide/skin.min.css create mode 100755 public/javascripts/tinymce/skins/ui/oxide/skin.mobile.min.css create mode 100755 public/javascripts/tinymce/themes/mobile/theme.min.js create mode 100755 public/javascripts/tinymce/themes/silver/theme.min.js create mode 100755 public/javascripts/tinymce/tinymce.min.js create mode 100755 public/nomaintenance.html create mode 100755 public/otw-logobox-transparent.png create mode 100755 public/robots.private.txt create mode 100755 public/robots.public.txt create mode 100755 public/status/24_hour.html create mode 100755 public/status/3_hour.html create mode 100755 public/status/index.html create mode 100755 public/status/jquery-ui.css create mode 100755 public/status/simple_status.html create mode 100755 public/stylesheets/.gitkeep create mode 100755 public/stylesheets/README.md create mode 100755 public/stylesheets/ebooks.css create mode 100755 public/stylesheets/forms-backup.css create mode 100755 public/stylesheets/masters/dark_mode/README.md create mode 100755 public/stylesheets/masters/dark_mode/dark_mode_midsize_.css create mode 100755 public/stylesheets/masters/dark_mode/dark_mode_site_screen_.css create mode 100755 public/stylesheets/masters/low_vision_default/README.md create mode 100755 public/stylesheets/masters/low_vision_default/low_vision_default_site_screen_.css create mode 100755 public/stylesheets/masters/reversi/README.md create mode 100755 public/stylesheets/masters/reversi/reversi_site_screen_.css create mode 100755 public/stylesheets/masters/snow/README.md create mode 100755 public/stylesheets/masters/snow/snow_site_screen_.css create mode 100755 public/stylesheets/masters/snow_blue/README.md create mode 100755 public/stylesheets/masters/snow_blue/snow_blue_site_screen_.css create mode 100755 public/stylesheets/sandbox.css create mode 100755 public/stylesheets/site/2.0/01-core.css create mode 100755 public/stylesheets/site/2.0/02-elements.css create mode 100755 public/stylesheets/site/2.0/03-region-header.css create mode 100755 public/stylesheets/site/2.0/04-region-dashboard.css create mode 100755 public/stylesheets/site/2.0/05-region-main.css create mode 100755 public/stylesheets/site/2.0/06-region-footer.css create mode 100755 public/stylesheets/site/2.0/07-interactions.css create mode 100755 public/stylesheets/site/2.0/08-actions.css create mode 100755 public/stylesheets/site/2.0/09-roles-states.css create mode 100755 public/stylesheets/site/2.0/10-types-groups.css create mode 100755 public/stylesheets/site/2.0/11-group-listbox.css create mode 100755 public/stylesheets/site/2.0/12-group-meta.css create mode 100755 public/stylesheets/site/2.0/13-group-blurb.css create mode 100755 public/stylesheets/site/2.0/14-group-preface.css create mode 100755 public/stylesheets/site/2.0/15-group-comments.css create mode 100755 public/stylesheets/site/2.0/16-zone-system.css create mode 100755 public/stylesheets/site/2.0/17-zone-home.css create mode 100755 public/stylesheets/site/2.0/18-zone-searchbrowse.css create mode 100755 public/stylesheets/site/2.0/19-zone-tags.css create mode 100755 public/stylesheets/site/2.0/20-zone-translation.css create mode 100755 public/stylesheets/site/2.0/21-userstuff.css create mode 100755 public/stylesheets/site/2.0/22-system-messages.css create mode 100755 public/stylesheets/site/2.0/23-role-translator.css create mode 100755 public/stylesheets/site/2.0/24-role-admin.css create mode 100755 public/stylesheets/site/2.0/25-media-midsize.css create mode 100755 public/stylesheets/site/2.0/26-media-narrow.css create mode 100755 public/stylesheets/site/2.0/27-media-aural.css create mode 100755 public/stylesheets/site/2.0/28-media-print.css create mode 100755 public/stylesheets/site/2.0/29-role-ie8_or_lower.css create mode 100755 public/stylesheets/site/2.0/30-role-ie5.css create mode 100755 public/stylesheets/site/2.0/31-role-ie6.css create mode 100755 public/stylesheets/site/2.0/32-role-ie7.css create mode 100755 public/stylesheets/site/2.0/preview.png create mode 100755 public/stylesheets/site/preview.png create mode 100755 public/stylesheets/site/user_skins_to_load/README.txt create mode 100755 public/stylesheets/tiny_mce_custom.css create mode 100755 public/stylesheets/work_skins/basic_formatting.css create mode 100755 rubocop/cop/README.md create mode 100755 rubocop/cop/cucumber/regex_step_name.rb create mode 100755 rubocop/cop/i18n/default_translation.rb create mode 100755 rubocop/cop/i18n/deprecated_helper.rb create mode 100755 rubocop/cop/i18n/deprecated_translation_key.rb create mode 100755 rubocop/cop/i18n/html_safe_translation.rb create mode 100755 rubocop/cop/migration/large_table_schema_update.rb create mode 100755 rubocop/rubocop.rb create mode 100755 script/create_admin.rb create mode 100755 script/docker/init.cmd create mode 100755 script/docker/init.sh create mode 100755 script/ensure_required_tags.rb create mode 100755 script/get_user_data.rb create mode 100755 script/gh-actions/configure_database.sh create mode 100755 script/gh-actions/multiple_redis.sh create mode 100755 script/lock_admin.rb create mode 100755 script/reset_database-prod.sh create mode 100755 script/reset_database.sh create mode 100755 script/unlock_admin.rb create mode 100755 spec/controllers/admin/activities_controller_spec.rb create mode 100755 spec/controllers/admin/admin_invitations_controller_spec.rb create mode 100755 spec/controllers/admin/admin_users_controller_spec.rb create mode 100755 spec/controllers/admin/api_controller_spec.rb create mode 100755 spec/controllers/admin/banners_controller_spec.rb create mode 100755 spec/controllers/admin/blacklisted_emails_controller_spec.rb create mode 100755 spec/controllers/admin/settings_controller_spec.rb create mode 100755 spec/controllers/admin/skins_controller_spec.rb create mode 100755 spec/controllers/admin/spam_controller_spec.rb create mode 100755 spec/controllers/admin/user_creations_controller_spec.rb create mode 100755 spec/controllers/admin_posts_controller_spec.rb create mode 100755 spec/controllers/api/api_helper.rb create mode 100755 spec/controllers/api/v2/api_authorization_spec.rb create mode 100755 spec/controllers/api/v2/api_base_controller_spec.rb create mode 100755 spec/controllers/api/v2/api_bookmarks_spec.rb create mode 100755 spec/controllers/api/v2/api_works_search_spec.rb create mode 100755 spec/controllers/api/v2/api_works_spec.rb create mode 100755 spec/controllers/archive_faqs_controller_spec.rb create mode 100755 spec/controllers/autocomplete_controller_spec.rb create mode 100755 spec/controllers/blocked/users_controller_spec.rb create mode 100755 spec/controllers/bookmarks_controller_spec.rb create mode 100755 spec/controllers/challenge_assignments_controller_spec.rb create mode 100755 spec/controllers/challenge_claims_controller_spec.rb create mode 100755 spec/controllers/challenge_signups_controller_spec.rb create mode 100755 spec/controllers/challenges_controller_spec.rb create mode 100755 spec/controllers/chapters_controller_spec.rb create mode 100755 spec/controllers/collection_items_controller_spec.rb create mode 100755 spec/controllers/collection_participants_controller_spec.rb create mode 100755 spec/controllers/collection_profile_controller_spec.rb create mode 100755 spec/controllers/collections_controller_spec.rb create mode 100755 spec/controllers/comments/blocking_spec.rb create mode 100755 spec/controllers/comments/comment_moderation_spec.rb create mode 100755 spec/controllers/comments/comments_controller_spec.rb create mode 100755 spec/controllers/comments/default_rails_actions_spec.rb create mode 100755 spec/controllers/comments/freeze_spec.rb create mode 100755 spec/controllers/comments/hide_spec.rb create mode 100755 spec/controllers/comments/reply_spec.rb create mode 100755 spec/controllers/creatorships_controller_spec.rb create mode 100755 spec/controllers/errors_controller_spec.rb create mode 100755 spec/controllers/external_authors_controller_spec.rb create mode 100755 spec/controllers/external_works_controller_spec.rb create mode 100755 spec/controllers/fandoms_controller_spec.rb create mode 100755 spec/controllers/feedbacks_controller_spec.rb create mode 100755 spec/controllers/gift_exchange_controller_spec.rb create mode 100755 spec/controllers/gifts_controller_spec.rb create mode 100755 spec/controllers/hit_count_controller_spec.rb create mode 100755 spec/controllers/inbox_controller_spec.rb create mode 100755 spec/controllers/invitations_controller_spec.rb create mode 100755 spec/controllers/invite_requests_controller_spec.rb create mode 100755 spec/controllers/known_issues_controller_spec.rb create mode 100755 spec/controllers/kudos_controller_spec.rb create mode 100755 spec/controllers/languages_controller_spec.rb create mode 100755 spec/controllers/locales_controller_spec.rb create mode 100755 spec/controllers/muted/users_controller_spec.rb create mode 100755 spec/controllers/opendoors/tools_controller_spec.rb create mode 100755 spec/controllers/orphans_controller_spec.rb create mode 100755 spec/controllers/owned_tag_sets_controller_spec.rb create mode 100755 spec/controllers/people_controller_spec.rb create mode 100755 spec/controllers/profile_controller_spec.rb create mode 100755 spec/controllers/prompt_meme_controller_spec.rb create mode 100755 spec/controllers/prompts_controller_spec.rb create mode 100755 spec/controllers/pseuds_controller_spec.rb create mode 100755 spec/controllers/questions_controller_spec.rb create mode 100755 spec/controllers/readings_controller_spec.rb create mode 100755 spec/controllers/related_works_controller_spec.rb create mode 100755 spec/controllers/serial_works_controller_spec.rb create mode 100755 spec/controllers/series_controller_spec.rb create mode 100755 spec/controllers/skins_controller_spec.rb create mode 100755 spec/controllers/subscriptions_controller_spec.rb create mode 100755 spec/controllers/tag_set_associations_controller_spec.rb create mode 100755 spec/controllers/tag_set_nominations_controller_spec.rb create mode 100755 spec/controllers/tag_wranglers_controller_spec.rb create mode 100755 spec/controllers/tag_wranglings_controller_spec.rb create mode 100755 spec/controllers/tags_controller_spec.rb create mode 100755 spec/controllers/troubleshooting_controller_spec.rb create mode 100755 spec/controllers/unsorted_tags_controller_spec.rb create mode 100755 spec/controllers/users/registrations_controller_spec.rb create mode 100755 spec/controllers/users_controller_spec.rb create mode 100755 spec/controllers/works/default_rails_actions_spec.rb create mode 100755 spec/controllers/works/drafts_spec.rb create mode 100755 spec/controllers/works/importing_spec.rb create mode 100755 spec/controllers/works/mark_for_later_spec.rb create mode 100755 spec/controllers/works/multiple_actions_spec.rb create mode 100755 spec/controllers/works/remove_user_cocreatorship_spec.rb create mode 100755 spec/controllers/works/updating_tags_spec.rb create mode 100755 spec/controllers/works/works_controller_spec.rb create mode 100755 spec/controllers/wrangling_guidelines_controller_spec.rb create mode 100755 spec/helpers/admin_helper_spec.rb create mode 100755 spec/helpers/admin_post_helper_spec.rb create mode 100755 spec/helpers/application_helper_spec.rb create mode 100755 spec/helpers/bookmarks_helper_spec.rb create mode 100755 spec/helpers/comments_helper_spec.rb create mode 100755 spec/helpers/date_helper_spec.rb create mode 100755 spec/helpers/exports_helper_spec.rb create mode 100755 spec/helpers/home_helper_spec.rb create mode 100755 spec/helpers/inbox_helper_spec.rb create mode 100755 spec/helpers/mailer_helper_spec.rb create mode 100755 spec/helpers/share_helper_spec.rb create mode 100755 spec/helpers/skins_helper_spec.rb create mode 100755 spec/helpers/tag_sets_helper_spec.rb create mode 100755 spec/helpers/tag_type_helper_spec.rb create mode 100755 spec/helpers/user_invite_requests_helper_spec.rb create mode 100755 spec/helpers/validation_helper_spec.rb create mode 100755 spec/helpers/works_helper_spec.rb create mode 100755 spec/jobs/hit_count_update_job_spec.rb create mode 100755 spec/jobs/report_attachment_job_spec.rb create mode 100755 spec/lib/autocomplete_source_spec.rb create mode 100755 spec/lib/collectible_spec.rb create mode 100755 spec/lib/css_cleaner_spec.rb create mode 100755 spec/lib/html_cleaner_spec.rb create mode 100755 spec/lib/i18n/i18n_tasks_spec.rb create mode 100755 spec/lib/i18n/pluralization_spec.rb create mode 100755 spec/lib/otw_sanitize/media_sanitizer_spec.rb create mode 100755 spec/lib/paragraph_maker_spec.rb create mode 100755 spec/lib/string_cleaner_spec.rb create mode 100755 spec/lib/tasks/admin_tasks.rake_spec.rb create mode 100755 spec/lib/tasks/after_tasks.rake_spec.rb create mode 100755 spec/lib/tasks/creatorships.rake_spec.rb create mode 100755 spec/lib/tasks/database_seed.rake_spec.rb create mode 100755 spec/lib/tasks/defaults.rake_spec.rb create mode 100755 spec/lib/tasks/notifications.rake_spec.rb create mode 100755 spec/lib/tasks/opendoors.rake_spec.rb create mode 100755 spec/lib/tasks/resanitize.rake_spec.rb create mode 100755 spec/lib/tasks/resque.rake_spec.rb create mode 100755 spec/lib/tasks/search_tasks.rake_spec.rb create mode 100755 spec/lib/tasks/skin_tasks.rake_spec.rb create mode 100755 spec/lib/tasks/tag_tasks.rake_spec.rb create mode 100755 spec/lib/tasks/work_tasks.rake_spec.rb create mode 100755 spec/lib/url_formatter_spec.rb create mode 100755 spec/lib/word_counter_spec.rb create mode 100755 spec/lib/works_owner_spec.rb create mode 100755 spec/lib/zoho_auth_client_spec.rb create mode 100755 spec/lib/zoho_resource_client_spec.rb create mode 100755 spec/mailers/admin_mailer_spec.rb create mode 100755 spec/mailers/archive_devise_mailer_spec.rb create mode 100755 spec/mailers/collection_mailer_spec.rb create mode 100755 spec/mailers/comment_mailer_spec.rb create mode 100755 spec/mailers/kudo_mailer_spec.rb create mode 100755 spec/mailers/tag_wrangling_supervisor_mailer_spec.rb create mode 100755 spec/mailers/tos_update_mailer_spec.rb create mode 100755 spec/mailers/user_mailer_spec.rb create mode 100755 spec/models/abuse_report_spec.rb create mode 100755 spec/models/admin_activity_spec.rb create mode 100755 spec/models/admin_blacklisted_email_spec.rb create mode 100755 spec/models/admin_post_spec.rb create mode 100755 spec/models/admin_setting_spec.rb create mode 100755 spec/models/admin_spec.rb create mode 100755 spec/models/archive_faq_spec.rb create mode 100755 spec/models/bookmark_spec.rb create mode 100755 spec/models/challenge_assignment_spec.rb create mode 100755 spec/models/challenge_claim_spec.rb create mode 100755 spec/models/chapter_spec.rb create mode 100755 spec/models/collection_item_spec.rb create mode 100755 spec/models/collection_spec.rb create mode 100755 spec/models/comment_spec.rb create mode 100755 spec/models/concerns/filterable_spec.rb create mode 100755 spec/models/concerns/justifiable_spec.rb create mode 100755 spec/models/concerns/password_resets_limitable_spec.rb create mode 100755 spec/models/concerns/wrangleable_spec.rb create mode 100755 spec/models/creatorship_spec.rb create mode 100755 spec/models/download_spec.rb create mode 100755 spec/models/external_author_spec.rb create mode 100755 spec/models/external_work_spec.rb create mode 100755 spec/models/favorite_tag_spec.rb create mode 100755 spec/models/feedback_reporters/abuse_reporter_spec.rb create mode 100755 spec/models/feedback_reporters/feedback_reporter_spec.rb create mode 100755 spec/models/feedback_reporters/support_reporter_spec.rb create mode 100755 spec/models/feedback_spec.rb create mode 100755 spec/models/filter_count_spec.rb create mode 100755 spec/models/gift_exchange_spec.rb create mode 100755 spec/models/gift_spec.rb create mode 100755 spec/models/indexing/cache_master_spec.rb create mode 100755 spec/models/indexing/index_queue_spec.rb create mode 100755 spec/models/invitation_spec.rb create mode 100755 spec/models/invite_request_spec.rb create mode 100755 spec/models/kudo_spec.rb create mode 100755 spec/models/language_spec.rb create mode 100755 spec/models/locale_spec.rb create mode 100755 spec/models/moderated_work_spec.rb create mode 100755 spec/models/owned_tag_set_spec.rb create mode 100755 spec/models/potential_match_spec.rb create mode 100755 spec/models/preference_spec.rb create mode 100755 spec/models/prompt_spec.rb create mode 100755 spec/models/pseud_spec.rb create mode 100755 spec/models/reading_spec.rb create mode 100755 spec/models/redis_hit_counter_spec.rb create mode 100755 spec/models/roles_user_spec.rb create mode 100755 spec/models/search/async_indexer_spec.rb create mode 100755 spec/models/search/bookmark_indexer_spec.rb create mode 100755 spec/models/search/bookmark_query_spec.rb create mode 100755 spec/models/search/bookmark_search_form_exclusion_filters_spec.rb create mode 100755 spec/models/search/bookmark_search_form_spec.rb create mode 100755 spec/models/search/bookmarkable_query_spec.rb create mode 100755 spec/models/search/bookmarked_work_indexer_spec.rb create mode 100755 spec/models/search/homepage_decorator_spec.rb create mode 100755 spec/models/search/index_sweeper_spec.rb create mode 100755 spec/models/search/pseud_decorator_spec.rb create mode 100755 spec/models/search/pseud_indexer_spec.rb create mode 100755 spec/models/search/pseud_query_spec.rb create mode 100755 spec/models/search/pseud_search_form_spec.rb create mode 100755 spec/models/search/query_cleaner_spec.rb create mode 100755 spec/models/search/query_spec.rb create mode 100755 spec/models/search/stat_counter_indexer_spec.rb create mode 100755 spec/models/search/tag_query_spec.rb create mode 100755 spec/models/search/tag_query_wrangling_spec.rb create mode 100755 spec/models/search/work_creator_indexer_spec.rb create mode 100755 spec/models/search/work_indexer_spec.rb create mode 100755 spec/models/search/work_query_spec.rb create mode 100755 spec/models/search/work_search_form_exclusion_filters_spec.rb create mode 100755 spec/models/search/work_search_form_spec.rb create mode 100755 spec/models/serial_work_spec.rb create mode 100755 spec/models/series_spec.rb create mode 100755 spec/models/skin_parent_spec.rb create mode 100755 spec/models/skin_spec.rb create mode 100755 spec/models/spam_report_spec.rb create mode 100755 spec/models/stat_counter_spec.rb create mode 100755 spec/models/story_parser_spec.rb create mode 100755 spec/models/subscription_spec.rb create mode 100755 spec/models/tag_set_nomination_spec.rb create mode 100755 spec/models/tag_spec.rb create mode 100755 spec/models/tag_wrangling_spec.rb create mode 100755 spec/models/tagset_models/tag_nomination_spec.rb create mode 100755 spec/models/unsorted_tag_spec.rb create mode 100755 spec/models/user_manager_spec.rb create mode 100755 spec/models/user_spec.rb create mode 100755 spec/models/work_original_creator_spec.rb create mode 100755 spec/models/work_spec.rb create mode 100755 spec/requests/blocked_users_n_plus_one_spec.rb create mode 100755 spec/requests/bookmarks_n_plus_one_spec.rb create mode 100755 spec/requests/collection_items_n_plus_one_spec.rb create mode 100755 spec/requests/comments_n_plus_one_spec.rb create mode 100755 spec/requests/muted_users_n_plus_one_spec.rb create mode 100755 spec/requests/people_n_plus_one_spec.rb create mode 100755 spec/requests/pseuds_n_plus_one_spec.rb create mode 100755 spec/requests/rack_attack_spec.rb create mode 100755 spec/requests/security_headers_spec.rb create mode 100755 spec/requests/skins_n_plus_one_spec.rb create mode 100755 spec/requests/works_n_plus_one_spec.rb create mode 100755 spec/requests/works_show_request_spec.rb create mode 100755 spec/rubocop/cop/cucumber/regex_step_name_spec.rb create mode 100755 spec/rubocop/cop/i18n/default_translation_spec.rb create mode 100755 spec/rubocop/cop/i18n/deprecated_helper_spec.rb create mode 100755 spec/rubocop/cop/i18n/deprecated_translation_key_spec.rb create mode 100755 spec/rubocop/cop/i18n/html_safe_translation_spec.rb create mode 100755 spec/rubocop/cop/migration/large_table_schema_update_spec.rb create mode 100755 spec/rubocop_spec_helper.rb create mode 100755 spec/spec_helper.rb create mode 100755 spec/support/fixtures/opendoors_import_url_mapping.csv create mode 100755 spec/support/i18n_newlines_tasks.rb create mode 100755 spec/support/login_macros.rb create mode 100755 spec/support/matchers/add_to_reindex_queue.rb create mode 100755 spec/support/matchers/be_valid_verbose.rb create mode 100755 spec/support/matchers/have_html_part_content.rb create mode 100755 spec/support/matchers/have_text_part_content.rb create mode 100755 spec/support/redirect_expectation_helper.rb create mode 100755 spec/support/shared_examples/access_shared_examples.rb create mode 100755 spec/support/shared_examples/mailer_shared_examples.rb create mode 100755 spec/support/task_example_group.rb create mode 100755 spec/support/zoho_client_spec_helper.rb create mode 100755 test/fixtures/admin_settings.yml create mode 100755 test/fixtures/admins.yml create mode 100755 test/fixtures/archive_faq_translations.yml create mode 100755 test/fixtures/archive_faqs.yml create mode 100755 test/fixtures/bookmarks.yml create mode 100755 test/fixtures/chapters.yml create mode 100755 test/fixtures/collection_items.yml create mode 100755 test/fixtures/collection_participants.yml create mode 100755 test/fixtures/collection_preferences.yml create mode 100755 test/fixtures/collection_profiles.yml create mode 100755 test/fixtures/collections.yml create mode 100755 test/fixtures/comments.yml create mode 100755 test/fixtures/common_taggings.yml create mode 100755 test/fixtures/creatorships.yml create mode 100755 test/fixtures/external_works.yml create mode 100755 test/fixtures/gifts.yml create mode 100755 test/fixtures/inbox_comments.yml create mode 100755 test/fixtures/languages.yml create mode 100755 test/fixtures/locales.yml create mode 100755 test/fixtures/preferences.yml create mode 100755 test/fixtures/profiles.yml create mode 100755 test/fixtures/pseuds.yml create mode 100755 test/fixtures/question_translations.yml create mode 100755 test/fixtures/questions.yml create mode 100755 test/fixtures/related_works.yml create mode 100755 test/fixtures/roles.yml create mode 100755 test/fixtures/roles_users.yml create mode 100755 test/fixtures/serial_works.yml create mode 100755 test/fixtures/series.yml create mode 100755 test/fixtures/stat_counters.yml create mode 100755 test/fixtures/taggings.yml create mode 100755 test/fixtures/tags.yml create mode 100755 test/fixtures/users.yml create mode 100755 test/fixtures/works.yml create mode 100755 test/mailers/previews/application_mailer_preview.rb create mode 100755 test/mailers/previews/archive_devise_mailer_preview.rb create mode 100755 test/mailers/previews/comment_mailer_preview.rb create mode 100755 test/mailers/previews/kudo_mailer_preview.rb create mode 100755 test/mailers/previews/tag_wrangling_supervisor_mailer_preview.rb create mode 100755 test/mailers/previews/tos_update_mailer_preview.rb create mode 100755 test/mailers/previews/user_mailer_preview.rb diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100755 index 0000000..15bd1c2 --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,12 @@ +exclude_paths: +- "bin/" +- "config/" +- "db/" +- "factories/" +- "features/" +- "public/**/*.min.js" +- "public/javascripts/bootstrap/" +- "public/javascripts/tinymce/" +- "script/" +- "spec/" +- "test/" diff --git a/.codecov.yml b/.codecov.yml new file mode 100755 index 0000000..69cb760 --- /dev/null +++ b/.codecov.yml @@ -0,0 +1 @@ +comment: false diff --git a/.erb-lint.yml b/.erb-lint.yml new file mode 100755 index 0000000..24920f5 --- /dev/null +++ b/.erb-lint.yml @@ -0,0 +1,45 @@ +--- +EnableDefaultLinters: true +linters: + AllowedScriptType: + allowed_types: + - "text/javascript" + - "speculationrules" + DeprecatedClasses: + enabled: true + rule_set: + - deprecated: ["bookmarks", "collections", "readings", "works"] + suggestion: "Avoid the plural form of these classes." + RequireInputAutocomplete: + enabled: false + Rubocop: + enabled: true + rubocop_config: + inherit_from: + - .rubocop.yml + Layout/ArgumentAlignment: + EnforcedStyle: with_fixed_indentation + Layout/InitialIndentation: + Enabled: false + Layout/LineLength: + Enabled: false + Layout/TrailingEmptyLines: + Enabled: false + Layout/TrailingWhitespace: + Enabled: false + Naming/FileName: + Enabled: false + Style/FrozenStringLiteralComment: + Enabled: false + Lint/UselessAssignment: + Enabled: false + # Workaround for RuboCop 0.72 and later + # https://github.com/Shopify/erb-lint/issues/130 + Rails: + Enabled: true + Rails/OutputSafety: + Enabled: false + SelfClosingTag: + enabled: true + # XHTML style + enforced_style: always diff --git a/.gitattributes b/.gitattributes new file mode 100755 index 0000000..e838c59 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto +# Bash scripts needs to have LF line endings, even on Windows +*.sh text eol=lf +# /usr/local/bin/ruby: warning: shebang line ending with \r may cause problems +/bin/* text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9bb29a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,127 @@ +*.swp +.DS_Store +.bundle +.idea +stdout +*~ +docker_compose.yml +docker-compose.yml +snapshot_cache +snapshot_cache/ +/snapshot_cache +/snapshot_cache/* +aria_log_control +.github/ +_state/ +/_state +/indices +/indices/* +_state +.github +.vscode/ +# / +/*.tmproj +/sphinx +/.DAV +/rerun.txt +/capybara-*.html +/.dropbox +/.dropbox.attr +/.rspec +REVISION +aria_log.00000001 +# /config/ +/config/brakeman.ignore +/config/docker/database.yml +/config/database.yml +/config/local.yml +/config/backup.yml +/config/*.sphinx.conf +/config/s3.yml +/config/sphinx.yml +/config/unicorn.rb +/config/newrelic.yml +/config/redis.yml +/config/redis-cucumber.conf +/config/skins.dump +config/local.yml.save +ibdata1 +ib_buffer_pool +ib_logfile0 +indices +indices/ +/indices/* +/_state/* +bunder_gems/ +bundler_gems/ +otwarchive_production/ +performance_schema/ +/bunder_gems +/bunder_gems/ +/bunder_gems/* +/bundler_gems +/bundler_gems/ +/bundler_gems/* +ibtmp1 +/performance_schema +/performance_schema/* +/performance-schema +/performance_schema/ +/mysql/* +/otwarchive_production/* +/db/* +/elastic-data/* +/elastic-data +/elastic-data/ +/elastic/* +# /config/environments/ +/config/environments/development.rb +elastic/ +elasic/ + +# /db/ +/db/*.sqlite3 +/db/backup +/db/sphinx +/db/seed + +# /log/ +/log/* + +# /public/ +/public/downloads +/public/stylesheets/cached_for_screen.css +/public/stylesheets/skins +public/system/development +/public/system/skins +public/system/test +/public/system/work_skins +/public/tags + +# /public/images/ +/public/images/Thumbs.db + +# /tmp/ +/tmp/* + +# ActiveRecord storage path +storage/ + +# /vendor/ +/vendor/gems + +# /vendor/gems/ +/vendor/gems/* + +# /vendor/plugins/ + +features/cassette_library/ + +spec/results.html +spec/results +features_report.html +coverage +redis-cucumber-dump.rdb + +.rspec + diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100755 index 0000000..427940c --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,21 @@ +tasks: + # See https://github.com/gitpod-io/gitpod/issues/7122 + - name: Configure Git committer email + before: | + git config --global user.email "${GIT_COMMITTER_EMAIL:-$(git config user.email)}" + - init: ./script/docker/init.sh + command: docker compose up -d web + +ports: + - port: 3000 + onOpen: open-browser + - port: 3306 + onOpen: ignore + - port: 6379 + onOpen: ignore + - port: 9200 + onOpen: ignore + - port: 9300 + onOpen: ignore + - port: 9400 + onOpen: ignore diff --git a/.hound.yml b/.hound.yml new file mode 100755 index 0000000..236f7f4 --- /dev/null +++ b/.hound.yml @@ -0,0 +1,9 @@ +# Available linter versions: +# http://help.houndci.com/en/articles/2461415-supported-linters + +jshint: + config_file: .jshintrc + ignore_file: .jshintignore + +rubocop: + enabled: false diff --git a/.jshintignore b/.jshintignore new file mode 100755 index 0000000..d86ef25 --- /dev/null +++ b/.jshintignore @@ -0,0 +1,4 @@ +coverage +public/**/*.min.js +public/javascripts/bootstrap +public/javascripts/tinymce diff --git a/.jshintrc b/.jshintrc new file mode 100755 index 0000000..0967ef4 --- /dev/null +++ b/.jshintrc @@ -0,0 +1 @@ +{} diff --git a/.phrase.yml b/.phrase.yml new file mode 100755 index 0000000..cc7e934 --- /dev/null +++ b/.phrase.yml @@ -0,0 +1,164 @@ +phrase: + project_id: a3667b8095533c2b3f8d3ac946bb642f + file_format: yml + push: + sources: + # controllers + - file: ./config/locales/controllers/en.yml + params: + update_translations: true + # devise + - file: ./config/locales/devise/en.yml + params: + update_translations: true + # mailers + - file: ./config/locales/mailers/en.yml + params: + update_translations: true + # models + - file: ./config/locales/models/en.yml + params: + update_translations: true + # validators + - file: ./config/locales/validators/en.yml + params: + update_translations: true + # views + - file: ./config/locales/views/en.yml + params: + update_translations: true + pull: + targets: + - file: ./config/locales/phrase-exports/af.yml + params: + locale_id: af + - file: ./config/locales/phrase-exports/ar.yml + params: + locale_id: ar + - file: ./config/locales/phrase-exports/bg.yml + params: + locale_id: bg + - file: ./config/locales/phrase-exports/bn.yml + params: + locale_id: bn + - file: ./config/locales/phrase-exports/ca.yml + params: + locale_id: ca + - file: ./config/locales/phrase-exports/cs.yml + params: + locale_id: cs + - file: ./config/locales/phrase-exports/cy.yml + params: + locale_id: cy + - file: ./config/locales/phrase-exports/da.yml + params: + locale_id: da + - file: ./config/locales/phrase-exports/de.yml + params: + locale_id: de + - file: ./config/locales/phrase-exports/el.yml + params: + locale_id: el + - file: ./config/locales/phrase-exports/es.yml + params: + locale_id: es + - file: ./config/locales/phrase-exports/fa.yml + params: + locale_id: fa + - file: ./config/locales/phrase-exports/fi.yml + params: + locale_id: fi + - file: ./config/locales/phrase-exports/fil.yml + params: + locale_id: fil + - file: ./config/locales/phrase-exports/fr.yml + params: + locale_id: fr + - file: ./config/locales/phrase-exports/he.yml + params: + locale_id: he + - file: ./config/locales/phrase-exports/hi.yml + params: + locale_id: hi + - file: ./config/locales/phrase-exports/hr.yml + params: + locale_id: hr + - file: ./config/locales/phrase-exports/hu.yml + params: + locale_id: hu + - file: ./config/locales/phrase-exports/id.yml + params: + locale_id: id + - file: ./config/locales/phrase-exports/it.yml + params: + locale_id: it + - file: ./config/locales/phrase-exports/ja.yml + params: + locale_id: ja + - file: ./config/locales/phrase-exports/ko.yml + params: + locale_id: ko + - file: ./config/locales/phrase-exports/lt.yml + params: + locale_id: lt + - file: ./config/locales/phrase-exports/lv.yml + params: + locale_id: lv + - file: ./config/locales/phrase-exports/mk.yml + params: + locale_id: mk + - file: ./config/locales/phrase-exports/mr.yml + params: + locale_id: mr + - file: ./config/locales/phrase-exports/ms.yml + params: + locale_id: ms + - file: ./config/locales/phrase-exports/nb.yml + params: + locale_id: nb + - file: ./config/locales/phrase-exports/nl.yml + params: + locale_id: nl + - file: ./config/locales/phrase-exports/pl.yml + params: + locale_id: pl + - file: ./config/locales/phrase-exports/pt-BR.yml + params: + locale_id: pt-BR + - file: ./config/locales/phrase-exports/pt-PT.yml + params: + locale_id: pt-PT + - file: ./config/locales/phrase-exports/ro.yml + params: + locale_id: ro + - file: ./config/locales/phrase-exports/ru.yml + params: + locale_id: ru + - file: ./config/locales/phrase-exports/scr.yml + params: + locale_id: scr + - file: ./config/locales/phrase-exports/sk.yml + params: + locale_id: sk + - file: ./config/locales/phrase-exports/sl.yml + params: + locale_id: sl + - file: ./config/locales/phrase-exports/sv.yml + params: + locale_id: sv + - file: ./config/locales/phrase-exports/th.yml + params: + locale_id: th + - file: ./config/locales/phrase-exports/tr.yml + params: + locale_id: tr + - file: ./config/locales/phrase-exports/uk.yml + params: + locale_id: uk + - file: ./config/locales/phrase-exports/vi.yml + params: + locale_id: vi + - file: ./config/locales/phrase-exports/zh-CN.yml + params: + locale_id: zh-CN + diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100755 index 0000000..7fec430 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,310 @@ +# Options available at https://github.com/bbatsov/rubocop/blob/master/config/default.yml + +require: + - rubocop-rails + - rubocop-rspec + - ./rubocop/rubocop + +inherit_mode: + merge: + - Exclude + +AllCops: + NewCops: enable + TargetRubyVersion: 3.1 + +Bundler/OrderedGems: + Enabled: false + +I18n/DeprecatedTranslationKey: + Rules: + name_with_colon: "Prefer `name` with `mailer.general.metadata_label_indicator` over `name_with_colon`" + +Layout/DotPosition: + EnforcedStyle: leading + +Layout/EmptyLinesAroundAttributeAccessor: + Enabled: false + +Layout/FirstArrayElementIndentation: + EnforcedStyle: consistent + +Layout/LineLength: + Enabled: false + +Layout/MultilineMethodCallIndentation: + EnforcedStyle: indented + +Layout/SingleLineBlockChain: + Enabled: true + +Layout/TrailingWhitespace: + Enabled: false + +Lint/AmbiguousBlockAssociation: + Exclude: + # Exception for specs where we use change matchers: + # https://github.com/rubocop-hq/rubocop/issues/4222 + - 'features/step_definitions/**/*.rb' + - 'spec/**/*.rb' + +Lint/AmbiguousRegexpLiteral: + Enabled: false + +Lint/RedundantSafeNavigation: + Exclude: + # Take a better safe than sorry approach to safe navigation in admin + # policies. + - 'app/policies/*.rb' + +Metrics/AbcSize: + Enabled: false + +Metrics/BlockLength: + Enabled: false + +Metrics/ClassLength: + Enabled: false + +Metrics/CyclomaticComplexity: + Enabled: false + +Metrics/MethodLength: + Enabled: false + +Metrics/ModuleLength: + Enabled: false + +Metrics/ParameterLists: + CountKeywordArgs: false + +Metrics/PerceivedComplexity: + Enabled: false + +Migration/LargeTableSchemaUpdate: + Tables: + - abuse_reports + - active_storage_attachments + - active_storage_blobs + - active_storage_variant_records + - admin_activities + - audits + - blocks + - bookmarks + - chapters + - comments + - common_taggings + - collection_items + - collection_participants + - collection_preferences + - collection_profiles + - collections + - creatorships + - external_works + - favorite_tags + - feedbacks + - filter_counts + - filter_taggings + - gifts + - inbox_comments + - invitations + - kudos + - log_items + - meta_taggings + - mutes + - preferences + - profiles + - prompts + - pseuds + - readings + - related_works + - set_taggings + - serial_works + - series + - skins + - stat_counters + - subscriptions + - tag_nominations + - tag_set_associations + - tag_sets + - taggings + - tags + - users + - works + +Naming/VariableNumber: + AllowedIdentifiers: + - age_over_13 + - no_age_over_13 + +Rails/DefaultScope: + Enabled: true + +Rails/DynamicFindBy: + AllowedMethods: + # Exceptions for Tag.find_by_name and Tag.find_by_name! + - find_by_name + - find_by_name! + # Exception for Tagging.find_by_tag + - find_by_tag + # Exceptions for Work.find_by_* + - find_by_url + - find_by_url_cache_key + - find_by_url_generation + - find_by_url_generation_key + - find_by_url_uncached + # Exceptions for InboxComment.find_by_filters + - find_by_filters + +Rails/EnvironmentVariableAccess: + Enabled: true + +# Allow all uses of html_safe, they're everywhere... +Rails/OutputSafety: + Enabled: false + +Rails/Output: + Exclude: + # Allow patches to print warnings to console: + - 'config/initializers/monkeypatches/*.rb' + # Allow migrations to print pt-osc comments to console: + - 'db/migrate/*.rb' + +Rails/RakeEnvironment: + Enabled: false + +Rails/ReversibleMigrationMethodDefinition: + Enabled: true + +# Allow update_attribute, update_all, touch, etc. +Rails/SkipsModelValidations: + Enabled: false + +Rails/UnknownEnv: + Environments: + - development + - test + - staging + - production + +RSpec: + Include: + - "(?:^|/)factories/" + - "(?:^|/)features/" + - "(?:^|/)spec/" + +# Allow "allow_any_instance_of" +RSpec/AnyInstance: + Enabled: false + +# By default allow only prefixes "when", "with", "without". +# We have too many, so let's allow everything. +RSpec/ContextWording: + Enabled: false + +RSpec/DescribeClass: + Exclude: + # Exception for specs about I18n configurations + - 'spec/lib/i18n/**/*.rb' + # Exception for rake specs, where the top level describe uses a task name + - 'spec/lib/tasks/*.rake_spec.rb' + # Exception for integration specs, which may not test a specific class + - 'spec/requests/**/*.rb' + +RSpec/DescribedClass: + Enabled: false + +RSpec/ExampleLength: + Enabled: false + +# Prefer: expect { run }.to change { Foo.bar } +# over: expect { run }.to change(Foo, :bar) +RSpec/ExpectChange: + EnforcedStyle: block + +RSpec/FilePath: + Exclude: + # Exception for WorksController, whose many specs need multiple files + - 'spec/controllers/works/*.rb' + # Exception for concern specs, which may test multiple classes + - 'spec/models/concerns/**/*.rb' + +# Avoid instance variables, except for those not assigned within the spec, +# e.g. @request. +RSpec/InstanceVariable: + AssignmentOnly: true + +# Allow unreferenced let! calls for test setup +RSpec/LetSetup: + Enabled: false + +# Allow both "have_received" and "receive" for expectations +RSpec/MessageSpies: + Enabled: false + +# Allow multiple top level describes (rake specs) +RSpec/MultipleDescribes: + Enabled: false + +# Allow unlimited expectations per test +RSpec/MultipleExpectations: + Enabled: false + +# Allow unnamed subjects +RSpec/NamedSubject: + Enabled: false + +# Allow unlimited nested groups +RSpec/NestedGroups: + Enabled: false + +RSpec/PredicateMatcher: + Enabled: false + +Style/AndOr: + EnforcedStyle: conditionals + +Style/ClassAndModuleChildren: + Enabled: false + +Style/Documentation: + Enabled: false + +Style/EmptyMethod: + EnforcedStyle: expanded + +# Prefer template tokens (like %{foo}) over annotated tokens (like %s) +Style/FormatStringToken: + EnforcedStyle: template + +Style/FrozenStringLiteralComment: + Enabled: false + +Style/GlobalVars: + AllowedVariables: + - $elasticsearch + - $rollout + +Style/PercentLiteralDelimiters: + Exclude: + # Exception for Cucumber step definitions, where we heavily use %{} for strings + - 'features/**/*.rb' + +# Stop checking if uses of "self" are redundant +Style/RedundantSelf: + Enabled: false + +Style/SelectByRegexp: + Enabled: true + +Style/SingleLineMethods: + AllowIfMethodIsEmpty: false + +Style/StringLiterals: + EnforcedStyle: double_quotes + +Style/SymbolArray: + Enabled: false + +Style/TernaryParentheses: + EnforcedStyle: require_parentheses_when_complex diff --git a/.ruby-version b/.ruby-version new file mode 100755 index 0000000..fb72f06 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +ruby-3.2.7 diff --git a/.simplecov b/.simplecov new file mode 100755 index 0000000..188e319 --- /dev/null +++ b/.simplecov @@ -0,0 +1,10 @@ +if ENV["CI"] == "true" + require "simplecov-cobertura" + SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter +end + +SimpleCov.start "rails" do + add_filter "/factories/" + merge_timeout 7200 + command_name ENV["TEST_GROUP"].gsub(/[^\w]/, "_") if ENV["TEST_GROUP"] +end diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md new file mode 100755 index 0000000..128480d --- /dev/null +++ b/ACKNOWLEDGMENTS.md @@ -0,0 +1,27 @@ +Acknowledgments +========= + +

BrowserStack for our cross-browser testing tool.

+ +

Capybara for integration testing.

+

Codeship for continuous integration.

+

Cucumber for integration testing.

+

Debian for our Linux distribution.

+

Elasticsearch for our tag searching.

+

Exim for mail sending.

+

Galera Cluster for clustered MySQL.

+

GitHub for collaborative programming.

+

HAProxy for load balancing.

+

Hound and reviewdog logo reviewdog for style guidance.

+

Jira for our issue tracking.

+

NGINX for our front end.

+

Memcached for caching.

+

MaxScale for MySQL load balancing.

+

Percona XtraDB Cluster for our relational database.

+

Rails for our framework.

+

Redis for NoSQL.

+

RSpec for unit tests.

+

Ruby as our language.

+

RubyMine for our integrated development environment.

+

Sentry for APM/application monitoring.

+

Slack for communications.

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100755 index 0000000..d1fbdf7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,63 @@ +# Contributing to OTW-Archive + +## Reporting bugs + +We maintain a [Jira issue tracker](https://otwarchive.atlassian.net/projects/AO3/issues) for developers, +and a [list of Known Issues](https://archiveofourown.org/known_issues) for +[Archive of Our Own](https://archiveofourown.org) users, neither of which are +publicly editable. + +If you need help using the site, or want to report an issue you have found, +please [contact the AO3 Support team](https://archiveofourown.org/support). Our Support team is staffed by volunteers, so please wait for a response before submitting another ticket. Duplicate submissions will not make things happen faster. + + +## Reporting security issues + +Please refer to [SECURITY.md](https://github.com/otwcode/otwarchive/blob/master/SECURITY.md). + + +## Updating documentation + +Our [development wiki](https://github.com/otwcode/otwarchive/wiki) is publicly +editable. Unless a page says at the top that it should only be edited by +official OTW volunteers, please feel free to make changes! + + +## Suggesting new features + +Please [contact the AO3 Support team](https://archiveofourown.org/support). Our Support team is staffed by volunteers, so please wait for a response before submitting another ticket. Duplicate submissions will not make things happen faster. + + +## Contributing code + +**We only accept pull requests for issues we have already added to [Jira](https://otwarchive.atlassian.net)**, +with the exception of spelling corrections and documentation improvements +(e.g. any Markdown files). We also do not accept code generated by AI tools; for more information, +please refer to [our commit policy](https://github.com/otwcode/otwarchive/wiki/Commit-Policy#scary-legal-stuff). + +Please check out our development wiki for more information on: + +- [how to set up a development environment](https://github.com/otwcode/otwarchive/wiki) +- [code conventions](https://github.com/otwcode/otwarchive/wiki/Commit-policy) + +### Workflow + +1. If you're a new contributor, start with an [issue reserved for first timers](https://otwarchive.atlassian.net/issues/?filter=13119). Otherwise, or if you're up for a challenge, choose any [open and unassigned issue](https://otwarchive.atlassian.net/issues/?filter=10800) available. (If you're a new contributor, don't worry about claiming the issue for now. If you make a Jira account, you'll get permissions for claiming issues in step 5.) +2. Write code to address the issue. If you already have Jira permissions, be sure to set the issue status to ["In Progress"](https://github.com/otwcode/otwarchive/wiki/Issue-Tracking-with-Jira#status-guide). +3. Optional: Create a Jira account if you'd like the ability to comment on, assign, and transition issues. Please make sure the Full Name on your Jira account either closely matches the name you'd like us to credit in the release notes or includes it in parentheses, e.g. "Nickname (CREDIT NAME)." +4. Submit the code with a pull request following the checklist on [our template](https://github.com/otwcode/otwarchive/blob/master/.github/PULL_REQUEST_TEMPLATE.md). +5. Once you've submitted a pull request, we'll review your code and give you permissions on Jira. (Please be patient with us! Due to our workload, it may take some time before we can review and eventually merge your pull request.) +6. Once your pull request is merged, we will deploy it to our internal testing site and our QA team will check that everything is working as intended. +7. If something is not working as intended, we may set the issue to ["Broken on Test"](https://github.com/otwcode/otwarchive/wiki/Issue-Tracking-with-Jira#status-guide) and ask you to make further changes in new pull requests. +8. If all is well, your contribution will be deployed to the [Archive of Our Own](https://archiveofourown.org) and you will be credited in the [release notes](https://archiveofourown.org/admin_posts?tag=1)! + + +## Volunteering for the OTW + +If you would like to donate more of your time and expertise in a multi-national, +inclusive, fandom-oriented team, you might enjoy [becoming an official OTW volunteer](http://transformativeworks.org/how-you-can-help/volunteer). + + +## Questions? + +[Drop us an email](mailto:otw-coders@transformativeworks.org) if you have any questions. diff --git a/Capfile b/Capfile new file mode 100755 index 0000000..e04728e --- /dev/null +++ b/Capfile @@ -0,0 +1,4 @@ +load 'deploy' if respond_to?(:namespace) # cap2 differentiator +Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) } + +load 'config/deploy' # remove this line to skip loading any of the default tasks \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100755 index 0000000..ec061e3 --- /dev/null +++ b/Gemfile @@ -0,0 +1,186 @@ +source 'https://rubygems.org' + +ruby "~> 3.2.7" + +gem 'test-unit', '~> 3.2' + +gem 'bundler' + +gem "rails", "~> 7.2" +gem "rails-i18n" +gem "rack", "~> 2.2" +gem "sprockets", "< 4" + +gem 'rails-observers', git: 'https://github.com/rails/rails-observers' +gem 'actionpack-page_caching' +gem 'rails-controller-testing' + +# Database +# gem 'sqlite3-ruby', require: 'sqlite3' +gem "mysql2" + +gem 'rack-attack' + +# Version of redis-rb gem +# We are currently running Redis 3.2.1 (7/2018) +gem "redis", "~> 3.3.5" +gem 'redis-namespace' + +# Here are all our application-specific gems + +# Used to convert strings to ascii +gem 'unicode' +gem 'unidecoder' +gem 'unicode_utils', '>=1.4.0' + +# Lograge is opinionated, very opinionated. +gem "lograge" # https://github.com/roidrage/lograge + +gem 'will_paginate', '>=3.0.2' +gem "pagy", "~> 9.3" +gem 'acts_as_list', '~> 0.9.7' +gem 'akismetor' + +gem 'httparty' +gem 'htmlentities' +gem 'whenever', '~>0.6.2', require: false +gem 'nokogiri', '>= 1.8.5' +gem 'mechanize' +gem 'sanitize', '>= 4.6.5' +gem "rest-client", "~> 2.1.0", require: "rest_client" +gem 'resque', '>=1.14.0' +gem 'resque-scheduler' +gem 'after_commit_everywhere' +#gem 'daemon-spawn', require: 'daemon_spawn' +gem "elasticsearch", "8.18.0" +gem "aws-sdk-s3" +gem 'css_parser' + +gem "terrapin" + +# for looking up image dimensions quickly +gem 'fastimage' + +# Gems for authentication +gem "devise" +gem "devise-async" # To mails through queues +gem "bcrypt" +gem "devise-pwned_password" + +# Needed for modern ssh +gem "ed25519", ">= 1.2", "< 2.0" +gem "bcrypt_pbkdf", ">= 1.0", "< 2.0" + +# A highly updated version of the authorization plugin +gem 'permit_yo' +gem "pundit" + +# fix for annoying UTF-8 error messages as per this: +# http://openhood.com/rack/ruby/2010/07/15/rack-test-warning/ +gem 'escape_utils', '1.2.1' + +gem 'timeliness' + +# for generating graphs +gem 'google_visualr', git: 'https://github.com/winston/google_visualr' + +# Globalize for translations +gem "globalize", "~> 7.0" + +# Add a clean notifier that shows we are on dev or test +gem 'rack-dev-mark', '>=0.7.8' + +#Phrase-app +gem 'phraseapp-in-context-editor-ruby', '>=1.0.6' + +# For URL mangling +gem 'addressable' +gem 'audited', '~> 5.3' + +# For controlling application behavour dynamically +gem 'rollout' + +# Use update memcached client with kinder, gentler I/O for Ruby +gem 'connection_pool' +gem 'dalli' +gem 'kgio', '2.10.0' + +gem "marcel", "1.0.2" + +# Library for helping run pt-online-schema-change commands: +gem "departure", "~> 6.8" + +gem "rack-timeout" +gem "puma_worker_killer" + +group :test do + gem "rspec-rails", "~> 6.0" + gem 'pickle' + gem 'shoulda' + gem "capybara" + gem "cucumber" + gem 'database_cleaner' + gem "selenium-webdriver" + gem 'capybara-screenshot' + gem 'cucumber-rails', require: false + gem 'launchy' # So you can do Then show me the page + + # Record and replay data from external URLs + gem "vcr", "~> 6.2" + gem "webmock" + gem 'timecop' + gem 'cucumber-timecop', require: false + # Code coverage + gem "simplecov" + gem "simplecov-cobertura", require: false + gem 'email_spec', '1.6.0' + gem "n_plus_one_control" +end + +group :test, :development do + gem 'awesome_print' + gem 'brakeman' + gem 'pry-byebug' + gem 'whiny_validation' + gem "factory_bot_rails" + gem 'minitest' + gem "i18n-tasks", require: false +end + +group :development do + gem 'bundler-audit' + gem 'active_record_query_trace', '~> 1.6', '>= 1.6.1' +end + +group :linters do + gem "erb_lint", "0.4.0" + gem "rubocop", "1.22.3" + gem "rubocop-rails", "2.12.4" + gem "rubocop-rspec", "2.6.0" +end + +group :test, :development, :staging do + gem 'bullet', '>= 5.7.3' + gem "factory_bot", require: false + gem "faker", require: false +end + +# Deploy with Capistrano +gem 'capistrano-gitflow_version', '>=0.0.3', require: false +gem 'rvm-capistrano' + +# Use unicorn as the web server +gem 'unicorn', '~> 5.5', require: false +# Install puma so we can migrate to it +gem "puma", "~> 6.5.0" +# Use god as the monitor +gem 'god', '~> 0.13.7' + +group :staging, :production do + gem "stackprof" + gem "sentry-ruby" + gem "sentry-rails" + gem "sentry-resque" +end + +gem "image_processing", "~> 1.12" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100755 index 0000000..c1d7682 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,781 @@ +GIT + remote: https://github.com/rails/rails-observers + revision: 389b577322d8b17336730b2dc4e179060a23c8e7 + specs: + rails-observers (0.2.0) + activemodel (>= 4.2) + +GIT + remote: https://github.com/winston/google_visualr + revision: 17b97114a345baadd011e7b442b9a6c91a2b7ab5 + specs: + google_visualr (2.5.1) + +GEM + remote: https://rubygems.org/ + specs: + aaronh-chronic (0.3.9) + actioncable (7.2.2.2) + actionpack (= 7.2.2.2) + activesupport (= 7.2.2.2) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (7.2.2.2) + actionpack (= 7.2.2.2) + activejob (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) + mail (>= 2.8.0) + actionmailer (7.2.2.2) + actionpack (= 7.2.2.2) + actionview (= 7.2.2.2) + activejob (= 7.2.2.2) + activesupport (= 7.2.2.2) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (7.2.2.2) + actionview (= 7.2.2.2) + activesupport (= 7.2.2.2) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4, < 3.2) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actionpack-page_caching (1.2.4) + actionpack (>= 4.0.0) + actiontext (7.2.2.2) + actionpack (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.2.2.2) + activesupport (= 7.2.2.2) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + active_record_query_trace (1.8.2) + activerecord (>= 6.0.0) + activejob (7.2.2.2) + activesupport (= 7.2.2.2) + globalid (>= 0.3.6) + activemodel (7.2.2.2) + activesupport (= 7.2.2.2) + activerecord (7.2.2.2) + activemodel (= 7.2.2.2) + activesupport (= 7.2.2.2) + timeout (>= 0.4.0) + activestorage (7.2.2.2) + actionpack (= 7.2.2.2) + activejob (= 7.2.2.2) + activerecord (= 7.2.2.2) + activesupport (= 7.2.2.2) + marcel (~> 1.0) + activesupport (7.2.2.2) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + acts_as_list (0.9.19) + activerecord (>= 3.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + after_commit_everywhere (1.6.0) + activerecord (>= 4.2) + activesupport + akismetor (1.0.0) + ast (2.4.3) + audited (5.8.0) + activerecord (>= 5.2, < 8.2) + activesupport (>= 5.2, < 8.2) + awesome_print (1.9.2) + aws-eventstream (1.3.0) + aws-partitions (1.895.0) + aws-sdk-core (3.191.3) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.8) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.77.0) + aws-sdk-core (~> 3, >= 3.191.0) + aws-sigv4 (~> 1.1) + aws-sdk-s3 (1.143.0) + aws-sdk-core (~> 3, >= 3.191.0) + aws-sdk-kms (~> 1) + aws-sigv4 (~> 1.8) + aws-sigv4 (1.8.0) + aws-eventstream (~> 1, >= 1.0.2) + base64 (0.3.0) + bcrypt (3.1.20) + bcrypt_pbkdf (1.1.0) + benchmark (0.4.1) + better_html (2.0.2) + actionview (>= 6.0) + activesupport (>= 6.0) + ast (~> 2.0) + erubi (~> 1.4) + parser (>= 2.4) + smart_properties + bigdecimal (3.2.2) + brakeman (7.0.2) + racc + builder (3.3.0) + bullet (8.0.8) + activesupport (>= 3.0.0) + uniform_notifier (~> 1.11) + bundler-audit (0.9.1) + bundler (>= 1.2.0, < 3) + thor (~> 1.0) + byebug (12.0.0) + capistrano (2.15.11) + highline + net-scp (>= 1.0.0) + net-sftp (>= 2.0.0) + net-ssh (>= 2.0.14) + net-ssh-gateway (>= 1.1.0) + capistrano-ext (1.2.1) + capistrano (>= 1.0.0) + capistrano-gitflow_version (0.0.3.1) + capistrano-ext (>= 1.2.1) + stringex + capybara (3.40.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.11) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + capybara-screenshot (1.0.26) + capybara (>= 1.0, < 4) + launchy + chronic (0.10.2) + climate_control (1.2.0) + coderay (1.1.3) + concurrent-ruby (1.3.5) + connection_pool (2.5.3) + crack (1.0.0) + bigdecimal + rexml + crass (1.0.6) + css_parser (1.16.0) + addressable + cucumber (9.2.1) + builder (~> 3.2) + cucumber-ci-environment (> 9, < 11) + cucumber-core (> 13, < 14) + cucumber-cucumber-expressions (~> 17.0) + cucumber-gherkin (> 24, < 28) + cucumber-html-formatter (> 20.3, < 22) + cucumber-messages (> 19, < 25) + diff-lcs (~> 1.5) + mini_mime (~> 1.1) + multi_test (~> 1.1) + sys-uname (~> 1.2) + cucumber-ci-environment (10.0.1) + cucumber-core (13.0.3) + cucumber-gherkin (>= 27, < 28) + cucumber-messages (>= 20, < 23) + cucumber-tag-expressions (> 5, < 7) + cucumber-cucumber-expressions (17.1.0) + bigdecimal + cucumber-gherkin (27.0.0) + cucumber-messages (>= 19.1.4, < 23) + cucumber-html-formatter (21.13.0) + cucumber-messages (> 19, < 28) + cucumber-messages (22.0.0) + cucumber-rails (3.1.1) + capybara (>= 3.11, < 4) + cucumber (>= 5, < 10) + railties (>= 5.2, < 9) + cucumber-tag-expressions (6.1.2) + cucumber-timecop (0.0.6) + chronic + cucumber + timecop + dalli (3.2.8) + database_cleaner (2.1.0) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.2.1) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) + date (3.4.1) + departure (6.8.0) + activerecord (>= 6.0.0, < 7.3.0, != 7.0.0) + mysql2 (>= 0.4.0, < 0.6.0) + railties (>= 6.0.0, < 7.3.0, != 7.0.0) + devise (4.9.3) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) + devise-async (1.0.0) + activejob (>= 5.0) + devise (>= 4.0) + devise-pwned_password (0.1.12) + devise (~> 4) + pwned (~> 2.4) + diff-lcs (1.6.2) + docile (1.4.1) + domain_name (0.6.20240107) + drb (2.2.3) + ed25519 (1.3.0) + elastic-transport (8.3.5) + faraday (< 3) + multi_json + elasticsearch (8.18.0) + elastic-transport (~> 8.3) + elasticsearch-api (= 8.18.0) + elasticsearch-api (8.18.0) + multi_json + email_spec (1.6.0) + launchy (~> 2.1) + mail (~> 2.2) + erb (5.0.2) + erb_lint (0.4.0) + activesupport + better_html (>= 2.0.1) + parser (>= 2.7.1.4) + rainbow + rubocop + smart_properties + erubi (1.13.1) + escape_utils (1.2.1) + et-orbi (1.2.11) + tzinfo + factory_bot (6.5.4) + activesupport (>= 6.1.0) + factory_bot_rails (6.5.0) + factory_bot (~> 6.5) + railties (>= 6.1.0) + faker (3.5.2) + i18n (>= 1.8.11, < 2) + faraday (2.13.1) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.0) + net-http (>= 0.5.0) + fastimage (2.3.0) + ffi (1.17.2) + fugit (1.11.1) + et-orbi (~> 1, >= 1.2.11) + raabro (~> 1.4) + get_process_mem (1.0.0) + bigdecimal (>= 2.0) + ffi (~> 1.0) + globalid (1.2.1) + activesupport (>= 6.1) + globalize (7.0.0) + activemodel (>= 7.0, < 8.1) + activerecord (>= 7.0, < 8.1) + activesupport (>= 7.0, < 8.1) + request_store (~> 1.0) + god (0.13.7) + hashdiff (1.2.0) + highline (3.1.2) + reline + htmlentities (4.3.4) + http-accept (1.7.0) + http-cookie (1.0.5) + domain_name (~> 0.5) + httparty (0.21.0) + mini_mime (>= 1.0.0) + multi_xml (>= 0.5.2) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + i18n-tasks (1.0.15) + activesupport (>= 4.0.2) + ast (>= 2.1.0) + erubi + highline (>= 2.0.0) + i18n + parser (>= 3.2.2.1) + rails-i18n + rainbow (>= 2.2.2, < 4.0) + ruby-progressbar (~> 1.8, >= 1.8.1) + terminal-table (>= 1.5.1) + image_processing (1.12.2) + mini_magick (>= 4.9.5, < 5) + ruby-vips (>= 2.0.17, < 3) + io-console (0.8.1) + irb (1.15.2) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jmespath (1.6.2) + json (2.12.2) + kgio (2.10.0) + launchy (2.5.2) + addressable (~> 2.8) + logger (1.7.0) + lograge (0.14.0) + actionpack (>= 4) + activesupport (>= 4) + railties (>= 4) + request_store (~> 1.0) + loofah (2.24.1) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.8.1) + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.0.2) + matrix (0.4.3) + mechanize (2.12.2) + addressable (~> 2.8) + base64 + domain_name (~> 0.5, >= 0.5.20190701) + http-cookie (~> 1.0, >= 1.0.3) + mime-types (~> 3.3) + net-http-digest_auth (~> 1.4, >= 1.4.1) + net-http-persistent (>= 2.5.2, < 5.0.dev) + nkf + nokogiri (~> 1.11, >= 1.11.2) + rubyntlm (~> 0.6, >= 0.6.3) + webrick (~> 1.7) + webrobots (~> 0.1.2) + method_source (1.1.0) + mime-types (3.5.2) + mime-types-data (~> 3.2015) + mime-types-data (3.2024.0206) + mini_magick (4.12.0) + mini_mime (1.1.5) + mini_portile2 (2.8.9) + minitest (5.25.5) + mono_logger (1.1.2) + multi_json (1.15.0) + multi_test (1.1.0) + multi_xml (0.6.0) + mustermann (3.0.0) + ruby2_keywords (~> 0.0.1) + mysql2 (0.5.6) + n_plus_one_control (0.7.2) + net-http (0.6.0) + uri + net-http-digest_auth (1.4.1) + net-http-persistent (4.0.2) + connection_pool (~> 2.2) + net-imap (0.5.9) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-scp (4.0.0) + net-ssh (>= 2.6.5, < 8.0.0) + net-sftp (4.0.0) + net-ssh (>= 5.0.0, < 8.0.0) + net-smtp (0.5.1) + net-protocol + net-ssh (7.2.1) + net-ssh-gateway (2.0.0) + net-ssh (>= 4.0.0) + netrc (0.11.0) + nio4r (2.7.4) + nkf (0.2.0) + nokogiri (1.18.9) + mini_portile2 (~> 2.8.2) + racc (~> 1.4) + orm_adapter (0.5.0) + pagy (9.3.3) + parallel (1.25.1) + parser (3.3.8.0) + ast (~> 2.4.1) + racc + permit_yo (2.1.3) + phraseapp-in-context-editor-ruby (1.4.0) + i18n (>= 0.6) + json (>= 1.8, < 3) + phraseapp-ruby (~> 1.3) + request_store (~> 1.3) + phraseapp-ruby (1.6.0) + pickle (0.9.0) + cucumber (>= 3.0, < 10.0) + rake + power_assert (2.0.3) + pp (0.6.2) + prettyprint + prettyprint (0.2.0) + pry (0.15.2) + coderay (~> 1.1) + method_source (~> 1.0) + pry-byebug (3.11.0) + byebug (~> 12.0) + pry (>= 0.13, < 0.16) + psych (5.2.6) + date + stringio + public_suffix (6.0.2) + puma (6.5.0) + nio4r (~> 2.0) + puma_worker_killer (1.0.0) + bigdecimal (>= 2.0) + get_process_mem (>= 0.2) + puma (>= 2.7) + pundit (2.3.1) + activesupport (>= 3.0.0) + pwned (2.4.1) + raabro (1.4.0) + racc (1.8.1) + rack (2.2.17) + rack-attack (6.7.0) + rack (>= 1.0, < 4) + rack-dev-mark (0.8.0) + rack (>= 1.1, < 4.0) + rack-protection (3.2.0) + base64 (>= 0.1.0) + rack (~> 2.2, >= 2.2.4) + rack-session (1.0.2) + rack (< 3) + rack-test (2.2.0) + rack (>= 1.3) + rack-timeout (0.7.0) + rackup (1.0.1) + rack (< 3) + webrick + rails (7.2.2.2) + actioncable (= 7.2.2.2) + actionmailbox (= 7.2.2.2) + actionmailer (= 7.2.2.2) + actionpack (= 7.2.2.2) + actiontext (= 7.2.2.2) + actionview (= 7.2.2.2) + activejob (= 7.2.2.2) + activemodel (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) + bundler (>= 1.15.0) + railties (= 7.2.2.2) + rails-controller-testing (1.0.5) + actionpack (>= 5.0.1.rc1) + actionview (>= 5.0.1.rc1) + activesupport (>= 5.0.1.rc1) + rails-dom-testing (2.3.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + rails-i18n (7.0.9) + i18n (>= 0.7, < 2) + railties (>= 6.0.0, < 8) + railties (7.2.2.2) + actionpack (= 7.2.2.2) + activesupport (= 7.2.2.2) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + raindrops (0.20.1) + rake (13.3.0) + rdoc (6.14.2) + erb + psych (>= 4.0.0) + redis (3.3.5) + redis-namespace (1.8.2) + redis (>= 3.0.4) + regexp_parser (2.10.0) + reline (0.6.2) + io-console (~> 0.5) + request_store (1.6.0) + rack (>= 1.4) + responders (3.1.1) + actionpack (>= 5.2) + railties (>= 5.2) + resque (2.6.0) + mono_logger (~> 1.0) + multi_json (~> 1.0) + redis-namespace (~> 1.6) + sinatra (>= 0.9.2) + resque-scheduler (4.10.2) + mono_logger (~> 1.0) + redis (>= 3.3) + resque (>= 1.27) + rufus-scheduler (~> 3.2, != 3.3) + rest-client (2.1.0) + http-accept (>= 1.7.0, < 2.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 4.0) + netrc (~> 0.8) + rexml (3.4.1) + rollout (2.4.3) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-rails (6.1.5) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) + rspec-support (3.13.4) + rubocop (1.22.3) + parallel (~> 1.10) + parser (>= 3.0.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.12.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.31.2) + parser (>= 3.3.0.4) + rubocop-rails (2.12.4) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.7.0, < 2.0) + rubocop-rspec (2.6.0) + rubocop (~> 1.19) + ruby-progressbar (1.13.0) + ruby-vips (2.2.1) + ffi (~> 1.12) + ruby2_keywords (0.0.5) + rubyntlm (0.6.3) + rubyzip (2.4.1) + rufus-scheduler (3.9.1) + fugit (~> 1.1, >= 1.1.6) + rvm-capistrano (1.5.6) + capistrano (~> 2.15.4) + sanitize (6.1.0) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + securerandom (0.4.1) + selenium-webdriver (4.34.0) + base64 (~> 0.2) + logger (~> 1.4) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + sentry-rails (5.18.0) + railties (>= 5.0) + sentry-ruby (~> 5.18.0) + sentry-resque (5.18.0) + resque (>= 1.24) + sentry-ruby (~> 5.18.0) + sentry-ruby (5.18.0) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + shoulda (4.0.0) + shoulda-context (~> 2.0) + shoulda-matchers (~> 4.0) + shoulda-context (2.0.0) + shoulda-matchers (4.5.1) + activesupport (>= 4.2.0) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-cobertura (3.0.0) + rexml + simplecov (~> 0.19) + simplecov-html (0.13.2) + simplecov_json_formatter (0.1.4) + sinatra (3.2.0) + mustermann (~> 3.0) + rack (~> 2.2, >= 2.2.4) + rack-protection (= 3.2.0) + tilt (~> 2.0) + smart_properties (1.17.0) + sprockets (3.7.2) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + stackprof (0.2.26) + stringex (2.8.6) + stringio (3.1.7) + sys-uname (1.3.1) + ffi (~> 1.1) + terminal-table (4.0.0) + unicode-display_width (>= 1.1.1, < 4) + terrapin (1.0.1) + climate_control + test-unit (3.6.2) + power_assert + thor (1.4.0) + tilt (2.3.0) + timecop (0.9.10) + timeliness (0.4.5) + timeout (0.4.3) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode (0.4.4.5) + unicode-display_width (2.6.0) + unicode_utils (1.4.0) + unicorn (5.8.0) + kgio (~> 2.6) + raindrops (~> 0.7) + unidecoder (1.1.2) + uniform_notifier (1.17.0) + uri (1.0.3) + useragent (0.16.11) + vcr (6.3.1) + base64 + warden (1.2.9) + rack (>= 2.0.9) + webmock (3.25.1) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) + webrick (1.9.1) + webrobots (0.1.2) + websocket (1.2.11) + websocket-driver (0.8.0) + base64 + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + whenever (0.6.8) + aaronh-chronic (>= 0.3.9) + activesupport (>= 2.3.4) + whiny_validation (1.1) + activemodel + activesupport + will_paginate (4.0.0) + xpath (3.2.0) + nokogiri (~> 1.8) + zeitwerk (2.7.3) + +PLATFORMS + ruby + +DEPENDENCIES + actionpack-page_caching + active_record_query_trace (~> 1.6, >= 1.6.1) + acts_as_list (~> 0.9.7) + addressable + after_commit_everywhere + akismetor + audited (~> 5.3) + awesome_print + aws-sdk-s3 + bcrypt + bcrypt_pbkdf (>= 1.0, < 2.0) + brakeman + bullet (>= 5.7.3) + bundler + bundler-audit + capistrano-gitflow_version (>= 0.0.3) + capybara + capybara-screenshot + connection_pool + css_parser + cucumber + cucumber-rails + cucumber-timecop + dalli + database_cleaner + departure (~> 6.8) + devise + devise-async + devise-pwned_password + ed25519 (>= 1.2, < 2.0) + elasticsearch (= 8.18.0) + email_spec (= 1.6.0) + erb_lint (= 0.4.0) + escape_utils (= 1.2.1) + factory_bot + factory_bot_rails + faker + fastimage + globalize (~> 7.0) + god (~> 0.13.7) + google_visualr! + htmlentities + httparty + i18n-tasks + image_processing (~> 1.12) + kgio (= 2.10.0) + launchy + lograge + marcel (= 1.0.2) + mechanize + minitest + mysql2 + n_plus_one_control + nokogiri (>= 1.8.5) + pagy (~> 9.3) + permit_yo + phraseapp-in-context-editor-ruby (>= 1.0.6) + pickle + pry-byebug + puma (~> 6.5.0) + puma_worker_killer + pundit + rack (~> 2.2) + rack-attack + rack-dev-mark (>= 0.7.8) + rack-timeout + rails (~> 7.2) + rails-controller-testing + rails-i18n + rails-observers! + redis (~> 3.3.5) + redis-namespace + resque (>= 1.14.0) + resque-scheduler + rest-client (~> 2.1.0) + rollout + rspec-rails (~> 6.0) + rubocop (= 1.22.3) + rubocop-rails (= 2.12.4) + rubocop-rspec (= 2.6.0) + rvm-capistrano + sanitize (>= 4.6.5) + selenium-webdriver + sentry-rails + sentry-resque + sentry-ruby + shoulda + simplecov + simplecov-cobertura + sprockets (< 4) + stackprof + terrapin + test-unit (~> 3.2) + timecop + timeliness + unicode + unicode_utils (>= 1.4.0) + unicorn (~> 5.5) + unidecoder + vcr (~> 6.2) + webmock + whenever (~> 0.6.2) + whiny_validation + will_paginate (>= 3.0.2) + +RUBY VERSION + ruby 3.2.7p253 + +BUNDLED WITH + 2.6.3 diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..23cb790 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +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. + + {signature of Ty Coon}, 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 Lesser General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100755 index 0000000..8724d77 --- /dev/null +++ b/README.md @@ -0,0 +1,46 @@ +OTW-Archive +========= +[![Build Status](https://img.shields.io/github/actions/workflow/status/otwcode/otwarchive/automated-tests.yml?branch=master)](https://github.com/otwcode/otwarchive/actions/workflows/automated-tests.yml?query=branch%3Amaster) [![Codeship Status](https://img.shields.io/codeship/1f7468f0-7e15-0131-c059-7a8d26daf885/master.svg?label=codeship)](https://www.codeship.io/projects/14476) [![Coverage Status](https://img.shields.io/codecov/c/github/otwcode/otwarchive/master.svg)](https://app.codecov.io/gh/otwcode/otwarchive) + +The OTW-Archive software is an open-source web application intended for hosting archives of fanworks, including fanfic, fanart, and fan vids. + +Its development is sponsored and managed by the [Organization for Transformative Works](https://www.transformativeworks.org/), a nonprofit organization by and for fans. + +Release Status +--------- +Development of the OTW-Archive software is an ongoing labor of love. You can see it in action on the [Archive of Our Own](https://archiveofourown.org/), aka AO3, a multifandom archive also run by the OTW. + +You can find more information about the [history and future of the AO3 project on the OTW website](https://www.transformativeworks.org/archive_of_our_own/). + +If you wish to use this software, SquidgeWorld has generously provided [setup notes](https://squidgeworld.org/works/34491). + +How to Contribute +---------- +We welcome pull requests for bugs described in our issue tracker. Please see our [Contributing Guidelines](https://github.com/otwcode/otwarchive/blob/master/CONTRIBUTING.md) for further information! + +* [Bug Tracker](https://otwarchive.atlassian.net/projects/AO3/issues) +* [Developer Documentation](https://github.com/otwcode/otwarchive/wiki) +* [Commit Policy](https://github.com/otwcode/otwarchive/wiki/Commit-policy) + +We do not have a public chat, but you are welcome to contact us at otw-coders@transformativeworks.org if you have any questions. + +We grant your Jira account permissions for commenting on, assigning, and transitioning issues [after you create your first pull request](https://github.com/otwcode/otwarchive/blob/master/CONTRIBUTING.md#workflow). + +API +---------- +There is currently no API for the OTW-Archive software. While it is something we're considering for the future, we ask that contributors instead focus on issues already in our [Jira issue tracker](https://otwarchive.atlassian.net/). + +License and Acknowledgments +---------- +The Archive code is licensed under [GPL-2.0-or-later](https://www.gnu.org/licenses/gpl-2.0.html) by the [Organization for Transformative Works](https://www.transformativeworks.org/). + +We benefit from software and services that are free to use for Open Source projects, including: + +* [RubyMine IDE](https://www.jetbrains.com/ruby/) by JetBrains +* [Codeship](https://codeship.com/) +* [Hound](https://houndci.com/) by [thoughtbot](https://thoughtbot.com/) +* [BrowserStack](https://www.browserstack.com) +* [Sentry](https://sentry.io) +* [Full list of acknowledgments](ACKNOWLEDGMENTS.md) + +Thank you kindly! diff --git a/Rakefile b/Rakefile new file mode 100755 index 0000000..303c321 --- /dev/null +++ b/Rakefile @@ -0,0 +1,9 @@ +# 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__) +require 'rake' +require 'resque/tasks' + +include Rake::DSL +Otwarchive::Application.load_tasks diff --git a/SECURITY.md b/SECURITY.md new file mode 100755 index 0000000..1a64647 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,14 @@ +# Reporting a security issue + +Please email us directly at [otw-coders@transformativeworks.org](mailto:otw-coders@transformativeworks.org) +with details and reproduction steps. We will get back to you as soon as possible, +and we may ask for additional information or guidance. + +Please avoid testing for security issues on the Archive of Our Own itself, +as you risk disrupting other users and violating the [Terms of Service](https://archiveofourown.org/content#II.K.1). + +Please give us a reasonable amount of time to address the issue before any +disclosure to the public or a third-party. + +We thank you for your effort and responsible disclosure! We will make sure you +receive due credit on [our public release notes](https://archiveofourown.org/admin_posts?tag=1). diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb new file mode 100755 index 0000000..bc13198 --- /dev/null +++ b/app/controllers/abuse_reports_controller.rb @@ -0,0 +1,38 @@ +class AbuseReportsController < ApplicationController + skip_before_action :store_location + before_action :load_abuse_languages + + def new + @abuse_report = AbuseReport.new + reporter = current_admin || current_user + if reporter.present? + @abuse_report.email = reporter.email + @abuse_report.username = reporter.login + end + @abuse_report.url = params[:url] || request.env["HTTP_REFERER"] + end + + def create + @abuse_report = AbuseReport.new(abuse_report_params) + @abuse_report.ip_address = request.remote_ip + if @abuse_report.save + @abuse_report.email_and_send + flash[:notice] = ts("Your report was submitted to the Policy & Abuse team. A confirmation message has been sent to the email address you provided.") + redirect_to root_path + else + render action: "new" + end + end + + private + + def load_abuse_languages + @abuse_languages = Language.where(abuse_support_available: true).default_order + end + + def abuse_report_params + params.require(:abuse_report).permit( + :username, :email, :language, :summary, :url, :comment + ) + end +end diff --git a/app/controllers/admin/activities_controller.rb b/app/controllers/admin/activities_controller.rb new file mode 100755 index 0000000..18837da --- /dev/null +++ b/app/controllers/admin/activities_controller.rb @@ -0,0 +1,11 @@ +class Admin::ActivitiesController < Admin::BaseController + def index + @activities = AdminActivity.order("created_at DESC").page(params[:page]) + authorize @activities + end + + def show + @activity = AdminActivity.find(params[:id]) + authorize @activity + end +end diff --git a/app/controllers/admin/admin_invitations_controller.rb b/app/controllers/admin/admin_invitations_controller.rb new file mode 100755 index 0000000..70d6614 --- /dev/null +++ b/app/controllers/admin/admin_invitations_controller.rb @@ -0,0 +1,61 @@ +class Admin::AdminInvitationsController < Admin::BaseController + + def index + end + + def create + @invitation = current_admin.invitations.new(invitation_params) + + if @invitation.invitee_email.blank? + flash[:error] = t('no_email', default: "Please enter an email address.") + render action: 'index' + elsif @invitation.save + flash[:notice] = t('sent', default: "An invitation was sent to %{email_address}", email_address: @invitation.invitee_email) + redirect_to admin_invitations_path + else + render action: 'index' + end + end + + def invite_from_queue + count = invitation_params[:invite_from_queue].to_i + InviteFromQueueJob.perform_later(count: count, creator: current_admin) + + flash[:notice] = t(".success", count: count) + redirect_to admin_invitations_path + end + + def grant_invites_to_users + if invitation_params[:user_group] == "All" + Invitation.grant_all(invitation_params[:number_of_invites].to_i) + else + Invitation.grant_empty(invitation_params[:number_of_invites].to_i) + end + flash[:notice] = t('invites_created', default: 'Invitations successfully created.') + redirect_to admin_invitations_path + end + + def find + unless invitation_params[:user_name].blank? + @user = User.find_by(login: invitation_params[:user_name]) + @hide_dashboard = true + @invitations = @user.invitations if @user + end + if !invitation_params[:token].blank? + @invitations = Invitation.where(token: invitation_params[:token]) + elsif invitation_params[:invitee_email].present? + @invitations = Invitation.where("invitee_email LIKE ?", "%#{invitation_params[:invitee_email]}%") + end + + return if @user || @invitations.present? + + flash.now[:error] = t(".user_not_found") + end + + private + + def invitation_params + params.require(:invitation).permit(:invitee_email, :invite_from_queue, + :user_group, :number_of_invites, :user_name, :token) + end +end diff --git a/app/controllers/admin/admin_users_controller.rb b/app/controllers/admin/admin_users_controller.rb new file mode 100755 index 0000000..8a0bce2 --- /dev/null +++ b/app/controllers/admin/admin_users_controller.rb @@ -0,0 +1,237 @@ +class Admin::AdminUsersController < Admin::BaseController + include ExportsHelper + + before_action :set_roles, only: [:index, :bulk_search] + before_action :load_user, only: [:show, :update, :confirm_delete_user_creations, :destroy_user_creations, :troubleshoot, :activate, :creations] + before_action :user_is_banned, only: [:confirm_delete_user_creations, :destroy_user_creations] + before_action :load_user_creations, only: [:confirm_delete_user_creations, :creations] + + def set_roles + @roles = Role.assignable.distinct + end + + def load_user + @user = User.find_by!(login: params[:id]) + end + + def user_is_banned + return if @user&.banned? + + flash[:error] = ts("That user is not banned!") + redirect_to admin_users_path + end + + def load_user_creations + @works = @user.works.paginate(page: params[:works_page]) + @comments = @user.comments.paginate(page: params[:comments_page]) + end + + def index + authorize User + + # Values for the role dropdown: + @role_values = @roles.map { |role| [role.name.humanize.titlecase, role.id] } + + return if search_params.empty? + + @query = UserQuery.new(search_params) + @users = @query.search_results.scope(:with_includes_for_admin_index) + end + + def bulk_search + authorize User + @emails = params[:emails].split if params[:emails] + if @emails.present? + found_users, not_found_emails, duplicates = User.search_multiple_by_email(@emails) + @users = found_users.paginate(page: params[:page] || 1) + + if params[:download_button] + header = [%w(Email Username)] + found = found_users.map { |u| [u.email, u.login] } + not_found = not_found_emails.map { |email| [email, ""] } + send_csv_data(header + found + not_found, "bulk_user_search_#{Time.now.strftime("%Y-%m-%d-%H%M")}.csv") + flash.now[:notice] = ts("Downloaded CSV") + end + @results = { + total: @emails.size, + searched: found_users.size + not_found_emails.size, + found_users: found_users, + not_found_emails: not_found_emails, + duplicates: duplicates + } + else + @results = {} + end + end + + # GET admin/users/1 + def show + authorize @user + @page_subtitle = t(".page_title", login: @user.login) + log_items + end + + # POST admin/users/update + def update + authorize @user + + attributes = permitted_attributes(@user) + if attributes[:email].present? + @user.skip_reconfirmation! + @user.email = attributes[:email] + end + if attributes[:roles].present? + # Roles that the current admin can add or remove + allowed_roles = UserPolicy::ALLOWED_USER_ROLES_BY_ADMIN_ROLES + .values_at(*current_admin.roles) + .compact + .flatten + + # Other roles the current user has + out_of_scope_roles = @user.roles.to_a.reject { |role| allowed_roles.include?(role.name) } + + request_roles = Role.where( + id: attributes[:roles], + name: [allowed_roles] + ) + + @user.roles = out_of_scope_roles + request_roles + end + + if @user.save + flash[:notice] = ts("User was successfully updated.") + else + flash[:error] = ts("The user %{name} could not be updated: %{errors}", name: params[:id], errors: @user.errors.full_messages.join(" ")) + end + redirect_to request.referer || root_path + end + + def update_next_of_kin + @user = authorize User.find_by!(login: params[:user_login]) + kin = User.find_by(login: params[:next_of_kin_name]) + kin_email = params[:next_of_kin_email] + + fnok = @user.fannish_next_of_kin + previous_kin = fnok&.kin + fnok ||= @user.build_fannish_next_of_kin + fnok.assign_attributes(kin: kin, kin_email: kin_email) + + unless fnok.changed? + flash[:notice] = ts("No change to fannish next of kin.") + redirect_to admin_user_path(@user) and return + end + + # Remove FNOK that already exists. + if fnok.persisted? && kin.blank? && kin_email.blank? + fnok.destroy + @user.log_removal_of_next_of_kin(previous_kin, admin: current_admin) + flash[:notice] = ts("Fannish next of kin was removed.") + redirect_to admin_user_path(@user) and return + end + + if fnok.save + @user.log_removal_of_next_of_kin(previous_kin, admin: current_admin) + @user.log_assignment_of_next_of_kin(kin, admin: current_admin) + flash[:notice] = ts("Fannish next of kin was updated.") + redirect_to admin_user_path(@user) + else + @hide_dashboard = true + log_items + render :show + end + end + + def update_status + @user = User.find_by!(login: params[:user_login]) + + # Authorize on the manager, as we need to check which specific actions the admin can do. + @user_manager = authorize UserManager.new(current_admin, @user, params) + if @user_manager.save + flash[:notice] = @user_manager.success_message + if @user_manager.admin_action == "spamban" + redirect_to confirm_delete_user_creations_admin_user_path(@user) + else + redirect_to admin_user_path(@user) + end + else + flash[:error] = @user_manager.error_message + redirect_to admin_user_path(@user) + end + end + + def confirm_delete_user_creations + authorize @user + @bookmarks = @user.bookmarks + @collections = @user.sole_owned_collections + @series = @user.series + @page_subtitle = t(".page_title", login: @user.login) + end + + def destroy_user_creations + authorize @user + + creations = @user.works + @user.bookmarks + @user.sole_owned_collections + creations.each do |creation| + AdminActivity.log_action(current_admin, creation, action: "destroy spam", summary: creation.inspect) + creation.mark_as_spam! if creation.respond_to?(:mark_as_spam!) + creation.destroy + end + + # comments are special and needs to be handled separately + @user.comments.not_deleted.each do |comment| + AdminActivity.log_action(current_admin, comment, action: "destroy spam", summary: comment.inspect) + comment.submit_spam + comment.destroy_or_mark_deleted # comments with replies cannot be destroyed, mark deleted instead + end + + flash[:notice] = t(".success", login: @user.login) + redirect_to(admin_users_path) + end + + def troubleshoot + authorize @user + + @user.fix_user_subscriptions + @user.set_user_work_dates + @user.reindex_user_creations + @user.update_works_index_timestamp! + @user.create_log_item(options = { action: ArchiveConfig.ACTION_TROUBLESHOOT, admin_id: current_admin.id }) + flash[:notice] = ts("User account troubleshooting complete.") + redirect_to(request.env["HTTP_REFERER"] || root_path) && return + end + + def activate + authorize @user + + @user.activate + if @user.active? + @user.create_log_item( options = { action: ArchiveConfig.ACTION_ACTIVATE, note: "Manually Activated", admin_id: current_admin.id }) + flash[:notice] = ts("User Account Activated") + redirect_to action: :show + else + flash[:error] = ts("Attempt to activate account failed.") + redirect_to action: :show + end + end + + def creations + authorize @user + @page_subtitle = t(".page_title", login: @user.login) + end + + private + + def search_params + allowed_params = if policy(User).can_view_past? + %i[name email role_id user_id inactive page commit search_past] + else + %i[name email role_id user_id inactive page commit] + end + + params.permit(*allowed_params) + end + + def log_items + @log_items ||= @user.log_items.sort_by(&:created_at).reverse + end +end diff --git a/app/controllers/admin/api_controller.rb b/app/controllers/admin/api_controller.rb new file mode 100755 index 0000000..e6efb99 --- /dev/null +++ b/app/controllers/admin/api_controller.rb @@ -0,0 +1,71 @@ +class Admin::ApiController < Admin::BaseController + before_action :check_for_cancel, only: [:create, :update] + + def index + @page_subtitle = t(".page_title") + @api_keys = if params[:query] + sql_query = "%" + params[:query] + "%" + ApiKey.where("name LIKE ?", sql_query).order("name").paginate(page: params[:page]) + else + ApiKey.order("name").paginate(page: params[:page]) + end + authorize @api_keys + end + + def show + redirect_to action: "index" + end + + def new + @page_subtitle = t(".page_title") + @api_key = authorize ApiKey.new + end + + def create + authorize ApiKey + # Use provided api key params if available otherwise fallback to empty + # ApiKey object + @api_key = params[:api_key].nil? ? ApiKey.new : ApiKey.new(api_key_params) + if @api_key.save + flash[:notice] = ts("New token successfully created") + redirect_to action: "index" + else + render "new" + end + end + + def edit + @page_subtitle = t(".page_title") + @api_key = authorize ApiKey.find(params[:id]) + end + + def update + @api_key = authorize ApiKey.find(params[:id]) + if @api_key.update(api_key_params) + flash[:notice] = ts("Access token was successfully updated") + redirect_to action: "index" + else + render "edit" + end + end + + def destroy + @api_key = authorize ApiKey.find(params[:id]) + @api_key.destroy + redirect_to(admin_api_path) + end + + private + + def api_key_params + params.require(:api_key).permit( + :name, :access_token, :banned + ) + end + + def check_for_cancel + if params[:cancel_button] + redirect_to action: "index" + end + end +end diff --git a/app/controllers/admin/banners_controller.rb b/app/controllers/admin/banners_controller.rb new file mode 100755 index 0000000..1a91130 --- /dev/null +++ b/app/controllers/admin/banners_controller.rb @@ -0,0 +1,82 @@ +class Admin::BannersController < Admin::BaseController + + # GET /admin/banners + def index + authorize(AdminBanner) + + @admin_banners = AdminBanner.order("id DESC").paginate(page: params[:page]) + end + + # GET /admin/banners/1 + def show + @admin_banner = authorize AdminBanner.find(params[:id]) + end + + # GET /admin/banners/new + def new + @admin_banner = authorize AdminBanner.new + end + + # GET /admin/banners/1/edit + def edit + @admin_banner = authorize AdminBanner.find(params[:id]) + end + + # POST /admin/banners + def create + @admin_banner = authorize AdminBanner.new(admin_banner_params) + + if @admin_banner.save + if @admin_banner.active? + AdminBanner.banner_on + flash[:notice] = ts('Setting banner back on for all users. This may take some time.') + else + flash[:notice] = ts('Banner successfully created.') + end + redirect_to @admin_banner + else + render action: 'new' + end + end + + # PUT /admin/banners/1 + def update + @admin_banner = authorize AdminBanner.find(params[:id]) + + if !@admin_banner.update(admin_banner_params) + render action: 'edit' + elsif params[:admin_banner_minor_edit] + flash[:notice] = ts('Updating banner for users who have not already dismissed it. This may take some time.') + redirect_to @admin_banner + else + if @admin_banner.active? + AdminBanner.banner_on + flash[:notice] = ts('Setting banner back on for all users. This may take some time.') + else + flash[:notice] = ts('Banner successfully updated.') + end + redirect_to @admin_banner + end + end + + # GET /admin/banners/1/confirm_delete + def confirm_delete + @admin_banner = authorize AdminBanner.find(params[:id]) + end + + # DELETE /admin/banners/1 + def destroy + @admin_banner = authorize AdminBanner.find(params[:id]) + @admin_banner.destroy + + flash[:notice] = ts('Banner successfully deleted.') + redirect_to admin_banners_path + end + + private + + def admin_banner_params + params.require(:admin_banner).permit(:content, :banner_type, :active) + end + +end diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb new file mode 100755 index 0000000..b70fd16 --- /dev/null +++ b/app/controllers/admin/base_controller.rb @@ -0,0 +1,3 @@ +class Admin::BaseController < ApplicationController + before_action :admin_only +end diff --git a/app/controllers/admin/blacklisted_emails_controller.rb b/app/controllers/admin/blacklisted_emails_controller.rb new file mode 100755 index 0000000..1348905 --- /dev/null +++ b/app/controllers/admin/blacklisted_emails_controller.rb @@ -0,0 +1,40 @@ +class Admin::BlacklistedEmailsController < Admin::BaseController + + def index + authorize AdminBlacklistedEmail + @admin_blacklisted_email = AdminBlacklistedEmail.new + if params[:query] + @admin_blacklisted_emails = AdminBlacklistedEmail.where(["email LIKE ?", '%' + params[:query] + '%']) + @admin_blacklisted_emails = @admin_blacklisted_emails.paginate(page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE) + end + @page_subtitle = t(".browser_title") + end + + def create + @admin_blacklisted_email = authorize AdminBlacklistedEmail.new(admin_blacklisted_email_params) + @page_subtitle = t(".browser_title") + + if @admin_blacklisted_email.save + flash[:notice] = ts("Email address %{email} banned.", email: @admin_blacklisted_email.email) + redirect_to admin_blacklisted_emails_path + else + render action: "index" + end + end + + def destroy + @admin_blacklisted_email = authorize AdminBlacklistedEmail.find(params[:id]) + @admin_blacklisted_email.destroy + + flash[:notice] = ts("Email address %{email} removed from banned emails list.", email: @admin_blacklisted_email.email) + redirect_to admin_blacklisted_emails_path + end + + private + + def admin_blacklisted_email_params + params.require(:admin_blacklisted_email).permit( + :email + ) + end +end diff --git a/app/controllers/admin/passwords_controller.rb b/app/controllers/admin/passwords_controller.rb new file mode 100755 index 0000000..dd092f4 --- /dev/null +++ b/app/controllers/admin/passwords_controller.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class Admin::PasswordsController < Devise::PasswordsController + before_action :user_logout_required + skip_before_action :store_location + layout "session" +end diff --git a/app/controllers/admin/sessions_controller.rb b/app/controllers/admin/sessions_controller.rb new file mode 100755 index 0000000..d7ea1b4 --- /dev/null +++ b/app/controllers/admin/sessions_controller.rb @@ -0,0 +1,14 @@ +# Namespaced Admin class +class Admin + # Handle admin session authentication + class SessionsController < Devise::SessionsController + before_action :user_logout_required, except: :destroy + skip_before_action :store_location, raise: false + + # GET /admin/logout + def confirm_logout + # If the user is already logged out, we just redirect to the front page. + redirect_to root_path unless admin_signed_in? + end + end +end diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb new file mode 100755 index 0000000..9099629 --- /dev/null +++ b/app/controllers/admin/settings_controller.rb @@ -0,0 +1,24 @@ +class Admin::SettingsController < Admin::BaseController + before_action :load_admin_setting + + def index + authorize @admin_setting + end + + # PUT /admin_settings/1 + def update + authorize @admin_setting + if @admin_setting.update(permitted_attributes(@admin_setting).merge(last_updated: current_admin)) + flash[:notice] = t(".success") + redirect_to admin_settings_path + else + render :index + end + end + + private + + def load_admin_setting + @admin_setting = AdminSetting.first || AdminSetting.create(last_updated_by: Admin.first) + end +end diff --git a/app/controllers/admin/skins_controller.rb b/app/controllers/admin/skins_controller.rb new file mode 100755 index 0000000..5bb5604 --- /dev/null +++ b/app/controllers/admin/skins_controller.rb @@ -0,0 +1,98 @@ +class Admin::SkinsController < Admin::BaseController + + def index + authorize Skin + @unapproved_skins = Skin.unapproved_skins.sort_by_recent + end + + def index_rejected + authorize Skin + @rejected_skins = Skin.rejected_skins.sort_by_recent + end + + def index_approved + authorize Skin + @approved_skins = Skin.approved_skins.usable.sort_by_recent + end + + def update + authorize Skin, :index? + + flash[:notice] = [] + modified_skin_titles = [] + %w(official rejected cached featured in_chooser).each do |action| + skins_to_set = params["make_#{action}"] ? Skin.where(id: params["make_#{action}"].map {|id| id.to_i}) : [] + skins_to_unset = params["make_un#{action}"] ? Skin.where(id: params["make_un#{action}"].map {|id| id.to_i}) : [] + skins_to_set.each do |skin| + # Silently fail if the user doesn't have permission to update: + next unless policy(skin).update? + + case action + when "official" + skin.update_attribute(:official, true) + when "rejected" + skin.update_attribute(:rejected, true) + when "cached" + next unless skin.official? && !skin.is_a?(WorkSkin) + skin.cache! + when "featured" + next unless skin.official? && !skin.is_a?(WorkSkin) + skin.cache! unless skin.cached? + skin.update_attribute(:featured, true) + when "in_chooser" + next unless skin.official? && !skin.is_a?(WorkSkin) + skin.cache! unless skin.cached? + skin.update_attribute(:in_chooser, true) + end + skin.update_attribute(:admin_note, params[:skin_admin_note]["#{skin.id}"]) if params[:skin_admin_note] && params[:skin_admin_note]["#{skin.id}"] + modified_skin_titles << skin.title + end + + skins_to_unset.each do |skin| + # Silently fail if the user doesn't have permission to update: + next unless policy(skin).update? + + case action + when "official" + skin.clear_cache! # no cache for unofficial skins + skin.update_attribute(:official, false) + skin.remove_me_from_preferences + when "rejected" + skin.update_attribute(:rejected, false) + when "cached" + next unless skin.official? && !skin.is_a?(WorkSkin) + skin.clear_cache! if skin.cached? + when "featured" + next unless skin.official? && !skin.is_a?(WorkSkin) + skin.update_attribute(:featured, false) + when "in_chooser" + next unless skin.official? && !skin.is_a?(WorkSkin) + skin.update_attribute(:in_chooser, false) + end + modified_skin_titles << skin.title + end + end + + flash[:notice] << ts("The following skins were updated: %{titles}", titles: modified_skin_titles.join(', ')) + + # set default + if params[:set_default].present? && params[:set_default] != AdminSetting.default_skin&.title + authorize Skin, :set_default? + + skin = Skin.find_by(title: params[:set_default], official: true) + @admin_setting = AdminSetting.first + if skin && @admin_setting + @admin_setting.default_skin = skin + @admin_setting.last_updated_by = params[:last_updated_by] + if @admin_setting.save + flash[:notice] << ts("Default skin changed to %{title}", title: skin.title) + else + flash[:error] = ts("We couldn't save the default skin change.") + end + end + end + + redirect_to admin_skins_path + end + +end diff --git a/app/controllers/admin/spam_controller.rb b/app/controllers/admin/spam_controller.rb new file mode 100755 index 0000000..8b65278 --- /dev/null +++ b/app/controllers/admin/spam_controller.rb @@ -0,0 +1,36 @@ +class Admin::SpamController < Admin::BaseController + def index + authorize ModeratedWork + + conditions = case params[:show] + when "reviewed" + { reviewed: true, approved: false } + when "approved" + { approved: true } + else + { reviewed: false, approved: false } + end + @works = ModeratedWork.where(conditions) + .joins(:work) + .includes(:work) + .order(:created_at) + .page(params[:page]) + end + + def bulk_update + authorize ModeratedWork + + if ModeratedWork.bulk_update(spam_params) + flash[:notice] = "Works were successfully updated" + else + flash[:error] = "Sorry, please try again" + end + redirect_to admin_spam_index_path + end + + private + + def spam_params + params.slice(:spam, :ham) + end +end diff --git a/app/controllers/admin/user_creations_controller.rb b/app/controllers/admin/user_creations_controller.rb new file mode 100755 index 0000000..995efe0 --- /dev/null +++ b/app/controllers/admin/user_creations_controller.rb @@ -0,0 +1,101 @@ +class Admin::UserCreationsController < Admin::BaseController + before_action :get_creation, only: [:hide, :set_spam, :destroy] + before_action :can_be_marked_as_spam, only: [:set_spam] + + def get_creation + raise "Redshirt: Attempted to constantize invalid class initialize #{params[:creation_type]}" unless %w(Bookmark ExternalWork Series Work).include?(params[:creation_type]) + @creation_class = params[:creation_type].constantize + @creation = @creation_class.find(params[:id]) + end + + def can_be_marked_as_spam + unless @creation_class && @creation_class == Work + flash[:error] = ts("You can only mark works as spam currently.") + redirect_to polymorphic_path(@creation) and return + end + end + + # Removes an object from public view + def hide + authorize @creation + @creation.hidden_by_admin = (params[:hidden] == "true") + @creation.save(validate: false) + action = @creation.hidden_by_admin? ? "hide" : "unhide" + AdminActivity.log_action(current_admin, @creation, action: action) + flash[:notice] = @creation.hidden_by_admin? ? + ts("Item has been hidden.") : + ts("Item is no longer hidden.") + if @creation_class == ExternalWork || @creation_class == Bookmark + redirect_to(request.env["HTTP_REFERER"] || root_path) + else + redirect_to polymorphic_path(@creation) + end + end + + def set_spam + authorize @creation + action = "mark as " + (params[:spam] == "true" ? "spam" : "not spam") + AdminActivity.log_action(current_admin, @creation, action: action, summary: @creation.inspect) + if params[:spam] == "true" + unless @creation.hidden_by_admin + @creation.notify_of_hiding_for_spam if @creation_class == Work + @creation.hidden_by_admin = true + end + @creation.mark_as_spam! + flash[:notice] = ts("Work was marked as spam and hidden.") + else + @creation.mark_as_ham! + @creation.update_attribute(:hidden_by_admin, false) + flash[:notice] = ts("Work was marked not spam and unhidden.") + end + redirect_to polymorphic_path(@creation) + end + + def destroy + authorize @creation + AdminActivity.log_action(current_admin, @creation, action: "destroy", summary: @creation.inspect) + @creation.destroy + flash[:notice] = ts("Item was successfully deleted.") + if @creation_class == Bookmark || @creation_class == ExternalWork + redirect_to bookmarks_path + else + redirect_to works_path + end + end + + def confirm_remove_pseud + @work = authorize Work.find(params[:id]) + + @orphan_pseuds = @work.orphan_pseuds + return unless @orphan_pseuds.empty? + + flash[:error] = t(".must_have_orphan_pseuds") + redirect_to work_path(@work) and return + end + + def remove_pseud + @work = authorize Work.find(params[:id]) + + pseuds = params[:pseuds] + orphan_account = User.orphan_account + if pseuds.blank? + pseuds = @work.orphan_pseuds + if pseuds.length > 1 + flash[:error] = t(".must_select_pseud") + redirect_to work_path(@work) and return + end + else + pseuds = Pseud.find(pseuds).select { |p| p.user_id == orphan_account.id } + end + + orphan_pseud = orphan_account.default_pseud + pseuds.each do |pseud| + pseud.change_ownership(@work, orphan_pseud) + end + unless pseuds.empty? + AdminActivity.log_action(current_admin, @work, action: "remove orphan_account pseuds") + flash[:notice] = t(".success", pseuds: pseuds.map(&:byline).to_sentence, count: pseuds.length) + end + redirect_to work_path(@work) + end +end diff --git a/app/controllers/admin_posts_controller.rb b/app/controllers/admin_posts_controller.rb new file mode 100755 index 0000000..426c71b --- /dev/null +++ b/app/controllers/admin_posts_controller.rb @@ -0,0 +1,101 @@ +class AdminPostsController < Admin::BaseController + + before_action :admin_only, except: [:index, :show] + before_action :load_languages, except: [:show, :destroy] + + # GET /admin_posts + def index + if params[:tag] + @tag = AdminPostTag.find_by(id: params[:tag]) + if @tag + @admin_posts = @tag.admin_posts + end + end + @admin_posts ||= AdminPost + if params[:language_id].present? && (@language = Language.find_by(short: params[:language_id])) + @admin_posts = @admin_posts.where(language_id: @language.id) + @tags = AdminPostTag.distinct.joins(:admin_posts).where(admin_posts: { language_id: @language.id }).order(:name) + else + @admin_posts = @admin_posts.non_translated + @tags = AdminPostTag.order(:name) + end + @admin_posts = @admin_posts.order('created_at DESC').page(params[:page]) + end + + # GET /admin_posts/1 + def show + admin_posts = AdminPost.non_translated + @admin_post = AdminPost.find_by(id: params[:id]) + unless @admin_post + raise ActiveRecord::RecordNotFound, "Couldn't find admin post '#{params[:id]}'" + end + @admin_posts = admin_posts.order('created_at DESC').limit(8) + @previous_admin_post = admin_posts.order('created_at DESC').where('created_at < ?', @admin_post.created_at).first + @next_admin_post = admin_posts.order('created_at ASC').where('created_at > ?', @admin_post.created_at).first + @page_subtitle = @admin_post.title.html_safe + respond_to do |format| + format.html # show.html.erb + format.js + end + end + + # GET /admin_posts/new + # GET /admin_posts/new.xml + def new + @admin_post = AdminPost.new + authorize @admin_post + end + + # GET /admin_posts/1/edit + def edit + @admin_post = AdminPost.find(params[:id]) + authorize @admin_post + end + + # POST /admin_posts + def create + @admin_post = AdminPost.new(admin_post_params) + authorize @admin_post + if @admin_post.save + flash[:notice] = ts("Admin Post was successfully created.") + redirect_to(@admin_post) + else + render action: "new" + end + end + + # PUT /admin_posts/1 + def update + @admin_post = AdminPost.find(params[:id]) + authorize @admin_post + if @admin_post.update(admin_post_params) + flash[:notice] = ts("Admin Post was successfully updated.") + redirect_to(@admin_post) + else + render action: "edit" + end + end + + # DELETE /admin_posts/1 + def destroy + @admin_post = AdminPost.find(params[:id]) + authorize @admin_post + @admin_post.destroy + redirect_to(admin_posts_path) + end + + protected + + def load_languages + @news_languages = Language.where(id: Locale.all.map(&:language_id)).default_order + end + + private + + def admin_post_params + params.require(:admin_post).permit( + :admin_id, :title, :content, :translated_post_id, :language_id, :tag_list, + :comment_permissions, :moderated_commenting_enabled + ) + end +end diff --git a/app/controllers/admins_controller.rb b/app/controllers/admins_controller.rb new file mode 100755 index 0000000..aed27dd --- /dev/null +++ b/app/controllers/admins_controller.rb @@ -0,0 +1,4 @@ +class AdminsController < Admin::BaseController + def index + end +end diff --git a/app/controllers/api/v2/base_controller.rb b/app/controllers/api/v2/base_controller.rb new file mode 100755 index 0000000..54eb47b --- /dev/null +++ b/app/controllers/api/v2/base_controller.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module Api + # Version the API explicitly in the URL to allow different versions with breaking changes to co-exist if necessary. + # The roll over to the next number should happen when code written against the old version will not work + # with the new version. + module V2 + class BaseController < ApplicationController + skip_before_action :verify_authenticity_token + before_action :restrict_access + + # Prevent unhandled errors from returning the normal HTML page + rescue_from StandardError, with: :render_standard_error_response + + private + + # Look for a token in the Authorization header only and check that the token isn't currently banned + def restrict_access + authenticate_or_request_with_http_token do |token, _| + ApiKey.exists?(access_token: token) && !ApiKey.find_by(access_token: token).banned? + end + end + + # Top-level error handling: returns a 403 forbidden if a valid archivist isn't supplied and a 400 + # if no works are supplied. If there is neither a valid archivist nor valid works, a 400 is returned + # with both errors as a message + def batch_errors(archivist, import_items) + errors = [] + status = "" + + if archivist&.is_archivist? + if import_items.nil? || import_items.empty? + status = :empty_request + errors << "No items to import were provided." + elsif import_items.size >= ArchiveConfig.IMPORT_MAX_WORKS_BY_ARCHIVIST + status = :too_many_request + errors << "This request contains too many items to import. A maximum of #{ArchiveConfig.IMPORT_MAX_WORKS_BY_ARCHIVIST} " \ + "items can be imported at one time by an archivist." + end + else + status = :forbidden + errors << "The \"archivist\" field must specify the name of an Archive user with archivist privileges." + end + + status = :ok if errors.empty? + [status, errors] + end + + # Return a standard HTTP + Json envelope for all API responses + def render_api_response(status, messages, response = {}) + # It's a bad request unless it's ok or an authorisation error + http_status = %i[forbidden ok].include?(status) ? status : :bad_request + render status: http_status, json: { status: status, messages: messages }.merge(response) + end + + # Return a standard HTTP + Json envelope for errors that drop through other handling + def render_standard_error_response(exception) + message = "An error occurred in the Archive code: #{exception.message}" + render status: :internal_server_error, json: { status: :internal_server_error, messages: [message] } + end + end + end +end diff --git a/app/controllers/api/v2/bookmarks_controller.rb b/app/controllers/api/v2/bookmarks_controller.rb new file mode 100755 index 0000000..8af657b --- /dev/null +++ b/app/controllers/api/v2/bookmarks_controller.rb @@ -0,0 +1,229 @@ +class Api::V2::BookmarksController < Api::V2::BaseController + respond_to :json + + # POST - search for bookmarks for this archivist + def search + archivist = User.find_by(login: params[:archivist]) + bookmarks = params[:bookmarks] + # check for top-level errors (not an archivist, no bookmarks...) + status, messages = batch_errors(archivist, bookmarks) + results = [] + + if status == :ok + archivist_bookmarks = Bookmark.where(pseud_id: archivist.default_pseud.id) + results = bookmarks.map do |bookmark| + found_result = {} + found_result = check_archivist_bookmark(archivist, bookmark[:url], archivist_bookmarks) unless archivist_bookmarks.empty? + + bookmark_response( + status: found_result[:bookmark_status] || :not_found, + bookmark_url: found_result[:bookmark_url] || "", + bookmark_id: bookmark[:id], + original_url: bookmark[:url], + messages: found_result[:bookmark_messages] || ["No bookmark found for archivist \"#{archivist.login}\" and URL \"#{bookmark[:url]}\""] + ) + end + messages = ["Successfully searched bookmarks for archivist '#{archivist.login}'"] + end + + render_api_response(status, messages, bookmarks: results) + end + + # POST - create a bookmark for this archivist + def create + archivist = User.find_by(login: params[:archivist]) + bookmarks = params[:bookmarks] + bookmarks_responses = [] + @bookmarks = [] + + # check for top-level errors (not an archivist, no bookmarks...) + status, messages = batch_errors(archivist, bookmarks) + + if status == :ok + # Flag error and successes + @some_errors = @some_success = false + + # Process the bookmarks + archivist_bookmarks = Bookmark.where(pseud_id: archivist.default_pseud_id, bookmarkable_type: "ExternalWork") + bookmarks.each do |bookmark| + bookmarks_responses << create_bookmark(archivist, bookmark, archivist_bookmarks) + end + + # set final response code and message depending on the flags + status = :bad_request if bookmarks_responses.any? { |r| [:ok, :created, :found].exclude?(r[:status]) } + messages = response_message(messages) + end + + render_api_response(status, messages, bookmarks: bookmarks_responses) + end + + private + + # Find bookmarks for this archivist + def check_archivist_bookmark(archivist, current_bookmark_url, archivist_bookmarks) + archivist_bookmarks = archivist_bookmarks + .select { |b| b&.bookmarkable.is_a?(ExternalWork) ? b&.bookmarkable&.url == current_bookmark_url : false } + .map { |b| [b, b.bookmarkable] } + + if archivist_bookmarks.present? + archivist_bookmark, archivist_bookmarkable = archivist_bookmarks.first + find_bookmark_response( + bookmarkable: archivist_bookmarkable, + bookmark_status: :found, + bookmark_message: "There is already a bookmark for #{archivist.login} and the URL #{current_bookmark_url}", + bookmark_url: bookmark_url(archivist_bookmark) + ) + else + find_bookmark_response( + bookmarkable: nil, + bookmark_status: :not_found, + bookmark_message: "There is no bookmark for #{archivist.login} and the URL #{current_bookmark_url}", + bookmark_url: "" + ) + end + end + + # Create a bookmark for this archivist using the Bookmark model + def create_bookmark(archivist, params, archivist_bookmarks) + found_result = {} + bookmark_attributes = bookmark_attributes(archivist, params) + external_work_attributes = external_work_attributes(params) + bookmark_status, bookmark_messages = external_work_errors(external_work_attributes) + bookmark_url = nil + original_url = nil + bookmarkable = nil + @some_errors = true + if bookmark_status == :ok + begin + + # Check if this bookmark is already imported by filtering the archivist's bookmarks + unless archivist_bookmarks.empty? + found_result = check_archivist_bookmark(archivist, external_work_attributes[:url], archivist_bookmarks) + bookmarkable = found_result[:bookmarkable] + end + + if found_result[:bookmark_status] == :found + found_result[:bookmark_status] = :already_imported + else + bookmarkable = ExternalWork.new(external_work_attributes) + bookmark = bookmarkable.bookmarks.build(bookmark_attributes) + if bookmarkable.save && bookmark.save + @bookmarks << bookmark + @some_success = true + @some_errors = false + bookmark_status = :created + bookmark_url = bookmark_url(bookmark) + bookmark_messages << "Successfully created bookmark for \"" + bookmarkable.title + "\"." + else + bookmark_status = :unprocessable_entity + bookmark_messages << bookmarkable.errors.full_messages + bookmark.errors.full_messages + end + end + rescue StandardError => exception + bookmark_status = :unprocessable_entity + bookmark_messages << exception.message + end + original_url = bookmarkable.url if bookmarkable + end + + bookmark_response( + status: bookmark_status || found_result[:bookmark_status], + bookmark_url: bookmark_url || found_result[:bookmark_url], + bookmark_id: params[:id], + original_url: original_url, + messages: bookmark_messages.flatten || found_result[:bookmark_messages] + ) + end + + # Error handling + + # Set messages based on success and error flags + def response_message(messages) + messages << if @some_success && @some_errors + "At least one bookmark was not created. Please check the individual bookmark results for further information." + elsif !@some_success && @some_errors + "None of the bookmarks were created. Please check the individual bookmark results for further information." + else + "All bookmarks were successfully created." + end + messages + end + + # Handling for incomplete requests + def external_work_errors(external_work_attributes) + status = :bad_request + errors = [] + + # Perform basic validation which the ExternalWork model doesn't do or returns strange messages for + # (title is validated correctly in the model and so isn't checked here) + url = external_work_attributes[:url] + author = external_work_attributes[:author] + fandom = external_work_attributes[:fandom_string] + + if url.nil? + # Unreachable and AO3 URLs are handled in the ExternalWork model + errors << "This bookmark does not contain a URL to an external site. Please specify a valid, non-AO3 URL." + end + + if author.nil? || author == "" + errors << "This bookmark does not contain an external author name. Please specify an author." + end + + if fandom.nil? || fandom == "" + errors << "This bookmark does not contain a fandom. Please specify a fandom." + end + + status = :ok if errors.empty? + [status, errors] + end + + # Request and response hashes + + # Map JSON request to attributes for bookmark + def bookmark_attributes(archivist, params) + { + pseud_id: archivist.default_pseud_id, + bookmarker_notes: params[:bookmarker_notes], + tag_string: params[:tag_string] || "", + collection_names: params[:collection_names], + private: params[:private].blank? ? false : params[:private], + rec: params[:recommendation].blank? ? false : params[:recommendation] + } + end + + # Map JSON request to attributes for external work + def external_work_attributes(params) + { + url: params[:url], + author: params[:author], + title: params[:title], + summary: params[:summary], + fandom_string: params[:fandom_string] || "", + rating_string: params[:rating_string] || "", + category_string: params[:category_string] ? params[:category_string].to_s.split(",") : [], # category is actually an array on bookmarks + relationship_string: params[:relationship_string] || "", + character_string: params[:character_string] || "" + } + end + + def bookmark_response(status:, bookmark_url:, bookmark_id:, original_url:, messages:) + messages = [messages] unless messages.respond_to?('each') + { + status: status, + archive_url: bookmark_url, + original_id: bookmark_id, + original_url: original_url, + messages: messages + } + end + + def find_bookmark_response(bookmarkable:, bookmark_status:, bookmark_message:, bookmark_url:) + bookmark_status = :not_found unless [:found, :not_found].include?(bookmark_status) + { + bookmarkable: bookmarkable, + bookmark_status: bookmark_status, + bookmark_messages: bookmark_message, + bookmark_url: bookmark_url + } + end +end diff --git a/app/controllers/api/v2/works_controller.rb b/app/controllers/api/v2/works_controller.rb new file mode 100755 index 0000000..32bc213 --- /dev/null +++ b/app/controllers/api/v2/works_controller.rb @@ -0,0 +1,225 @@ +class Api::V2::WorksController < Api::V2::BaseController + respond_to :json + + # POST - search for works based on imported url + def search + works = params[:works] + original_urls = works.map { |w| w[:original_urls] }.flatten + + results = [] + messages = [] + if original_urls.nil? || original_urls.blank? || original_urls.empty? + status = :empty_request + messages << "Please provide a list of URLs to find." + elsif original_urls.size >= ArchiveConfig.IMPORT_MAX_CHAPTERS + status = :too_many_request + messages << "Please provide no more than #{ArchiveConfig.IMPORT_MAX_CHAPTERS} URLs to find." + else + status = :ok + results = find_existing_works(original_urls) + messages << "Successfully searched all provided URLs." + end + render_api_response(status, messages, works: results) + end + + # POST - create a work and invite authors to claim + def create + archivist = User.find_by(login: params[:archivist]) + external_works = params[:items] || params[:works] + works_responses = [] + + # check for top-level errors (not an archivist, no works...) + status, messages = batch_errors(archivist, external_works) + + if status == :ok + # Process the works, updating the flags + works_responses = external_works.map { |external_work| import_work(archivist, external_work.merge(params.permit!)) } + success_responses, error_responses = works_responses.partition { |r| [:ok, :created, :found].include?(r[:status]) } + + # Send claim notification emails for successful works + if params[:send_claim_emails] && success_responses.present? + notified_authors = notify_and_return_authors(success_responses.map { |r| r[:work] }, archivist) + messages << "Claim emails sent to #{notified_authors.to_sentence}." + end + + # set final status code and message depending on the flags + status = :bad_request if error_responses.present? + messages = response_message(messages, success_responses.present?, error_responses.present?) + end + render_api_response(status, messages, works: works_responses.map { |r| r.except!(:work) }) + end + + private + + # Set messages based on success and error flags + def response_message(messages, any_success, any_errors) + messages << if any_success && any_errors + "At least one work was not imported. Please check individual work responses for further information." + elsif !any_success && any_errors + "None of the works were imported. Please check individual work responses for further information." + else + "All works were successfully imported." + end + messages + end + + # Work-level error handling for requests that are incomplete or too large + def work_errors(work) + status = :bad_request + errors = [] + urls = work[:chapter_urls] + if urls.nil? || urls.empty? + status = :empty_request + errors << "This work doesn't contain any chapter URLs. " + + "Works can only be imported from publicly-accessible chapter URLs." + elsif urls.length >= ArchiveConfig.IMPORT_MAX_CHAPTERS + status = :too_many_requests + errors << "This work contains too many chapter URLs. A maximum of #{ArchiveConfig.IMPORT_MAX_CHAPTERS} " \ + "chapters can be imported per work." + end + status = :ok if errors.empty? + [status, errors] + end + + # Search for works imported from the provided URLs + def find_existing_works(original_urls) + results = [] + messages = [] + original_urls.each do |original| + original_id = "" + if original.class == String + original_url = original + else + original_id = original[:id] + original_url = original[:url] + end + + # Search for works - there may be duplicates + search_results = find_work_by_import_url(original_url) + if search_results[:works].empty? + results << { status: :not_found, + original_id: original_id, + original_url: original_url, + messages: [search_results[:message]] } + else + work_results = search_results[:works].map do |work| + archive_url = work_url(work) + message = "Work \"#{work.title}\", created on #{work.created_at.to_date.to_fs(:iso_date)} was found at \"#{archive_url}\"." + messages << message + { archive_url: archive_url, + created: work.created_at, + message: message } + end + results << { status: :found, + original_id: original_id, + original_url: original_url, + search_results: work_results, + messages: messages + } + end + end + results + end + + def find_work_by_import_url(original_url) + works = nil + if original_url.blank? + message = "Please provide the original URL for the work." + else + # We know the url will be identical no need for a call to find_by_url + works = Work.where(imported_from_url: original_url) + message = if works.empty? + "No work has been imported from \"" + original_url + "\"." + else + "Found #{works.size} work(s) imported from \"" + original_url + "\"." + end + end + { + original_url: original_url, + works: works, + message: message + } + end + + # Use the story parser to scrape works from the chapter URLs + def import_work(archivist, external_work) + work_status, work_messages = work_errors(external_work) + work_url = "" + original_url = "" + if work_status == :ok + urls = external_work[:chapter_urls] + original_url = urls.first + storyparser = StoryParser.new + options = story_parser_options(archivist, external_work) + begin + response = storyparser.import_chapters_into_story(urls, options) + work = response[:work] + work_status = response[:status] + + work.save if work_status == :created + work_url = work_url(work) + work_messages << response[:message] + rescue => exception + Rails.logger.error("------- API v2: error: #{exception.inspect}") + work_status = :unprocessable_entity + work_messages << "Unable to import this work." + work_messages << exception.message + end + end + + { + status: work_status, + archive_url: work_url, + original_id: external_work[:id], + original_url: original_url, + messages: work_messages, + work: work + } + end + + # Send invitations to external authors for a given set of works + def notify_and_return_authors(success_works, archivist) + notified_authors = [] + external_authors = success_works.map(&:external_authors).flatten.uniq + external_authors&.each do |external_author| + external_author.find_or_invite(archivist) + # One of the external author pseuds is its email address so filter that one out + author_names = external_author.names.reject { |a| a.name == external_author.email }.map(&:name).flatten.join(", ") + notified_authors << author_names + end + notified_authors + end + + # Request and response hashes + + # Create options map for StoryParser + def story_parser_options(archivist, work_params) + { + archivist: archivist, + import_multiple: "chapters", + importing_for_others: true, + do_not_set_current_author: true, + post_without_preview: work_params[:post_without_preview].blank? ? true : work_params[:post_without_preview], + restricted: work_params[:restricted], + override_tags: work_params[:override_tags].nil? ? true : work_params[:override_tags], + detect_tags: work_params[:detect_tags].nil? ? true : work_params[:detect_tags], + collection_names: work_params[:collection_names], + title: work_params[:title], + fandom: work_params[:fandoms], + archive_warning: work_params[:warnings], + character: work_params[:characters], + rating: work_params[:rating], + relationship: work_params[:relationships], + category: work_params[:categories], + freeform: work_params[:additional_tags], + language_id: Language.find_by(short: work_params[:language_code])&.id, + summary: work_params[:summary], + notes: work_params[:notes], + encoding: work_params[:encoding], + external_author_name: work_params[:external_author_name], + external_author_email: work_params[:external_author_email], + external_coauthor_name: work_params[:external_coauthor_name], + external_coauthor_email: work_params[:external_coauthor_email] + } + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100755 index 0000000..f24368b --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,564 @@ +class ApplicationController < ActionController::Base + include ActiveStorage::SetCurrent + include Pundit::Authorization + protect_from_forgery with: :exception, prepend: true + rescue_from ActionController::InvalidAuthenticityToken, with: :display_auth_error + + rescue_from Pundit::NotAuthorizedError do + admin_only_access_denied + end + + # sets admin user for pundit policies + def pundit_user + current_admin + end + + rescue_from ActionController::UnknownFormat, with: :raise_not_found + rescue_from Elastic::Transport::Transport::Errors::ServiceUnavailable do + # Non-standard code to distinguish Elasticsearch errors from standard 503s. + # We can't use 444 because nginx will close connections without sending + # response headers. + head 445 + end + + def raise_not_found + redirect_to '/404' + end + + rescue_from Rack::Timeout::RequestTimeoutException, with: :raise_timeout + + def raise_timeout + redirect_to timeout_error_path + end + + helper :all # include all helpers, all the time + + include HtmlCleaner + before_action :sanitize_ac_params + + # sanitize_params works best with a hash, and will convert + # ActionController::Parameters to a hash in order to work with them anyway. + # + # Controllers need to deal with ActionController::Parameters, not hashes. + # These methods hand the params as a hash to sanitize_params, and then + # transforms the results back into ActionController::Parameters. + def sanitize_ac_params + sanitize_params(params.to_unsafe_h).each do |key, value| + params[key] = transform_sanitized_hash_to_ac_params(key, value) + end + end + + include Pagy::Backend + def pagy(collection, **vars) + pagy_overflow_handler do + super + end + end + + def pagy_query_result(query_result, **vars) + pagy_overflow_handler do + Pagy.new( + count: query_result.total_entries, + page: query_result.current_page, + limit: query_result.per_page, + **vars + ) + end + end + + def pagy_overflow_handler(*) + yield + rescue Pagy::OverflowError + nil + end + + def display_auth_error + respond_to do |format| + format.html do + redirect_to auth_error_path + end + format.any(:js, :json) do + render json: { + errors: { + auth_error: "Your current session has expired and we can't authenticate your request. Try logging in again, refreshing the page, or clearing your cache if you continue to experience problems.".html_safe + } + }, status: :unprocessable_entity + end + end + end + + def transform_sanitized_hash_to_ac_params(key, value) + if value.is_a?(Hash) + ActionController::Parameters.new(value) + elsif value.is_a?(Array) + value.map.with_index do |val, index| + value[index] = transform_sanitized_hash_to_ac_params(key, val) + end + else + value + end + end + + helper_method :current_user + helper_method :current_admin + helper_method :logged_in? + helper_method :logged_in_as_admin? + helper_method :guest? + + # Title helpers + helper_method :process_title + + # clear out the flash-being-set + before_action :clear_flash_cookie + def clear_flash_cookie + cookies.delete(:flash_is_set) + end + + after_action :check_for_flash + def check_for_flash + cookies[:flash_is_set] = 1 unless flash.empty? + end + + # Override redirect_to so that if it's called in a before_action hook, it'll + # still call check_for_flash after it runs. + def redirect_to(*args, **kwargs) + super.tap do + check_for_flash + end + end + + after_action :ensure_admin_credentials + def ensure_admin_credentials + if logged_in_as_admin? + # if we are logged in as an admin and we don't have the admin_credentials + # set then set that cookie + cookies[:admin_credentials] = { value: 1, expires: 1.year.from_now } unless cookies[:admin_credentials] + else + # if we are NOT logged in as an admin and we have the admin_credentials + # set then delete that cookie + cookies.delete :admin_credentials unless cookies[:admin_credentials].nil? + end + end + + # If there is no user_credentials cookie and the user appears to be logged in, + # redirect to the lost cookie page. Needs to be before the code to fix + # the user_credentials cookie or it won't fire. + before_action :logout_if_not_user_credentials + def logout_if_not_user_credentials + if logged_in? && cookies[:user_credentials].nil? && controller_name != "sessions" + logger.error "Forcing logout" + sign_out + redirect_to '/lost_cookie' and return + end + end + + # The user_credentials cookie is used by nginx to figure out whether or not + # to cache the page, so we want to make sure that it's set when the user is + # logged in, and cleared when the user is logged out. + after_action :ensure_user_credentials + def ensure_user_credentials + if logged_in? + cookies[:user_credentials] = { value: 1, expires: 1.year.from_now } unless cookies[:user_credentials] + else + cookies.delete :user_credentials unless cookies[:user_credentials].nil? + end + end + +protected + + def logged_in? + user_signed_in? + end + + def logged_in_as_admin? + admin_signed_in? + end + + def guest? + !(logged_in? || logged_in_as_admin?) + end + + def process_title(string) + string = string.humanize.titleize + + string = string.sub("Faq", "FAQ") + string = string.sub("Tos", "TOS") + string = string.sub("Dmca", "DMCA") + return string + end + +public + + before_action :load_admin_banner + def load_admin_banner + if Rails.env.development? + @admin_banner = AdminBanner.where(active: true).last + else + # http://stackoverflow.com/questions/12891790/will-returning-a-nil-value-from-a-block-passed-to-rails-cache-fetch-clear-it + # Basically we need to store a nil separately. + @admin_banner = Rails.cache.fetch("admin_banner") do + banner = AdminBanner.where(active: true).last + banner.nil? ? "" : banner + end + @admin_banner = nil if @admin_banner == "" + end + end + + before_action :load_tos_popup + def load_tos_popup + # Integers only, YYYY-MM-DD format of date Board approved TOS + @current_tos_version = 2024_11_19 # rubocop:disable Style/NumericLiterals + end + + # store previous page in session to make redirecting back possible + # if already redirected once, don't redirect again. + before_action :store_location + def store_location + if session[:return_to] == "redirected" + session.delete(:return_to) + elsif request.fullpath.length > 200 + # Sessions are stored in cookies, which has a 4KB size limit. + # Don't store paths that are too long (e.g. filters with lots of exclusions). + # Also remove the previous stored path. + session.delete(:return_to) + else + session[:return_to] = request.fullpath + end + end + + # Redirect to the URI stored by the most recent store_location call or + # to the passed default. + def redirect_back_or_default(default = root_path) + back = session[:return_to] + session.delete(:return_to) + if back + session[:return_to] = "redirected" + redirect_to(back) and return + else + redirect_to(default) and return + end + end + + def after_sign_in_path_for(resource) + if resource.is_a?(Admin) + admins_path + else + back = session[:return_to] + session.delete(:return_to) + + back || user_path(current_user) + end + end + + def authenticate_admin! + if admin_signed_in? + super + else + redirect_to root_path, notice: "I'm sorry, only an admin can look at that area" + ## if you want render 404 page + ## render file: File.join(Rails.root, 'public/404'), formats: [:html], status: 404, layout: false + end + end + + # Filter method - keeps users out of admin areas + def admin_only + authenticate_admin! || admin_only_access_denied + end + + # Filter method to prevent admin users from accessing certain actions + def users_only + logged_in? || access_denied + end + + # Filter method - requires user to have opendoors privs + def opendoors_only + (logged_in? && permit?("opendoors")) || access_denied + end + + # Redirect as appropriate when an access request fails. + # + # The default action is to redirect to the login screen. + # + # Override this method in your controllers if you want to have special + # behavior in case the user is not authorized + # to access the requested action. For example, a popup window might + # simply close itself. + def access_denied(options ={}) + store_location + if logged_in? + destination = options[:redirect].blank? ? user_path(current_user) : options[:redirect] + # i18n-tasks-use t('users.reconfirm_email.access_denied.logged_in') + flash[:error] = t(".access_denied.logged_in", default: t("application.access_denied.access_denied.logged_in")) # rubocop:disable I18n/DefaultTranslation + redirect_to destination + else + destination = options[:redirect].blank? ? new_user_session_path : options[:redirect] + flash[:error] = ts "Sorry, you don't have permission to access the page you were trying to reach. Please log in." + redirect_to destination + end + false + end + + def admin_only_access_denied + respond_to do |format| + format.html do + flash[:error] = t("admin.access.page_access_denied") + redirect_to root_path + end + format.json do + errors = [t("admin.access.action_access_denied")] + render json: { errors: errors }, status: :forbidden + end + format.js do + flash[:error] = t("admin.access.page_access_denied") + render js: "window.location.href = '#{root_path}';" + end + end + end + + # Filter method - prevents users from logging in as admin + def user_logout_required + if logged_in? + flash[:notice] = 'Please log out of your user account first!' + redirect_to root_path + end + end + + # Prevents admin from logging in as users + def admin_logout_required + if logged_in_as_admin? + flash[:notice] = 'Please log out of your admin account first!' + redirect_to root_path + end + end + + # Hide admin banner via cookies + before_action :hide_banner + def hide_banner + if params[:hide_banner] + session[:hide_banner] = true + end + end + + # Store the current user as a class variable in the User class, + # so other models can access it with "User.current_user" + around_action :set_current_user + def set_current_user + User.current_user = logged_in_as_admin? ? current_admin : current_user + @current_user = current_user + unless current_user.nil? + @current_user_subscriptions_count, @current_user_visible_work_count, @current_user_bookmarks_count, @current_user_owned_collections_count, @current_user_challenge_signups_count, @current_user_offer_assignments, @current_user_unposted_works_size= + Rails.cache.fetch("user_menu_counts_#{current_user.id}", + expires_in: 2.hours, + race_condition_ttl: 5) { "#{current_user.subscriptions.count}, #{current_user.visible_work_count}, #{current_user.bookmarks.count}, #{current_user.owned_collections.count}, #{current_user.challenge_signups.count}, #{current_user.offer_assignments.undefaulted.count + current_user.pinch_hit_assignments.undefaulted.count}, #{current_user.unposted_works.size}" }.split(",").map(&:to_i) + end + + yield + + User.current_user = nil + @current_user = nil + end + + def load_collection + @collection = Collection.find_by(name: params[:collection_id]) if params[:collection_id] + end + + def collection_maintainers_only + logged_in? && @collection && @collection.user_is_maintainer?(current_user) || access_denied + end + + def collection_owners_only + logged_in? && @collection && @collection.user_is_owner?(current_user) || access_denied + end + + def not_allowed(fallback=nil) + flash[:error] = ts("Sorry, you're not allowed to do that.") + redirect_to (fallback || root_path) rescue redirect_to '/' + end + + + def get_page_title(fandom, author, title, options = {}) + # truncate any piece that is over 15 chars long to the nearest word + if options[:truncate] + fandom = fandom.gsub(/^(.{15}[\w.]*)(.*)/) {$2.empty? ? $1 : $1 + '...'} + author = author.gsub(/^(.{15}[\w.]*)(.*)/) {$2.empty? ? $1 : $1 + '...'} + title = title.gsub(/^(.{15}[\w.]*)(.*)/) {$2.empty? ? $1 : $1 + '...'} + end + + @page_title = "" + if logged_in? && !current_user.preference.try(:work_title_format).blank? + @page_title = current_user.preference.work_title_format.dup + @page_title.gsub!(/FANDOM/, fandom) + @page_title.gsub!(/AUTHOR/, author) + @page_title.gsub!(/TITLE/, title) + else + @page_title = title + " - " + author + " - " + fandom + end + + @page_title += " [#{ArchiveConfig.APP_NAME}]" unless options[:omit_archive_name] + @page_title.html_safe + end + + public + + #### -- AUTHORIZATION -- #### + + # It is just much easier to do this here than to try to stuff variable values into a constant in environment.rb + + def is_registered_user? + logged_in? || logged_in_as_admin? + end + + def is_admin? + logged_in_as_admin? + end + + def see_adult? + params[:anchor] = "comments" if (params[:show_comments] && params[:anchor].blank?) + return true if cookies[:view_adult] || logged_in_as_admin? + return false unless current_user + return true if current_user.is_author_of?(@work) + return true if current_user.preference && current_user.preference.adult + return false + end + + def use_caching? + %w(staging production test).include?(Rails.env) && AdminSetting.current.enable_test_caching? + end + + protected + + # Prevents banned and suspended users from adding/editing content + def check_user_status + if current_user.is_a?(User) && (current_user.suspended? || current_user.banned?) + if current_user.suspended? + suspension_end = current_user.suspended_until + + # Unban threshold is 6:51pm, 12 hours after the unsuspend_users rake task located in schedule.rb is run at 6:51am + unban_theshold = DateTime.new(suspension_end.year, suspension_end.month, suspension_end.day, 18, 51, 0, "+00:00") + + # If the stated suspension end date is after the unban threshold we need to advance a day + suspension_end = suspension_end.next_day(1) if suspension_end > unban_theshold + localized_suspension_end = view_context.date_in_zone(suspension_end) + flash[:error] = t("users.status.suspension_notice_html", suspended_until: localized_suspension_end, contact_abuse_link: view_context.link_to(t("users.contact_abuse"), new_abuse_report_path)) + + else + flash[:error] = t("users.status.ban_notice_html", contact_abuse_link: view_context.link_to(t("users.contact_abuse"), new_abuse_report_path)) + end + redirect_to current_user + end + end + + # Prevents temporarily suspended users from deleting content + def check_user_not_suspended + return unless current_user.is_a?(User) && current_user.suspended? + + suspension_end = current_user.suspended_until + + # Unban threshold is 6:51pm, 12 hours after the unsuspend_users rake task located in schedule.rb is run at 6:51am + unban_theshold = DateTime.new(suspension_end.year, suspension_end.month, suspension_end.day, 18, 51, 0, "+00:00") + + # If the stated suspension end date is after the unban threshold we need to advance a day + suspension_end = suspension_end.next_day(1) if suspension_end > unban_theshold + localized_suspension_end = view_context.date_in_zone(suspension_end) + + flash[:error] = t("users.status.suspension_notice_html", suspended_until: localized_suspension_end, contact_abuse_link: view_context.link_to(t("users.contact_abuse"), new_abuse_report_path)) + + redirect_to current_user + end + + # Does the current user own a specific object? + def current_user_owns?(item) + !item.nil? && current_user.is_a?(User) && (item.is_a?(User) ? current_user == item : current_user.is_author_of?(item)) + end + + # Make sure a specific object belongs to the current user and that they have permission + # to view, edit or delete it + def check_ownership + access_denied(redirect: @check_ownership_of) unless current_user_owns?(@check_ownership_of) + end + def check_ownership_or_admin + return true if logged_in_as_admin? + access_denied(redirect: @check_ownership_of) unless current_user_owns?(@check_ownership_of) + end + + # Make sure the user is allowed to see a specific page + # includes a special case for restricted works and series, since we want to encourage people to sign up to read them + def check_visibility + if @check_visibility_of.respond_to?(:restricted) && @check_visibility_of.restricted && User.current_user.nil? + redirect_to new_user_session_path(restricted: true) + elsif @check_visibility_of.is_a? Skin + access_denied unless logged_in_as_admin? || current_user_owns?(@check_visibility_of) || @check_visibility_of.official? + else + is_hidden = (@check_visibility_of.respond_to?(:visible) && !@check_visibility_of.visible) || + (@check_visibility_of.respond_to?(:visible?) && !@check_visibility_of.visible?) || + (@check_visibility_of.respond_to?(:hidden_by_admin?) && @check_visibility_of.hidden_by_admin?) + can_view_hidden = logged_in_as_admin? || current_user_owns?(@check_visibility_of) + access_denied if (is_hidden && !can_view_hidden) + end + end + + # Make sure user is allowed to access tag wrangling pages + def check_permission_to_wrangle + if AdminSetting.current.tag_wrangling_off? && !logged_in_as_admin? + flash[:error] = "Wrangling is disabled at the moment. Please check back later." + redirect_to root_path + else + logged_in_as_admin? || permit?("tag_wrangler") || access_denied + end + end + + # Checks if user is allowed to see related page if parent item is hidden or in unrevealed collection + # Checks if user is logged in if parent item is restricted + def check_visibility_for(parent) + return if logged_in_as_admin? || current_user_owns?(parent) # Admins and the owner can see all related pages + + access_denied(redirect: root_path) if parent.try(:hidden_by_admin) || parent.try(:in_unrevealed_collection) || (parent.respond_to?(:visible?) && !parent.visible?) + end + + public + + def valid_sort_column(param, model='work') + allowed = [] + if model.to_s.downcase == 'work' + allowed = %w(author title date created_at word_count hit_count) + elsif model.to_s.downcase == 'tag' + allowed = %w[name created_at taggings_count_cache uses] + elsif model.to_s.downcase == 'collection' + allowed = %w(collections.title collections.created_at) + elsif model.to_s.downcase == 'prompt' + allowed = %w(fandom created_at prompter) + elsif model.to_s.downcase == 'claim' + allowed = %w(created_at claimer) + end + !param.blank? && allowed.include?(param.to_s.downcase) + end + + def set_sort_order + # sorting + @sort_column = (valid_sort_column(params[:sort_column],"prompt") ? params[:sort_column] : 'id') + @sort_direction = (valid_sort_direction(params[:sort_direction]) ? params[:sort_direction] : 'DESC') + if !params[:sort_direction].blank? && !valid_sort_direction(params[:sort_direction]) + params[:sort_direction] = 'DESC' + end + @sort_order = @sort_column + " " + @sort_direction + end + + def valid_sort_direction(param) + !param.blank? && %w(asc desc).include?(param.to_s.downcase) + end + + def flash_search_warnings(result) + if result.respond_to?(:error) && result.error + flash.now[:error] = result.error + elsif result.respond_to?(:notice) && result.notice + flash.now[:notice] = result.notice + end + end + + # Don't get unnecessary data for json requests + + skip_before_action :load_admin_banner, + :store_location, + if: proc { %w(js json).include?(request.format) } + +end diff --git a/app/controllers/archive_faqs_controller.rb b/app/controllers/archive_faqs_controller.rb new file mode 100755 index 0000000..8a8a881 --- /dev/null +++ b/app/controllers/archive_faqs_controller.rb @@ -0,0 +1,195 @@ +class ArchiveFaqsController < ApplicationController + before_action :admin_only, except: [:index, :show] + before_action :set_locale + before_action :validate_locale, if: :logged_in_as_admin? + before_action :require_language_id + before_action :default_locale_only, only: [:new, :create, :manage, :update_positions, :confirm_delete, :destroy] + around_action :with_locale + + # GET /archive_faqs + def index + @archive_faqs = ArchiveFaq.order("position ASC") + unless logged_in_as_admin? + @archive_faqs = @archive_faqs.with_translations(I18n.locale) + end + respond_to do |format| + format.html # index.html.erb + end + end + + # GET /archive_faqs/1 + def show + @questions = [] + @archive_faq = ArchiveFaq.find_by!(slug: params[:id]) + if params[:language_id] == "en" + @questions = @archive_faq.questions + else + @archive_faq.questions.each do |question| + question.translations.each do |translation| + if translation.is_translated == "1" && params[:language_id].to_s == translation.locale.to_s + @questions << question + end + end + end + end + @page_subtitle = @archive_faq.title + ts(" FAQ") + + respond_to do |format| + format.html # show.html.erb + end + end + + protected + + def build_questions + notice = "" + num_to_build = params["num_questions"] ? params["num_questions"].to_i : @archive_faq.questions.count + if num_to_build < @archive_faq.questions.count + notice += ts("There are currently %{num} questions. You can only submit a number equal to or greater than %{num}. ", num: @archive_faq.questions.count) + num_to_build = @archive_faq.questions.count + elsif params["num_questions"] + notice += ts("Set up %{num} questions. ", num: num_to_build) + end + num_existing = @archive_faq.questions.count + num_existing.upto(num_to_build-1) do + @archive_faq.questions.build + end + unless notice.blank? + flash[:notice] = notice + end + end + + public + + # GET /archive_faqs/new + def new + @archive_faq = authorize ArchiveFaq.new + 1.times { @archive_faq.questions.build(attributes: { question: "This is a temporary question", content: "This is temporary content", anchor: "ThisIsATemporaryAnchor"})} + respond_to do |format| + format.html # new.html.erb + end + end + + # GET /archive_faqs/1/edit + def edit + @archive_faq = authorize ArchiveFaq.find_by(slug: params[:id]) + authorize :archive_faq, :full_access? if default_locale? + build_questions + end + + # GET /archive_faqs/manage + def manage + @archive_faqs = authorize ArchiveFaq.order("position ASC") + end + + # POST /archive_faqs + def create + @archive_faq = authorize ArchiveFaq.new(archive_faq_params) + if @archive_faq.save + flash[:notice] = t(".success") + redirect_to(@archive_faq) + else + render action: "new" + end + end + + # PUT /archive_faqs/1 + def update + @archive_faq = authorize ArchiveFaq.find_by(slug: params[:id]) + authorize :archive_faq, :full_access? if default_locale? + + if @archive_faq.update(archive_faq_params) + flash[:notice] = t(".success") + redirect_to(@archive_faq) + else + render action: "edit" + end + end + + # reorder FAQs + def update_positions + authorize :archive_faq + if params[:archive_faqs] + @archive_faqs = ArchiveFaq.reorder_list(params[:archive_faqs]) + flash[:notice] = t(".success") + elsif params[:archive_faq] + params[:archive_faq].each_with_index do |id, position| + ArchiveFaq.update(id, position: position + 1) + (@archive_faqs ||= []) << ArchiveFaq.find(id) + end + end + respond_to do |format| + format.html { redirect_to(archive_faqs_path) } + format.js { render nothing: true } + end + end + + # The ?language_id=somelanguage needs to persist throughout URL changes + # Get the value from set_locale to make sure there's no problem with order + def default_url_options + { language_id: set_locale.to_s } + end + + # Set the locale as an instance variable first + def set_locale + session[:language_id] = params[:language_id] if Locale.exists?(iso: params[:language_id]) + + if current_user.present? + @i18n_locale = session[:language_id].presence || current_user.preference.locale.iso + else + @i18n_locale = session[:language_id].presence || I18n.default_locale + end + end + + def validate_locale + return if params[:language_id].blank? || Locale.exists?(iso: params[:language_id]) + + flash[:error] = "The specified locale does not exist." + redirect_to url_for(request.query_parameters.merge(language_id: I18n.default_locale)) + end + + def require_language_id + return if params[:language_id].present? && Locale.exists?(iso: params[:language_id]) + + redirect_to url_for(request.query_parameters.merge(language_id: @i18n_locale.to_s)) + end + + def default_locale_only + return if default_locale? + + flash[:error] = t("archive_faqs.default_locale_only") + redirect_to archive_faqs_path + end + + # Setting I18n.locale directly is not thread safe + def with_locale + I18n.with_locale(@i18n_locale) { yield } + end + + # GET /archive_faqs/1/confirm_delete + def confirm_delete + @archive_faq = authorize ArchiveFaq.find_by(slug: params[:id]) + end + + # DELETE /archive_faqs/1 + def destroy + @archive_faq = authorize ArchiveFaq.find_by(slug: params[:id]) + @archive_faq.destroy + redirect_to(archive_faqs_path) + end + + private + + def default_locale? + @i18n_locale.to_s == I18n.default_locale.to_s + end + + def archive_faq_params + params.require(:archive_faq).permit( + :title, + questions_attributes: [ + :id, :question, :anchor, :content, :screencast, :_destroy, :is_translated + ] + ) + end +end diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb new file mode 100755 index 0000000..620d53d --- /dev/null +++ b/app/controllers/autocomplete_controller.rb @@ -0,0 +1,224 @@ +class AutocompleteController < ApplicationController + respond_to :json + + skip_before_action :store_location + skip_around_action :set_current_user, except: [:collection_parent_name, :owned_tag_sets, :site_skins] + skip_before_action :sanitize_ac_params # can we dare! + + #### DO WE NEED THIS AT ALL? IF IT FIRES WITHOUT A TERM AND 500s BECAUSE USER DID SOMETHING WACKY SO WHAT + # # If you have an autocomplete that should fire without a term add it here + # before_action :require_term, except: [:tag_in_fandom, :relationship_in_fandom, :character_in_fandom, :nominated_parents] + # + # def require_term + # if params[:term].blank? + # flash[:error] = ts("What were you trying to autocomplete?") + # redirect_to(request.env["HTTP_REFERER"] || root_path) and return + # end + # end + # + ######################################### + ############# LOOKUP ACTIONS GO HERE + + # PSEUDS + def pseud + return if params[:term].blank? + + render_output(Pseud.autocomplete_lookup(search_param: params[:term], autocomplete_prefix: "autocomplete_pseud").map { |res| Pseud.fullname_from_autocomplete(res) }) + end + + ## TAGS + private + def tag_output(search_param, tag_type) + tags = Tag.autocomplete_lookup(search_param: search_param, autocomplete_prefix: "autocomplete_tag_#{tag_type}") + render_output tags.map {|r| Tag.name_from_autocomplete(r)} + end + public + # these are all basically duplicates but make our calls to autocomplete more readable + def tag; tag_output(params[:term], params[:type] || "all"); end + def fandom; tag_output(params[:term], "fandom"); end + def character; tag_output(params[:term], "character"); end + def relationship; tag_output(params[:term], "relationship"); end + def freeform; tag_output(params[:term], "freeform"); end + + + ## TAGS IN FANDOMS + private + def tag_in_fandom_output(params) + render_output(Tag.autocomplete_fandom_lookup(params).map {|r| Tag.name_from_autocomplete(r)}) + end + public + def character_in_fandom; tag_in_fandom_output(params.merge({tag_type: "character"})); end + def relationship_in_fandom; tag_in_fandom_output(params.merge({tag_type: "relationship"})); end + + + ## TAGS IN SETS + # + # Note that only tagsets in OwnedTagSets are in autocomplete + # + + # expects the following params: + # :tag_set - tag set ids comma-separated + # :tag_type - tag type as a string unless "all" desired + # :in_any - set to false if only want tags in ALL specified sets + # :term - the search term + def tags_in_sets + results = TagSet.autocomplete_lookup(params) + render_output(results.map {|r| Tag.name_from_autocomplete(r)}) + end + + # expects the following params: + # :fandom - fandom name(s) as an array or a comma-separated string + # :tag_set - tag set id(s) as an array or a comma-separated string + # :tag_type - tag type as a string unless "all" desired + # :include_wrangled - set to false if you only want tags from the set associations and NOT tags wrangled into the fandom + # :fallback - set to false to NOT do + # :term - the search term + def associated_tags + if params[:fandom].blank? + render_output([ts("Please select a fandom first!")]) + else + results = TagSetAssociation.autocomplete_lookup(params) + render_output(results.map {|r| Tag.name_from_autocomplete(r)}) + end + end + + ## NONCANONICAL TAGS + def noncanonical_tag + search_param = Query.new.escape_reserved_characters(params[:term]) + raise "Redshirt: Attempted to constantize invalid class initialize noncanonical_tag #{params[:type].classify}" unless Tag::TYPES.include?(params[:type].classify) + + tag_class = params[:type].classify.constantize + one_tag = tag_class.find_by(canonical: false, name: params[:term]) if params[:term].present? + # If there is an exact match in the database, ensure it is the first thing suggested. + match = if one_tag + [one_tag.name] + else + [] + end + + # As explained in https://stackoverflow.com/a/54080114, the Elasticsearch suggestion suggester does not support + # matches in the middle of a series of words. Therefore, we break the autocomplete query into its individual + # words – based on whitespace – except for the last word, which could be incomplete, so a prefix match is + # appropriate. This emulates the behavior of SQL `LIKE '%text%'. + + word_list = search_param.split + last_word = word_list.pop + search_list = word_list.map { |w| { term: { name: { value: w, case_insensitive: true } } } } + [{ prefix: { name: { value: last_word, case_insensitive: true } } }] + begin + # Size is chosen so we get enough search results from each shard. + search_results = $elasticsearch.search( + index: TagIndexer.index_name, + body: { size: "100", query: { bool: { filter: [{ match: { tag_type: params[:type].capitalize } }, { match: { canonical: false } }], must: search_list } } } + ) + render_output((match + search_results["hits"]["hits"].first(10).map { |t| t["_source"]["name"] }).uniq) + rescue Elastic::Transport::Transport::Errors::BadRequest + render_output(match) + end + end + + # more-specific autocompletes should be added below here when they can't be avoided + + # look up collections ranked by number of items they contain + + def collection_fullname + results = Collection.autocomplete_lookup(search_param: params[:term], autocomplete_prefix: "autocomplete_collection_all").map {|res| Collection.fullname_from_autocomplete(res)} + render_output(results) + end + + # return collection names + + def open_collection_names + # in this case we want different ids from names so we can display the title but only put in the name + results = Collection.autocomplete_lookup(search_param: params[:term], autocomplete_prefix: "autocomplete_collection_open").map do |str| + {id: (whole_name = Collection.name_from_autocomplete(str)), name: Collection.title_from_autocomplete(str) + " (#{whole_name})" } + end + respond_with(results) + end + + # For creating collections, autocomplete the name of a parent collection owned by the user only + def collection_parent_name + render_output(current_user.maintained_collections.top_level.with_name_like(params[:term]).pluck(:name).sort) + end + + # for looking up existing urls for external works to avoid duplication + def external_work + render_output(ExternalWork.where(["url LIKE ?", '%' + params[:term] + '%']).limit(10).order(:url).pluck(:url)) + end + + # the pseuds of the potential matches who could fulfill the requests in the given signup + def potential_offers + potential_matches(false) + end + + # the pseuds of the potential matches who want the offers in the given signup + def potential_requests + potential_matches(true) + end + + # Return matching potential requests or offers + def potential_matches(return_requests=true) + search_param = params[:term] + signup_id = params[:signup_id] + signup = ChallengeSignup.find(signup_id) + pmatches = return_requests ? + signup.offer_potential_matches.sort.reverse.map {|pm| pm.request_signup.pseud.byline} : + signup.request_potential_matches.sort.reverse.map {|pm| pm.offer_signup.pseud.byline} + pmatches.select! { |pm| pm.match(/#{Regexp.escape(search_param)}/) } if search_param.present? + render_output(pmatches) + end + + # owned tag sets that are usable by all + def owned_tag_sets + if params[:term].length > 0 + search_param = '%' + params[:term] + '%' + render_output(OwnedTagSet.limit(10).order(:title).usable.where("owned_tag_sets.title LIKE ?", search_param).collect(&:title)) + end + end + + # skins for parenting + def site_skins + if params[:term].present? + search_param = '%' + params[:term] + '%' + query = Skin.site_skins.where("title LIKE ?", search_param).limit(15).sort_by_recent + if logged_in? + query = query.approved_or_owned_by(current_user) + else + query = query.approved_skins + end + render_output(query.pluck(:title)) + end + end + + # admin posts for translations, formatted as Admin Post Title (Post #id) + def admin_posts + if params[:term].present? + search_param = '%' + params[:term] + '%' + results = AdminPost.non_translated.where("title LIKE ?", search_param).limit(ArchiveConfig.MAX_RECENT).map do |result| + {id: (post_id = result.id), + name: result.title + " (Post ##{post_id})" } + end + respond_with(results) + end + end + + def admin_post_tags + if params[:term].present? + search_param = '%' + params[:term].strip + '%' + query = AdminPostTag.where("name LIKE ?", search_param).limit(ArchiveConfig.MAX_RECENT) + render_output(query.pluck(:name)) + end + end + +private + + # Because of the respond_to :json at the top of the controller, this will return a JSON-encoded + # response which the autocomplete javascript on the other end should be able to handle :) + def render_output(result_strings) + if result_strings.first.is_a?(String) + respond_with(result_strings.map {|str| {id: str, name: str}}) + else + respond_with(result_strings) + end + end + +end diff --git a/app/controllers/blocked/users_controller.rb b/app/controllers/blocked/users_controller.rb new file mode 100755 index 0000000..827e8b1 --- /dev/null +++ b/app/controllers/blocked/users_controller.rb @@ -0,0 +1,89 @@ +module Blocked + class UsersController < ApplicationController + before_action :set_user + + before_action :check_ownership, except: :index + before_action :check_ownership_or_admin, only: :index + before_action :check_admin_permissions, only: :index + + before_action :build_block, only: [:confirm_block, :create] + before_action :set_block, only: [:confirm_unblock, :destroy] + + # GET /users/:user_id/blocked/users + def index + @blocks = @user.blocks_as_blocker + .joins(:blocked) + .includes(blocked: [:pseuds, { default_pseud: { icon_attachment: { blob: { + variant_records: { image_attachment: :blob }, + preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } } + } } } }]) + .order(created_at: :desc).order(id: :desc).page(params[:page]) + + @pseuds = @blocks.map { |b| b.blocked.default_pseud } + @rec_counts = Pseud.rec_counts_for_pseuds(@pseuds) + @work_counts = Pseud.work_counts_for_pseuds(@pseuds) + + @page_subtitle = "Blocked Users" + end + + # GET /users/:user_id/blocked/users/confirm_block + def confirm_block + @hide_dashboard = true + + return if @block.valid? + + # We can't block this user for whatever reason + flash[:error] = @block.errors.full_messages.first + redirect_to user_blocked_users_path(@user) + end + + # GET /users/:user_id/blocked/users/confirm_unblock + def confirm_unblock + @hide_dashboard = true + + @blocked = @block.blocked + end + + # POST /users/:user_id/blocked/users + def create + if @block.save + flash[:notice] = t(".blocked", name: @block.blocked.login) + else + # We can't block this user for whatever reason + flash[:error] = @block.errors.full_messages.first + end + + redirect_to user_blocked_users_path(@user) + end + + # DELETE /users/:user_id/blocked/users/:id + def destroy + @block.destroy + flash[:notice] = t(".unblocked", name: @block.blocked.login) + redirect_to user_blocked_users_path(@user) + end + + private + + # Sets the user whose blocks we're viewing/modifying. + def set_user + @user = User.find_by!(login: params[:user_id]) + @check_ownership_of = @user + end + + # Builds (but doesn't save) a block matching the desired params: + def build_block + blocked_byline = params.fetch(:blocked_id, "") + @block = @user.blocks_as_blocker.build(blocked_byline: blocked_byline) + @blocked = @block.blocked + end + + def set_block + @block = @user.blocks_as_blocker.find(params[:id]) + end + + def check_admin_permissions + authorize Block if logged_in_as_admin? + end + end +end diff --git a/app/controllers/bookmarks_controller.rb b/app/controllers/bookmarks_controller.rb new file mode 100755 index 0000000..050a1ad --- /dev/null +++ b/app/controllers/bookmarks_controller.rb @@ -0,0 +1,397 @@ +class BookmarksController < ApplicationController + before_action :load_collection + before_action :load_owner, only: [:index] + before_action :load_bookmarkable, only: [:index, :new, :create] + before_action :users_only, only: [:new, :create, :edit, :update] + before_action :check_user_status, only: [:new, :create, :edit, :update] + before_action :check_parent_visible, only: [:index, :new] + before_action :load_bookmark, only: [:show, :edit, :update, :destroy, :confirm_delete, :share] + before_action :check_visibility, only: [:show, :share] + before_action :check_ownership, only: [:edit, :update, :destroy, :confirm_delete, :share] + + before_action :check_pseud_ownership, only: [:create, :update] + + skip_before_action :store_location, only: [:share] + + def check_pseud_ownership + if params[:bookmark][:pseud_id] + pseud = Pseud.find(bookmark_params[:pseud_id]) + unless pseud && current_user && current_user.pseuds.include?(pseud) + flash[:error] = ts("You can't bookmark with that pseud.") + redirect_to root_path and return + end + end + end + + def check_parent_visible + check_visibility_for(@bookmarkable) + end + + # get the parent + def load_bookmarkable + if params[:work_id] + @bookmarkable = Work.find(params[:work_id]) + elsif params[:external_work_id] + @bookmarkable = ExternalWork.find(params[:external_work_id]) + elsif params[:series_id] + @bookmarkable = Series.find(params[:series_id]) + end + end + + def load_bookmark + @bookmark = Bookmark.find(params[:id]) + @check_ownership_of = @bookmark + @check_visibility_of = @bookmark + end + + def search + @languages = Language.default_order + options = params[:bookmark_search].present? ? bookmark_search_params : {} + options.merge!(page: params[:page]) if params[:page].present? + options[:show_private] = false + options[:show_restricted] = logged_in? || logged_in_as_admin? + @search = BookmarkSearchForm.new(options) + @page_subtitle = ts("Search Bookmarks") + if params[:bookmark_search].present? && params[:edit_search].blank? + if @search.query.present? + @page_subtitle = ts("Bookmarks Matching '%{query}'", query: @search.query) + end + @bookmarks = @search.search_results.scope(:for_blurb) + flash_search_warnings(@bookmarks) + set_own_bookmarks + render 'search_results' + end + end + + def index + if @bookmarkable + @bookmarks = @bookmarkable.bookmarks.not_private.order_by_created_at.paginate(page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE) + @bookmarks = @bookmarks.where(hidden_by_admin: false) unless logged_in_as_admin? + else + base_options = { + show_private: (@user.present? && @user == current_user), + show_restricted: logged_in? || logged_in_as_admin?, + page: params[:page] + } + + options = params[:bookmark_search].present? ? bookmark_search_params : {} + + if params[:include_bookmark_search].present? + params[:include_bookmark_search].keys.each do |key| + options[key] ||= [] + options[key] << params[:include_bookmark_search][key] + options[key].flatten! + end + end + + if params[:exclude_bookmark_search].present? + params[:exclude_bookmark_search].keys.each do |key| + # Keep bookmarker tags separate, so we can search for them on bookmarks + # and search for the rest on bookmarkables + options_key = key == "tag_ids" ? :excluded_bookmark_tag_ids : :excluded_tag_ids + options[options_key] ||= [] + options[options_key] << params[:exclude_bookmark_search][key] + options[options_key].flatten! + end + end + + options.merge!(base_options) + @page_subtitle = index_page_title + + if @owner.present? + @search = BookmarkSearchForm.new(options.merge(faceted: true, parent: @owner)) + + if @user.blank? + # When it's not a particular user's bookmarks, we want + # to list *bookmarkable* items to avoid duplication + @bookmarkable_items = @search.bookmarkable_search_results.scope(:for_blurb) + flash_search_warnings(@bookmarkable_items) + @facets = @bookmarkable_items.facets + else + # We're looking at a particular user's bookmarks, so + # just retrieve the standard search results and their facets. + @bookmarks = @search.search_results.scope(:for_blurb) + flash_search_warnings(@bookmarks) + @facets = @bookmarks.facets + end + + if @search.options[:excluded_tag_ids].present? || @search.options[:excluded_bookmark_tag_ids].present? + # Excluded tags do not appear in search results, so we need to generate empty facets + # to keep them as checkboxes on the filters. + excluded_tag_ids = @search.options[:excluded_tag_ids] || [] + excluded_bookmark_tag_ids = @search.options[:excluded_bookmark_tag_ids] || [] + + # It's possible to determine the tag types by looking at + # the original parameters params[:exclude_bookmark_search], + # but we need the tag names too, so a database query is unavoidable. + tags = Tag.where(id: excluded_tag_ids + excluded_bookmark_tag_ids) + tags.each do |tag| + if excluded_tag_ids.include?(tag.id.to_s) + key = tag.class.to_s.underscore + @facets[key] ||= [] + @facets[key] << QueryFacet.new(tag.id, tag.name, 0) + end + if excluded_bookmark_tag_ids.include?(tag.id.to_s) + key = 'tag' + @facets[key] ||= [] + @facets[key] << QueryFacet.new(tag.id, tag.name, 0) + end + end + end + elsif use_caching? + @bookmarks = Rails.cache.fetch("bookmarks/index/latest/v2_true", expires_in: ArchiveConfig.SECONDS_UNTIL_BOOKMARK_INDEX_EXPIRE.seconds) do + search = BookmarkSearchForm.new(show_private: false, show_restricted: false, sort_column: 'created_at') + results = search.search_results.scope(:for_blurb) + flash_search_warnings(results) + results.to_a + end + else + @bookmarks = Bookmark.latest.for_blurb.to_a + end + end + set_own_bookmarks + + @pagy = + if @bookmarks.respond_to?(:total_pages) + pagy_query_result(@bookmarks) + elsif @bookmarkable_items.respond_to?(:total_pages) + pagy_query_result(@bookmarkable_items) + end + end + + # GET /:locale/bookmark/:id + # GET /:locale/users/:user_id/bookmarks/:id + # GET /:locale/works/:work_id/bookmark/:id + # GET /:locale/external_works/:external_work_id/bookmark/:id + def show + end + + # GET /bookmarks/new + # GET /bookmarks/new.xml + def new + @bookmark = Bookmark.new + respond_to do |format| + format.html + format.js { + @button_name = ts("Create") + @action = :create + render action: "bookmark_form_dynamic" + } + end + end + + # GET /bookmarks/1/edit + def edit + @bookmarkable = @bookmark.bookmarkable + respond_to do |format| + format.html + format.js { + @button_name = ts("Update") + @action = :update + render action: "bookmark_form_dynamic" + } + end + end + + # POST /bookmarks + # POST /bookmarks.xml + def create + @bookmarkable ||= ExternalWork.new(external_work_params) + @bookmark = Bookmark.new(bookmark_params.merge(bookmarkable: @bookmarkable)) + if @bookmark.errors.empty? && @bookmark.save + flash[:notice] = ts("Bookmark was successfully created. It should appear in bookmark listings within the next few minutes.") + redirect_to(bookmark_path(@bookmark)) + else + render :new + end + end + + # PUT /bookmarks/1 + # PUT /bookmarks/1.xml + def update + new_collections = [] + unapproved_collections = [] + errors = [] + bookmark_params[:collection_names]&.split(",")&.map(&:strip)&.uniq&.each do |collection_name| + collection = Collection.find_by(name: collection_name) + if collection.nil? + errors << ts("%{name} does not exist.", name: collection_name) + else + if @bookmark.collections.include?(collection) + next + elsif collection.closed? && !collection.user_is_maintainer?(User.current_user) + errors << ts("%{title} is closed to new submissions.", title: collection.title) + elsif @bookmark.add_to_collection(collection) && @bookmark.save + if @bookmark.approved_collections.include?(collection) + new_collections << collection + else + unapproved_collections << collection + end + else + errors << ts("Something went wrong trying to add collection %{title}, sorry!", title: collection.title) + end + end + end + + # messages to the user + unless errors.empty? + flash[:error] = ts("We couldn't add your submission to the following collections: ") + errors.join("
") + end + + unless new_collections.empty? + flash[:notice] = ts("Added to collection(s): %{collections}.", + collections: new_collections.collect(&:title).join(", ")) + end + unless unapproved_collections.empty? + flash[:notice] = flash[:notice] ? flash[:notice] + " " : "" + flash[:notice] += if unapproved_collections.size > 1 + ts("You have submitted your bookmark to moderated collections (%{all_collections}). It will not become a part of those collections until it has been approved by a moderator.", all_collections: unapproved_collections.map(&:title).join(", ")) + else + ts("You have submitted your bookmark to the moderated collection '%{collection}'. It will not become a part of the collection until it has been approved by a moderator.", collection: unapproved_collections.first.title) + end + end + + flash[:notice] = (flash[:notice]).html_safe unless flash[:notice].blank? + flash[:error] = (flash[:error]).html_safe unless flash[:error].blank? + + if @bookmark.update(bookmark_params) && errors.empty? + flash[:notice] = flash[:notice] ? " " + flash[:notice] : "" + flash[:notice] = ts("Bookmark was successfully updated.").html_safe + flash[:notice] + flash[:notice] = flash[:notice].html_safe + redirect_to(@bookmark) + else + @bookmarkable = @bookmark.bookmarkable + render :edit and return + end + end + + # GET /bookmarks/1/share + def share + if request.xhr? + if @bookmark.bookmarkable.is_a?(Work) && @bookmark.bookmarkable.unrevealed? + render template: "errors/404", status: :not_found + else + render layout: false + end + else + # Avoid getting an unstyled page if JavaScript is disabled + flash[:error] = ts("Sorry, you need to have JavaScript enabled for this.") + redirect_back(fallback_location: root_path) + end + end + + def confirm_delete + end + + # DELETE /bookmarks/1 + # DELETE /bookmarks/1.xml + def destroy + @bookmark.destroy + flash[:notice] = ts("Bookmark was successfully deleted.") + redirect_to user_bookmarks_path(current_user) + end + + protected + + def load_owner + if params[:user_id].present? + @user = User.find_by(login: params[:user_id]) + unless @user + raise ActiveRecord::RecordNotFound, "Couldn't find user named '#{params[:user_id]}'" + end + if params[:pseud_id].present? + @pseud = @user.pseuds.find_by(name: params[:pseud_id]) + unless @pseud + raise ActiveRecord::RecordNotFound, "Couldn't find pseud named '#{params[:pseud_id]}'" + end + end + end + if params[:tag_id] + @tag = Tag.find_by_name(params[:tag_id]) + unless @tag + raise ActiveRecord::RecordNotFound, "Couldn't find tag named '#{params[:tag_id]}'" + end + unless @tag.canonical? + if @tag.merger.present? + redirect_to tag_bookmarks_path(@tag.merger) and return + else + redirect_to tag_path(@tag) and return + end + end + end + @owner = @bookmarkable || @pseud || @user || @collection || @tag + end + + def index_page_title + if @owner.present? + owner_name = case @owner.class.to_s + when 'Pseud' + @owner.name + when 'User' + @owner.login + when 'Collection' + @owner.title + else + @owner.try(:name) + end + "#{owner_name} - Bookmarks".html_safe + else + "Latest Bookmarks" + end + end + + def set_own_bookmarks + return unless @bookmarks + @own_bookmarks = [] + if current_user.is_a?(User) + pseud_ids = current_user.pseuds.pluck(:id) + @own_bookmarks = @bookmarks.select do |b| + pseud_ids.include?(b.pseud_id) + end + end + end + + private + + def bookmark_params + params.require(:bookmark).permit( + :pseud_id, :bookmarker_notes, :tag_string, :collection_names, :private, :rec + ) + end + + def external_work_params + params.require(:external_work).permit( + :url, :author, :title, :fandom_string, :rating_string, :relationship_string, + :character_string, :summary, category_strings: [] + ) + end + + def bookmark_search_params + params.require(:bookmark_search).permit( + :bookmark_query, + :bookmarkable_query, + :bookmarker, + :bookmark_notes, + :rec, + :with_notes, + :bookmarkable_type, + :language_id, + :date, + :bookmarkable_date, + :sort_column, + :other_tag_names, + :excluded_tag_names, + :other_bookmark_tag_names, + :excluded_bookmark_tag_names, + rating_ids: [], + warning_ids: [], # backwards compatibility + archive_warning_ids: [], + category_ids: [], + fandom_ids: [], + character_ids: [], + relationship_ids: [], + freeform_ids: [], + tag_ids: [], + ) + end +end diff --git a/app/controllers/challenge/gift_exchange_controller.rb b/app/controllers/challenge/gift_exchange_controller.rb new file mode 100755 index 0000000..dccf8e0 --- /dev/null +++ b/app/controllers/challenge/gift_exchange_controller.rb @@ -0,0 +1,109 @@ +class Challenge::GiftExchangeController < ChallengesController + + before_action :users_only + before_action :load_collection + before_action :load_challenge, except: [:new, :create] + before_action :collection_owners_only, only: [:new, :create, :edit, :update, :destroy] + + # ACTIONS + + def show + end + + def new + if (@collection.challenge) + flash[:notice] = ts("There is already a challenge set up for this collection.") + # TODO this will break if the challenge isn't a gift exchange + redirect_to edit_collection_gift_exchange_path(@collection) + else + @challenge = GiftExchange.new + end + end + + def edit + end + + def create + @challenge = GiftExchange.new(gift_exchange_params) + if @challenge.save + @collection.challenge = @challenge + @collection.save + flash[:notice] = ts('Challenge was successfully created.') + redirect_to collection_profile_path(@collection) + else + render action: :new + end + end + + def update + if @challenge.update(gift_exchange_params) + flash[:notice] = ts('Challenge was successfully updated.') + + # expire the cache on the signup form + ActionController::Base.new.expire_fragment('challenge_signups/new') + + # see if we initialized the tag set + redirect_to collection_profile_path(@collection) + else + render action: :edit + end + end + + def destroy + @challenge.destroy + flash[:notice] = 'Challenge settings were deleted.' + redirect_to @collection + end + + private + + def gift_exchange_params + params.require(:gift_exchange).permit( + :signup_open, :time_zone, :signups_open_at_string, :signups_close_at_string, + :assignments_due_at_string, :requests_summary_visible, :requests_num_required, + :requests_num_allowed, :offers_num_required, :offers_num_allowed, + :signup_instructions_general, :signup_instructions_requests, + :signup_instructions_offers, :request_url_label, :offer_url_label, + :offer_description_label, :request_description_label, :works_reveal_at_string, + :authors_reveal_at_string, + request_restriction_attributes: [ + :id, :optional_tags_allowed, :title_required, :title_allowed, :description_required, + :description_allowed, :url_required, :url_allowed, :fandom_num_required, + :fandom_num_allowed, :allow_any_fandom, :require_unique_fandom, + :character_num_required, :character_num_allowed, :allow_any_character, + :require_unique_character, :relationship_num_required, :relationship_num_allowed, + :allow_any_relationship, :require_unique_relationship, :rating_num_required, + :rating_num_allowed, :allow_any_rating, :require_unique_rating, + :category_num_required, :category_num_allowed, :allow_any_category, + :require_unique_category, :freeform_num_required, :freeform_num_allowed, + :allow_any_freeform, :require_unique_freeform, :archive_warning_num_required, + :archive_warning_num_allowed, :allow_any_archive_warning, :require_unique_archive_warning + ], + offer_restriction_attributes: [ + :id, :optional_tags_allowed, :title_required, :title_allowed, + :description_required, :description_allowed, :url_required, :url_allowed, + :fandom_num_required, :fandom_num_allowed, :allow_any_fandom, + :require_unique_fandom, :character_num_required, :character_num_allowed, + :allow_any_character, :require_unique_character, :relationship_num_required, + :relationship_num_allowed, :allow_any_relationship, :require_unique_relationship, + :rating_num_required, :rating_num_allowed, :rating_num_required, :allow_any_rating, :require_unique_rating, + :category_num_required, :category_num_allowed, :allow_any_category, + :require_unique_category, :freeform_num_required, :freeform_num_allowed, + :allow_any_freeform, :require_unique_freeform, :archive_warning_num_required, + :archive_warning_num_allowed, :allow_any_archive_warning, :require_unique_archive_warning, + :tag_sets_to_add, :character_restrict_to_fandom, + :character_restrict_to_tag_set, :relationship_restrict_to_fandom, + :relationship_restrict_to_tag_set, + tag_sets_to_remove: [] + ], + potential_match_settings_attributes: [ + :id, :num_required_prompts, :num_required_fandoms, :num_required_characters, + :num_required_relationships, :num_required_freeforms, :num_required_categories, + :num_required_ratings, :num_required_archive_warnings, :include_optional_fandoms, + :include_optional_characters, :include_optional_relationships, + :include_optional_freeforms, :include_optional_categories, :include_optional_ratings, + :include_optional_archive_warnings + ] + ) + end +end diff --git a/app/controllers/challenge/prompt_meme_controller.rb b/app/controllers/challenge/prompt_meme_controller.rb new file mode 100755 index 0000000..4415cd4 --- /dev/null +++ b/app/controllers/challenge/prompt_meme_controller.rb @@ -0,0 +1,80 @@ +class Challenge::PromptMemeController < ChallengesController + + before_action :users_only + before_action :load_collection + before_action :load_challenge, except: [:new, :create] + before_action :collection_owners_only, only: [:new, :create, :edit, :update, :destroy] + + # ACTIONS + + # is actually a blank page - should it be redirected to collection profile? + def show + end + + # The new form for prompt memes is actually the challenge settings page because challenges are always created in the context of a collection. + def new + if (@collection.challenge) + flash[:notice] = ts("There is already a challenge set up for this collection.") + redirect_to edit_collection_prompt_meme_path(@collection) + else + @challenge = PromptMeme.new + end + end + + def edit + end + + def create + @challenge = PromptMeme.new(prompt_meme_params) + if @challenge.save + @collection.challenge = @challenge + @collection.save + flash[:notice] = ts('Challenge was successfully created.') + redirect_to collection_profile_path(@collection) + else + render action: :new + end + end + + def update + if @challenge.update(prompt_meme_params) + flash[:notice] = 'Challenge was successfully updated.' + # expire the cache on the signup form + ActionController::Base.new.expire_fragment('challenge_signups/new') + redirect_to @collection + else + render action: :edit + end + end + + def destroy + @challenge.destroy + flash[:notice] = 'Challenge settings were deleted.' + redirect_to @collection + end + + private + + def prompt_meme_params + params.require(:prompt_meme).permit( + :signup_open, :time_zone, :signups_open_at_string, :signups_close_at_string, + :assignments_due_at_string, :anonymous, :requests_num_required, :requests_num_allowed, + :signup_instructions_general, :signup_instructions_requests, :request_url_label, + :request_description_label, :works_reveal_at_string, :authors_reveal_at_string, + request_restriction_attributes: [ :id, :optional_tags_allowed, :title_required, + :title_allowed, :description_required, :description_allowed, :url_required, + :url_allowed, :fandom_num_required, :fandom_num_allowed, :require_unique_fandom, + :character_num_required, :character_num_allowed, :category_num_required, + :category_num_allowed, :require_unique_category, :require_unique_character, + :relationship_num_required, :relationship_num_allowed, :require_unique_relationship, + :rating_num_required, :rating_num_allowed, :require_unique_rating, + :freeform_num_required, :freeform_num_allowed, :require_unique_freeform, + :archive_warning_num_required, :archive_warning_num_allowed, :require_unique_archive_warning, + :tag_sets_to_remove, :tag_sets_to_add, :character_restrict_to_fandom, + :character_restrict_to_tag_set, :relationship_restrict_to_fandom, + :relationship_restrict_to_tag_set, tag_sets_to_remove: [] + ] + ) + end + +end diff --git a/app/controllers/challenge_assignments_controller.rb b/app/controllers/challenge_assignments_controller.rb new file mode 100755 index 0000000..39e6b84 --- /dev/null +++ b/app/controllers/challenge_assignments_controller.rb @@ -0,0 +1,243 @@ +class ChallengeAssignmentsController < ApplicationController + before_action :users_only + + before_action :load_collection, except: [:index] + before_action :load_challenge, except: [:index] + before_action :collection_owners_only, except: [:index, :show, :default] + + before_action :load_assignment_from_id, only: [:show, :default] + before_action :owner_only, only: [:default] + + before_action :check_signup_closed, except: [:index] + before_action :check_assignments_not_sent, only: [:generate, :set, :send_out] + before_action :check_assignments_sent, only: [:default, :purge, :confirm_purge] + + + # PERMISSIONS AND STATUS CHECKING + + def load_challenge + @challenge = @collection.challenge if @collection + no_challenge unless @challenge + end + + def no_challenge + flash[:error] = t('challenge_assignments.no_challenge', default: "What challenge did you want to work with?") + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + def load_assignment_from_id + @challenge_assignment = @collection.assignments.find(params[:id]) + end + + def owner_only + return if current_user == @challenge_assignment.offering_pseud.user + + flash[:error] = t("challenge_assignments.validation.not_owner") + redirect_to root_path + end + + def check_signup_closed + signup_open and return unless !@challenge.signup_open + end + + def signup_open + flash[:error] = t('challenge_assignments.signup_open', default: "Signup is currently open, you cannot make assignments now.") + redirect_to @collection rescue redirect_to '/' + false + end + + def check_assignments_not_sent + assignments_sent and return unless @challenge.assignments_sent_at.nil? + end + + def assignments_sent + flash[:error] = t('challenge_assignments.assignments_sent', default: "Assignments have already been sent! If necessary, you can purge them.") + redirect_to collection_assignments_path(@collection) rescue redirect_to '/' + false + end + + def check_assignments_sent + assignments_not_sent and return unless @challenge.assignments_sent_at + end + + def assignments_not_sent + flash[:error] = t('challenge_assignments.assignments_not_sent', default: "Assignments have not been sent! You might want matching instead.") + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + + + # ACTIONS + + def index + if params[:user_id] && (@user = User.find_by(login: params[:user_id])) + if current_user == @user + if params[:collection_id] && (@collection = Collection.find_by(name: params[:collection_id])) + @challenge_assignments = @user.offer_assignments.in_collection(@collection).undefaulted + @user.pinch_hit_assignments.in_collection(@collection).undefaulted + else + @challenge_assignments = @user.offer_assignments.undefaulted + @user.pinch_hit_assignments.undefaulted + end + else + flash[:error] = ts("You aren't allowed to see that user's assignments.") + redirect_to '/' and return + end + else + # do error-checking for the collection case + return unless load_collection + @challenge = @collection.challenge if @collection + signup_open and return unless !@challenge.signup_open + access_denied and return unless @challenge.user_allowed_to_see_assignments?(current_user) + + # we temporarily are ordering by requesting pseud to avoid left join + @assignments = case + when params[:pinch_hit] + # order by pinch hitter name + ChallengeAssignment.unfulfilled_in_collection(@collection).undefaulted.with_pinch_hitter.joins("INNER JOIN pseuds ON (challenge_assignments.pinch_hitter_id = pseuds.id)").order("pseuds.name") + when params[:fulfilled] + @collection.assignments.fulfilled.order_by_requesting_pseud + when params[:unfulfilled] + ChallengeAssignment.unfulfilled_in_collection(@collection).undefaulted.order_by_requesting_pseud + else + @collection.assignments.defaulted.uncovered.order_by_requesting_pseud + end + @assignments = @assignments.page(params[:page]) + end + end + + def show + unless @challenge.user_allowed_to_see_assignments?(current_user) || @challenge_assignment.offering_pseud.user == current_user + flash[:error] = ts("You aren't allowed to see that assignment!") + redirect_to "/" and return + end + if @challenge_assignment.defaulted? + flash[:notice] = ts("This assignment has been defaulted-on.") + end + end + + def generate + # regenerate assignments using the current potential matches + ChallengeAssignment.generate(@collection) + flash[:notice] = ts("Beginning regeneration of assignments. This may take some time, especially if your challenge is large.") + redirect_to collection_potential_matches_path(@collection) + end + + def send_out + no_giver_count = @collection.assignments.with_request.with_no_offer.count + no_recip_count = @collection.assignments.with_offer.with_no_request.count + if (no_giver_count + no_recip_count) > 0 + flash[:error] = ts("Some participants still aren't assigned. Please either delete them or match them to a placeholder before sending out assignments.") + redirect_to collection_potential_matches_path(@collection) + else + ChallengeAssignment.send_out(@collection) + flash[:notice] = "Assignments are now being sent out." + redirect_to collection_assignments_path(@collection) + end + end + + def set + # update all the assignments + all_assignment_params = challenge_assignment_params + + @assignments = [] + + @collection.assignments.where(id: all_assignment_params.keys).each do |assignment| + assignment_params = all_assignment_params[assignment.id.to_s] + @assignments << assignment unless assignment.update(assignment_params) + end + + ChallengeAssignment.update_placeholder_assignments!(@collection) + if @assignments.empty? + flash[:notice] = "Assignments updated" + redirect_to collection_potential_matches_path(@collection) + else + flash[:error] = ts("These assignments could not be saved because the two participants do not match. Did you mean to write in a giver?") + render template: "potential_matches/index" + end + end + + def confirm_purge + end + + def purge + ChallengeAssignment.clear!(@collection) + @challenge.assignments_sent_at = nil + @challenge.save + flash[:notice] = ts("Assignments purged!") + redirect_to collection_path(@collection) + end + + def update_multiple + @errors = [] + params.each_pair do |key, val| + action, id = key.split(/_/) + next unless %w(approve default undefault cover).include?(action) + assignment = @collection.assignments.find_by(id: id) + unless assignment + @errors << ts("Couldn't find assignment with id #{id}!") + next + end + case action + when "default" + # default_assignment_id = y/n + assignment.default || (@errors << ts("We couldn't default the assignment for %{offer}", offer: assignment.offer_byline)) + when "undefault" + # undefault_[assignment_id] = y/n - if set, undefault + assignment.defaulted_at = nil + assignment.save || (@errors << ts("We couldn't undefault the assignment covering %{request}.", request: assignment.request_byline)) + when "approve" + assignment.get_collection_item.approve_by_collection if assignment.get_collection_item + when "cover" + # cover_[assignment_id] = pinch hitter pseud + next if val.blank? || assignment.pinch_hitter.try(:byline) == val + pseud = Pseud.parse_byline(val) + if pseud.nil? + @errors << ts("We couldn't find the user %{val} to assign that to.", val: val) + else + assignment.cover(pseud) || (@errors << ts("We couldn't assign %{val} to cover %{request}.", val: val, request: assignment.request_byline)) + end + end + end + if @errors.empty? + flash[:notice] = "Assignment updates complete!" + redirect_to collection_assignments_path(@collection) + else + flash[:error] = @errors + redirect_to collection_assignments_path(@collection) + end + end + + def default_all + # mark all unfulfilled assignments as defaulted + unfulfilled_assignments = ChallengeAssignment.unfulfilled_in_collection(@collection).readonly(false) + unfulfilled_assignments.update_all defaulted_at: Time.now + flash[:notice] = "All unfulfilled assignments marked as defaulting." + redirect_to collection_assignments_path(@collection) + end + + def default + @challenge_assignment.defaulted_at = Time.now + @challenge_assignment.save + + assignments_page_url = collection_assignments_url(@challenge_assignment.collection) + + @challenge_assignment.collection.notify_maintainers_challenge_default(@challenge_assignment, assignments_page_url) + + flash[:notice] = "We have notified the collection maintainers that you had to default on your assignment." + redirect_to user_assignments_path(current_user) + end + + private + + def challenge_assignment_params + params.slice(:challenge_assignments).permit( + challenge_assignments: [ + :request_signup_pseud, + :offer_signup_pseud, + :pinch_hitter_byline + ] + ).require(:challenge_assignments) + end + +end diff --git a/app/controllers/challenge_claims_controller.rb b/app/controllers/challenge_claims_controller.rb new file mode 100755 index 0000000..a29fd2e --- /dev/null +++ b/app/controllers/challenge_claims_controller.rb @@ -0,0 +1,148 @@ +class ChallengeClaimsController < ApplicationController + + before_action :users_only + before_action :load_collection, except: [:index] + before_action :collection_owners_only, except: [:index, :show, :create, :destroy] + before_action :load_claim_from_id, only: [:show, :destroy] + + before_action :load_challenge, except: [:index] + + before_action :allowed_to_destroy, only: [:destroy] + + + # PERMISSIONS AND STATUS CHECKING + + def load_challenge + if @collection + @challenge = @collection.challenge + elsif @challenge_claim + @challenge = @challenge_claim.collection.challenge + end + no_challenge and return unless @challenge + end + + def no_challenge + flash[:error] = ts("What challenge did you want to work with?") + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + def load_claim_from_id + @challenge_claim = ChallengeClaim.find(params[:id]) + no_claim and return unless @challenge_claim + end + + def no_claim + flash[:error] = ts("What claim did you want to work on?") + if @collection + redirect_to collection_path(@collection) rescue redirect_to '/' + else + redirect_to user_path(@user) rescue redirect_to '/' + end + false + end + + def load_user + @user = User.find_by(login: params[:user_id]) if params[:user_id] + no_user and return unless @user + end + + def no_user + flash[:error] = ts("What user were you trying to work with?") + redirect_to "/" and return + false + end + + def owner_only + unless @user == @challenge_claim.claiming_user + flash[:error] = ts("You aren't the claimer of that prompt.") + redirect_to "/" and return false + end + end + + def allowed_to_destroy + @challenge_claim.user_allowed_to_destroy?(current_user) || not_allowed(@collection) + end + + + # ACTIONS + + def index + if !(@collection = Collection.find_by(name: params[:collection_id])).nil? && @collection.closed? && !@collection.user_is_maintainer?(current_user) + flash[:notice] = ts("This challenge is currently closed to new posts.") + end + if params[:collection_id] + return unless load_collection + + @challenge = @collection.challenge + not_allowed(@collection) unless user_scoped? || @challenge.user_allowed_to_see_assignments?(current_user) + + @claims = ChallengeClaim.unposted_in_collection(@collection) + @claims = @claims.where(claiming_user_id: current_user.id) if user_scoped? + + # sorting + set_sort_order + + if params[:sort] == "claimer" + @claims = @claims.order_by_offering_pseud(@sort_direction) + else + @claims = @claims.order(@sort_order) + end + elsif params[:user_id] && (@user = User.find_by(login: params[:user_id])) + if current_user == @user + @claims = @user.request_claims.order_by_date.unposted + if params[:posted] + @claims = @user.request_claims.order_by_date.posted + end + if params[:collection_id] && (@collection = Collection.find_by(name: params[:collection_id])) + @claims = @claims.in_collection(@collection) + end + else + flash[:error] = ts("You aren't allowed to see that user's claims.") + redirect_to '/' and return + end + end + @claims = @claims.paginate page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE + end + + def show + # this is here just as a failsafe, this path should not be used + redirect_to collection_prompt_path(@collection, @challenge_claim.request_prompt) + end + + def create + # create a new claim + prompt = @collection.prompts.find(params[:prompt_id]) + claim = prompt.request_claims.build(claiming_user: current_user) + if claim.save + flash[:notice] = "New claim made." + else + flash[:error] = "We couldn't save the new claim." + end + redirect_to collection_claims_path(@collection, for_user: true) + end + + def destroy + redirect_path = collection_claims_path(@collection) + flash[:notice] = ts("The claim was deleted.") + + if @challenge_claim.claiming_user == current_user + redirect_path = collection_claims_path(@collection, for_user: true) + flash[:notice] = ts("Your claim was deleted.") + end + + begin + @challenge_claim.destroy + rescue + flash.delete(:notice) + flash[:error] = ts("We couldn't delete that right now, sorry! Please try again later.") + end + redirect_to redirect_path + end + + private + + def user_scoped? + params[:for_user].to_s.casecmp?("true") + end +end diff --git a/app/controllers/challenge_requests_controller.rb b/app/controllers/challenge_requests_controller.rb new file mode 100755 index 0000000..cb0072b --- /dev/null +++ b/app/controllers/challenge_requests_controller.rb @@ -0,0 +1,41 @@ +class ChallengeRequestsController < ApplicationController + + before_action :load_collection + before_action :check_visibility + + def check_visibility + unless @collection + flash.now[:notice] = ts("Collection could not be found") + redirect_to '/' and return + end + unless @collection.challenge_type == "PromptMeme" || (@collection.challenge_type == "GiftExchange" && @collection.challenge.user_allowed_to_see_requests_summary?(current_user)) + flash.now[:notice] = ts("You are not allowed to view the requests summary!") + redirect_to collection_path(@collection) and return + end + end + + def index + @show_request_fandom_tags = @collection.challenge.request_restriction.allowed("fandom").positive? + + # sorting + set_sort_order + direction = (@sort_direction.casecmp("ASC").zero? ? "ASC" : "DESC") + + # actual content, do the efficient method unless we need the full query + + if @sort_column == "fandom" + query = "SELECT prompts.*, GROUP_CONCAT(tags.name) AS tagnames FROM prompts INNER JOIN set_taggings ON prompts.tag_set_id = set_taggings.tag_set_id + INNER JOIN tags ON tags.id = set_taggings.tag_id + WHERE prompts.type = 'Request' AND tags.type = 'Fandom' AND prompts.collection_id = " + @collection.id.to_s + " GROUP BY prompts.id ORDER BY tagnames " + @sort_direction + @requests = Prompt.paginate_by_sql(query, page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE) + elsif @sort_column == "prompter" && !@collection.prompts.where(anonymous: true).exists? + @requests = @collection.prompts.where("type = 'Request'"). + joins(challenge_signup: :pseud). + order("pseuds.name #{direction}"). + paginate(page: params[:page]) + else + @requests = @collection.prompts.where("type = 'Request'").order(@sort_order).paginate(page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE) + end + end + +end diff --git a/app/controllers/challenge_signups_controller.rb b/app/controllers/challenge_signups_controller.rb new file mode 100755 index 0000000..d81a23d --- /dev/null +++ b/app/controllers/challenge_signups_controller.rb @@ -0,0 +1,389 @@ +# For exporting to Excel CSV format +require 'csv' + +class ChallengeSignupsController < ApplicationController + include ExportsHelper + + before_action :users_only, except: [:summary] + before_action :load_collection, except: [:index] + before_action :load_challenge, except: [:index] + before_action :load_signup_from_id, only: [:show, :edit, :update, :destroy, :confirm_delete] + before_action :allowed_to_destroy, only: [:destroy, :confirm_delete] + before_action :signup_owner_only, only: [:edit, :update] + before_action :maintainer_or_signup_owner_only, only: [:show] + before_action :check_signup_open, only: [:new, :create, :edit, :update] + before_action :check_pseud_ownership, only: [:create, :update] + before_action :check_signup_in_collection, only: [:show, :edit, :update, :destroy, :confirm_delete] + + def load_challenge + @challenge = @collection.challenge + no_challenge and return unless @challenge + end + + def no_challenge + flash[:error] = ts("What challenge did you want to sign up for?") + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + def check_signup_open + signup_closed and return unless (@challenge.signup_open || @collection.user_is_maintainer?(current_user)) + end + + def signup_closed + flash[:error] = ts("Sign-up is currently closed: please contact a moderator for help.") + redirect_to @collection rescue redirect_to '/' + false + end + + def signup_closed_owner? + @collection.challenge_type == "GiftExchange" && !@challenge.signup_open && @collection.user_is_owner?(current_user) + end + + def signup_owner_only + not_signup_owner and return unless @challenge_signup.pseud.user == current_user || signup_closed_owner? + end + + def maintainer_or_signup_owner_only + not_allowed(@collection) and return unless (@challenge_signup.pseud.user == current_user || @collection.user_is_maintainer?(current_user)) + end + + def not_signup_owner + flash[:error] = ts("You can't edit someone else's sign-up!") + redirect_to @collection + false + end + + def allowed_to_destroy + @challenge_signup.user_allowed_to_destroy?(current_user) || not_allowed(@collection) + end + + def load_signup_from_id + @challenge_signup = ChallengeSignup.find(params[:id]) + end + + def check_pseud_ownership + if params[:challenge_signup][:pseud_id] && (pseud = Pseud.find(params[:challenge_signup][:pseud_id])) + # either you have to own the pseud, OR you have to be a mod editing after signups are closed and NOT changing the pseud + unless current_user.pseuds.include?(pseud) || (@challenge_signup && @challenge_signup.pseud == pseud && signup_closed_owner?) + flash[:error] = ts("You can't sign up with that pseud.") + redirect_to root_path and return + end + end + end + + def check_signup_in_collection + unless @challenge_signup.collection_id == @collection.id + flash[:error] = ts("Sorry, that sign-up isn't associated with that collection.") + redirect_to @collection + end + end + + #### ACTIONS + + def index + if params[:user_id] && (@user = User.find_by(login: params[:user_id])) + if current_user == @user + @challenge_signups = @user.challenge_signups.order_by_date + render action: :index and return + else + flash[:error] = ts("You aren't allowed to see that user's sign-ups.") + redirect_to '/' and return + end + else + load_collection + load_challenge if @collection + return false unless @challenge + end + + # using respond_to in order to provide Excel output + # see ExportsHelper for export_csv method + respond_to do |format| + format.html { + if @challenge.user_allowed_to_see_signups?(current_user) + @challenge_signups = @collection.signups.joins(:pseud) + if params[:query] + @query = params[:query] + @challenge_signups = @challenge_signups.where("pseuds.name LIKE ?", '%' + params[:query] + '%') + end + @challenge_signups = @challenge_signups.order("pseuds.name").paginate(page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE) + elsif params[:user_id] && (@user = User.find_by(login: params[:user_id])) + @challenge_signups = @collection.signups.by_user(current_user) + else + not_allowed(@collection) + end + } + format.csv { + if (@collection.gift_exchange? && @challenge.user_allowed_to_see_signups?(current_user)) || + (@collection.prompt_meme? && @collection.user_is_maintainer?(current_user)) + csv_data = self.send("#{@challenge.class.name.underscore}_to_csv") + filename = "#{@collection.name}_signups_#{Time.now.strftime('%Y-%m-%d-%H%M')}.csv" + send_csv_data(csv_data, filename) + else + flash[:error] = ts("You aren't allowed to see the CSV summary.") + redirect_to collection_path(@collection) rescue redirect_to '/' and return + end + } + end + end + + def summary + @summary = ChallengeSignupSummary.new(@collection) + + if @collection.signups.count < (ArchiveConfig.ANONYMOUS_THRESHOLD_COUNT/2) + flash.now[:notice] = ts("Summary does not appear until at least %{count} sign-ups have been made!", count: ((ArchiveConfig.ANONYMOUS_THRESHOLD_COUNT/2))) + elsif @collection.signups.count > ArchiveConfig.MAX_SIGNUPS_FOR_LIVE_SUMMARY + # too many signups in this collection to show the summary page "live" + modification_time = @summary.cached_time + + # The time is always written alongside the cache, so if the time is + # missing, then the cache must be missing as well -- and we want to + # generate it. We also want to generate it if signups are open and it was + # last generated more than an hour ago. + if modification_time.nil? || + (@collection.challenge.signup_open? && modification_time < 1.hour.ago) + + # Touch the cache so that we don't try to generate the summary a second + # time on subsequent page loads. + @summary.touch_cache + + # Generate the cache of the summary in the background. + @summary.enqueue_for_generation + end + else + # generate it on the fly + @tag_type = @summary.tag_type + @summary_tags = @summary.summary + @generated_live = true + end + end + + def show + unless @challenge_signup.valid? + flash[:error] = ts("This sign-up is invalid. Please check your sign-ups for a duplicate or edit to fix any other problems.") + end + end + + protected + def build_prompts + notice = "" + @challenge.class::PROMPT_TYPES.each do |prompt_type| + num_to_build = params["num_#{prompt_type}"] ? params["num_#{prompt_type}"].to_i : @challenge.required(prompt_type) + if num_to_build < @challenge.required(prompt_type) + notice += ts("You must submit at least %{required} #{prompt_type}. ", required: @challenge.required(prompt_type)) + num_to_build = @challenge.required(prompt_type) + elsif num_to_build > @challenge.allowed(prompt_type) + notice += ts("You can only submit up to %{allowed} #{prompt_type}. ", allowed: @challenge.allowed(prompt_type)) + num_to_build = @challenge.allowed(prompt_type) + elsif params["num_#{prompt_type}"] + notice += ts("Set up %{num} #{prompt_type.pluralize}. ", num: num_to_build) + end + num_existing = @challenge_signup.send(prompt_type).count + num_existing.upto(num_to_build-1) do + @challenge_signup.send(prompt_type).build + end + end + unless notice.blank? + flash[:notice] = notice + end + end + + public + def new + if (@challenge_signup = ChallengeSignup.in_collection(@collection).by_user(current_user).first) + flash[:notice] = ts("You are already signed up for this challenge. You can edit your sign-up below.") + redirect_to edit_collection_signup_path(@collection, @challenge_signup) + else + @challenge_signup = ChallengeSignup.new + build_prompts + end + end + + def edit + build_prompts + end + + def create + @challenge_signup = ChallengeSignup.new(challenge_signup_params) + + @challenge_signup.pseud = current_user.default_pseud unless @challenge_signup.pseud + @challenge_signup.collection = @collection + # we check validity first to prevent saving tag sets if invalid + if @challenge_signup.valid? && @challenge_signup.save + flash[:notice] = ts('Sign-up was successfully created.') + redirect_to collection_signup_path(@collection, @challenge_signup) + else + render action: :new + end + end + + def update + if @challenge_signup.update(challenge_signup_params) + flash[:notice] = ts('Sign-up was successfully updated.') + redirect_to collection_signup_path(@collection, @challenge_signup) + else + render action: :edit + end + end + + def confirm_delete + end + + def destroy + unless @challenge.signup_open || @collection.user_is_maintainer?(current_user) + flash[:error] = ts("You cannot delete your sign-up after sign-ups are closed. Please contact a moderator for help.") + else + @challenge_signup.destroy + flash[:notice] = ts("Challenge sign-up was deleted.") + end + if @collection.user_is_maintainer?(current_user) && !@collection.prompt_meme? + redirect_to collection_signups_path(@collection) + elsif @collection.prompt_meme? + redirect_to collection_requests_path(@collection) + else + redirect_to @collection + end + end + + +protected + + def request_to_array(type, request) + any_types = TagSet::TAG_TYPES.select {|type| request && request.send("any_#{type}")} + any_types.map! { |type| ts("Any %{type}", type: type.capitalize) } + tags = request.nil? ? [] : request.tag_set.tags.map {|tag| tag.name} + rarray = [(tags + any_types).join(", ")] + + if @challenge.send("#{type}_restriction").optional_tags_allowed + rarray << (request.nil? ? "" : request.optional_tag_set.tags.map {|tag| tag.name}.join(", ")) + end + + if @challenge.send("#{type}_restriction").title_allowed + rarray << (request.nil? ? "" : sanitize_field(request, :title)) + end + + if @challenge.send("#{type}_restriction").description_allowed + description = (request.nil? ? "" : sanitize_field(request, :description)) + # Didn't find a way to get Excel 2007 to accept line breaks + # withing a field; not even when the row delimiter is set to + # \r\n and linebreaks within the field are only \n. :-( + # + # Thus stripping linebreaks. + rarray << description.gsub(/[\n\r]/, " ") + end + + rarray << (request.nil? ? "" : request.url) if + @challenge.send("#{type}_restriction").url_allowed + + return rarray + end + + + def gift_exchange_to_csv + header = ["Pseud", "Email", "Sign-up URL"] + + %w(request offer).each do |type| + @challenge.send("#{type.pluralize}_num_allowed").times do |i| + header << "#{type.capitalize} #{i+1} Tags" + header << "#{type.capitalize} #{i+1} Optional Tags" if + @challenge.send("#{type}_restriction").optional_tags_allowed + header << "#{type.capitalize} #{i+1} Title" if + @challenge.send("#{type}_restriction").title_allowed + header << "#{type.capitalize} #{i+1} Description" if + @challenge.send("#{type}_restriction").description_allowed + header << "#{type.capitalize} #{i+1} URL" if + @challenge.send("#{type}_restriction").url_allowed + end + end + + csv_array = [] + csv_array << header + + @collection.signups.each do |signup| + row = [signup.pseud.name, signup.pseud.user.email, + collection_signup_url(@collection, signup)] + + %w(request offer).each do |type| + @challenge.send("#{type.pluralize}_num_allowed").times do |i| + row += request_to_array(type, signup.send(type.pluralize)[i]) + end + end + csv_array << row + end + + csv_array + end + + + def prompt_meme_to_csv + header = ["Pseud", "Sign-up URL", "Tags"] + header << "Optional Tags" if @challenge.request_restriction.optional_tags_allowed + header << "Title" if @challenge.request_restriction.title_allowed + header << "Description" if @challenge.request_restriction.description_allowed + header << "URL" if @challenge.request_restriction.url_allowed + + csv_array = [] + csv_array << header + @collection.prompts.where(type: "Request").each do |request| + row = + if request.anonymous? + ["(Anonymous)", ""] + else + [request.challenge_signup.pseud.name, + collection_signup_url(@collection, request.challenge_signup)] + end + csv_array << (row + request_to_array("request", request)) + end + + csv_array + end + + private + + def challenge_signup_params + params.require(:challenge_signup).permit( + :pseud_id, + requests_attributes: nested_prompt_params, + offers_attributes: nested_prompt_params + ) + end + + def nested_prompt_params + [ + :id, + :title, + :url, + :any_fandom, + :any_character, + :any_relationship, + :any_freeform, + :any_category, + :any_rating, + :any_archive_warning, + :anonymous, + :description, + :_destroy, + tag_set_attributes: [ + :id, + :updated_at, + :character_tagnames, + :relationship_tagnames, + :freeform_tagnames, + :category_tagnames, + :rating_tagnames, + :archive_warning_tagnames, + :fandom_tagnames, + character_tagnames: [], + relationship_tagnames: [], + freeform_tagnames: [], + category_tagnames: [], + rating_tagnames: [], + archive_warning_tagnames: [], + fandom_tagnames: [], + ], + optional_tag_set_attributes: [ + :tagnames + ] + ] + end +end diff --git a/app/controllers/challenges_controller.rb b/app/controllers/challenges_controller.rb new file mode 100755 index 0000000..cfe8754 --- /dev/null +++ b/app/controllers/challenges_controller.rb @@ -0,0 +1,68 @@ +class ChallengesController < ApplicationController + # This is the PARENT controller for all the challenge controller classes + # + # Here's how challenges work: + # + # For each TYPE of challenge, you use the challenge generator: + # script/generate challenge WhatEver -- eg, script/generate challenge + # Flashfic, script/generate challenge BigBang, etc + # This creates: + # - a model called Challenge::WhatEver -- eg, Challenge::Flashfic, + # Challenge::BigBang, etc which actually implements a challenge + # - a controller Challenge::WhatEverController -- + # Challenge::FlashficController which goes in + # controllers/challenge/flashfic_controller.rb + # - a views subfolder called views/challenge/whatever -- + # eg, views/challenge/flashfic/, views/challenge/bigbang/ + # + # Example: + # script/generate challenge Flashfic creates: + # - controllers/challenge/flashfics_controller.rb + # - models/challenge/flashfic.rb + # - views/challenges/flashfics/ + # - db/migrate/create_challenge_flashfics to create challenge_flashfics table + # + # Setting up an instance: + # - create the collection SGA_Flashfic + # - mark it as a challenge collection + # - choose "Regular Single Prompt (flashfic-style)" as the challenge type + # + # This feeds us into challenges/new and creates a new empty Challenge object + # with collection -> SGA_Flashfic + # and implementation -> Challenge::Flashfic.new + # We are then redirected to Challenge::FlashficController new -> + # views/challenges/flashfic/new.html.erb + # + # These can have lots of options specific to flashfics, including eg how often + # prompts are posted, if they should automatically + # be closed, whether we take user suggestions for prompts, etc. + # + + before_action :load_collection + + def no_collection + flash[:error] = t('challenge.no_collection', + default: 'What collection did you want to work with?') + redirect_to(request.env['HTTP_REFERER'] || root_path) + false + end + + def no_challenge + flash[:error] = t('challenges.no_challenge', + default: 'What challenge did you want to work on?') + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + def load_collection + @collection ||= Collection.find_by(name: params[:collection_id]) if + params[:collection_id] + no_collection && return unless @collection + end + + def load_challenge + @challenge = @collection.challenge + no_challenge and return unless @challenge + end + +end diff --git a/app/controllers/chapters_controller.rb b/app/controllers/chapters_controller.rb new file mode 100755 index 0000000..2c52d12 --- /dev/null +++ b/app/controllers/chapters_controller.rb @@ -0,0 +1,295 @@ +class ChaptersController < ApplicationController + # only registered users and NOT admin should be able to create new chapters + before_action :users_only, except: [:index, :show, :destroy, :confirm_delete] + before_action :check_user_status, only: [:new, :create, :update, :update_positions] + before_action :check_user_not_suspended, only: [:edit, :remove_user_creatorship, :confirm_delete, :destroy] + before_action :load_work + # only authors of a work should be able to edit its chapters + before_action :check_ownership, except: [:index, :show] + before_action :check_visibility, only: [:show] + before_action :load_chapter, only: [:show, :edit, :remove_user_creatorship, :update, :preview, :post, :confirm_delete, :destroy] + + cache_sweeper :feed_sweeper + + # GET /work/:work_id/chapters + # GET /work/:work_id/chapters.xml + def index + # this route is never used + redirect_to work_path(params[:work_id]) + end + + # GET /work/:work_id/chapters/manage + def manage + @chapters = @work.chapters_in_order(include_content: false, + include_drafts: true) + end + + # GET /work/:work_id/chapters/:id + # GET /work/:work_id/chapters/:id.xml + def show + @tag_groups = @work.tag_groups + + redirect_to url_for(controller: :chapters, action: :show, work_id: @work.id, id: params[:selected_id]) and return if params[:selected_id] + + @chapters = @work.chapters_in_order( + include_content: false, + include_drafts: (logged_in_as_admin? || + @work.user_is_owner_or_invited?(current_user)) + ) + + unless @chapters.include?(@chapter) + access_denied + return + end + + chapter_position = @chapters.index(@chapter) + if @chapters.length > 1 + @previous_chapter = @chapters[chapter_position - 1] unless chapter_position.zero? + @next_chapter = @chapters[chapter_position + 1] + end + + if @work.unrevealed? + @page_title = t(".unrevealed") + t(".chapter_position", position: @chapter.position.to_s) + else + fandoms = @tag_groups["Fandom"] + fandom = fandoms.empty? ? t(".unspecified_fandom") : fandoms[0].name + title_fandom = fandoms.size > 3 ? t(".multifandom") : fandom + author = @work.anonymous? ? t(".anonymous") : @work.pseuds.sort.collect(&:byline).join(", ") + @page_title = get_page_title(title_fandom, author, @work.title + t(".chapter_position", position: @chapter.position.to_s)) + end + + if params[:view_adult] + cookies[:view_adult] = "true" + elsif @work.adult? && !see_adult? + render "works/_adult", layout: "application" and return + end + + @kudos = @work.kudos.with_user.includes(:user) + + if current_user.respond_to?(:subscriptions) + @subscription = current_user.subscriptions.where(subscribable_id: @work.id, + subscribable_type: "Work").first || + current_user.subscriptions.build(subscribable: @work) + end + # update the history. + Reading.update_or_create(@work, current_user) if current_user + + respond_to do |format| + format.html + format.js + end + end + + # GET /work/:work_id/chapters/new + # GET /work/:work_id/chapters/new.xml + def new + @chapter = @work.chapters.build(position: @work.number_of_chapters + 1) + end + + # GET /work/:work_id/chapters/1/edit + def edit + end + + def remove_user_creatorship + @chapter.creatorships.for_user(current_user).destroy_all + if @work.chapters.any? { |c| current_user.is_author_of?(c) } + flash[:notice] = ts("You have been removed as a creator from the chapter.") + redirect_to @work and return + end + + # remove from work if no longer co-creator on any chapter + pseuds_with_author_removed = @work.pseuds - current_user.pseuds + + if pseuds_with_author_removed.empty? + redirect_to controller: "orphans", action: "new", work_id: @work.id + else + @work.remove_author(current_user) + flash[:notice] = ts("You have been removed as a creator from the work.") + redirect_to current_user + end + end + + def draft_flash_message(work) + flash[:notice] = work.posted ? t("chapters.draft_flash.posted_work") : t("chapters.draft_flash.unposted_work_html", deletion_date: view_context.date_in_zone(work.created_at + 29.days)).html_safe + end + + # POST /work/:work_id/chapters + # POST /work/:work_id/chapters.xml + def create + if params[:cancel_button] + redirect_back_or_default(root_path) + return + end + + @chapter = @work.chapters.build(chapter_params) + @work.wip_length = params[:chapter][:wip_length] + + if params[:edit_button] || chapter_cannot_be_saved? + render :new + else # :post_without_preview or :preview + @chapter.posted = true if params[:post_without_preview_button] + @work.set_revised_at_by_chapter(@chapter) + if @chapter.save && @work.save + if @chapter.posted + post_chapter + redirect_to [@work, @chapter] + else + draft_flash_message(@work) + redirect_to preview_work_chapter_path(@work, @chapter) + end + else + render :new + end + end + end + + # PUT /work/:work_id/chapters/1 + # PUT /work/:work_id/chapters/1.xml + def update + if params[:cancel_button] + # Not quite working yet - should send the user back to wherever they were before they hit edit + redirect_back_or_default(root_path) + return + end + + @chapter.attributes = chapter_params + @work.wip_length = params[:chapter][:wip_length] + + if params[:edit_button] || chapter_cannot_be_saved? + render :edit + elsif params[:preview_button] + @preview_mode = true + if @chapter.posted? + flash[:notice] = ts("This is a preview of what this chapter will look like after your changes have been applied. You should probably read the whole thing to check for problems before posting.") + else + draft_flash_message(@work) + end + render :preview + else + @chapter.posted = true if params[:post_button] || params[:post_without_preview_button] + posted_changed = @chapter.posted_changed? + @work.set_revised_at_by_chapter(@chapter) + if @chapter.save && @work.save + flash[:notice] = ts("Chapter was successfully #{posted_changed ? 'posted' : 'updated'}.") + redirect_to work_chapter_path(@work, @chapter) + else + render :edit + end + end + end + + def update_positions + if params[:chapters] + @work.reorder_list(params[:chapters]) + flash[:notice] = ts("Chapter order has been successfully updated.") + elsif params[:chapter] + params[:chapter].each_with_index do |id, position| + @work.chapters.update(id, position: position + 1) + (@chapters ||= []) << Chapter.find(id) + end + end + respond_to do |format| + format.html { redirect_to(@work) and return } + format.js { head :ok } + end + end + + # GET /chapters/1/preview + def preview + @preview_mode = true + end + + # POST /chapters/1/post + def post + if params[:cancel_button] + redirect_to @work + elsif params[:edit_button] + redirect_to [:edit, @work, @chapter] + else + @chapter.posted = true + @work.set_revised_at_by_chapter(@chapter) + if @chapter.save && @work.save + post_chapter + redirect_to(@work) + else + render :preview + end + end + end + + # GET /work/:work_id/chapters/1/confirm_delete + def confirm_delete + end + + # DELETE /work/:work_id/chapters/1 + # DELETE /work/:work_id/chapters/1.xml + def destroy + if @chapter.is_only_chapter? || @chapter.only_non_draft_chapter? + flash[:error] = t(".only_chapter") + redirect_to(edit_work_path(@work)) + return + end + + was_draft = !@chapter.posted? + if @chapter.destroy + @work.minor_version = @work.minor_version + 1 unless was_draft + @work.set_revised_at + @work.save + flash[:notice] = ts("The chapter #{was_draft ? 'draft ' : ''}was successfully deleted.") + else + flash[:error] = ts("Something went wrong. Please try again.") + end + redirect_to controller: "works", action: "show", id: @work + end + + private + + # Check whether we should display :new or :edit instead of previewing or + # saving the user's changes. + def chapter_cannot_be_saved? + # The chapter can only be saved if the work can be saved: + if @work.invalid? + @work.errors.full_messages.each do |message| + @chapter.errors.add(:base, message) + end + end + + @chapter.errors.any? || @chapter.invalid? + end + + # fetch work these chapters belong to from db + def load_work + @work = params[:work_id] ? Work.find_by(id: params[:work_id]) : Chapter.find_by(id: params[:id]).try(:work) + if @work.blank? + flash[:error] = ts("Sorry, we couldn't find the work you were looking for.") + redirect_to root_path and return + end + @check_ownership_of = @work + @check_visibility_of = @work + end + + # Loads the specified chapter from the database. Redirects to the work if no + # chapter is specified, or if the specified chapter doesn't exist. + def load_chapter + @chapter = @work.chapters.find_by(id: params[:id]) + + return if @chapter + + flash[:error] = ts("Sorry, we couldn't find the chapter you were looking for.") + redirect_to work_path(@work) + end + + def post_chapter + @work.update_attribute(:posted, true) unless @work.posted + flash[:notice] = ts("Chapter has been posted!") + end + + private + + def chapter_params + params.require(:chapter).permit(:title, :position, :wip_length, :"published_at(3i)", + :"published_at(2i)", :"published_at(1i)", :summary, + :notes, :endnotes, :content, :published_at, + author_attributes: [:byline, ids: [], coauthors: []]) + end +end diff --git a/app/controllers/collection_items_controller.rb b/app/controllers/collection_items_controller.rb new file mode 100755 index 0000000..1dbafd8 --- /dev/null +++ b/app/controllers/collection_items_controller.rb @@ -0,0 +1,229 @@ +class CollectionItemsController < ApplicationController + before_action :load_collection + before_action :load_user, only: [:update_multiple] + before_action :load_collectible_item, only: [:new, :create] + before_action :check_parent_visible, only: [:new] + before_action :users_only, only: [:new] + + cache_sweeper :collection_sweeper + + def index + + # TODO: AO3-6507 Refactor to use send instead of case statements. + if @collection && @collection.user_is_maintainer?(current_user) + @collection_items = @collection.collection_items.include_for_works + @collection_items = case params[:status] + when "approved" + @collection_items.approved_by_both + when "rejected_by_collection" + @collection_items.rejected_by_collection + when "rejected_by_user" + @collection_items.rejected_by_user + when "unreviewed_by_user" + @collection_items.invited_by_collection + else + @collection_items.unreviewed_by_collection + end + elsif params[:user_id] && (@user = User.find_by(login: params[:user_id])) && @user == current_user + @collection_items = CollectionItem.for_user(@user).includes(:collection).merge(Collection.with_attached_icon) + @collection_items = case params[:status] + when "approved" + @collection_items.approved_by_both + when "rejected_by_collection" + @collection_items.rejected_by_collection + when "rejected_by_user" + @collection_items.rejected_by_user + when "unreviewed_by_collection" + @collection_items.approved_by_user.unreviewed_by_collection + else + @collection_items.unreviewed_by_user + end + else + flash[:error] = ts("You don't have permission to see that, sorry!") + redirect_to collections_path and return + end + + sort = "created_at DESC" + @collection_items = @collection_items.order(sort).paginate page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE + end + + def load_collectible_item + if params[:work_id] + @item = Work.find(params[:work_id]) + elsif params[:bookmark_id] + @item = Bookmark.find(params[:bookmark_id]) + end + end + + def check_parent_visible + check_visibility_for(@item) + end + + def load_user + unless @collection + @user = User.find_by(login: params[:user_id]) + end + end + + def new + end + + def create + unless params[:collection_names] + flash[:error] = ts("What collections did you want to add?") + redirect_to(request.env["HTTP_REFERER"] || root_path) and return + end + unless @item + flash[:error] = ts("What did you want to add to a collection?") + redirect_to(request.env["HTTP_REFERER"] || root_path) and return + end + if !current_user.archivist && @item.respond_to?(:allow_collection_invitation?) && !@item.allow_collection_invitation? + flash[:error] = t(".invitation_not_sent", default: "This item could not be invited.") + redirect_to(@item) and return + end + # for each collection name + # see if it exists, is open, and isn't already one of this item's collections + # add the collection and save + # if there are errors, add them to errors + new_collections = [] + invited_collections = [] + unapproved_collections = [] + errors = [] + params[:collection_names].split(',').map {|name| name.strip}.uniq.each do |collection_name| + collection = Collection.find_by(name: collection_name) + if !collection + errors << ts("%{name}, because we couldn't find a collection with that name. Make sure you are using the one-word name, and not the title.", name: collection_name) + elsif @item.collections.include?(collection) + if @item.rejected_collections.include?(collection) + errors << ts("%{collection_title}, because the %{object_type}'s owner has rejected the invitation.", collection_title: collection.title, object_type: @item.class.name.humanize.downcase) + else + errors << ts("%{collection_title}, because this item has already been submitted.", collection_title: collection.title) + end + elsif collection.closed? && !collection.user_is_maintainer?(User.current_user) + errors << ts("%{collection_title} is closed to new submissions.", collection_title: collection.title) + elsif (collection.anonymous? || collection.unrevealed?) && !current_user.is_author_of?(@item) + errors << ts("%{collection_title}, because you don't own this item and the collection is anonymous or unrevealed.", collection_title: collection.title) + elsif !current_user.is_author_of?(@item) && !collection.user_is_maintainer?(current_user) + errors << ts("%{collection_title}, either you don't own this item or are not a moderator of the collection.", collection_title: collection.title) + elsif @item.is_a?(Work) && @item.anonymous? && !current_user.is_author_of?(@item) + errors << ts("%{collection_title}, because you don't own this item and the item is anonymous.", collection_title: collection.title) + # add the work to a collection, and try to save it + elsif @item.add_to_collection(collection) && @item.save(validate: false) + # approved_by_user? and approved_by_collection? are both true. + # This is will be true for archivists adding works to collections they maintain + # or creators adding their works to a collection with auto-approval. + if @item.approved_collections.include?(collection) + new_collections << collection + # if the current_user is a maintainer of the collection then approved_by_user must have been false (which means + # the current_user isn't the owner of the item), then the maintainer is attempting to invite this work to + # their collection + elsif collection.user_is_maintainer?(current_user) + invited_collections << collection + # otherwise the current_user is the owner of the item and approved_by_COLLECTION was false (which means the + # current_user isn't a collection_maintainer), so the item owner is attempting to add their work to a moderated + # collection + else + unapproved_collections << collection + end + else + errors << ts("Something went wrong trying to add collection %{name}, sorry!", name: collection_name) + end + end + + # messages to the user + unless errors.empty? + flash[:error] = ts("We couldn't add your submission to the following collection(s): ") + "
" + end + flash[:notice] = "" unless new_collections.empty? && unapproved_collections.empty? + unless new_collections.empty? + flash[:notice] = ts("Added to collection(s): %{collections}.", + collections: new_collections.collect(&:title).join(", ")) + end + unless invited_collections.empty? + invited_collections.each do |needs_user_approval| + flash[:notice] ||= "" + flash[:notice] = t(".invited_to_collections_html", + invited_link: view_context.link_to(t(".invited"), + collection_items_path(needs_user_approval, status: :unreviewed_by_user)), + collection_title: needs_user_approval.title) + end + end + unless unapproved_collections.empty? + flash[:notice] ||= "" + flash[:notice] += ts(" You have submitted your work to #{unapproved_collections.size > 1 ? "moderated collections (%{all_collections}). It will not become a part of those collections" : "the moderated collection '%{all_collections}'. It will not become a part of the collection"} until it has been approved by a moderator.", all_collections: unapproved_collections.map { |f| f.title }.join(', ')) + end + + flash[:notice] = (flash[:notice]).html_safe unless flash[:notice].blank? + flash[:error] = (flash[:error]).html_safe unless flash[:error].blank? + + redirect_to(@item) + end + + def update_multiple + if @collection&.user_is_maintainer?(current_user) + update_multiple_with_params( + allowed_items: @collection.collection_items, + update_params: collection_update_multiple_params, + success_path: collection_items_path(@collection) + ) + elsif @user && @user == current_user + update_multiple_with_params( + allowed_items: CollectionItem.for_user(@user), + update_params: user_update_multiple_params, + success_path: user_collection_items_path(@user) + ) + else + flash[:error] = ts("You don't have permission to do that, sorry!") + redirect_to(@collection || @user) + end + end + + # The main work performed by update_multiple. Uses the passed-in parameters + # to update, and only updates items that can be found in allowed_items (which + # should be a relation on CollectionItems). When all items are successfully + # updated, redirects to success_path. + def update_multiple_with_params(allowed_items:, update_params:, success_path:) + # Collect any failures so that we can display errors: + @collection_items = [] + + # Make sure that the keys are integers so that we can look up the + # parameters by ID. + update_params.transform_keys!(&:to_i) + + # By using where() here and updating each item individually, instead of + # using allowed_items.update(update_params.keys, update_params.values) -- + # which uses find() under the hood -- we ensure that we'll fail silently if + # the user tries to update an item they're not allowed to. + allowed_items.where(id: update_params.keys).each do |item| + item_data = update_params[item.id] + if item_data[:remove] == "1" + next unless item.user_allowed_to_destroy?(current_user) + + @collection_items << item unless item.destroy + else + @collection_items << item unless item.update(item_data) + end + end + + if @collection_items.empty? + flash[:notice] = ts("Collection status updated!") + redirect_to success_path + else + render action: "index" + end + end + + private + + def user_update_multiple_params + allowed = %i[user_approval_status remove] + params.slice(:collection_items).permit(collection_items: allowed). + require(:collection_items) + end + + def collection_update_multiple_params + allowed = %i[collection_approval_status unrevealed anonymous remove] + params.slice(:collection_items).permit(collection_items: allowed). + require(:collection_items) + end +end diff --git a/app/controllers/collection_participants_controller.rb b/app/controllers/collection_participants_controller.rb new file mode 100755 index 0000000..ed336ee --- /dev/null +++ b/app/controllers/collection_participants_controller.rb @@ -0,0 +1,135 @@ +class CollectionParticipantsController < ApplicationController + before_action :users_only + before_action :load_collection + before_action :load_participant, only: [:update, :destroy] + before_action :allowed_to_promote, only: [:update] + before_action :allowed_to_destroy, only: [:destroy] + before_action :has_other_owners, only: [:update, :destroy] + before_action :collection_maintainers_only, only: [:index, :add, :update] + + cache_sweeper :collection_sweeper + + def owners_required + flash[:error] = t("collection_participants.validation.owners_required") + redirect_to collection_participants_path(@collection) + false + end + + def load_collection + @collection = Collection.find_by!(name: params[:collection_id]) + end + + def load_participant + @participant = @collection.collection_participants.find(params[:id]) + end + + def allowed_to_promote + @new_role = collection_participant_params[:participant_role] + @participant.user_allowed_to_promote?(current_user, @new_role) || not_allowed(@collection) + end + + def allowed_to_destroy + @participant.user_allowed_to_destroy?(current_user) || not_allowed(@collection) + end + + def has_other_owners + !@participant.is_owner? || (@collection.owners != [@participant.pseud]) || owners_required + end + + ## ACTIONS + + def join + unless @collection + flash[:error] = t('no_collection', default: "Which collection did you want to join?") + redirect_to(request.env["HTTP_REFERER"] || root_path) and return + end + participants = CollectionParticipant.in_collection(@collection).for_user(current_user) unless current_user.nil? + if participants.empty? + @participant = CollectionParticipant.new( + collection: @collection, + pseud: current_user.default_pseud, + participant_role: CollectionParticipant::NONE + ) + @participant.save + flash[:notice] = t('applied_to_join_collection', default: "You have applied to join %{collection}.", collection: @collection.title) + else + participants.each do |participant| + if participant.is_invited? + participant.approve_membership! + flash[:notice] = t('collection_participants.accepted_invite', default: "You are now a member of %{collection}.", collection: @collection.title) + redirect_to(request.env["HTTP_REFERER"] || root_path) and return + end + end + + flash[:notice] = t('collection_participants.no_invitation', default: "You have already joined (or applied to) this collection.") + end + + redirect_to(request.env["HTTP_REFERER"] || root_path) + end + + def index + @collection_participants = @collection.collection_participants.reject {|p| p.pseud.nil?}.sort_by {|participant| participant.pseud.name.downcase } + end + + def update + if @participant.update(collection_participant_params) + flash[:notice] = t('collection_participants.update_success', default: "Updated %{participant}.", participant: @participant.pseud.name) + else + flash[:error] = t(".failure", participant: @participant.pseud.name) + end + redirect_to collection_participants_path(@collection) + end + + def destroy + @participant.destroy + flash[:notice] = t('collection_participants.destroy', default: "Removed %{participant} from collection.", participant: @participant.pseud.name) + redirect_to(request.env["HTTP_REFERER"] || root_path) + end + + def add + @participants_added = [] + @participants_invited = [] + pseud_results = Pseud.parse_bylines(params[:participants_to_invite]) + pseud_results[:pseuds].each do |pseud| + if @collection.participants.include?(pseud) + participant = CollectionParticipant.where(collection_id: @collection.id, pseud_id: pseud.id).first + if participant && participant.is_none? + @participants_added << participant if participant.approve_membership! + end + else + participant = CollectionParticipant.new(collection: @collection, pseud: pseud, participant_role: CollectionParticipant::MEMBER) + @participants_invited << participant if participant.save + end + end + + if @participants_invited.empty? && @participants_added.empty? + if pseud_results[:banned_pseuds].present? + flash[:error] = ts("%{name} cannot participate in challenges.", + name: pseud_results[:banned_pseuds].to_sentence + ) + else + flash[:error] = ts("We couldn't find anyone new by that name to add.") + end + else + flash[:notice] = "" + end + + unless @participants_invited.empty? + @participants_invited = @participants_invited.sort_by {|participant| participant.pseud.name.downcase } + flash[:notice] += ts("New members invited: ") + @participants_invited.collect(&:pseud).collect(&:byline).join(', ') + end + + unless @participants_added.empty? + @participants_added = @participants_added.sort_by {|participant| participant.pseud.name.downcase } + flash[:notice] += ts("Members added: ") + @participants_added.collect(&:pseud).collect(&:byline).join(', ') + end + + redirect_to collection_participants_path(@collection) + end + + private + + def collection_participant_params + params.require(:collection_participant).permit(:participant_role) + end +end diff --git a/app/controllers/collection_profile_controller.rb b/app/controllers/collection_profile_controller.rb new file mode 100755 index 0000000..2f50993 --- /dev/null +++ b/app/controllers/collection_profile_controller.rb @@ -0,0 +1,13 @@ +class CollectionProfileController < ApplicationController + + before_action :load_collection + + def show + unless @collection + flash[:error] = "What collection did you want to look at?" + redirect_to collections_path and return + end + @page_subtitle = t(".page_title", collection_title: @collection.title) + end + +end diff --git a/app/controllers/collections_controller.rb b/app/controllers/collections_controller.rb new file mode 100755 index 0000000..51d75d7 --- /dev/null +++ b/app/controllers/collections_controller.rb @@ -0,0 +1,214 @@ +class CollectionsController < ApplicationController + before_action :users_only, only: [:new, :edit, :create, :update] + before_action :load_collection_from_id, only: [:show, :edit, :update, :destroy, :confirm_delete] + before_action :collection_owners_only, only: [:edit, :update, :destroy, :confirm_delete] + before_action :check_user_status, only: [:new, :create, :edit, :update, :destroy] + before_action :validate_challenge_type + before_action :check_parent_visible, only: [:index] + cache_sweeper :collection_sweeper + + # Lazy fix to prevent passing unsafe values to eval via challenge_type + # In both CollectionsController#create and CollectionsController#update there are a vulnerable usages of eval + # For now just make sure the values passed to it are safe + def validate_challenge_type + if params[:challenge_type] and not ["", "GiftExchange", "PromptMeme"].include?(params[:challenge_type]) + return render status: :bad_request, text: "invalid challenge_type" + end + end + + def load_collection_from_id + @collection = Collection.find_by(name: params[:id]) + unless @collection + raise ActiveRecord::RecordNotFound, "Couldn't find collection named '#{params[:id]}'" + end + end + + def check_parent_visible + return unless params[:work_id] && (@work = Work.find_by(id: params[:work_id])) + + check_visibility_for(@work) + end + + def index + if params[:work_id] + @work = Work.find(params[:work_id]) + @collections = @work.approved_collections + .by_title + .for_blurb + .paginate(page: params[:page]) + elsif params[:collection_id] + @collection = Collection.find_by!(name: params[:collection_id]) + @collections = @collection.children + .by_title + .for_blurb + .paginate(page: params[:page]) + @page_subtitle = t(".subcollections_page_title", collection_title: @collection.title) + elsif params[:user_id] + @user = User.find_by!(login: params[:user_id]) + @collections = @user.maintained_collections + .by_title + .for_blurb + .paginate(page: params[:page]) + @page_subtitle = ts("%{username} - Collections", username: @user.login) + else + @sort_and_filter = true + params[:collection_filters] ||= {} + params[:sort_column] = "collections.created_at" if !valid_sort_column(params[:sort_column], 'collection') + params[:sort_direction] = 'DESC' if !valid_sort_direction(params[:sort_direction]) + sort = params[:sort_column] + " " + params[:sort_direction] + @collections = Collection.sorted_and_filtered(sort, params[:collection_filters], params[:page]) + end + end + + # display challenges that are currently taking signups + def list_challenges + @page_subtitle = "Open Challenges" + @hide_dashboard = true + @challenge_collections = (Collection.signup_open("GiftExchange").limit(15) + Collection.signup_open("PromptMeme").limit(15)) + end + + def list_ge_challenges + @page_subtitle = "Open Gift Exchange Challenges" + @challenge_collections = Collection.signup_open("GiftExchange").limit(15) + end + + def list_pm_challenges + @page_subtitle = "Open Prompt Meme Challenges" + @challenge_collections = Collection.signup_open("PromptMeme").limit(15) + end + + def show + @page_subtitle = @collection.title + + if @collection.collection_preference.show_random? || params[:show_random] + # show a random selection of works/bookmarks + @works = WorkQuery.new( + collection_ids: [@collection.id], show_restricted: is_registered_user? + ).sample(count: ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) + + @bookmarks = BookmarkQuery.new( + collection_ids: [@collection.id], show_restricted: is_registered_user? + ).sample(count: ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) + else + # show recent + @works = WorkQuery.new( + collection_ids: [@collection.id], show_restricted: is_registered_user?, + sort_column: "revised_at", + per_page: ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD + ).search_results + + @bookmarks = BookmarkQuery.new( + collection_ids: [@collection.id], show_restricted: is_registered_user?, + sort_column: "created_at", + per_page: ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD + ).search_results + end + end + + def new + @hide_dashboard = true + @collection = Collection.new + if params[:collection_id] && (@collection_parent = Collection.find_by(name: params[:collection_id])) + @collection.parent_name = @collection_parent.name + end + end + + def edit + end + + def create + @hide_dashboard = true + @collection = Collection.new(collection_params) + + # add the owner + owner_attributes = [] + (params[:owner_pseuds] || [current_user.default_pseud_id]).each do |pseud_id| + pseud = Pseud.find(pseud_id) + owner_attributes << {pseud: pseud, participant_role: CollectionParticipant::OWNER} if pseud + end + @collection.collection_participants.build(owner_attributes) + + if @collection.save + flash[:notice] = ts('Collection was successfully created.') + unless params[:challenge_type].blank? + if params[:challenge_type] == "PromptMeme" + redirect_to new_collection_prompt_meme_path(@collection) and return + elsif params[:challenge_type] == "GiftExchange" + redirect_to new_collection_gift_exchange_path(@collection) and return + end + else + redirect_to collection_path(@collection) + end + else + @challenge_type = params[:challenge_type] + render action: "new" + end + end + + def update + if @collection.update(collection_params) + flash[:notice] = ts('Collection was successfully updated.') + if params[:challenge_type].blank? + if @collection.challenge + # trying to destroy an existing challenge + flash[:error] = ts("Note: if you want to delete an existing challenge, please do so on the challenge page.") + end + else + if @collection.challenge + if @collection.challenge.class.name != params[:challenge_type] + flash[:error] = ts("Note: if you want to change the type of challenge, first please delete the existing challenge on the challenge page.") + else + if params[:challenge_type] == "PromptMeme" + redirect_to edit_collection_prompt_meme_path(@collection) and return + elsif params[:challenge_type] == "GiftExchange" + redirect_to edit_collection_gift_exchange_path(@collection) and return + end + end + else + if params[:challenge_type] == "PromptMeme" + redirect_to new_collection_prompt_meme_path(@collection) and return + elsif params[:challenge_type] == "GiftExchange" + redirect_to new_collection_gift_exchange_path(@collection) and return + end + end + end + redirect_to collection_path(@collection) + else + render action: "edit" + end + end + + def confirm_delete + end + + def destroy + @hide_dashboard = true + @collection = Collection.find_by(name: params[:id]) + begin + @collection.destroy + flash[:notice] = ts("Collection was successfully deleted.") + rescue + flash[:error] = ts("We couldn't delete that right now, sorry! Please try again later.") + end + redirect_to(collections_path) + end + + private + + def collection_params + params.require(:collection).permit( + :name, :title, :email, :header_image_url, :description, + :parent_name, :challenge_type, :icon, :delete_icon, + :icon_alt_text, :icon_comment_text, + collection_profile_attributes: [ + :id, :intro, :faq, :rules, + :gift_notification, :assignment_notification + ], + collection_preference_attributes: [ + :id, :moderated, :closed, :unrevealed, :anonymous, + :gift_exchange, :show_random, :prompt_meme, :email_notify + ] + ) + end + +end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb new file mode 100755 index 0000000..d863da4 --- /dev/null +++ b/app/controllers/comments_controller.rb @@ -0,0 +1,700 @@ +class CommentsController < ApplicationController + skip_before_action :store_location, except: [:show, :index, :new] + before_action :load_commentable, + only: [:index, :new, :create, :edit, :update, :show_comments, + :hide_comments, :add_comment_reply, + :cancel_comment_reply, :delete_comment, + :cancel_comment_delete, :unreviewed, :review_all] + before_action :check_user_status, only: [:new, :create, :edit, :update, :destroy] + before_action :load_comment, only: [:show, :edit, :update, :delete_comment, :destroy, :cancel_comment_edit, :cancel_comment_delete, :review, :approve, :reject, :freeze, :unfreeze, :hide, :unhide] + before_action :check_visibility, only: [:show] + before_action :check_if_restricted + before_action :check_tag_wrangler_access + before_action :check_parent_visible + before_action :check_modify_parent, + only: [:new, :create, :edit, :update, :add_comment_reply, + :cancel_comment_reply, :cancel_comment_edit] + before_action :check_pseud_ownership, only: [:create, :update] + before_action :check_ownership, only: [:edit, :update, :cancel_comment_edit] + before_action :check_permission_to_edit, only: [:edit, :update ] + before_action :check_permission_to_delete, only: [:delete_comment, :destroy] + before_action :check_guest_comment_admin_setting, only: [:new, :create, :add_comment_reply] + before_action :check_parent_comment_permissions, only: [:new, :create, :add_comment_reply] + before_action :check_unreviewed, only: [:add_comment_reply] + before_action :check_frozen, only: [:new, :create, :add_comment_reply] + before_action :check_hidden_by_admin, only: [:new, :create, :add_comment_reply] + before_action :check_not_replying_to_spam, only: [:new, :create, :add_comment_reply] + before_action :check_guest_replies_preference, only: [:new, :create, :add_comment_reply] + before_action :check_permission_to_review, only: [:unreviewed] + before_action :check_permission_to_access_single_unreviewed, only: [:show] + before_action :check_permission_to_moderate, only: [:approve, :reject] + before_action :check_permission_to_modify_frozen_status, only: [:freeze, :unfreeze] + before_action :check_permission_to_modify_hidden_status, only: [:hide, :unhide] + before_action :admin_logout_required, only: [:new, :create, :add_comment_reply] + + include BlockHelper + + before_action :check_blocked, only: [:new, :create, :add_comment_reply, :edit, :update] + def check_blocked + parent = find_parent + + if blocked_by?(parent) + flash[:comment_error] = t("comments.check_blocked.parent") + redirect_to_all_comments(parent, show_comments: true) + elsif @comment && blocked_by_comment?(@comment.commentable) + # edit and update set @comment to the comment being edited + flash[:comment_error] = t("comments.check_blocked.reply") + redirect_to_all_comments(parent, show_comments: true) + elsif @comment.nil? && blocked_by_comment?(@commentable) + # new, create, and add_comment_reply don't set @comment, but do set @commentable + flash[:comment_error] = t("comments.check_blocked.reply") + redirect_to_all_comments(parent, show_comments: true) + end + end + + def check_pseud_ownership + return unless params[:comment][:pseud_id] + pseud = Pseud.find(params[:comment][:pseud_id]) + return if pseud && current_user && current_user.pseuds.include?(pseud) + flash[:error] = ts("You can't comment with that pseud.") + redirect_to root_path + end + + def load_comment + @comment = Comment.find(params[:id]) + @check_ownership_of = @comment + @check_visibility_of = @comment + end + + def check_parent_visible + check_visibility_for(find_parent) + end + + def check_modify_parent + parent = find_parent + # No one can create or update comments on something hidden by an admin. + if parent.respond_to?(:hidden_by_admin) && parent.hidden_by_admin + flash[:error] = ts("Sorry, you can't add or edit comments on a hidden work.") + redirect_to work_path(parent) + end + # No one can create or update comments on unrevealed works. + if parent.respond_to?(:in_unrevealed_collection) && parent.in_unrevealed_collection + flash[:error] = ts("Sorry, you can't add or edit comments on an unrevealed work.") + redirect_to work_path(parent) + end + end + + def find_parent + if @comment.present? + @comment.ultimate_parent + elsif @commentable.is_a?(Comment) + @commentable.ultimate_parent + elsif @commentable.present? && @commentable.respond_to?(:work) + @commentable.work + else + @commentable + end + end + + # Check to see if the ultimate_parent is a Work, and if so, if it's restricted + def check_if_restricted + parent = find_parent + + return unless parent.respond_to?(:restricted) && parent.restricted? && !(logged_in? || logged_in_as_admin?) + redirect_to new_user_session_path(restricted_commenting: true) + end + + # Check to see if the ultimate_parent is a Work or AdminPost, and if so, if it allows + # comments for the current user. + def check_parent_comment_permissions + parent = find_parent + if parent.is_a?(Work) + translation_key = "work" + elsif parent.is_a?(AdminPost) + translation_key = "admin_post" + else + return + end + + if parent.disable_all_comments? + flash[:error] = t("comments.commentable.permissions.#{translation_key}.disable_all") + redirect_to parent + elsif parent.disable_anon_comments? && !logged_in? + flash[:error] = t("comments.commentable.permissions.#{translation_key}.disable_anon") + redirect_to parent + end + end + + def check_guest_comment_admin_setting + admin_settings = AdminSetting.current + + return unless admin_settings.guest_comments_off? && guest? + + flash[:error] = t("comments.commentable.guest_comments_disabled") + redirect_back(fallback_location: root_path) + end + + def check_guest_replies_preference + return unless guest? && @commentable.respond_to?(:guest_replies_disallowed?) && @commentable.guest_replies_disallowed? + + flash[:error] = t("comments.check_guest_replies_preference.error") + redirect_back(fallback_location: root_path) + end + + def check_unreviewed + return unless @commentable.respond_to?(:unreviewed?) && @commentable.unreviewed? + + flash[:error] = ts("Sorry, you cannot reply to an unapproved comment.") + redirect_to logged_in? ? root_path : new_user_session_path + end + + def check_frozen + return unless @commentable.respond_to?(:iced?) && @commentable.iced? + + flash[:error] = t("comments.check_frozen.error") + redirect_back(fallback_location: root_path) + end + + def check_hidden_by_admin + return unless @commentable.respond_to?(:hidden_by_admin?) && @commentable.hidden_by_admin? + + flash[:error] = t("comments.check_hidden_by_admin.error") + redirect_back(fallback_location: root_path) + end + + def check_not_replying_to_spam + return unless @commentable.respond_to?(:approved?) && !@commentable.approved? + + flash[:error] = t("comments.check_not_replying_to_spam.error") + redirect_back(fallback_location: root_path) + end + + def check_permission_to_review + parent = find_parent + return if logged_in_as_admin? || current_user_owns?(parent) + flash[:error] = ts("Sorry, you don't have permission to see those unreviewed comments.") + redirect_to logged_in? ? root_path : new_user_session_path + end + + def check_permission_to_access_single_unreviewed + return unless @comment.unreviewed? + parent = find_parent + return if logged_in_as_admin? || current_user_owns?(parent) || current_user_owns?(@comment) + flash[:error] = ts("Sorry, that comment is currently in moderation.") + redirect_to logged_in? ? root_path : new_user_session_path + end + + def check_permission_to_moderate + parent = find_parent + unless logged_in_as_admin? || current_user_owns?(parent) + flash[:error] = ts("Sorry, you don't have permission to moderate that comment.") + redirect_to(logged_in? ? root_path : new_user_session_path) + end + end + + def check_tag_wrangler_access + if @commentable.is_a?(Tag) || (@comment&.parent&.is_a?(Tag)) + logged_in_as_admin? || permit?("tag_wrangler") || access_denied + end + end + + # Must be able to delete other people's comments on owned works, not just owned comments! + def check_permission_to_delete + access_denied(redirect: @comment) unless logged_in_as_admin? || current_user_owns?(@comment) || current_user_owns?(@comment.ultimate_parent) + end + + # Comments cannot be edited after they've been replied to or if they are frozen. + def check_permission_to_edit + if @comment&.iced? + flash[:error] = t("comments.check_permission_to_edit.error.frozen") + redirect_back(fallback_location: root_path) + elsif !@comment&.count_all_comments&.zero? + flash[:error] = ts("Comments with replies cannot be edited") + redirect_back(fallback_location: root_path) + end + end + + # Comments on works can be frozen or unfrozen by admins with proper + # authorization or the work creator. + # Comments on tags can be frozen or unfrozen by admins with proper + # authorization. + # Comments on admin posts can be frozen or unfrozen by any admin. + def check_permission_to_modify_frozen_status + return if permission_to_modify_frozen_status + + # i18n-tasks-use t('comments.freeze.permission_denied') + # i18n-tasks-use t('comments.unfreeze.permission_denied') + flash[:error] = t("comments.#{action_name}.permission_denied") + redirect_back(fallback_location: root_path) + end + + def check_permission_to_modify_hidden_status + return if policy(@comment).can_hide_comment? + + # i18n-tasks-use t('comments.hide.permission_denied') + # i18n-tasks-use t('comments.unhide.permission_denied') + flash[:error] = t("comments.#{action_name}.permission_denied") + redirect_back(fallback_location: root_path) + end + + # Get the thing the user is trying to comment on + def load_commentable + @thread_view = false + if params[:comment_id] + @thread_view = true + if params[:id] + @commentable = Comment.find(params[:id]) + @thread_root = Comment.find(params[:comment_id]) + else + @commentable = Comment.find(params[:comment_id]) + @thread_root = @commentable + end + elsif params[:chapter_id] + @commentable = Chapter.find(params[:chapter_id]) + elsif params[:work_id] + @commentable = Work.find(params[:work_id]) + elsif params[:admin_post_id] + @commentable = AdminPost.find(params[:admin_post_id]) + elsif params[:tag_id] + @commentable = Tag.find_by_name(params[:tag_id]) + @page_subtitle = @commentable.try(:name) + end + end + + def index + return raise_not_found if @commentable.blank? + + return unless @commentable.class == Comment + + # we link to the parent object at the top + @commentable = @commentable.ultimate_parent + end + + def unreviewed + @comments = @commentable.find_all_comments + .unreviewed_only + .for_display + .page(params[:page]) + end + + # GET /comments/1 + # GET /comments/1.xml + def show + @comments = CommentDecorator.wrap_comments([@comment]) + @thread_view = true + @thread_root = @comment + params[:comment_id] = params[:id] + end + + # GET /comments/new + def new + if @commentable.nil? + flash[:error] = ts("What did you want to comment on?") + redirect_back_or_default(root_path) + else + @comment = Comment.new + @controller_name = params[:controller_name] if params[:controller_name] + @name = + case @commentable.class.name + when /Work/ + @commentable.title + when /Chapter/ + @commentable.work.title + when /Tag/ + @commentable.name + when /AdminPost/ + @commentable.title + when /Comment/ + ts("Previous Comment") + else + @commentable.class.name + end + end + end + + # GET /comments/1/edit + def edit + respond_to do |format| + format.html + format.js + end + end + + # POST /comments + # POST /comments.xml + def create + if @commentable.nil? + flash[:error] = ts("What did you want to comment on?") + redirect_back_or_default(root_path) + else + @comment = Comment.new(comment_params) + @comment.ip_address = request.remote_ip + @comment.user_agent = request.env["HTTP_USER_AGENT"]&.to(499) + @comment.commentable = Comment.commentable_object(@commentable) + @controller_name = params[:controller_name] + + # First, try saving the comment + if @comment.save + flash[:comment_notice] = if @comment.unreviewed? + # i18n-tasks-use t("comments.create.success.moderated.admin_post") + # i18n-tasks-use t("comments.create.success.moderated.work") + t("comments.create.success.moderated.#{@comment.ultimate_parent.model_name.i18n_key}") + else + t("comments.create.success.not_moderated") + end + respond_to do |format| + format.html do + if request.referer&.match(/inbox/) + redirect_to user_inbox_path(current_user, filters: filter_params[:filters], page: params[:page]) + elsif request.referer&.match(/new/) || (@comment.unreviewed? && current_user) + # If the referer is the new comment page, go to the comment's page + # instead of reloading the full work. + # If the comment is unreviewed and commenter is logged in, take + # them to the comment's page so they can access the edit and + # delete options for the comment, since unreviewed comments don't + # appear on the commentable. + redirect_to comment_path(@comment) + elsif request.referer == root_url + # replying on the homepage + redirect_to root_path + elsif @comment.unreviewed? + redirect_to_all_comments(@commentable) + else + redirect_to_comment(@comment, { view_full_work: (params[:view_full_work] == "true"), page: params[:page] }) + end + end + end + else + flash[:error] = ts("Couldn't save comment!") + render action: "new" + end + end + end + + # PUT /comments/1 + # PUT /comments/1.xml + def update + updated_comment_params = comment_params.merge(edited_at: Time.current) + if @comment.update(updated_comment_params) + flash[:comment_notice] = ts('Comment was successfully updated.') + respond_to do |format| + format.html do + redirect_to comment_path(@comment) and return if @comment.unreviewed? + redirect_to_comment(@comment) + end + format.js # updating the comment in place + end + else + render action: "edit" + end + end + + # DELETE /comments/1 + # DELETE /comments/1.xml + def destroy + authorize @comment if logged_in_as_admin? + + parent = @comment.ultimate_parent + parent_comment = @comment.reply_comment? ? @comment.commentable : nil + unreviewed = @comment.unreviewed? + + if !@comment.destroy_or_mark_deleted + # something went wrong? + flash[:comment_error] = ts("We couldn't delete that comment.") + redirect_to_comment(@comment) + elsif unreviewed + # go back to the rest of the unreviewed comments + flash[:notice] = ts("Comment deleted.") + redirect_back(fallback_location: unreviewed_work_comments_path(@comment.commentable)) + elsif parent_comment + flash[:comment_notice] = ts("Comment deleted.") + redirect_to_comment(parent_comment) + else + flash[:comment_notice] = ts("Comment deleted.") + redirect_to_all_comments(parent, {show_comments: true}) + end + end + + def review + if logged_in_as_admin? + authorize @comment + else + return unless current_user_owns?(@comment.ultimate_parent) + end + + return unless @comment&.unreviewed? + + @comment.toggle!(:unreviewed) + # mark associated inbox comments as read + InboxComment.where(user_id: current_user.id, feedback_comment_id: @comment.id).update_all(read: true) unless logged_in_as_admin? + flash[:notice] = ts("Comment approved.") + respond_to do |format| + format.html do + if params[:approved_from] == "inbox" + redirect_to user_inbox_path(current_user, page: params[:page], filters: filter_params[:filters]) + elsif params[:approved_from] == "home" + redirect_to root_path + elsif @comment.ultimate_parent.is_a?(AdminPost) + redirect_to unreviewed_admin_post_comments_path(@comment.ultimate_parent) + else + redirect_to unreviewed_work_comments_path(@comment.ultimate_parent) + end + return + end + format.js + end + end + + def review_all + authorize @commentable, policy_class: CommentPolicy if logged_in_as_admin? + unless (@commentable && current_user_owns?(@commentable)) || (@commentable && logged_in_as_admin? && @commentable.is_a?(AdminPost)) + flash[:error] = ts("What did you want to review comments on?") + redirect_back_or_default(root_path) + return + end + + @comments = @commentable.find_all_comments.unreviewed_only + @comments.each { |c| c.toggle!(:unreviewed) } + flash[:notice] = ts("All moderated comments approved.") + redirect_to @commentable + end + + def approve + authorize @comment + @comment.mark_as_ham! + redirect_to_all_comments(@comment.ultimate_parent, show_comments: true) + end + + def reject + authorize @comment if logged_in_as_admin? + @comment.mark_as_spam! + redirect_to_all_comments(@comment.ultimate_parent, show_comments: true) + end + + # PUT /comments/1/freeze + def freeze + # TODO: When AO3-5939 is fixed, we can use + # comments = @comment.full_set + if @comment.iced? + flash[:comment_error] = t(".error") + else + comments = @comment.set_to_freeze_or_unfreeze + Comment.mark_all_frozen!(comments) + flash[:comment_notice] = t(".success") + end + + redirect_to_all_comments(@comment.ultimate_parent, show_comments: true) + rescue StandardError + flash[:comment_error] = t(".error") + redirect_to_all_comments(@comment.ultimate_parent, show_comments: true) + end + + # PUT /comments/1/unfreeze + def unfreeze + # TODO: When AO3-5939 is fixed, we can use + # comments = @comment.full_set + if @comment.iced? + comments = @comment.set_to_freeze_or_unfreeze + Comment.mark_all_unfrozen!(comments) + flash[:comment_notice] = t(".success") + else + flash[:comment_error] = t(".error") + end + + redirect_to_all_comments(@comment.ultimate_parent, show_comments: true) + rescue StandardError + flash[:comment_error] = t(".error") + redirect_to_all_comments(@comment.ultimate_parent, show_comments: true) + end + + # PUT /comments/1/hide + def hide + if !@comment.hidden_by_admin? + @comment.mark_hidden! + AdminActivity.log_action(current_admin, @comment, action: "hide comment") + flash[:comment_notice] = t(".success") + else + flash[:comment_error] = t(".error") + end + redirect_to_all_comments(@comment.ultimate_parent, show_comments: true) + end + + # PUT /comments/1/unhide + def unhide + if @comment.hidden_by_admin? + @comment.mark_unhidden! + AdminActivity.log_action(current_admin, @comment, action: "unhide comment") + flash[:comment_notice] = t(".success") + else + flash[:comment_error] = t(".error") + end + redirect_to_all_comments(@comment.ultimate_parent, show_comments: true) + end + + def show_comments + respond_to do |format| + format.html do + # if non-ajax it could mean sudden javascript failure OR being redirected from login + # so we're being extra-nice and preserving any intention to comment along with the show comments option + options = {show_comments: true} + options[:add_comment_reply_id] = params[:add_comment_reply_id] if params[:add_comment_reply_id] + options[:view_full_work] = params[:view_full_work] if params[:view_full_work] + options[:page] = params[:page] + redirect_to_all_comments(@commentable, options) + end + + format.js do + @comments = CommentDecorator.for_commentable(@commentable, page: params[:page]) + end + end + end + + def hide_comments + respond_to do |format| + format.html do + redirect_to_all_comments(@commentable) + end + format.js + end + end + + # If JavaScript is enabled, use add_comment_reply.js to load the reply form + # Otherwise, redirect to a comment view with the form already loaded + def add_comment_reply + @comment = Comment.new + respond_to do |format| + format.html do + options = {show_comments: true} + options[:controller] = @commentable.class.to_s.underscore.pluralize + options[:anchor] = "comment_#{params[:id]}" + options[:page] = params[:page] + options[:view_full_work] = params[:view_full_work] + if @thread_view + options[:id] = @thread_root + options[:add_comment_reply_id] = params[:id] + redirect_to_comment(@commentable, options) + else + options[:id] = @commentable.id # work, chapter or other stuff that is not a comment + options[:add_comment_reply_id] = params[:id] + redirect_to_all_comments(@commentable, options) + end + end + format.js { @commentable = Comment.find(params[:id]) } + end + end + + def cancel_comment_reply + respond_to do |format| + format.html do + options = {} + options[:show_comments] = params[:show_comments] if params[:show_comments] + redirect_to_all_comments(@commentable, options) + end + format.js { @commentable = Comment.find(params[:id]) } + end + end + + def cancel_comment_edit + respond_to do |format| + format.html { redirect_to_comment(@comment) } + format.js + end + end + + def delete_comment + respond_to do |format| + format.html do + options = {} + options[:show_comments] = params[:show_comments] if params[:show_comments] + options[:delete_comment_id] = params[:id] if params[:id] + redirect_to_comment(@comment, options) # TO DO: deleting without javascript doesn't work and it never has! + end + format.js + end + end + + def cancel_comment_delete + respond_to do |format| + format.html do + options = {} + options[:show_comments] = params[:show_comments] if params[:show_comments] + redirect_to_comment(@comment, options) + end + format.js + end + end + + protected + + # redirect to a particular comment in a thread, going into the thread + # if necessary to display it + def redirect_to_comment(comment, options = {}) + if comment.depth > ArchiveConfig.COMMENT_THREAD_MAX_DEPTH + if comment.ultimate_parent.is_a?(Tag) + default_options = { + controller: :comments, + action: :show, + id: comment.commentable.id, + tag_id: comment.ultimate_parent.to_param, + anchor: "comment_#{comment.id}" + } + else + default_options = { + controller: comment.commentable.class.to_s.underscore.pluralize, + action: :show, + id: (comment.commentable.is_a?(Tag) ? comment.commentable.to_param : comment.commentable.id), + anchor: "comment_#{comment.id}" + } + end + # display the comment's direct parent (and its associated thread) + redirect_to(url_for(default_options.merge(options))) + else + # need to redirect to the specific chapter; redirect_to_all will then retrieve full work view if applicable + redirect_to_all_comments(comment.parent, options.merge({show_comments: true, anchor: "comment_#{comment.id}"})) + end + end + + def redirect_to_all_comments(commentable, options = {}) + default_options = {anchor: "comments"} + options = default_options.merge(options) + + if commentable.is_a?(Tag) + redirect_to comments_path(tag_id: commentable.to_param, + add_comment_reply_id: options[:add_comment_reply_id], + delete_comment_id: options[:delete_comment_id], + page: options[:page], + anchor: options[:anchor]) + else + if commentable.is_a?(Chapter) && (options[:view_full_work] || current_user.try(:preference).try(:view_full_works)) + commentable = commentable.work + end + redirect_to polymorphic_path(commentable, + options.slice(:show_comments, + :add_comment_reply_id, + :delete_comment_id, + :view_full_work, + :anchor, + :page)) + end + end + + def permission_to_modify_frozen_status + parent = find_parent + return true if policy(@comment).can_freeze_comment? + return true if parent.is_a?(Work) && current_user_owns?(parent) + + false + end + + private + + def comment_params + params.require(:comment).permit( + :pseud_id, :comment_content, :name, :email, :edited_at + ) + end + + def filter_params + params.permit! + end +end diff --git a/app/controllers/concerns/tag_wrangling.rb b/app/controllers/concerns/tag_wrangling.rb new file mode 100755 index 0000000..b0e9f1b --- /dev/null +++ b/app/controllers/concerns/tag_wrangling.rb @@ -0,0 +1,14 @@ +module TagWrangling + extend ActiveSupport::Concern + + # When used an around_action, record_wrangling_activity will + # mark that some wrangling activity has occurred. If a Wrangleable + # is saved during the action, a LastWranglingActivity will be + # recorded. Otherwise no additional steps are taken. + def record_wrangling_activity + User.should_update_wrangling_activity = true + yield + ensure + User.should_update_wrangling_activity = false + end +end diff --git a/app/controllers/creatorships_controller.rb b/app/controllers/creatorships_controller.rb new file mode 100755 index 0000000..e5ef053 --- /dev/null +++ b/app/controllers/creatorships_controller.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +# A controller for viewing co-creator requests -- that is, creatorships where +# the creator hasn't yet approved it. +class CreatorshipsController < ApplicationController + before_action :load_user + before_action :check_ownership + + # Show all of the creatorships associated with the current user. Displays a + # form where the user can select multiple creatorships and perform actions + # (accept, reject) in bulk. + def show + @page_subtitle = ts("Co-Creator Requests") + @creatorships = @creatorships.unapproved.order(id: :desc). + paginate(page: params[:page]) + end + + # Update the selected creatorships. + def update + @creatorships = @creatorships.where(id: params[:selected]) + + if params[:accept] + accept_update + elsif params[:reject] + reject_update + end + + redirect_to user_creatorships_path(@user, page: params[:page]) + end + + private + + # When the user presses "Accept" on the co-creator request listing, this is + # the code that runs. + def accept_update + flash[:notice] = [] + + @creatorships.each do |creatorship| + creatorship.accept! + link = view_context.link_to(title_for_creation(creatorship.creation), + creatorship.creation) + flash[:notice] << ts("You are now listed as a co-creator on %{link}.", + link: link).html_safe + end + end + + # When the user presses "Reject" on the co-creator request listing, this is + # the code that runs. Note that rejection is equivalent to destroying the + # request. + def reject_update + @creatorships.each(&:destroy) + flash[:notice] = ts("Requests rejected.") + end + + # A helper method used to display a nicely formatted title for a creation. + helper_method :title_for_creation + def title_for_creation(creation) + if creation.is_a?(Chapter) + "Chapter #{creation.position} of #{creation.work.title}" + else + creation.title + end + end + + # Load the user, and set @creatorships equal to all co-creator requests for + # that user. + def load_user + @user = User.find_by!(login: params[:user_id]) + @check_ownership_of = @user + @creatorships = Creatorship.unapproved.for_user(@user) + end +end diff --git a/app/controllers/downloads_controller.rb b/app/controllers/downloads_controller.rb new file mode 100755 index 0000000..4fe5aa9 --- /dev/null +++ b/app/controllers/downloads_controller.rb @@ -0,0 +1,72 @@ +class DownloadsController < ApplicationController + + skip_before_action :store_location, only: :show + before_action :load_work, only: :show + before_action :check_download_posted_status, only: :show + before_action :check_download_visibility, only: :show + around_action :remove_downloads, only: :show + + def show + respond_to :html, :pdf, :mobi, :epub, :azw3 + @download = Download.new(@work, mime_type: request.format) + @download.generate + + # Make sure we were able to generate the download. + unless @download.exists? + flash[:error] = ts("We were not able to render this work. Please try again in a little while or try another format.") + redirect_to work_path(@work) + return + end + + # Send file synchronously so we don't delete it before we have finished + # sending it + File.open(@download.file_path, 'r') do |f| + send_data f.read, filename: "#{@download.file_name}.#{@download.file_type}", type: @download.mime_type + end + end + +protected + + # Set up the work and check revealed status + # Once a format has been created, we want nginx to be able to serve + # it directly, without going through Rails again (until the work changes). + # This means no processing per user. Consider this the "published" version. + # It can't contain unposted chapters, nor unrevealed creators, even + # if the creator is the one requesting the download. + def load_work + unless AdminSetting.current.downloads_enabled? + flash[:error] = ts("Sorry, downloads are currently disabled.") + redirect_back_or_default works_path + return + end + + @work = Work.find(params[:id]) + end + + # We're currently just writing everything to tmp and feeding them through + # nginx so we don't want to keep the files around. + def remove_downloads + yield + ensure + @download.remove + end + + # We can't use check_visibility because this controller doesn't have access to + # cookies on production or staging. + def check_download_visibility + return unless @work.hidden_by_admin || @work.in_unrevealed_collection? + message = if @work.hidden_by_admin + ts("Sorry, you can't download a work that has been hidden by an admin.") + else + ts("Sorry, you can't download an unrevealed work.") + end + flash[:error] = message + redirect_to work_path(@work) + end + + def check_download_posted_status + return if @work.posted + flash[:error] = ts("Sorry, you can't download a draft.") + redirect_to work_path(@work) + end +end diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb new file mode 100755 index 0000000..c78a0df --- /dev/null +++ b/app/controllers/errors_controller.rb @@ -0,0 +1,16 @@ +class ErrorsController < ApplicationController + %w[403 404 422 500].each do |error_code| + define_method error_code.to_sym do + render error_code, status: error_code.to_i, formats: :html + end + end + + def auth_error + @page_subtitle = t(".browser_title") + end + + def timeout_error + @page_subtitle = t(".browser_title") + render "timeout_error", status: :gateway_timeout + end +end diff --git a/app/controllers/external_authors_controller.rb b/app/controllers/external_authors_controller.rb new file mode 100755 index 0000000..584f4e1 --- /dev/null +++ b/app/controllers/external_authors_controller.rb @@ -0,0 +1,104 @@ +class ExternalAuthorsController < ApplicationController + before_action :load_user + before_action :check_ownership, only: [:edit] + before_action :check_user_status, only: [:edit] + before_action :get_external_author_from_invitation, only: [:claim, :complete_claim] + before_action :users_only, only: [:complete_claim] + + def load_user + @user = User.find_by(login: params[:user_id]) + @check_ownership_of = @user + end + + def index + if @user && current_user == @user + @external_authors = @user.external_authors + elsif logged_in? && current_user.archivist + @external_authors = ExternalCreatorship.where(archivist_id: current_user).collect(&:external_author).uniq + elsif logged_in? + redirect_to user_external_authors_path(current_user) + else + flash[:notice] = "You can't see that information." + redirect_to root_path + end + end + + def edit + @external_author = ExternalAuthor.find(params[:id]) + end + + def get_external_author_from_invitation + token = params[:invitation_token] || (params[:user] && params[:user][:invitation_token]) + @invitation = Invitation.find_by(token: token) + unless @invitation + flash[:error] = ts("You need an invitation to do that.") + redirect_to root_path + return + end + + @external_author = @invitation.external_author + return if @external_author + flash[:error] = ts("There are no stories to claim on this invitation. Did you want to sign up instead?") + redirect_to signup_path(@invitation.token) + end + + def claim + end + + def complete_claim + # go ahead and give the user the works + @external_author.claim!(current_user) + @invitation.mark_as_redeemed(current_user) if @invitation + flash[:notice] = t('external_author_claimed', default: "We have added the stories imported under %{email} to your account.", email: @external_author.email) + redirect_to user_external_authors_path(current_user) + end + + def update + @invitation = Invitation.find_by(token: params[:invitation_token]) + @external_author = ExternalAuthor.find(params[:id]) + unless (@invitation && @invitation.external_author == @external_author) || @external_author.user == current_user + flash[:error] = "You don't have permission to do that." + redirect_to root_path + return + end + + flash[:notice] = "" + if params[:imported_stories] == "nothing" + flash[:notice] += "Okay, we'll leave things the way they are! You can use the email link any time if you change your mind. " + elsif params[:imported_stories] == "orphan" + # orphan the works + @external_author.orphan(params[:remove_pseud]) + flash[:notice] += "Your imported stories have been orphaned. Thank you for leaving them in the archive! " + elsif params[:imported_stories] == "delete" + # delete the works + @external_author.delete_works + flash[:notice] += "Your imported stories have been deleted. " + end + + if @invitation && + params[:imported_stories].present? && + params[:imported_stories] != "nothing" + @invitation.mark_as_redeemed + end + + if @external_author.update(external_author_params[:external_author] || {}) + flash[:notice] += "Your preferences have been saved." + redirect_to @user ? user_external_authors_path(@user) : root_path + else + flash[:error] = "There were problems saving your preferences." + render action: "edit" + end + end + + private + + def external_author_params + params.permit( + :id, :user_id, :utf8, :_method, :authenticity_token, :invitation_token, + :imported_stories, :commit, :remove_pseud, + external_author: [ + :email, :do_not_email, :do_not_import + ] + ) + end +end diff --git a/app/controllers/external_works_controller.rb b/app/controllers/external_works_controller.rb new file mode 100755 index 0000000..d40b6db --- /dev/null +++ b/app/controllers/external_works_controller.rb @@ -0,0 +1,69 @@ +class ExternalWorksController < ApplicationController + before_action :admin_only, only: [:edit, :update] + before_action :users_only, only: [:new] + before_action :check_user_status, only: [:new] + + def new + @bookmarkable = ExternalWork.new + @bookmark = Bookmark.new + end + + # Used with bookmark form to get an existing external work and return it via ajax + def fetch + if params[:external_work_url] + url = Addressable::URI.heuristic_parse(params[:external_work_url]).to_str + @external_work = ExternalWork.where(url: url).first + end + respond_to do |format| + format.js + end + end + + def index + if params[:show] == "duplicates" + unless logged_in_as_admin? + access_denied + return + end + + @external_works = ExternalWork.duplicate.order("created_at DESC").paginate(page: params[:page]) + else + @external_works = ExternalWork.order("created_at DESC").paginate(page: params[:page]) + end + end + + def show + @external_work = ExternalWork.find(params[:id]) + end + + def edit + @external_work = authorize ExternalWork.find(params[:id]) + @work = @external_work + end + + def update + @external_work = authorize ExternalWork.find(params[:id]) + @external_work.attributes = work_params + if @external_work.update(external_work_params) + flash[:notice] = t(".successfully_updated") + redirect_to(@external_work) + else + render action: "edit" + end + end + + private + + def external_work_params + params.require(:external_work).permit( + :url, :author, :title, :summary, :language_id + ) + end + + def work_params + params.require(:work).permit( + :rating_string, :fandom_string, :relationship_string, :character_string, + :freeform_string, category_strings: [], archive_warning_strings: [] + ) + end +end diff --git a/app/controllers/fandoms_controller.rb b/app/controllers/fandoms_controller.rb new file mode 100755 index 0000000..9440ec2 --- /dev/null +++ b/app/controllers/fandoms_controller.rb @@ -0,0 +1,56 @@ +class FandomsController < ApplicationController + before_action :load_collection + + def index + if @collection + @media = Media.canonical.by_name - [Media.find_by(name: ArchiveConfig.MEDIA_NO_TAG_NAME)] - [Media.find_by(name: ArchiveConfig.MEDIA_UNCATEGORIZED_NAME)] + @page_subtitle = t(".collection_page_title", collection_title: @collection.title) + @medium = Media.find_by_name(params[:media_id]) if params[:media_id] + @counts = SearchCounts.fandom_ids_for_collection(@collection) + @fandoms = (@medium ? @medium.fandoms : Fandom.all).where(id: @counts.keys).by_name + elsif params[:media_id] + @medium = Media.find_by_name!(params[:media_id]) + @page_subtitle = @medium.name + @fandoms = if @medium == Media.uncategorized + @medium.fandoms.in_use.by_name + else + @medium.fandoms.canonical.by_name.with_count + end + else + flash[:notice] = t(".choose_media") + redirect_to media_index_path and return + end + @fandoms_by_letter = @fandoms.group_by { |f| f.sortable_name[0].upcase } + end + + def show + @fandom = Fandom.find_by_name(params[:id]) + if @fandom.nil? + flash[:error] = ts("Could not find fandom named %{fandom_name}", fandom_name: params[:id]) + redirect_to media_index_path and return + end + @characters = @fandom.characters.canonical.by_name + end + + def unassigned + join_string = "LEFT JOIN wrangling_assignments + ON (wrangling_assignments.fandom_id = tags.id) + LEFT JOIN users + ON (users.id = wrangling_assignments.user_id)" + conditions = "canonical = 1 AND users.id IS NULL" + unless params[:media_id].blank? + @media = Media.find_by_name(params[:media_id]) + if @media + join_string << " INNER JOIN common_taggings + ON (tags.id = common_taggings.common_tag_id)" + conditions << " AND common_taggings.filterable_id = #{@media.id} + AND common_taggings.filterable_type = 'Tag'" + end + end + @fandoms = Fandom.joins(join_string). + where(conditions). + order(params[:sort] == 'count' ? "count DESC" : "sortable_name ASC"). + with_count. + paginate(page: params[:page], per_page: 250) + end +end diff --git a/app/controllers/favorite_tags_controller.rb b/app/controllers/favorite_tags_controller.rb new file mode 100755 index 0000000..c77ed12 --- /dev/null +++ b/app/controllers/favorite_tags_controller.rb @@ -0,0 +1,52 @@ +class FavoriteTagsController < ApplicationController + skip_before_action :store_location, only: [:create, :destroy] + before_action :users_only + before_action :load_user + before_action :check_ownership + + respond_to :html, :json + + # POST /favorites_tags + def create + @favorite_tag = current_user.favorite_tags.build(favorite_tag_params) + success_message = ts("You have successfully added %{tag_name} to your favorite tags. You can find them on the Archive homepage.", tag_name: @favorite_tag.tag_name) + if @favorite_tag.save + respond_to do |format| + format.html { redirect_to tag_works_path(tag_id: @favorite_tag.tag.to_param), notice: success_message.html_safe } + format.json { render json: { item_id: @favorite_tag.id, item_success_message: success_message }, status: :created } + end + else + respond_to do |format| + format.html do + flash.keep + redirect_to tag_works_path(tag_id: @favorite_tag.tag.to_param), flash: { error: @favorite_tag.errors.full_messages } + end + format.json { render json: { errors: @favorite_tag.errors.full_messages }, status: :unprocessable_entity } + end + end + end + + # DELETE /favorite_tags/1 + def destroy + @favorite_tag = FavoriteTag.find(params[:id]) + @favorite_tag.destroy + success_message = ts('You have successfully removed %{tag_name} from your favorite tags.', tag_name: @favorite_tag.tag_name) + respond_to do |format| + format.html { redirect_to tag_works_path(tag_id: @favorite_tag.tag.to_param), notice: success_message } + format.json { render json: { item_success_message: success_message }, status: :ok } + end + end + + private + + def load_user + @user = User.find_by(login: params[:user_id]) + @check_ownership_of = @user + end + + def favorite_tag_params + params.require(:favorite_tag).permit( + :tag_id + ) + end +end diff --git a/app/controllers/feedbacks_controller.rb b/app/controllers/feedbacks_controller.rb new file mode 100755 index 0000000..1ce99c0 --- /dev/null +++ b/app/controllers/feedbacks_controller.rb @@ -0,0 +1,48 @@ +class FeedbacksController < ApplicationController + skip_before_action :store_location + before_action :load_support_languages + + def new + @admin_setting = AdminSetting.current + @feedback = Feedback.new + @feedback.referer = request.referer + if logged_in_as_admin? + @feedback.email = current_admin.email + elsif is_registered_user? + @feedback.email = current_user.email + @feedback.username = current_user.login + end + end + + def create + @admin_setting = AdminSetting.current + @feedback = Feedback.new(feedback_params) + @feedback.rollout = @feedback.rollout_string + @feedback.user_agent = request.env["HTTP_USER_AGENT"]&.to(499) + @feedback.ip_address = request.remote_ip + @feedback.referer = nil unless @feedback.referer && ArchiveConfig.PERMITTED_HOSTS.include?(URI(@feedback.referer).host) + @feedback.site_skin = helpers.current_skin + if @feedback.save + @feedback.email_and_send + flash[:notice] = t("successfully_sent", + default: "Your message was sent to the Archive team - thank you!") + redirect_back_or_default(root_path) + else + flash[:error] = t("failure_send", + default: "Sorry, your message could not be saved - please try again!") + render action: "new" + end + end + + private + + def load_support_languages + @support_languages = Language.where(support_available: true).default_order + end + + def feedback_params + params.require(:feedback).permit( + :comment, :email, :summary, :username, :language, :referer + ) + end +end diff --git a/app/controllers/gifts_controller.rb b/app/controllers/gifts_controller.rb new file mode 100755 index 0000000..87a11a9 --- /dev/null +++ b/app/controllers/gifts_controller.rb @@ -0,0 +1,61 @@ +class GiftsController < ApplicationController + + before_action :load_collection + + def index + @user = User.find_by!(login: params[:user_id]) if params[:user_id] + @recipient_name = params[:recipient] + @page_subtitle = ts("Gifts for %{name}", name: (@user ? @user.login : @recipient_name)) + unless @user || @recipient_name + flash[:error] = ts("Whose gifts did you want to see?") + redirect_to(@collection || root_path) and return + end + if @user + if current_user.nil? + @works = @user.gift_works.visible_to_all + else + if @user == current_user && params[:refused] + @works = @user.rejected_gift_works.visible_to_registered_user + else + @works = @user.gift_works.visible_to_registered_user + end + end + else + pseud = Pseud.parse_byline(@recipient_name) + if pseud + if current_user.nil? + @works = pseud.gift_works.visible_to_all + else + @works = pseud.gift_works.visible_to_registered_user + end + else + if current_user.nil? + @works = Work.giftworks_for_recipient_name(@recipient_name).visible_to_all + else + @works = Work.giftworks_for_recipient_name(@recipient_name).visible_to_registered_user + end + end + end + @works = @works.in_collection(@collection) if @collection + @works = @works.order('revised_at DESC').paginate(page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE) + end + + def toggle_rejected + @gift = Gift.find(params[:id]) + # have to have the gift, be logged in, and the owner of the gift + if @gift && current_user && @gift.user == current_user + @gift.rejected = !@gift.rejected? + @gift.save! + if @gift.rejected? + flash[:notice] = ts("This work will no longer be listed among your gifts.") + else + flash[:notice] = ts("This work will now be listed among your gifts.") + end + else + # user doesn't have permission + access_denied + return + end + redirect_to user_gifts_path(current_user) and return + end +end diff --git a/app/controllers/hit_count_controller.rb b/app/controllers/hit_count_controller.rb new file mode 100755 index 0000000..976cc09 --- /dev/null +++ b/app/controllers/hit_count_controller.rb @@ -0,0 +1,31 @@ +# This controller is exclusively used to track hit counts on works. +# +# Note that we deliberately only accept JSON requests because JSON requests +# bypass a lot of the usual before_action hooks, many of which can trigger +# database queries. We want this action to avoid hitting the database if at +# all possible. +class HitCountController < ApplicationController + skip_around_action :set_current_user + + skip_before_action :logout_if_not_user_credentials + + skip_after_action :ensure_user_credentials, + :ensure_admin_credentials + + def create + respond_to do |format| + format.json do + if ENV["REQUEST_FROM_BOT"] + head :forbidden + else + RedisHitCounter.add( + params[:work_id].to_i, + request.remote_ip + ) + + head :ok + end + end + end + end +end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb new file mode 100755 index 0000000..6b82518 --- /dev/null +++ b/app/controllers/home_controller.rb @@ -0,0 +1,87 @@ +class HomeController < ApplicationController + + before_action :users_only, only: [:first_login_help] + skip_before_action :store_location, only: [:first_login_help, :token_dispenser] + + # unicorn_test + def unicorn_test + end + + def content + @page_subtitle = t(".page_title") + render action: "content", layout: "application" + end + + def privacy + @page_subtitle = t(".page_title") + render action: "privacy", layout: "application" + end + + # terms of service + def tos + @page_subtitle = t(".page_title") + render action: "tos", layout: "application" + end + + # terms of service faq + def tos_faq + @page_subtitle = t(".page_title") + render action: "tos_faq", layout: "application" + end + + # dmca policy + def dmca + render action: "dmca", layout: "application" + end + + # lost cookie + def lost_cookie + render action: 'lost_cookie', layout: 'application' + end + + # for updating form tokens on cached pages + def token_dispenser + respond_to do |format| + format.json { render json: { token: form_authenticity_token } } + end + end + + # diversity statement + def diversity + render action: "diversity_statement", layout: "application" + end + + # site map + def site_map + render action: "site_map", layout: "application" + end + + # donate + def donate + @page_subtitle = t(".page_title") + render action: "donate", layout: "application" + end + + # about + def about + @page_subtitle = t(".page_title") + render action: "about", layout: "application" + end + + def first_login_help + render action: "first_login_help", layout: false + end + + # home page itself + def index + @homepage = Homepage.new(@current_user) + @random_user = User.unscoped.order(Arel.sql("RAND()")).first + unless @homepage.logged_in? + @user_count, @work_count, @fandom_count = @homepage.rounded_counts + end + + @hide_dashboard = true + render action: 'index', layout: 'application' +end +end + diff --git a/app/controllers/inbox_controller.rb b/app/controllers/inbox_controller.rb new file mode 100755 index 0000000..26f71b2 --- /dev/null +++ b/app/controllers/inbox_controller.rb @@ -0,0 +1,75 @@ +class InboxController < ApplicationController + include BlockHelper + + before_action :load_user + before_action :check_ownership_or_admin + + before_action :load_commentable, only: :reply + before_action :check_blocked, only: :reply + + def load_user + @user = User.find_by(login: params[:user_id]) + @check_ownership_of = @user + end + + def show + authorize InboxComment if logged_in_as_admin? + @page_subtitle = t(".page_title", user: @user.login) + @inbox_total = @user.inbox_comments.with_bad_comments_removed.count + @unread = @user.inbox_comments.with_bad_comments_removed.count_unread + @filters = filter_params[:filters] || {} + @inbox_comments = @user.inbox_comments.with_bad_comments_removed.find_by_filters(@filters).page(params[:page]) + end + + def reply + @comment = Comment.new + respond_to do |format| + format.html do + redirect_to comment_path(@commentable, add_comment_reply_id: @commentable.id, anchor: 'comment_' + @commentable.id.to_s) + end + format.js + end + end + + def update + authorize InboxComment if logged_in_as_admin? + begin + @inbox_comments = InboxComment.find(params[:inbox_comments]) + if params[:read] + @inbox_comments.each { |i| i.update_attribute(:read, true) } + elsif params[:unread] + @inbox_comments.each { |i| i.update_attribute(:read, false) } + elsif params[:delete] + @inbox_comments.each { |i| i.destroy } + end + success_message = t(".success") + rescue + flash[:caution] = t(".must_select_item") + end + respond_to do |format| + format.html { redirect_to request.referer || user_inbox_path(@user, page: params[:page], filters: params[:filters]), notice: success_message } + format.json { render json: { item_success_message: success_message }, status: :ok } + end + end + + private + + # Allow flexible params through, since we're not posting any data + def filter_params + params.permit! + end + + def load_commentable + @commentable = Comment.find(params[:comment_id]) + end + + def check_blocked + if blocked_by?(@commentable.ultimate_parent) + flash[:error] = t("comments.check_blocked.parent") + redirect_back(fallback_location: user_inbox_path(@user)) + elsif blocked_by_comment?(@commentable) + flash[:error] = t("comments.check_blocked.reply") + redirect_back(fallback_location: user_inbox_path(@user)) + end + end +end diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb new file mode 100755 index 0000000..42df0c2 --- /dev/null +++ b/app/controllers/invitations_controller.rb @@ -0,0 +1,93 @@ +class InvitationsController < ApplicationController + before_action :check_permission + before_action :admin_only, only: [:create, :destroy] + before_action :check_user_status, only: [:index, :manage, :invite_friend, :update] + before_action :load_invitation, only: [:show, :invite_friend, :update, :destroy] + before_action :check_ownership_or_admin, only: [:show, :invite_friend, :update] + + def load_invitation + @invitation = Invitation.find(params[:id] || invitation_params[:id]) + @check_ownership_of = @invitation + end + + def check_permission + @user = User.find_by(login: params[:user_id]) + access_denied unless policy(User).can_manage_users? || @user.present? && @user == current_user + end + + def index + @unsent_invitations = @user.invitations.unsent.limit(5) + end + + def manage + status = params[:status] + @invitations = @user.invitations + if %w(unsent unredeemed redeemed).include?(status) + @invitations = @invitations.send(status) + end + end + + def show + end + + def invite_friend + if !invitation_params[:invitee_email].blank? + @invitation.invitee_email = invitation_params[:invitee_email] + if @invitation.save + flash[:notice] = 'Invitation was successfully sent.' + redirect_to([@user, @invitation]) + else + render action: "show" + end + else + flash[:error] = "Please enter an email address." + render action: "show" + end + end + + def create + if invitation_params[:number_of_invites].to_i > 0 + invitation_params[:number_of_invites].to_i.times do + @user.invitations.create + end + end + flash[:notice] = "Invitations were successfully created." + redirect_to user_invitations_path(@user) + end + + def update + @invitation.attributes = invitation_params + + if @invitation.invitee_email_changed? && @invitation.update(invitation_params) + flash[:notice] = 'Invitation was successfully sent.' + if logged_in_as_admin? + redirect_to find_admin_invitations_path("invitation[token]" => @invitation.token) + else + redirect_to([@user, @invitation]) + end + else + flash[:error] = "Please enter an email address." if @invitation.invitee_email.blank? + render action: "show" + end + end + + def destroy + @user = @invitation.creator + if @invitation.destroy + flash[:notice] = "Invitation successfully destroyed" + else + flash[:error] = "Invitation was not destroyed." + end + if @user.is_a?(User) + redirect_to user_invitations_path(@user) + else + redirect_to admin_invitations_path + end + end + + private + + def invitation_params + params.require(:invitation).permit(:id, :invitee_email, :number_of_invites) + end +end diff --git a/app/controllers/invite_requests_controller.rb b/app/controllers/invite_requests_controller.rb new file mode 100755 index 0000000..9789f59 --- /dev/null +++ b/app/controllers/invite_requests_controller.rb @@ -0,0 +1,124 @@ +class InviteRequestsController < ApplicationController + before_action :admin_only, only: [:manage, :destroy] + + # GET /invite_requests + # Set browser page title to Invitation Requests + def index + @invite_request = InviteRequest.new + @page_subtitle = t(".page_title") + end + + # GET /invite_requests/1 + def show + @invite_request = InviteRequest.find_by(email: params[:email]) + + if @invite_request.present? + @position_in_queue = @invite_request.position + else + @invitation = Invitation.unredeemed.from_queue.find_by(invitee_email: params[:email]) + end + + respond_to do |format| + format.html + format.js + end + end + + def resend + @invitation = Invitation.unredeemed.from_queue.find_by(invitee_email: params[:email]) + + if @invitation.nil? + flash[:error] = t("invite_requests.resend.not_found") + elsif !@invitation.can_resend? + flash[:error] = t("invite_requests.resend.not_yet", + count: ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION) + else + @invitation.send_and_set_date(resend: true) + + if @invitation.errors.any? + flash[:error] = @invitation.errors.full_messages.first + else + flash[:notice] = t("invite_requests.resend.success", email: @invitation.invitee_email) + end + end + + redirect_to status_invite_requests_path + end + + # POST /invite_requests + def create + unless AdminSetting.current.invite_from_queue_enabled? + flash[:error] = t(".queue_disabled.html", + closed_bold: helpers.tag.strong(t("invite_requests.create.queue_disabled.closed")), + news_link: helpers.link_to(t("invite_requests.create.queue_disabled.news"), admin_posts_path(tag: 143))) + redirect_to invite_requests_path + return + end + + @invite_request = InviteRequest.new(invite_request_params) + @invite_request.ip_address = request.remote_ip + if @invite_request.save + flash[:notice] = t(".success", + date: l(@invite_request.proposed_fill_time.to_date, format: :long), + return_address: ArchiveConfig.RETURN_ADDRESS) + redirect_to invite_requests_path + else + render action: :index + end + end + + def manage + authorize(InviteRequest) + + @invite_requests = InviteRequest.all + + if params[:query].present? + query = "%#{params[:query]}%" + @invite_requests = InviteRequest.where( + "simplified_email LIKE ? OR ip_address LIKE ?", + query, query + ) + + # Keep track of the fact that this has been filtered, so the position + # will not cleanly correspond to the page that we're on and the index of + # the request on the page: + @filtered = true + end + + @invite_requests = @invite_requests.order(:id).page(params[:page]) + end + + def destroy + @invite_request = InviteRequest.find(params[:id]) + authorize @invite_request + + if @invite_request.destroy + success_message = ts("Request for %{email} was removed from the queue.", email: @invite_request.email) + respond_to do |format| + format.html { redirect_to manage_invite_requests_path(page: params[:page], query: params[:query]), notice: success_message } + format.json { render json: { item_success_message: success_message }, status: :ok } + end + else + error_message = ts("Request could not be removed. Please try again.") + respond_to do |format| + format.html do + flash.keep + redirect_to manage_invite_requests_path(page: params[:page], query: params[:query]), flash: { error: error_message } + end + format.json { render json: { errors: error_message }, status: :unprocessable_entity } + end + end + end + + def status + @page_subtitle = t(".browser_title") + end + + private + + def invite_request_params + params.require(:invite_request).permit( + :email, :note, :query + ) + end +end diff --git a/app/controllers/known_issues_controller.rb b/app/controllers/known_issues_controller.rb new file mode 100755 index 0000000..793daff --- /dev/null +++ b/app/controllers/known_issues_controller.rb @@ -0,0 +1,58 @@ +class KnownIssuesController < ApplicationController + before_action :admin_only, except: [:index] + + # GET /known_issues + def index + @known_issues = KnownIssue.all + end + + # GET /known_issues/1 + def show + @known_issue = authorize KnownIssue.find(params[:id]) + end + + # GET /known_issues/new + def new + @known_issue = authorize KnownIssue.new + end + + # GET /known_issues/1/edit + def edit + @known_issue = authorize KnownIssue.find(params[:id]) + end + + # POST /known_issues + def create + @known_issue = authorize KnownIssue.new(known_issue_params) + if @known_issue.save + flash[:notice] = "Known issue was successfully created." + redirect_to(@known_issue) + else + render action: "new" + end + end + + # PUT /known_issues/1 + def update + @known_issue = authorize KnownIssue.find(params[:id]) + if @known_issue.update(known_issue_params) + flash[:notice] = "Known issue was successfully updated." + redirect_to(@known_issue) + else + render action: "edit" + end + end + + # DELETE /known_issues/1 + def destroy + @known_issue = authorize KnownIssue.find(params[:id]) + @known_issue.destroy + redirect_to(known_issues_path) + end + + private + + def known_issue_params + params.require(:known_issue).permit(:title, :content) + end +end diff --git a/app/controllers/kudos_controller.rb b/app/controllers/kudos_controller.rb new file mode 100755 index 0000000..636296a --- /dev/null +++ b/app/controllers/kudos_controller.rb @@ -0,0 +1,94 @@ +class KudosController < ApplicationController + skip_before_action :store_location + before_action :load_parent, only: [:index] + before_action :check_parent_visible, only: [:index] + before_action :admin_logout_required, only: [:create] + + def load_parent + @work = Work.find(params[:work_id]) + end + + def check_parent_visible + check_visibility_for(@work) + end + + def index + @kudos = @work.kudos.includes(:user).with_user + @guest_kudos_count = @work.kudos.by_guest.count + + respond_to do |format| + format.html do + @kudos = @kudos.order(id: :desc).paginate( + page: params[:page], + per_page: ArchiveConfig.MAX_KUDOS_TO_SHOW + ) + end + + format.js do + @kudos = @kudos.where("id < ?", params[:before].to_i) if params[:before] + end + end + end + + def create + @kudo = Kudo.new(kudo_params) + if current_user.present? + @kudo.user = current_user + else + @kudo.ip_address = request.remote_ip + end + + if @kudo.save + respond_to do |format| + format.html do + flash[:kudos_notice] = t(".success") + redirect_to request.referer and return + end + + format.js do + @commentable = @kudo.commentable + @kudos = @commentable.kudos.with_user.includes(:user) + render :create, status: :created + end + end + else + error_message = @kudo.errors.full_messages.first + respond_to do |format| + format.html do + # If user is suspended or banned, JavaScript disabled, redirect user to dashboard with message instead. + return if check_user_status + + flash[:kudos_error] = error_message + redirect_to request.referer and return + end + + format.js do + render json: { error_message: error_message }, status: :unprocessable_entity + end + end + end + rescue ActiveRecord::RecordNotUnique + # Uniqueness checks at application level (Rails validations) are inherently + # prone to race conditions. If we pass Rails validations but get rejected + # by database unique indices, use the usual duplicate error message. + # + # https://api.rubyonrails.org/v5.1/classes/ActiveRecord/Validations/ClassMethods.html#method-i-validates_uniqueness_of-label-Concurrency+and+integrity + error_message = t("activerecord.errors.models.kudo.taken") + respond_to do |format| + format.html do + flash[:kudos_error] = error_message + redirect_to request.referer + end + + format.js do + render json: { error_message: error_message }, status: :unprocessable_entity + end + end + end + + private + + def kudo_params + params.require(:kudo).permit(:commentable_id, :commentable_type) + end +end diff --git a/app/controllers/languages_controller.rb b/app/controllers/languages_controller.rb new file mode 100755 index 0000000..2a42320 --- /dev/null +++ b/app/controllers/languages_controller.rb @@ -0,0 +1,53 @@ +class LanguagesController < ApplicationController + def index + @languages = Language.default_order + @works_counts = Rails.cache.fetch("/v1/languages/work_counts/#{current_user.present?}", expires_in: 1.day) do + WorkQuery.new.works_per_language(@languages.count) + end + end + + def new + @language = Language.new + authorize @language + end + + def create + @language = Language.new(language_params) + authorize @language + if @language.save + flash[:notice] = t("languages.successfully_added") + redirect_to languages_path + else + render action: "new" + end + end + + def edit + @language = Language.find_by(short: params[:id]) + authorize @language + return unless @language == Language.default + + flash[:error] = t("languages.cannot_edit_default") + redirect_to languages_path + end + + def update + @language = Language.find_by(short: params[:id]) + authorize @language + + if @language.update(permitted_attributes(@language)) + flash[:notice] = t("languages.successfully_updated") + redirect_to languages_path + else + render action: "new" + end + end + + private + + def language_params + params.require(:language).permit( + :name, :short, :support_available, :abuse_support_available, :sortable_name + ) + end +end diff --git a/app/controllers/locales_controller.rb b/app/controllers/locales_controller.rb new file mode 100755 index 0000000..b36bec3 --- /dev/null +++ b/app/controllers/locales_controller.rb @@ -0,0 +1,55 @@ +class LocalesController < ApplicationController + + def index + authorize Locale + + @locales = Locale.default_order + end + + def new + @locale = Locale.new + authorize @locale + @languages = Language.default_order + end + + # GET /locales/en/edit + def edit + @locale = Locale.find_by(iso: params[:id]) + authorize @locale + @languages = Language.default_order + end + + def update + @locale = Locale.find_by(iso: params[:id]) + @locale.attributes = locale_params + authorize @locale + if @locale.save + flash[:notice] = ts('Your locale was successfully updated.') + redirect_to action: 'index', status: 303 + else + @languages = Language.default_order + render action: "edit" + end + end + + + def create + @locale = Locale.new(locale_params) + authorize @locale + if @locale.save + flash[:notice] = t('successfully_added', default: 'Locale was successfully added.') + redirect_to locales_path + else + @languages = Language.default_order + render action: "new" + end + end + + private + + def locale_params + params.require(:locale).permit( + :name, :iso, :language_id, :email_enabled, :interface_enabled + ) + end +end diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb new file mode 100755 index 0000000..579d3c6 --- /dev/null +++ b/app/controllers/media_controller.rb @@ -0,0 +1,25 @@ +class MediaController < ApplicationController + before_action :load_collection + skip_before_action :store_location, only: [:show] + + def index + uncategorized = Media.uncategorized + @media = Media.canonical.by_name.where.not(name: [ArchiveConfig.MEDIA_UNCATEGORIZED_NAME, ArchiveConfig.MEDIA_NO_TAG_NAME]) + [uncategorized] + @fandom_listing = {} + @media.each do |medium| + if medium == uncategorized + @fandom_listing[medium] = medium.children.in_use.by_type('Fandom').order('created_at DESC').limit(5) + else + @fandom_listing[medium] = (logged_in? || logged_in_as_admin?) ? + # was losing the select trying to do this through the parents association + Fandom.unhidden_top(5).joins(:common_taggings).where(canonical: true, common_taggings: {filterable_id: medium.id, filterable_type: 'Tag'}) : + Fandom.public_top(5).joins(:common_taggings).where(canonical: true, common_taggings: {filterable_id: medium.id, filterable_type: 'Tag'}) + end + end + @page_subtitle = t(".browser_title") + end + + def show + redirect_to media_fandoms_path(media_id: params[:id]) + end +end diff --git a/app/controllers/menu_controller.rb b/app/controllers/menu_controller.rb new file mode 100755 index 0000000..86ae0da --- /dev/null +++ b/app/controllers/menu_controller.rb @@ -0,0 +1,23 @@ +class MenuController < ApplicationController + + # about menu + def about + render action: "about", layout: "application" + end + + # browse menu + def browse + render action: "browse", layout: "application" + end + + # fandoms menu + def fandoms + render action: "fandoms", layout: "application" + end + + # search menu + def search + render action: "search", layout: "application" + end + +end \ No newline at end of file diff --git a/app/controllers/muted/users_controller.rb b/app/controllers/muted/users_controller.rb new file mode 100755 index 0000000..86b36fe --- /dev/null +++ b/app/controllers/muted/users_controller.rb @@ -0,0 +1,89 @@ +module Muted + class UsersController < ApplicationController + before_action :set_user + + before_action :check_ownership, except: :index + before_action :check_ownership_or_admin, only: :index + before_action :check_admin_permissions, only: :index + + before_action :build_mute, only: [:confirm_mute, :create] + before_action :set_mute, only: [:confirm_unmute, :destroy] + + # GET /users/:user_id/muted/users + def index + @mutes = @user.mutes_as_muter + .joins(:muted) + .includes(muted: [:pseuds, { default_pseud: { icon_attachment: { blob: { + variant_records: { image_attachment: :blob }, + preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } } + } } } }]) + .order(created_at: :desc).order(id: :desc).page(params[:page]) + + @pseuds = @mutes.map { |b| b.muted.default_pseud } + @rec_counts = Pseud.rec_counts_for_pseuds(@pseuds) + @work_counts = Pseud.work_counts_for_pseuds(@pseuds) + + @page_subtitle = t(".title") + end + + # GET /users/:user_id/muted/users/confirm_mute + def confirm_mute + @hide_dashboard = true + + return if @mute.valid? + + # We can't mute this user for whatever reason + flash[:error] = @mute.errors.full_messages.first + redirect_to user_muted_users_path(@user) + end + + # GET /users/:user_id/muted/users/confirm_unmute + def confirm_unmute + @hide_dashboard = true + + @muted = @mute.muted + end + + # POST /users/:user_id/muted/users + def create + if @mute.save + flash[:notice] = t(".muted", name: @mute.muted.login) + else + # We can't mute this user for whatever reason + flash[:error] = @mute.errors.full_messages.first + end + + redirect_to user_muted_users_path(@user) + end + + # DELETE /users/:user_id/muted/users/:id + def destroy + @mute.destroy + flash[:notice] = t(".unmuted", name: @mute.muted.login) + redirect_to user_muted_users_path(@user) + end + + private + + # Sets the user whose mutes we're viewing/modifying. + def set_user + @user = User.find_by!(login: params[:user_id]) + @check_ownership_of = @user + end + + # Builds (but doesn't save) a mute matching the desired params: + def build_mute + muted_byline = params.fetch(:muted_id, "") + @mute = @user.mutes_as_muter.build(muted_byline: muted_byline) + @muted = @mute.muted + end + + def set_mute + @mute = @user.mutes_as_muter.find(params[:id]) + end + + def check_admin_permissions + authorize Mute if logged_in_as_admin? + end + end +end diff --git a/app/controllers/opendoors/external_authors_controller.rb b/app/controllers/opendoors/external_authors_controller.rb new file mode 100755 index 0000000..5dd6eb3 --- /dev/null +++ b/app/controllers/opendoors/external_authors_controller.rb @@ -0,0 +1,78 @@ +class Opendoors::ExternalAuthorsController < ApplicationController + + before_action :users_only + before_action :opendoors_only + before_action :load_external_author, only: [:show, :forward] + + def load_external_author + @external_author = ExternalAuthor.find(params[:id]) + end + + def index + if params[:query] + @query = params[:query] + sql_query = '%' + @query +'%' + @external_authors = ExternalAuthor.where("external_authors.email LIKE ?", sql_query) + else + @external_authors = ExternalAuthor.unclaimed + end + # list in reverse order + @external_authors = @external_authors.order("created_at DESC").paginate(page: params[:page]) + end + + def show + end + + def new + @external_author = ExternalAuthor.new + end + + # create an external author identity (and pre-emptively block it) + def create + @external_author = ExternalAuthor.new(external_author_params) + unless @external_author.save + flash[:error] = ts("We couldn't save that address.") + else + flash[:notice] = ts("We have saved and blocked the email address %{email}", email: @external_author.email) + end + + redirect_to opendoors_tools_path + end + + def forward + if @external_author.is_claimed + flash[:error] = ts("This external author has already been claimed!") + redirect_to opendoors_external_author_path(@external_author) and return + end + + # get the invitation + @invitation = Invitation.where(external_author_id: @external_author.id).first + + unless @invitation + # if there is no invite we create one + @invitation = Invitation.new(external_author: @external_author) + end + + # send the invitation to specified address + @email = params[:email] + @invitation.invitee_email = @email + @invitation.creator = User.find_by(login: "open_doors") || current_user + if @invitation.save + flash[:notice] = ts("Claim invitation for %{author_email} has been forwarded to %{invitee_email}!", author_email: @external_author.email, invitee_email: @invitation.invitee_email) + else + flash[:error] = ts("We couldn't forward the claim for %{author_email} to that email address.", author_email: @external_author.email) + @invitation.errors.full_messages.join(", ") + end + + # redirect to external author listing for that user + redirect_to opendoors_external_authors_path(query: @external_author.email) + end + + private + + def external_author_params + params.require(:external_author).permit( + :email, :do_not_email, :do_not_import + ) + end + +end diff --git a/app/controllers/opendoors/tools_controller.rb b/app/controllers/opendoors/tools_controller.rb new file mode 100755 index 0000000..1f3cb80 --- /dev/null +++ b/app/controllers/opendoors/tools_controller.rb @@ -0,0 +1,61 @@ +class Opendoors::ToolsController < ApplicationController + + before_action :users_only + before_action :opendoors_only + + def index + @imported_from_url = params[:imported_from_url] + @external_author = ExternalAuthor.new + end + + # Update the imported_from_url value on an existing AO3 work + # This is not RESTful but is IMO a better idea than setting up a works controller under the opendoors namespace, + # since the functionality we want to provide is so limited. + def url_update + + # extract the work id and find the work + if params[:work_url] && params[:work_url].match(/works\/([0-9]+)\/?$/) + work_id = $1 + @work = Work.find_by_id(work_id) + end + unless @work + flash[:error] = ts("We couldn't find that work on the Archive. Have you put in the full URL?") + redirect_to action: :index and return + end + + # check validity of the new redirecting url + unless params[:imported_from_url].blank? + # try to parse the original entered url + begin + URI.parse(params[:imported_from_url]) + @imported_from_url = params[:imported_from_url] + rescue + end + + # if that didn't work, try to encode the URL and then parse it + if @imported_from_url.blank? + begin + URI.parse(URI::Parser.new.escape(params[:imported_from_url])) + @imported_from_url = URI::Parser.new.escape(params[:imported_from_url]) + rescue + end + end + end + + if @imported_from_url.blank? + flash[:error] = ts("The imported-from url you are trying to set doesn't seem valid.") + else + # check for any other works + works = Work.where(imported_from_url: @imported_from_url) + if works.count > 0 + flash[:error] = ts("There is already a work imported from the url %{url}.", url: @imported_from_url) + else + # ok let's try to update + @work.update_attribute(:imported_from_url, @imported_from_url) + flash[:notice] = "Updated imported-from url for #{@work.title} to #{@imported_from_url}" + end + end + redirect_to action: :index, imported_from_url: @imported_from_url and return + end + +end diff --git a/app/controllers/orphans_controller.rb b/app/controllers/orphans_controller.rb new file mode 100755 index 0000000..b5edab1 --- /dev/null +++ b/app/controllers/orphans_controller.rb @@ -0,0 +1,90 @@ +class OrphansController < ApplicationController + # You must be logged in to orphan works - relies on current_user data + before_action :users_only, except: [:index] + + before_action :check_user_not_suspended, except: [:index] + before_action :load_pseuds, only: [:create] + before_action :load_orphans, only: [:create] + + def index + @user = User.orphan_account + @works = @user.works + end + + def new + if params[:work_id] + @to_be_orphaned = Work.find(params[:work_id]) + check_one_owned(@to_be_orphaned, current_user.works) + elsif params[:work_ids] + @to_be_orphaned = Work.where(id: params[:work_ids]).to_a + check_all_owned(@to_be_orphaned, current_user.works) + elsif params[:series_id] + @to_be_orphaned = Series.find(params[:series_id]) + check_one_owned(@to_be_orphaned, current_user.series) + elsif params[:pseud_id] + @to_be_orphaned = Pseud.find(params[:pseud_id]) + check_one_owned(@to_be_orphaned, current_user.pseuds) + else + @to_be_orphaned = current_user + end + end + + def create + use_default = params[:use_default] == "true" + Creatorship.orphan(@pseuds, @orphans, use_default) + flash[:notice] = ts("Orphaning was successful.") + redirect_to user_path(current_user) + end + + protected + + def show_orphan_permission_error + flash[:error] = ts("You don't have permission to orphan that!") + redirect_to root_path + end + + # Given an ActiveRecord item and an ActiveRecord relation, check whether the + # item is in the relation. If not, show a flash error. + def check_one_owned(chosen_item, all_owned_items) + show_orphan_permission_error unless all_owned_items.exists?(chosen_item.id) + end + + # Given a collection of ActiveRecords and an ActiveRecord relation, check + # whether all items in the collection are contained in the relation. If not, + # show a flash error. + def check_all_owned(chosen_items, all_owned_items) + chosen_ids = chosen_items.map(&:id) + owned_ids = all_owned_items.where(id: chosen_ids).pluck(:id) + unowned_ids = chosen_ids - owned_ids + show_orphan_permission_error if unowned_ids.any? + end + + # Load the list of works or series into the @orphans variable, and verify + # that the current user owns the works/series in question. + def load_orphans + if params[:work_ids] + @orphans = Work.where(id: params[:work_ids]).to_a + check_all_owned(@orphans, current_user.works) + elsif params[:series_id] + @orphans = Series.where(id: params[:series_id]).to_a + check_all_owned(@orphans, current_user.series) + else + flash[:error] = ts("What did you want to orphan?") + redirect_to current_user + end + end + + # If a pseud_id is specified, load it and check that it belongs to the + # current user. Otherwise, assume that the user wants to orphan with all of + # their pseuds. + def load_pseuds + if params[:pseud_id] + @pseuds = Pseud.where(id: params[:pseud_id]).to_a + check_all_owned(@pseuds, current_user.pseuds) + else + @pseuds = current_user.pseuds + # We don't need to check ownership here because these pseuds are + # guaranteed to be owned by the current user. + end + end +end diff --git a/app/controllers/owned_tag_sets_controller.rb b/app/controllers/owned_tag_sets_controller.rb new file mode 100755 index 0000000..f157775 --- /dev/null +++ b/app/controllers/owned_tag_sets_controller.rb @@ -0,0 +1,239 @@ +class OwnedTagSetsController < ApplicationController + cache_sweeper :tag_set_sweeper + + before_action :load_tag_set, except: [:index, :new, :create, :show_options] + before_action :users_only, only: [:new, :create] + before_action :moderators_only, except: [:index, :new, :create, :show, :show_options] + before_action :owners_only, only: [:destroy] + + def load_tag_set + @tag_set = OwnedTagSet.find_by(id: params[:id]) + unless @tag_set + flash[:error] = ts("What Tag Set did you want to look at?") + redirect_to tag_sets_path and return + end + end + + def moderators_only + @tag_set.user_is_moderator?(current_user) || access_denied + end + + def owners_only + @tag_set.user_is_owner?(current_user) || access_denied + end + + def nominated_only + @tag_set.nominated || access_denied + end + + ### ACTIONS + + def index + if params[:user_id] + @user = User.find_by login: params[:user_id] + @tag_sets = OwnedTagSet.owned_by(@user) + elsif params[:restriction] + @restriction = PromptRestriction.find(params[:restriction]) + @tag_sets = OwnedTagSet.in_prompt_restriction(@restriction) + if @tag_sets.count == 1 + redirect_to tag_set_path(@tag_sets.first, tag_type: (params[:tag_type] || "fandom")) and return + end + else + @tag_sets = OwnedTagSet + if params[:query] + @query = params[:query] + @tag_sets = @tag_sets.where("title LIKE ?", '%' + params[:query] + '%') + else + # show a random selection + @tag_sets = @tag_sets.order("created_at DESC") + end + end + @tag_sets = @tag_sets.paginate(per_page: (params[:per_page] || ArchiveConfig.ITEMS_PER_PAGE), page: (params[:page] || 1)) + end + + def show_options + @restriction = PromptRestriction.find_by(id: params[:restriction]) + unless @restriction + flash[:error] = ts("Which Tag Set did you want to look at?") + redirect_to tag_sets_path and return + end + @tag_sets = OwnedTagSet.in_prompt_restriction(@restriction) + @tag_set_ids = @tag_sets.pluck(:tag_set_id) + @tag_type = params[:tag_type] && TagSet::TAG_TYPES.include?(params[:tag_type]) ? params[:tag_type] : "fandom" + # @tag_type is restricted by in_prompt_restriction and therefore safe to pass to constantize + @tags = @tag_type.classify.constantize.joins(:set_taggings).where("set_taggings.tag_set_id IN (?)", @tag_set_ids).by_name_without_articles + end + + def show + # don't bother collecting tags unless the user gets to see them + if @tag_set.visible || @tag_set.user_is_moderator?(current_user) + + # we use this to collect up fandom parents for characters and relationships + @fandom_keys_from_other_tags = [] + + # we use this to store the tag name results + @tag_hash = HashWithIndifferentAccess.new + + %w[character relationship].each do |tag_type| + next unless @tag_set.has_type?(tag_type) + + ## names_by_parent returns a hash of arrays like so: + ## hash[parent_name] => [child name, child name, child name] + + # get the manually associated fandoms + assoc_hash = TagSetAssociation.names_by_parent(TagSetAssociation.for_tag_set(@tag_set), tag_type) + + # get canonically associated fandoms + # Safe for constantize as tag_type restricted to character relationship + canonical_hash = Tag.names_by_parent(tag_type.classify.constantize.in_tag_set(@tag_set).canonical, "fandom") + + # merge the values of the two hashes (each value is an array) as a set (ie remove duplicates) + @tag_hash[tag_type] = assoc_hash.merge(canonical_hash) { |_key, oldval, newval| (oldval | newval) } + + # get any tags without a fandom + remaining = @tag_set.with_type(tag_type).where.not(name: @tag_hash[tag_type].values.flatten) + if remaining.any? + @tag_hash[tag_type]["(No linked fandom - might need association)"] ||= [] + @tag_hash[tag_type]["(No linked fandom - might need association)"] += remaining.pluck(:name) + end + + # store the parents + @fandom_keys_from_other_tags += @tag_hash[tag_type].keys + end + + # get rid of duplicates and sort + @fandom_keys_from_other_tags = @fandom_keys_from_other_tags.compact.uniq.sort {|a,b| a.gsub(/^(the |an |a )/, '') <=> b.gsub(/^(the |an |a )/, '')} + + # now handle fandoms + if @tag_set.has_type?("fandom") + # Get fandoms hashed by media -- just the canonical associations + @tag_hash[:fandom] = Tag.names_by_parent(Fandom.in_tag_set(@tag_set), "media") + + # get any fandoms without a media + if @tag_set.with_type("fandom").with_no_parents.count > 0 + @tag_hash[:fandom]["(No Media)"] ||= [] + @tag_hash[:fandom]["(No Media)"] += @tag_set.with_type("fandom").with_no_parents.pluck(:name) + end + + # we want to collect and warn about any chars or relationships not in the set's fandoms + @character_seen = {} + @relationship_seen = {} + + # clear out the fandoms we're showing from the list of other tags + if @fandom_keys_from_other_tags && !@fandom_keys_from_other_tags.empty? + @fandom_keys_from_other_tags -= @tag_hash[:fandom].values.flatten + end + + @unassociated_chars = [] + @unassociated_rels = [] + unless @fandom_keys_from_other_tags.empty? + if @tag_hash[:character] + @unassociated_chars = @tag_hash[:character].values_at(*@fandom_keys_from_other_tags).flatten.compact.uniq + end + if @tag_hash[:relationship] + @unassociated_rels = @tag_hash[:relationship].values_at(*@fandom_keys_from_other_tags).flatten.compact.uniq + end + end + end + end + end + + def new + @tag_set = OwnedTagSet.new + end + + def create + @tag_set = OwnedTagSet.new(owned_tag_set_params) + @tag_set.add_owner(current_user.default_pseud) + if @tag_set.save + flash[:notice] = ts('Tag Set was successfully created.') + redirect_to tag_set_path(@tag_set) + else + render action: "new" + end + end + + def edit + get_parent_child_tags + end + + def update + if @tag_set.update(owned_tag_set_params) && @tag_set.tag_set.save! + flash[:notice] = ts("Tag Set was successfully updated.") + redirect_to tag_set_path(@tag_set) + else + get_parent_child_tags + render action: :edit + end + end + + def confirm_delete + end + + def destroy + @tag_set = OwnedTagSet.find(params[:id]) + begin + name = @tag_set.title + @tag_set.destroy + flash[:notice] = ts("Your Tag Set %{name} was deleted.", name: name) + rescue + flash[:error] = ts("We couldn't delete that right now, sorry! Please try again later.") + end + redirect_to tag_sets_path + end + + def batch_load + end + + def do_batch_load + if params[:batch_associations] + failed = @tag_set.load_batch_associations!(params[:batch_associations], do_relationships: (params[:batch_do_relationships] ? true : false)) + if failed.empty? + flash[:notice] = ts("Tags and associations loaded!") + redirect_to tag_set_path(@tag_set) and return + else + flash.now[:notice] = ts("We couldn't add all the tags and associations you wanted -- the ones left below didn't work. See the help for suggestions!") + @failed_batch_associations = failed.join("\n") + render action: :batch_load and return + end + else + flash[:error] = ts("What did you want to load?") + redirect_to action: :batch_load and return + end + end + + + + + protected + + # for manual associations + def get_parent_child_tags + @tags_in_set = Tag.joins(:set_taggings).where("set_taggings.tag_set_id = ?", @tag_set.tag_set_id).order("tags.name ASC") + @parent_tags_in_set = @tags_in_set.where(type: 'Fandom').pluck :name, :id + @child_tags_in_set = @tags_in_set.where("type IN ('Relationship', 'Character')").pluck :name, :id + end + + private + + def owned_tag_set_params + params.require(:owned_tag_set).permit( + :owner_changes, :moderator_changes, :title, :description, :visible, + :usable, :nominated, :fandom_nomination_limit, :character_nomination_limit, + :relationship_nomination_limit, :freeform_nomination_limit, + associations_to_remove: [], + tag_set_associations_attributes: [ + :id, :create_association, :tag_id, :parent_tag_id, :_destroy + ], + tag_set_attributes: [ + :id, + :from_owned_tag_set, :fandom_tagnames_to_add, :character_tagnames_to_add, + :relationship_tagnames_to_add, :freeform_tagnames_to_add, + character_tagnames: [], rating_tagnames: [], archive_warning_tagnames: [], + category_tagnames: [], fandom_tags_to_remove: [], character_tags_to_remove: [], + relationship_tags_to_remove: [], freeform_tags_to_remove: [] + ] + ) + end + +end diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb new file mode 100755 index 0000000..58be0b3 --- /dev/null +++ b/app/controllers/people_controller.rb @@ -0,0 +1,33 @@ +class PeopleController < ApplicationController + + before_action :load_collection + + def search + if people_search_params.blank? + @search = PseudSearchForm.new({}) + else + options = people_search_params.merge(page: params[:page]) + @search = PseudSearchForm.new(options) + @people = @search.search_results.scope(:for_search) + flash_search_warnings(@people) + end + end + + def index + if @collection.present? + @people = @collection.participants.with_attached_icon.includes(:user).order(:name).page(params[:page]) + @rec_counts = Pseud.rec_counts_for_pseuds(@people) + @work_counts = Pseud.work_counts_for_pseuds(@people) + @page_subtitle = t(".collection_page_title", collection_title: @collection.title) + else + redirect_to search_people_path + end + end + + protected + + def people_search_params + return {} unless params[:people_search].present? + params[:people_search].permit! + end +end diff --git a/app/controllers/potential_matches_controller.rb b/app/controllers/potential_matches_controller.rb new file mode 100755 index 0000000..8b19c74 --- /dev/null +++ b/app/controllers/potential_matches_controller.rb @@ -0,0 +1,146 @@ +class PotentialMatchesController < ApplicationController + + before_action :users_only + before_action :load_collection + before_action :collection_maintainers_only + before_action :load_challenge + before_action :check_assignments_not_sent + before_action :check_signup_closed, only: [:generate] + before_action :load_potential_match_from_id, only: [:show] + + + def load_challenge + @challenge = @collection.challenge + no_challenge and return unless @challenge + end + + def no_challenge + flash[:error] = ts("What challenge did you want to sign up for?") + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + def load_potential_match_from_id + @potential_match = PotentialMatch.find(params[:id]) + no_potential_match and return unless @potential_match + end + + def no_assignment + flash[:error] = ts("What potential match did you want to work on?") + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + def check_signup_closed + signup_open and return unless !@challenge.signup_open + end + + def signup_open + flash[:error] = ts("Sign-up is still open, you cannot determine potential matches now.") + redirect_to @collection rescue redirect_to '/' + false + end + + def check_assignments_not_sent + assignments_sent and return unless @challenge.assignments_sent_at.nil? + end + + def assignments_sent + flash[:error] = ts("Assignments have already been sent! If necessary, you can purge them.") + redirect_to collection_assignments_path(@collection) rescue redirect_to '/' + false + end + + def index + @settings = @collection.challenge.potential_match_settings + + if (invalid_ids = PotentialMatch.invalid_signups_for(@collection)).present? + # there are invalid signups + @invalid_signups = ChallengeSignup.where(id: invalid_ids) + elsif PotentialMatch.in_progress?(@collection) + # we're generating + @in_progress = true + @progress = PotentialMatch.progress(@collection) + elsif ChallengeAssignment.in_progress?(@collection) + @assignment_in_progress = true + elsif @collection.potential_matches.count > 0 && @collection.assignments.count == 0 + flash[:error] = ts("There has been an error in the potential matching. Please first try regenerating assignments, and if that doesn't work, all potential matches. If the problem persists, please contact Support.") + elsif @collection.potential_matches.count > 0 + # we have potential_matches and assignments + + ### find assignments with no potential recipients + # first get signups with no offer potential matches + no_opms = ChallengeSignup.in_collection(@collection).no_potential_offers.pluck(:id) + @assignments_with_no_potential_recipients = @collection.assignments.where(offer_signup_id: no_opms) + + ### find assignments with no potential giver + # first get signups with no request potential matches + no_rpms = ChallengeSignup.in_collection(@collection).no_potential_requests.pluck(:id) + @assignments_with_no_potential_givers = @collection.assignments.where(request_signup_id: no_rpms) + + # list the assignments by requester + if params[:no_giver] + @assignments = @collection.assignments.with_request.with_no_offer.order_by_requesting_pseud + elsif params[:no_recipient] + # ordering causes this to hang on large challenge due to + # left join required to get offering pseuds + @assignments = @collection.assignments.with_offer.with_no_request # .order_by_offering_pseud + elsif params[:dup_giver] + @assignments = ChallengeAssignment.duplicate_givers(@collection).order_by_offering_pseud + elsif params[:dup_recipient] + @assignments = ChallengeAssignment.duplicate_recipients(@collection).order_by_requesting_pseud + else + @assignments = @collection.assignments.with_request.with_offer.order_by_requesting_pseud + end + @assignments = @assignments.paginate page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE + end + end + + # Generate potential matches + def generate + if PotentialMatch.in_progress?(@collection) + flash[:error] = ts("Potential matches are already being generated for this collection!") + else + # delete all existing assignments and potential matches for this collection + ChallengeAssignment.clear!(@collection) + PotentialMatch.clear!(@collection) + + flash[:notice] = ts("Beginning generation of potential matches. This may take some time, especially if your challenge is large.") + PotentialMatch.set_up_generating(@collection) + PotentialMatch.generate(@collection) + end + + # redirect to index + redirect_to collection_potential_matches_path(@collection) + end + + # Regenerate matches for one signup + def regenerate_for_signup + if params[:signup_id].blank? || (@signup = ChallengeSignup.where(id: params[:signup_id]).first).nil? + flash[:error] = ts("What sign-up did you want to regenerate matches for?") + else + PotentialMatch.regenerate_for_signup(@signup) + flash[:notice] = ts("Matches are being regenerated for ") + @signup.pseud.byline + + ts(". Please allow at least 5 minutes for this process to complete before refreshing the page.") + end + # redirect to index + redirect_to collection_potential_matches_path(@collection) + end + + def cancel_generate + if !PotentialMatch.in_progress?(@collection) + flash[:error] = ts("Potential matches are not currently being generated for this challenge.") + elsif PotentialMatch.canceled?(@collection) + flash[:error] = ts("Potential match generation has already been canceled, please refresh again shortly.") + else + PotentialMatch.cancel_generation(@collection) + flash[:notice] = ts("Potential match generation cancellation requested. This may take a while, please refresh shortly.") + end + + redirect_to collection_potential_matches_path(@collection) + end + + def show + end + +end diff --git a/app/controllers/preferences_controller.rb b/app/controllers/preferences_controller.rb new file mode 100755 index 0000000..69f6592 --- /dev/null +++ b/app/controllers/preferences_controller.rb @@ -0,0 +1,72 @@ +class PreferencesController < ApplicationController + before_action :load_user + before_action :check_ownership + skip_before_action :store_location + + # Ensure that the current user is authorized to view and change this information + def load_user + @user = User.find_by(login: params[:user_id]) + @check_ownership_of = @user + end + + def index + @user = User.find_by(login: params[:user_id]) + @preference = @user.preference + @available_skins = (current_user.skins.site_skins + Skin.approved_skins.site_skins).uniq + @available_locales = Locale.where(email_enabled: true) + end + + def update + @user = User.find_by(login: params[:user_id]) + @preference = @user.preference + @user.preference.attributes = preference_params + @available_skins = (current_user.skins.site_skins + Skin.approved_skins.site_skins).uniq + @available_locales = Locale.where(email_enabled: true) + + if params[:preference][:skin_id].present? + # unset session skin if user changed their skin + session[:site_skin] = nil + end + + if @user.preference.save + flash[:notice] = ts('Your preferences were successfully updated.') + redirect_to user_path(@user) + else + flash[:error] = ts('Sorry, something went wrong. Please try that again.') + render action: :index + end + end + + private + + def preference_params + params.require(:preference).permit( + :minimize_search_engines, + :disable_share_links, + :adult, + :view_full_works, + :hide_warnings, + :hide_freeform, + :disable_work_skins, + :skin_id, + :time_zone, + :preferred_locale, + :work_title_format, + :comment_emails_off, + :comment_inbox_off, + :comment_copy_to_self_off, + :kudos_emails_off, + :admin_emails_off, + :allow_collection_invitation, + :collection_emails_off, + :collection_inbox_off, + :recipient_emails_off, + :history_enabled, + :first_login, + :banner_seen, + :allow_cocreator, + :allow_gifts, + :guest_replies_off + ) + end +end diff --git a/app/controllers/profile_controller.rb b/app/controllers/profile_controller.rb new file mode 100755 index 0000000..add7370 --- /dev/null +++ b/app/controllers/profile_controller.rb @@ -0,0 +1,45 @@ +class ProfileController < ApplicationController + before_action :load_user_and_pseuds + + def show + @user = User.find_by(login: params[:user_id]) + if @user.profile.nil? + Profile.create(user_id: @user.id) + @user.reload + end + + @profile = @user.profile + + # code the same as the stuff in users_controller + if current_user.respond_to?(:subscriptions) + @subscription = current_user.subscriptions.where(subscribable_id: @user.id, + subscribable_type: "User").first || + current_user.subscriptions.build(subscribable: @user) + end + @page_subtitle = t(".page_title", username: @user.login) + end + + def pseuds + respond_to do |format| + format.html do + redirect_to user_pseuds_path(@user) + end + + format.js + end + end + + private + + def load_user_and_pseuds + @user = User.find_by(login: params[:user_id]) + + if @user.nil? + flash[:error] = ts("Sorry, there's no user by that name.") + redirect_to root_path + return + end + + @pseuds = @user.pseuds.default_alphabetical.paginate(page: params[:page]) + end +end diff --git a/app/controllers/prompts_controller.rb b/app/controllers/prompts_controller.rb new file mode 100755 index 0000000..69a084e --- /dev/null +++ b/app/controllers/prompts_controller.rb @@ -0,0 +1,211 @@ +class PromptsController < ApplicationController + + before_action :users_only, except: [:show] + before_action :load_collection, except: [:index] + before_action :load_challenge, except: [:index] + before_action :load_prompt_from_id, only: [:show, :edit, :update, :destroy] + before_action :load_signup, except: [:index, :destroy, :show] + # before_action :promptmeme_only, except: [:index, :new] + before_action :allowed_to_destroy, only: [:destroy] + before_action :allowed_to_view, only: [:show] + before_action :signup_owner_only, only: [:edit, :update] + before_action :check_signup_open, only: [:new, :create, :edit, :update] + before_action :check_prompt_in_collection, only: [:show, :edit, :update, :destroy] + + # def promptmeme_only + # unless @collection.challenge_type == "PromptMeme" + # flash[:error] = ts("Only available for prompt meme challenges, not gift exchanges") + # redirect_to collection_path(@collection) rescue redirect_to '/' + # end + # end + + def load_challenge + @challenge = @collection.challenge + no_challenge and return unless @challenge + end + + def no_challenge + flash[:error] = ts("What challenge did you want to sign up for?") + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + def load_signup + unless @challenge_signup + @challenge_signup = ChallengeSignup.in_collection(@collection).by_user(current_user).first + end + no_signup and return unless @challenge_signup + end + + def no_signup + flash[:error] = ts("Please submit a basic sign-up with the required fields first.") + redirect_to new_collection_signup_path(@collection) rescue redirect_to '/' + false + end + + def check_signup_open + signup_closed and return unless (@challenge.signup_open || @collection.user_is_owner?(current_user) || @collection.user_is_moderator?(current_user)) + end + + def signup_closed + flash[:error] = ts("Signup is currently closed: please contact a moderator for help.") + redirect_to @collection rescue redirect_to '/' + false + end + + def signup_owner_only + not_signup_owner and return unless (@challenge_signup.pseud.user == current_user || (@collection.challenge_type == "GiftExchange" && !@challenge.signup_open && @collection.user_is_owner?(current_user))) + end + + def maintainer_or_signup_owner_only + not_allowed(@collection) and return unless (@challenge_signup.pseud.user == current_user || @collection.user_is_maintainer?(current_user)) + end + + def not_signup_owner + flash[:error] = ts("You can't edit someone else's sign-up!") + redirect_to @collection + false + end + + def allowed_to_destroy + @challenge_signup.user_allowed_to_destroy?(current_user) || not_allowed(@collection) + end + + def load_prompt_from_id + @prompt = Prompt.find_by(id: params[:id]) + if @prompt.nil? + no_prompt + return + end + @challenge_signup = @prompt.challenge_signup + end + + def no_prompt + flash[:error] = ts("What prompt did you want to work on?") + redirect_to collection_path(@collection) rescue redirect_to '/' + false + end + + def check_prompt_in_collection + unless @prompt.collection_id == @collection.id + flash[:error] = ts("Sorry, that prompt isn't associated with that collection.") + redirect_to @collection + end + end + + def allowed_to_view + unless @challenge.user_allowed_to_see_prompt?(current_user, @prompt) + access_denied(redirect: @collection) + end + end + + #### ACTIONS + + def index + # this currently doesn't get called anywhere + # should probably list all the prompts in a given collection (instead of using challenge signup for that) + end + + def show + end + + def new + if params[:prompt_type] == "offer" + @index = @challenge_signup.offers.count + @prompt = @challenge_signup.offers.build + else + @index = @challenge_signup.requests.count + @prompt = @challenge_signup.requests.build + end + end + + def edit + @index = @challenge_signup.send(@prompt.class.name.downcase.pluralize).index(@prompt) + end + + def create + if params[:prompt_type] == "offer" + @prompt = @challenge_signup.offers.build(prompt_params) + else + @prompt = @challenge_signup.requests.build(prompt_params) + end + + if @challenge_signup.save + flash[:notice] = ts("Prompt was successfully added.") + redirect_to collection_signup_path(@collection, @challenge_signup) + else + flash[:error] = ts("That prompt would make your overall sign-up invalid, sorry.") + redirect_to edit_collection_signup_path(@collection, @challenge_signup) + end + end + + def update + if @prompt.update(prompt_params) + flash[:notice] = ts("Prompt was successfully updated.") + redirect_to collection_signup_path(@collection, @challenge_signup) + else + render action: :edit + end + end + + def destroy + if !(@challenge.signup_open || @collection.user_is_maintainer?(current_user)) + flash[:error] = ts("You cannot delete a prompt after sign-ups are closed. Please contact a moderator for help.") + else + if !@prompt.can_delete? + flash[:error] = ts("That would make your sign-up invalid, sorry! Please edit instead.") + else + @prompt.destroy + flash[:notice] = ts("Prompt was deleted.") + end + end + if @collection.user_is_maintainer?(current_user) && @collection.challenge_type == "PromptMeme" + redirect_to collection_requests_path(@collection) + elsif @prompt.challenge_signup + redirect_to collection_signup_path(@collection, @prompt.challenge_signup) + elsif @collection.user_is_maintainer?(current_user) + redirect_to collection_signups_path(@collection) + else + redirect_to @collection + end + end + + private + + def prompt_params + params.require(:prompt).permit( + :title, + :url, + :anonymous, + :description, + :any_fandom, + :any_character, + :any_relationship, + :any_freeform, + :any_category, + :any_rating, + :any_archive_warning, + tag_set_attributes: [ + :fandom_tagnames, + :id, + :updated_at, + :character_tagnames, + :relationship_tagnames, + :freeform_tagnames, + :category_tagnames, + :rating_tagnames, + :archive_warning_tagnames, + fandom_tagnames: [], + character_tagnames: [], + relationship_tagnames: [], + freeform_tagnames: [], + category_tagnames: [], + rating_tagnames: [], + archive_warning_tagnames: [] + ], + optional_tag_set_attributes: [ + :tagnames + ] + ) + end +end diff --git a/app/controllers/pseuds_controller.rb b/app/controllers/pseuds_controller.rb new file mode 100755 index 0000000..b3f0428 --- /dev/null +++ b/app/controllers/pseuds_controller.rb @@ -0,0 +1,143 @@ +class PseudsController < ApplicationController + cache_sweeper :pseud_sweeper + + before_action :load_user + before_action :check_ownership, only: [:create, :destroy, :new] + before_action :check_ownership_or_admin, only: [:edit, :update] + before_action :check_user_status, only: [:new, :create, :edit, :update] + + def load_user + @user = User.find_by!(login: params[:user_id]) + @check_ownership_of = @user + end + + # GET /pseuds + # GET /pseuds.xml + def index + @pseuds = @user.pseuds.with_attached_icon.alphabetical.paginate(page: params[:page]) + @rec_counts = Pseud.rec_counts_for_pseuds(@pseuds) + @work_counts = Pseud.work_counts_for_pseuds(@pseuds) + @page_subtitle = @user.login + end + + # GET /users/:user_id/pseuds/:id + def show + @pseud = @user.pseuds.find_by!(name: params[:id]) + @page_subtitle = @pseud.name + + # very similar to show under users - if you change something here, change it there too + if logged_in? || logged_in_as_admin? + visible_works = @pseud.works.visible_to_registered_user + visible_series = @pseud.series.visible_to_registered_user + visible_bookmarks = @pseud.bookmarks.visible_to_registered_user + else + visible_works = @pseud.works.visible_to_all + visible_series = @pseud.series.visible_to_all + visible_bookmarks = @pseud.bookmarks.visible_to_all + end + + visible_works = visible_works.revealed.non_anon + visible_series = visible_series.exclude_anonymous + + @fandoms = \ + Fandom.select("tags.*, count(DISTINCT works.id) as work_count") + .joins(:filtered_works).group("tags.id").merge(visible_works) + .where(filter_taggings: { inherited: false }) + .order("work_count DESC").load + + @works = visible_works.order("revised_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) + @series = visible_series.order("updated_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) + @bookmarks = visible_bookmarks.order("updated_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) + + return unless current_user.respond_to?(:subscriptions) + + @subscription = current_user.subscriptions.where(subscribable_id: @user.id, + subscribable_type: "User").first || + current_user.subscriptions.build(subscribable: @user) + end + + # GET /pseuds/new + # GET /pseuds/new.xml + def new + @pseud = @user.pseuds.build + end + + # GET /pseuds/1/edit + def edit + @pseud = @user.pseuds.find_by!(name: params[:id]) + authorize @pseud if logged_in_as_admin? + end + + # POST /pseuds + # POST /pseuds.xml + def create + @pseud = Pseud.new(permitted_attributes(Pseud)) + if @user.pseuds.where(name: @pseud.name).blank? + @pseud.user_id = @user.id + old_default = @user.default_pseud + if @pseud.save + flash[:notice] = t(".successfully_created") + if @pseud.is_default + # if setting this one as default, unset the attribute of the current default pseud + old_default.update_attribute(:is_default, false) + end + redirect_to polymorphic_path([@user, @pseud]) + else + render action: "new" + end + else + # user tried to add pseud they already have + flash[:error] = t(".already_have_pseud_with_name") + render action: "new" + end + end + + # PUT /pseuds/1 + # PUT /pseuds/1.xml + def update + @pseud = @user.pseuds.find_by(name: params[:id]) + authorize @pseud if logged_in_as_admin? + default = @user.default_pseud + if @pseud.update(permitted_attributes(@pseud)) + if logged_in_as_admin? && @pseud.ticket_url.present? + link = view_context.link_to("Ticket ##{@pseud.ticket_number}", @pseud.ticket_url) + summary = "#{link} for User ##{@pseud.user_id}" + AdminActivity.log_action(current_admin, @pseud, action: "edit pseud", summary: summary) + end + # if setting this one as default, unset the attribute of the current default pseud + default.update_attribute(:is_default, false) if @pseud.is_default && default != @pseud + flash[:notice] = t(".successfully_updated") + redirect_to([@user, @pseud]) + else + render action: "edit" + end + end + + # DELETE /pseuds/1 + # DELETE /pseuds/1.xml + def destroy + @hide_dashboard = true + if params[:cancel_button] + flash[:notice] = t(".not_deleted") + redirect_to(user_pseuds_path(@user)) && return + end + + @pseud = @user.pseuds.find_by(name: params[:id]) + if @pseud.is_default + flash[:error] = t(".cannot_delete_default") + elsif @pseud.name == @user.login + flash[:error] = t(".cannot_delete_matching_username") + elsif params[:bookmarks_action] == "transfer_bookmarks" + @pseud.change_bookmarks_ownership + @pseud.replace_me_with_default + flash[:notice] = t(".successfully_deleted") + elsif params[:bookmarks_action] == "delete_bookmarks" || @pseud.bookmarks.empty? + @pseud.replace_me_with_default + flash[:notice] = t(".successfully_deleted") + else + render "delete_preview" and return + end + + redirect_to(user_pseuds_path(@user)) + end +end diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb new file mode 100755 index 0000000..4c82934 --- /dev/null +++ b/app/controllers/questions_controller.rb @@ -0,0 +1,38 @@ +class QuestionsController < ApplicationController + before_action :load_archive_faq, except: :update_positions + + # GET /archive_faq/:archive_faq_id/questions/manage + def manage + authorize :archive_faq, :full_access? + @questions = @archive_faq.questions.order("position") + end + + # fetch archive_faq these questions belong to from db + def load_archive_faq + @archive_faq = ArchiveFaq.find_by(slug: params[:archive_faq_id]) + unless @archive_faq.present? + flash[:error] = t("questions.not_found") + redirect_to root_path and return + end + end + + # Update the position number of questions within a archive_faq + def update_positions + authorize :archive_faq, :full_access? + if params[:questions] + @archive_faq = ArchiveFaq.find_by(slug: params[:archive_faq_id]) + @archive_faq.reorder_list(params[:questions]) + flash[:notice] = t(".success") + elsif params[:question] + params[:question].each_with_index do |id, position| + Question.update(id, position: position + 1) + (@questions ||= []) << Question.find(id) + end + flash[:notice] = t(".success") + end + respond_to do |format| + format.html { redirect_to(@archive_faq) and return } + format.js { render nothing: true } + end + end +end diff --git a/app/controllers/readings_controller.rb b/app/controllers/readings_controller.rb new file mode 100755 index 0000000..e68d001 --- /dev/null +++ b/app/controllers/readings_controller.rb @@ -0,0 +1,70 @@ +class ReadingsController < ApplicationController + before_action :users_only + before_action :load_user + before_action :check_ownership + before_action :check_history_enabled + + def load_user + @user = User.find_by(login: params[:user_id]) + @check_ownership_of = @user + end + + def index + @readings = @user.readings.visible + @page_subtitle = t(".history_page_title") + if params[:show] == 'to-read' + @readings = @readings.where(toread: true) + @page_subtitle = t(".marked_for_later_page_title") + end + @readings = @readings.order("last_viewed DESC") + @pagy, @readings = pagy(@readings) + end + + def destroy + @reading = @user.readings.find(params[:id]) + if @reading.destroy + success_message = ts('Work successfully deleted from your history.') + respond_to do |format| + format.html { redirect_to request.referer || user_readings_path(current_user, page: params[:page]), notice: success_message } + format.json { render json: { item_success_message: success_message }, status: :ok } + end + else + respond_to do |format| + format.html do + flash.keep + redirect_to request.referer || user_readings_path(current_user, page: params[:page]), flash: { error: @reading.errors.full_messages } + end + format.json { render json: { errors: @reading.errors.full_messages }, status: :unprocessable_entity } + end + end + end + + def clear + success = true + + @user.readings.each do |reading| + reading.destroy! + rescue ActiveRecord::RecordNotDestroyed + success = false + end + + if success + flash[:notice] = t(".success") + else + flash[:error] = t(".error") + end + + redirect_to user_readings_path(current_user) + end + + protected + + # checks if user has history enabled and redirects to preferences if not, so they can potentially change it + def check_history_enabled + unless current_user.preference.history_enabled? + flash[:notice] = ts("You have reading history disabled in your preferences. Change it below if you'd like us to keep track of it.") + redirect_to user_preferences_path(current_user) + end + end + +end diff --git a/app/controllers/redirect_controller.rb b/app/controllers/redirect_controller.rb new file mode 100755 index 0000000..320cc5c --- /dev/null +++ b/app/controllers/redirect_controller.rb @@ -0,0 +1,29 @@ +class RedirectController < ApplicationController + + def index + do_redirect + end + + def do_redirect + url = params[:original_url] + if url.blank? + flash[:error] = ts("What url did you want to look up?") + else + @work = Work.find_by_url(url) + if @work + flash[:notice] = ts("You have been redirected here from %{url}. Please update the original link if possible!", url: url) + redirect_to work_path(@work) and return + else + flash[:error] = ts("We could not find a work imported from that url in the Archive of Our Own, sorry! Try another url?") + end + end + redirect_to redirect_path + end + + def show + if params[:original_url].present? + redirect_to action: :do_redirect, original_url: params[:original_url] and return + end + end + +end diff --git a/app/controllers/related_works_controller.rb b/app/controllers/related_works_controller.rb new file mode 100755 index 0000000..9c98f19 --- /dev/null +++ b/app/controllers/related_works_controller.rb @@ -0,0 +1,96 @@ +class RelatedWorksController < ApplicationController + + before_action :load_user, only: [:index] + before_action :users_only, except: [:index] + before_action :get_instance_variables, except: [:index] + + def index + @page_subtitle = t(".page_title", login: @user.login) + @translations_of_user = @user.related_works.posted.where(translation: true) + @remixes_of_user = @user.related_works.posted.where(translation: false) + @translations_by_user = @user.parent_work_relationships.posted.where(translation: true) + @remixes_by_user = @user.parent_work_relationships.posted.where(translation: false) + + return if @user == current_user + + # Extra constraints on what we display if someone else is viewing @user's + # related works page: + @translations_of_user = @translations_of_user.merge(Work.revealed.non_anon) + @remixes_of_user = @remixes_of_user.merge(Work.revealed.non_anon) + @translations_by_user = @translations_by_user.merge(Work.revealed.non_anon) + @remixes_by_user = @remixes_by_user.merge(Work.revealed.non_anon) + end + + # GET /related_works/1 + # GET /related_works/1.xml + def show + end + + def update + # updates are done by the owner of the parent, to aprove or remove links on the parent work. + unless @user + if current_user_owns?(@child) + flash[:error] = ts("Sorry, but you don't have permission to do that. Try removing the link from your own work.") + redirect_back_or_default(user_related_works_path(current_user)) + return + else + flash[:error] = ts("Sorry, but you don't have permission to do that.") + redirect_back_or_default(root_path) + return + end + end + # the assumption here is that any update is a toggle from what was before + @related_work.reciprocal = !@related_work.reciprocal? + if @related_work.update_attribute(:reciprocal, @related_work.reciprocal) + notice = @related_work.reciprocal? ? ts("Link was successfully approved") : + ts("Link was successfully removed") + flash[:notice] = notice + redirect_to(@related_work.parent) + else + flash[:error] = ts('Sorry, something went wrong.') + redirect_to(@related_work) + end + end + + def destroy + # destroys are done by the owner of the child, to remove links to the parent work which also removes the link back if it exists. + unless current_user_owns?(@child) + if @user + flash[:error] = ts("Sorry, but you don't have permission to do that. You can only approve or remove the link from your own work.") + redirect_back_or_default(user_related_works_path(current_user)) + return + else + flash[:error] = ts("Sorry, but you don't have permission to do that.") + redirect_back_or_default(root_path) + return + end + end + @related_work.destroy + redirect_back(fallback_location: user_related_works_path(current_user)) + end + + private + + def load_user + if params[:user_id].blank? + flash[:error] = ts("Whose related works were you looking for?") + redirect_back_or_default(search_people_path) + else + @user = User.find_by(login: params[:user_id]) + if @user.blank? + flash[:error] = ts("Sorry, we couldn't find that user") + redirect_back_or_default(root_path) + end + end + end + + def get_instance_variables + @related_work = RelatedWork.find(params[:id]) + @child = @related_work.work + if @related_work.parent.is_a? (Work) + @owners = @related_work.parent.pseuds.map(&:user) + @user = current_user if @owners.include?(current_user) + end + end + +end diff --git a/app/controllers/serial_works_controller.rb b/app/controllers/serial_works_controller.rb new file mode 100755 index 0000000..fbdec65 --- /dev/null +++ b/app/controllers/serial_works_controller.rb @@ -0,0 +1,25 @@ +# Controller for Serial Works +class SerialWorksController < ApplicationController + + before_action :load_serial_work + before_action :check_ownership + + def load_serial_work + @serial_work = SerialWork.find(params[:id]) + @check_ownership_of = @serial_work.series + end + + # DELETE /related_works/1 + # Updated so if last work in series is deleted redirects to current user works listing instead of throwing 404 + def destroy + last_work = (@serial_work.series.works.count <= 1) + + @serial_work.destroy + + if last_work + redirect_to current_user + else + redirect_to series_path(@serial_work.series) + end + end +end diff --git a/app/controllers/series_controller.rb b/app/controllers/series_controller.rb new file mode 100755 index 0000000..ca1757e --- /dev/null +++ b/app/controllers/series_controller.rb @@ -0,0 +1,157 @@ +class SeriesController < ApplicationController + before_action :check_user_status, only: [:new, :create, :edit, :update] + before_action :load_series, only: [:show, :edit, :remove_user_creatorship, :update, :manage, :destroy, :confirm_delete] + before_action :check_ownership, only: [:edit, :update, :manage, :destroy, :confirm_delete] + before_action :check_visibility, only: [:show] + + def load_series + @series = Series.find_by(id: params[:id]) + unless @series + raise ActiveRecord::RecordNotFound, "Couldn't find series '#{params[:id]}'" + end + @check_ownership_of = @series + @check_visibility_of = @series + end + + # GET /series + # GET /series.xml + def index + unless params[:user_id] + flash[:error] = ts("Whose series did you want to see?") + redirect_to(root_path) and return + end + @user = User.find_by!(login: params[:user_id]) + @page_subtitle = t(".page_title", username: @user.login) + + @series = if current_user.nil? + Series.visible_to_all + else + Series.visible_to_registered_user + end + + if params[:pseud_id] + @pseud = @user.pseuds.find_by!(name: params[:pseud_id]) + @page_subtitle = t(".page_title", username: @pseud.name) + @series = @series.exclude_anonymous.for_pseud(@pseud) + else + @series = @series.exclude_anonymous.for_user(@user) + end + @series = @series.paginate(page: params[:page]) + end + + # GET /series/1 + # GET /series/1.xml + def show + @works = @series.works_in_order.posted.select(&:visible?).paginate(page: params[:page]) + + # sets the page title with the data for the series + if @series.unrevealed? + @page_subtitle = t(".unrevealed_series") + else + @page_title = get_page_title(@series.allfandoms.collect(&:name).join(t("support.array.words_connector")), @series.anonymous? ? t(".anonymous") : @series.allpseuds.collect(&:byline).join(t("support.array.words_connector")), @series.title) + end + + if current_user.respond_to?(:subscriptions) + @subscription = current_user.subscriptions.where(subscribable_id: @series.id, + subscribable_type: 'Series').first || + current_user.subscriptions.build(subscribable: @series) + end + end + + # GET /series/new + # GET /series/new.xml + def new + @series = Series.new + end + + # GET /series/1/edit + def edit + end + + def remove_user_creatorship + pseuds_with_author_removed = @series.pseuds - current_user.pseuds + if pseuds_with_author_removed.empty? + redirect_to controller: "orphans", action: "new", series_id: @series.id + else + begin + @series.remove_author(current_user) + flash[:notice] = ts("You have been removed as a creator from the series and its works.") + redirect_to @series + rescue StandardError => e + flash[:error] = e.message + redirect_to @series + end + end + end + + # GET /series/1/manage + def manage + @serial_works = @series.serial_works.includes(:work).order(:position) + end + + # POST /series + # POST /series.xml + def create + @series = Series.new(series_params) + if @series.save + flash[:notice] = ts('Series was successfully created.') + redirect_to(@series) + else + render action: "new" + end + end + + # PUT /series/1 + # PUT /series/1.xml + def update + @series.attributes = series_params + if @series.errors.empty? && @series.save + flash[:notice] = ts('Series was successfully updated.') + redirect_to(@series) + else + render action: "edit" + end + end + + def update_positions + if params[:serial_works] + @series = Series.find(params[:id]) + @series.reorder_list(params[:serial_works]) + flash[:notice] = ts("Series order has been successfully updated.") + elsif params[:serial] + params[:serial].each_with_index do |id, position| + SerialWork.update(id, position: position + 1) + (@serial_works ||= []) << SerialWork.find(id) + end + end + respond_to do |format| + format.html { redirect_to series_path(@series) and return } + format.json { head :ok } + end + end + + # GET /series/1/confirm_delete + def confirm_delete + end + + # DELETE /series/1 + # DELETE /series/1.xml + def destroy + if @series.destroy + flash[:notice] = ts("Series was successfully deleted.") + redirect_to(current_user) + else + flash[:error] = ts("Sorry, we couldn't delete the series. Please try again.") + redirect_to(@series) + end + end + + private + + def series_params + params.require(:series).permit( + :title, :summary, :series_notes, :complete, + author_attributes: [:byline, ids: [], coauthors: []] + ) + end +end diff --git a/app/controllers/skins_controller.rb b/app/controllers/skins_controller.rb new file mode 100755 index 0000000..4351e88 --- /dev/null +++ b/app/controllers/skins_controller.rb @@ -0,0 +1,223 @@ +class SkinsController < ApplicationController + before_action :users_only, only: [:new, :create, :destroy] + before_action :load_skin, except: [:index, :new, :create, :unset] + before_action :check_ownership_or_admin, only: [:edit, :update] + before_action :check_ownership, only: [:confirm_delete, :destroy] + before_action :check_visibility, only: [:show] + before_action :check_editability, only: [:edit, :update, :confirm_delete, :destroy] + + #### ACTIONS + + # GET /skins + def index + is_work_skin = params[:skin_type] && params[:skin_type] == "WorkSkin" + if current_user && current_user.is_a?(User) + @preference = current_user.preference + end + if params[:user_id] && (@user = User.find_by(login: params[:user_id])) + redirect_to new_user_session_path and return unless logged_in? + if @user != current_user + flash[:error] = "You can only browse your own skins and approved public skins." + redirect_to skins_path and return + end + if is_work_skin + @skins = @user.work_skins.sort_by_recent.includes(:author).with_attached_icon + @title = ts('My Work Skins') + else + @skins = @user.skins.site_skins.sort_by_recent.includes(:author).with_attached_icon + @title = ts('My Site Skins') + end + else + if is_work_skin + @skins = WorkSkin.approved_skins.sort_by_recent_featured.includes(:author).with_attached_icon + @title = ts('Public Work Skins') + else + @skins = if logged_in? + Skin.approved_skins.usable.site_skins.sort_by_recent_featured.with_attached_icon + else + Skin.approved_skins.usable.site_skins.cached.sort_by_recent_featured.with_attached_icon + end + @title = ts('Public Site Skins') + end + end + end + + # GET /skins/1 + def show + @page_subtitle = @skin.title.html_safe + end + + # GET /skins/new + def new + @skin = Skin.new + if params[:wizard] + render :new_wizard + else + render :new + end + end + + # POST /skins + def create + unless params[:skin_type].nil? || params[:skin_type] && %w(Skin WorkSkin).include?(params[:skin_type]) + flash[:error] = ts("What kind of skin did you want to create?") + redirect_to :new and return + end + loaded = load_archive_parents unless params[:skin_type] && params[:skin_type] == 'WorkSkin' + if params[:skin_type] == "WorkSkin" + @skin = WorkSkin.new(skin_params) + else + @skin = Skin.new(skin_params) + end + @skin.author = current_user + if @skin.save + flash[:notice] = ts("Skin was successfully created.") + if loaded + flash[:notice] += ts(" We've added all the archive skin components as parents. You probably want to remove some of them now!") + redirect_to edit_skin_path(@skin) + else + redirect_to skin_path(@skin) + end + else + if params[:wizard] + render :new_wizard + else + render :new + end + end + end + + # GET /skins/1/edit + def edit + authorize @skin if logged_in_as_admin? + end + + def update + authorize @skin if logged_in_as_admin? + + loaded = load_archive_parents + if @skin.update(skin_params) + @skin.cache! if @skin.cached? + @skin.recache_children! + flash[:notice] = ts("Skin was successfully updated.") + if loaded + if flash[:error].present? + flash[:notice] = ts("Any other edits were saved.") + else + flash[:notice] += ts(" We've added all the archive skin components as parents. You probably want to remove some of them now!") + end + redirect_to edit_skin_path(@skin) + else + redirect_to @skin + end + else + render action: "edit" + end + end + + # Get /skins/1/preview + def preview + flash[:notice] = [] + flash[:notice] << ts("You are previewing the skin %{title}. This is a randomly chosen page.", title: @skin.title) + flash[:notice] << ts("Go back or click any link to remove the skin.") + flash[:notice] << ts("Tip: You can preview any archive page you want by tacking on '?site_skin=[skin_id]' like you can see in the url above.") + flash[:notice] << "".html_safe + ts("Return To Skin To Use") + "".html_safe + tag = FilterCount.where("public_works_count BETWEEN 10 AND 20").random_order.first.filter + redirect_to tag_works_path(tag, site_skin: @skin.id) + end + + def set + if @skin.cached? + flash[:notice] = ts("The skin %{title} has been set. This will last for your current session.", title: @skin.title) + session[:site_skin] = @skin.id + else + flash[:error] = ts("Sorry, but only certain skins can be used this way (for performance reasons). Please drop a support request if you'd like %{title} to be added!", title: @skin.title) + end + redirect_to(request.referer || @skin) + end + + def unset + session[:site_skin] = nil + if logged_in? && current_user.preference + current_user.preference.skin_id = AdminSetting.default_skin_id + current_user.preference.save + end + flash[:notice] = ts("You are now using the default Archive skin again!") + redirect_to(request.referer || root_path) + end + + # GET /skins/1/confirm_delete + def confirm_delete + end + + # DELETE /skins/1 + def destroy + @skin = Skin.find_by(id: params[:id]) + begin + @skin.destroy + flash[:notice] = ts("The skin was deleted.") + rescue + flash[:error] = ts("We couldn't delete that right now, sorry! Please try again later.") + end + + if current_user && current_user.is_a?(User) && current_user.preference.skin_id == @skin.id + current_user.preference.skin_id = AdminSetting.default_skin_id + current_user.preference.save + end + redirect_to user_skins_path(current_user) rescue redirect_to skins_path + end + + private + + def skin_params + params.require(:skin).permit( + :title, :description, :public, :css, :role, :ie_condition, :unusable, + :font, :base_em, :margin, :paragraph_margin, :background_color, + :foreground_color, :headercolor, :accent_color, :icon, + media: [], + skin_parents_attributes: [ + :id, :position, :parent_skin_id, :parent_skin_title, :_destroy + ] + ) + end + + def load_skin + @skin = Skin.find_by(id: params[:id]) + unless @skin + flash[:error] = "Skin not found" + redirect_to skins_path and return + end + @check_ownership_of = @skin + @check_visibility_of = @skin + end + + def check_editability + unless @skin.editable? + flash[:error] = ts("Sorry, you don't have permission to edit this skin") + redirect_to @skin + end + end + + # if we've been asked to load the archive parents, we do so and add them to params + def load_archive_parents + if params[:add_site_parents] + params[:skin][:skin_parents_attributes] ||= ActionController::Parameters.new + archive_parents = Skin.get_current_site_skin.get_all_parents + skin_parent_titles = params[:skin][:skin_parents_attributes].values.map { |v| v[:parent_skin_title] } + skin_parents = skin_parent_titles.empty? ? [] : Skin.where(title: skin_parent_titles).pluck(:id) + skin_parents += @skin.get_all_parents.collect(&:id) if @skin + unless (skin_parents.uniq & archive_parents.map(&:id)).empty? + flash[:error] = ts("You already have some of the archive components as parents, so we couldn't load the others. Please remove the existing components first if you really want to do this!") + return true + end + last_position = params[:skin][:skin_parents_attributes]&.keys&.map(&:to_i)&.max || 0 + archive_parents.each do |parent_skin| + last_position += 1 + new_skin_parent_hash = ActionController::Parameters.new({ position: last_position, parent_skin_id: parent_skin.id }) + params[:skin][:skin_parents_attributes].merge!({last_position.to_s => new_skin_parent_hash}) + end + return true + end + false + end +end diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb new file mode 100755 index 0000000..8ebb530 --- /dev/null +++ b/app/controllers/stats_controller.rb @@ -0,0 +1,130 @@ +class StatsController < ApplicationController + + before_action :users_only + before_action :load_user + before_action :check_ownership + + # only the current user + def load_user + @user = current_user + @check_ownership_of = @user + end + + # gather statistics for the user on all their works + def index + user_works = Work.joins(pseuds: :user).where(users: { id: @user.id }).where(posted: true) + user_chapters = Chapter.joins(pseuds: :user).where(users: { id: @user.id }).where(posted: true) + work_query = user_works + .joins(:taggings) + .joins("inner join tags on taggings.tagger_id = tags.id AND tags.type = 'Fandom'") + .select("distinct tags.name as fandom, works.id as id, works.title as title") + + # sort + + # NOTE: Because we are going to be eval'ing the @sort variable later we MUST make sure that its content is + # checked against the allowlist of valid options + sort_options = %w[hits date kudos.count comment_thread_count bookmarks.count subscriptions.count word_count] + @sort = sort_options.include?(params[:sort_column]) ? params[:sort_column] : "hits" + + @dir = params[:sort_direction] == "ASC" ? "ASC" : "DESC" + params[:sort_column] = @sort + params[:sort_direction] = @dir + + # gather works and sort by specified count + @years = ["All Years"] + user_chapters.pluck(:published_at).map { |date| date.year.to_s } + .uniq.sort + @current_year = @years.include?(params[:year]) ? params[:year] : "All Years" + if @current_year == "All Years" + work_query = work_query.select("works.revised_at as date, works.word_count as word_count") + else + next_year = @current_year.to_i + 1 + start_date = DateTime.parse("01/01/#{@current_year}") + end_date = DateTime.parse("01/01/#{next_year}") + work_query = work_query + .joins(:chapters) + .where("chapters.posted = 1 AND chapters.published_at >= ? AND chapters.published_at < ?", start_date, end_date) + .select("CONVERT(MAX(chapters.published_at), datetime) as date, SUM(chapters.word_count) as word_count") + .group(:id, :fandom) + end + works = work_query.all.sort_by { |w| @dir == "ASC" ? (stat_element(w, @sort) || 0) : (0 - (stat_element(w, @sort) || 0).to_i) } + + # on the off-chance a new user decides to look at their stats and have no works + render "no_stats" and return if works.blank? + + # group by fandom or flat view + if params[:flat_view] + @works = {ts("All Fandoms") => works.uniq} + else + @works = works.group_by(&:fandom) + end + + # gather totals for all works + @totals = {} + (sort_options - ["date"]).each do |value| + # the inject is used to collect the sum in the "result" variable as we iterate over all the works + @totals[value.split(".")[0].to_sym] = works.uniq.inject(0) { |result, work| result + (stat_element(work, value) || 0) } # sum the works + end + @totals[:user_subscriptions] = Subscription.where(subscribable_id: @user.id, subscribable_type: 'User').count + + # graph top 5 works + @chart_data = GoogleVisualr::DataTable.new + @chart_data.new_column('string', 'Title') + + chart_col = @sort == "date" ? "hits" : @sort + chart_col_title = chart_col.split(".")[0].titleize == "Comments" ? ts("Comment Threads") : chart_col.split(".")[0].titleize + if @sort == "date" && @dir == "ASC" + chart_title = ts("Oldest") + elsif @sort == "date" && @dir == "DESC" + chart_title = ts("Most Recent") + elsif @dir == "ASC" + chart_title = ts("Bottom Five By #{chart_col_title}") + else + chart_title = ts("Top Five By #{chart_col_title}") + end + @chart_data.new_column('number', chart_col_title) + + # Add Rows and Values + @chart_data.add_rows(works.uniq[0..4].map { |w| [w.title, stat_element(w, chart_col)] }) + + # image version of bar chart + # opts from here: http://code.google.com/apis/chart/image/docs/gallery/bar_charts.html + @image_chart = GoogleVisualr::Image::BarChart.new(@chart_data, {isVertical: true}).uri({ + chtt: chart_title, + chs: "800x350", + chbh: "a", + chxt: "x", + chm: "N,000000,0,-1,11" + }) + + options = { + colors: ["#993333"], + title: chart_title, + vAxis: { + viewWindow: { min: 0 } + } + } + @chart = GoogleVisualr::Interactive::ColumnChart.new(@chart_data, options) + + end + + private + + def stat_element(work, element) + case element.downcase + when "date" + work.date + when "hits" + work.hits + when "kudos.count" + work.kudos.count + when "comment_thread_count" + work.comment_thread_count + when "bookmarks.count" + work.bookmarks.count + when "subscriptions.count" + work.subscriptions.count + when "word_count" + work.word_count + end + end +end diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb new file mode 100644 index 0000000..bb5449b --- /dev/null +++ b/app/controllers/statuses_controller.rb @@ -0,0 +1,112 @@ +class StatusesController < ApplicationController + before_action :users_only, except: [:index, :show, :timeline] + before_action :set_status, only: [:show, :edit, :update, :destroy] + before_action :set_user, except: [:timeline] + before_action :check_ownership, only: [:edit, :update, :destroy] + + + def redirect_to_current_user + if current_user + redirect_to user_status_path(current_user) + else + redirect_to new_user_session_path, alert: "Please log in to view statuses." + end + end + def check_ownership + unless @status && @status.user == current_user + redirect_to user_status_path(@user || current_user), alert: "You don't have permission to do that silly!" + end +end + + def edit + @user = current_user + end + + def update + @user = current_user + if @status.update(status_params) + redirect_to user_status_path(@user, @status), notice: "Status updated!" + else + render :edit + end + end + + def show + end + def destroy + @status.destroy + redirect_to user_statuses_path(@user), notice: "Status deleted." + end + + def redirect_to_current_user_new + if current_user + redirect_to new_user_status_path(current_user) + else + redirect_to new_user_session_path, alert: "Please log in to create a status." + end + end + def index + if params[:user_id].present? + @user = User.find_by(id: params[:user_id]) || User.find_by(login: params[:user_id]) + end + if @user + @statuses = @user.statuses.order(created_at: :desc) + else + @statuses = [] + end +end + def new + if @user != current_user + redirect_to user_statuses_path(current_user, @status), alert: "You can't do that silly!" + return + end + @status = current_user.statuses.new +end + def create + if @user != current_user + redirect_to user_status_path(current_user), alert: "You can't do that silly!" + return + end + @status = current_user.statuses.new(status_params) + if @status.save + redirect_to user_statuses_path(current_user, @status), notice: "Status created!" + else + render :new + end + end + def timeline + @statuses = Status.includes(:user, :icon_attachment) + .order(created_at: :desc) + end + private + +def set_status + return unless params[:id].present? + + @status = Status.find_by(id: params[:id]) + unless @status + redirect_to user_statuses_path(current_user), alert: "Status not found." + return + end + + @user = @status.user +end + +def set_user + return if @user.present? + @user = if params[:user_id].present? + User.find_by(id: params[:user_id]) || User.find_by(login: params[:user_id]) + else + current_user + end + + unless @user + redirect_to root_path, alert: "User not found." + end +end + +def status_params + params.require(:status).permit(:icon, :text, :mood, :music) + end +end + diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb new file mode 100755 index 0000000..355a2ce --- /dev/null +++ b/app/controllers/subscriptions_controller.rb @@ -0,0 +1,97 @@ +class SubscriptionsController < ApplicationController + + skip_before_action :store_location, only: [:create, :destroy] + + before_action :users_only + before_action :load_user + before_action :load_subscribable_type, only: [:index, :confirm_delete_all, :delete_all] + before_action :check_ownership + + def load_user + @user = User.find_by(login: params[:user_id]) + @check_ownership_of = @user + end + + # GET /subscriptions + # GET /subscriptions.xml + def index + @subscriptions = @user.subscriptions.includes(:subscribable) + @subscriptions = @subscriptions.where(subscribable_type: @subscribable_type.classify) if @subscribable_type + + @subscriptions = @subscriptions.to_a.sort { |a,b| a.name.downcase <=> b.name.downcase } + @subscriptions = @subscriptions.paginate page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE + @page_subtitle = @subscribable_type ? t(".subscription_type_page_title", username: @user.login, subscription_type: @subscribable_type.classify) : t(".page_title", username: @user.login) + end + + # POST /subscriptions + # POST /subscriptions.xml + def create + @subscription = @user.subscriptions.build(subscription_params) + + success_message = ts("You are now following %{name}. If you'd like to stop receiving email updates, you can unsubscribe from your Subscriptions page.", name: @subscription.name).html_safe + if @subscription.save + respond_to do |format| + format.html { redirect_to request.referer || @subscription.subscribable, notice: success_message } + format.json { render json: { item_id: @subscription.id, item_success_message: success_message }, status: :created } + end + else + respond_to do |format| + format.html { + flash.keep + redirect_to request.referer || @subscription.subscribable, flash: { error: @subscription.errors.full_messages } + } + format.json { render json: { errors: @subscription.errors.full_messages }, status: :unprocessable_entity } + end + end + end + + # DELETE /subscriptions/1 + # DELETE /subscriptions/1.xml + def destroy + @subscription = Subscription.find(params[:id]) + @subscribable = @subscription.subscribable + @subscription.destroy + + success_message = ts("You have successfully unsubscribed from %{name}.", name: @subscription.name).html_safe + respond_to do |format| + format.html { redirect_to request.referer || user_subscriptions_path(current_user), notice: success_message } + format.json { render json: { item_success_message: success_message }, status: :ok } + end + end + + def confirm_delete_all + end + + def delete_all + @subscriptions = @user.subscriptions + @subscriptions = @subscriptions.where(subscribable_type: @subscribable_type.classify) if @subscribable_type + + success = true + @subscriptions.each do |subscription| + subscription.destroy! + rescue StandardError + success = false + end + + if success + flash[:notice] = t(".success") + else + flash[:error] = t(".error") + end + + redirect_to user_subscriptions_path(current_user, type: @subscribable_type) + end + + private + + def load_subscribable_type + @subscribable_type = params[:type].pluralize.downcase if params[:type] && Subscription::VALID_SUBSCRIBABLES.include?(params[:type].singularize.titleize) + end + + def subscription_params + params.require(:subscription).permit( + :subscribable_id, :subscribable_type + ) + end + +end diff --git a/app/controllers/tag_set_associations_controller.rb b/app/controllers/tag_set_associations_controller.rb new file mode 100755 index 0000000..4aa3508 --- /dev/null +++ b/app/controllers/tag_set_associations_controller.rb @@ -0,0 +1,77 @@ +class TagSetAssociationsController < ApplicationController + cache_sweeper :tag_set_sweeper + + before_action :load_tag_set + before_action :users_only + before_action :moderators_only + + def load_tag_set + @tag_set = OwnedTagSet.find_by(id: params[:tag_set_id]) + unless @tag_set + flash[:error] = ts("What tag set did you want to look at?") + redirect_to tag_sets_path and return + end + end + + def moderators_only + @tag_set.user_is_moderator?(current_user) || access_denied + end + + def index + get_tags_to_associate + end + + def update_multiple + # we get params like "create_association_[tag_id]_[parent_tagname]" + @errors = [] + params.each_pair do |key, val| + next unless val.present? + if key.match(/^create_association_(\d+)_(.*?)$/) + tag_id = $1 + parent_tagname = $2 + + # fix back the tagnames if they have [] brackets -- see _review_individual_nom for details + parent_tagname = parent_tagname.gsub('#LBRACKET', '[').gsub('#RBRACKET', ']') + + assoc = @tag_set.tag_set_associations.build(tag_id: tag_id, parent_tagname: parent_tagname, create_association: true) + if assoc.valid? + assoc.save + else + @errors += assoc.errors.full_messages + end + end + end + + if @errors.empty? + flash[:notice] = ts("Nominated associations were added.") + redirect_to tag_set_path(@tag_set) + else + flash[:error] = ts("We couldn't add all of your specified associations. See more detailed errors below!") + get_tags_to_associate + render action: :index + end + end + + + + protected + def get_tags_to_associate + # get the tags for which we have a parent nomination which doesn't already exist in the database + @tags_to_associate = Tag.joins(:set_taggings).where("set_taggings.tag_set_id = ?", @tag_set.tag_set_id). + joins("INNER JOIN tag_nominations ON tag_nominations.tagname = tags.name"). + joins("INNER JOIN tag_set_nominations ON tag_nominations.tag_set_nomination_id = tag_set_nominations.id"). + where("tag_set_nominations.owned_tag_set_id = ?", @tag_set.id). + where("tag_nominations.parented = 0 AND tag_nominations.rejected != 1 AND EXISTS + (SELECT * from tags WHERE tags.name = tag_nominations.parent_tagname)") + + # skip already associated tags + associated_tag_ids = TagSetAssociation.where(owned_tag_set_id: @tag_set.id).pluck :tag_id + @tags_to_associate = @tags_to_associate.where("tags.id NOT IN (?)", associated_tag_ids) unless associated_tag_ids.empty? + + # now get out just the tags and nominated parent tagnames + @tags_to_associate = @tags_to_associate.select("DISTINCT tags.id, tags.name, tag_nominations.parent_tagname"). + order("tag_nominations.parent_tagname ASC, tags.name ASC") + + end + +end diff --git a/app/controllers/tag_set_nominations_controller.rb b/app/controllers/tag_set_nominations_controller.rb new file mode 100755 index 0000000..1b45bcd --- /dev/null +++ b/app/controllers/tag_set_nominations_controller.rb @@ -0,0 +1,371 @@ +class TagSetNominationsController < ApplicationController + cache_sweeper :tag_set_sweeper + + before_action :users_only + before_action :load_tag_set, except: [ :index ] + before_action :check_pseud_ownership, only: [:create, :update] + before_action :load_nomination, only: [:show, :edit, :update, :destroy, :confirm_delete] + before_action :set_limit, only: [:new, :edit, :show, :create, :update] + + def check_pseud_ownership + if !tag_set_nomination_params[:pseud_id].blank? + pseud = Pseud.find(tag_set_nomination_params[:pseud_id]) + unless pseud && current_user && current_user.pseuds.include?(pseud) + flash[:error] = ts("You can't nominate tags with that pseud.") + redirect_to root_path and return + end + end + end + + def load_tag_set + @tag_set = OwnedTagSet.find_by_id(params[:tag_set_id]) + unless @tag_set + flash[:error] = ts("What tag set did you want to nominate for?") + redirect_to tag_sets_path and return + end + end + + def load_nomination + @tag_set_nomination = @tag_set.tag_set_nominations.find_by(id: params[:id]) + unless @tag_set_nomination + flash[:error] = ts("Which nominations did you want to work with?") + redirect_to tag_set_path(@tag_set) and return + end + unless current_user.is_author_of?(@tag_set_nomination) || @tag_set.user_is_moderator?(current_user) + flash[:error] = ts("You can only see your own nominations or nominations for a set you moderate.") + redirect_to tag_set_path(@tag_set) and return + end + end + + def set_limit + @limit = @tag_set.limits + end + + # used in new/edit to build any nominations that don't already exist before we open the form + def build_nominations + @limit[:fandom].times do |i| + fandom_nom = @tag_set_nomination.fandom_nominations[i] || @tag_set_nomination.fandom_nominations.build + @limit[:character].times {|j| fandom_nom.character_nominations[j] || fandom_nom.character_nominations.build } + @limit[:relationship].times {|j| fandom_nom.relationship_nominations[j] || fandom_nom.relationship_nominations.build } + end + + if @limit[:fandom] == 0 + @limit[:character].times {|j| @tag_set_nomination.character_nominations[j] || @tag_set_nomination.character_nominations.build } + @limit[:relationship].times {|j| @tag_set_nomination.relationship_nominations[j] || @tag_set_nomination.relationship_nominations.build } + end + + @limit[:freeform].times {|i| @tag_set_nomination.freeform_nominations[i] || @tag_set_nomination.freeform_nominations.build } + end + + + def index + if params[:user_id] + @user = User.find_by(login: params[:user_id]) + if @user != current_user + flash[:error] = ts("You can only view your own nominations, sorry.") + redirect_to tag_sets_path and return + else + @tag_set_nominations = TagSetNomination.owned_by(@user) + end + elsif (@tag_set = OwnedTagSet.find_by_id(params[:tag_set_id])) + if @tag_set.user_is_moderator?(current_user) + # reviewing nominations + setup_for_review + else + flash[:error] = ts("You can't see those nominations, sorry.") + redirect_to tag_sets_path and return + end + else + flash[:error] = ts("What nominations did you want to work with?") + redirect_to tag_sets_path and return + end + end + + def show + end + + def new + if @tag_set_nomination = TagSetNomination.for_tag_set(@tag_set).owned_by(current_user).first + redirect_to edit_tag_set_nomination_path(@tag_set, @tag_set_nomination) + else + @tag_set_nomination = TagSetNomination.new(pseud: current_user.default_pseud, owned_tag_set: @tag_set) + build_nominations + end + end + + def edit + # build up extra nominations if not all were used + build_nominations + end + + def create + @tag_set_nomination = @tag_set.tag_set_nominations.build(tag_set_nomination_params) + if @tag_set_nomination.save + flash[:notice] = ts('Your nominations were successfully submitted.') + redirect_to tag_set_nomination_path(@tag_set, @tag_set_nomination) + else + build_nominations + render action: "new" + end + end + + + def update + if @tag_set_nomination.update(tag_set_nomination_params) + flash[:notice] = ts("Your nominations were successfully updated.") + redirect_to tag_set_nomination_path(@tag_set, @tag_set_nomination) + else + build_nominations + render action: "edit" + end + end + + def destroy + unless @tag_set_nomination.unreviewed? || @tag_set.user_is_moderator?(current_user) + flash[:error] = ts("You cannot delete nominations after some of them have been reviewed, sorry!") + redirect_to tag_set_nomination_path(@tag_set, @tag_set_nomination) + else + @tag_set_nomination.destroy + flash[:notice] = ts("Your nominations were deleted.") + redirect_to tag_set_path(@tag_set) + end + end + + def base_nom_query(tag_type) + TagNomination.where(type: (tag_type.is_a?(Array) ? tag_type.map {|t| "#{t.classify}Nomination"} : "#{tag_type.classify}Nomination")). + for_tag_set(@tag_set).unreviewed.limit(@nom_limit) + end + + # set up various variables for reviewing nominations + def setup_for_review + set_limit + + # Only this amount of tag nominations is shown on the review page. + # If there are more (more_noms == true), moderators have to approve/reject from the shown noms to see more noms. + # TODO: AO3-3764 Show all tag set nominations + @nom_limit = 30 + @nominations = HashWithIndifferentAccess.new + @nominations_count = HashWithIndifferentAccess.new + more_noms = false + + if @tag_set.includes_fandoms? + # all char and rel tags happen under fandom noms + @nominations_count[:fandom] = @tag_set.fandom_nominations.unreviewed.count + more_noms = true if @nominations_count[:fandom] > @nom_limit + # Show a random selection of nominations if there are more noms than can be shown at once + @nominations[:fandom] = more_noms ? base_nom_query("fandom").random_order : base_nom_query("fandom").order(:tagname) + if (@limit[:character] > 0 || @limit[:relationship] > 0) + @nominations[:cast] = base_nom_query(%w(character relationship)). + join_fandom_nomination. + where('fandom_nominations_tag_nominations.approved = 1'). + order(:parent_tagname, :type, :tagname) + end + else + # if there are no fandoms we're going to assume this is a one or few fandom tagset + @nominations_count[:character] = @tag_set.character_nominations.unreviewed.count + @nominations_count[:relationship] = @tag_set.relationship_nominations.unreviewed.count + more_noms = true if (@tag_set.character_nominations.unreviewed.count > @nom_limit || @tag_set.relationship_nominations.unreviewed.count > @nom_limit) + @nominations[:character] = base_nom_query("character") if @limit[:character] > 0 + @nominations[:relationship] = base_nom_query("relationship") if @limit[:relationship] > 0 + if more_noms # Show a random selection of nominations if there are more noms than can be shown at once + parent_tagnames = TagNomination.for_tag_set(@tag_set).unreviewed.random_order.limit(100).pluck(:parent_tagname).uniq.first(30) + @nominations[:character] = @nominations[:character].where(parent_tagname: parent_tagnames) if @limit[:character] > 0 + @nominations[:relationship] = @nominations[:relationship].where(parent_tagname: parent_tagnames) if @limit[:relationship] > 0 + end + @nominations[:character] = @nominations[:character].order(:parent_tagname, :tagname) if @limit[:character] > 0 + @nominations[:relationship] = @nominations[:relationship].order(:parent_tagname, :tagname) if @limit[:relationship] > 0 + end + @nominations_count[:freeform] = @tag_set.freeform_nominations.unreviewed.count + more_noms = true if @nominations_count[:freeform] > @nom_limit + # Show a random selection of nominations if there are more noms than can be shown at once + @nominations[:freeform] = (more_noms ? base_nom_query("freeform").random_order : base_nom_query("freeform").order(:tagname)) unless @limit[:freeform].zero? + + if more_noms + flash[:notice] = ts("There are too many nominations to show at once, so here's a randomized selection! Additional nominations will appear after you approve or reject some.") + end + + if @tag_set.tag_nominations.unreviewed.empty? + flash[:notice] = ts("No nominations to review!") + end + end + + def confirm_delete + end + + def confirm_destroy_multiple + end + + def destroy_multiple + unless @tag_set.user_is_owner?(current_user) + flash[:error] = ts("You don't have permission to do that.") + redirect_to tag_set_path(@tag_set) and return + end + + @tag_set.clear_nominations! + flash[:notice] = ts("All nominations for this Tag Set have been cleared.") + redirect_to tag_set_path(@tag_set) + end + + # update_multiple gets called from the index/review form. + # we expect params like "character_approve_My Awesome Tag" and "fandom_reject_My Lousy Tag" + def update_multiple + unless @tag_set.user_is_moderator?(current_user) + flash[:error] = ts("You don't have permission to do that.") + redirect_to tag_set_path(@tag_set) and return + end + + # Collate the input into @approve, @reject, @synonym, @change, checking for: + # - invalid tag name changes + # - approve & reject both selected + # put errors in @errors, mark types to force to be expanded with @force_expand + @approve = HashWithIndifferentAccess.new; @synonym = HashWithIndifferentAccess.new + @reject = HashWithIndifferentAccess.new; @change = HashWithIndifferentAccess.new + @errors = []; @force_expand = {} + collect_update_multiple_results + + # If we have errors don't move ahead + unless @errors.empty? + render_index_on_error and return + end + + # OK, now we're going ahead and making piles of db changes! eep! D: + TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| + # we're adding the approved tags and synonyms + @tagnames_to_add = @approve[tag_type] + @synonym[tag_type] + @tagnames_to_remove = @reject[tag_type] + + # If we've approved a tag, change any other nominations that have this tag as a synonym to the synonym + if @tagnames_to_add.present? + tagnames_to_change = TagNomination.for_tag_set(@tag_set).where(type: "#{tag_type.classify}Nomination").where("synonym IN (?)", @tagnames_to_add).pluck(:tagname).uniq + tagnames_to_change.each do |oldname| + synonym = TagNomination.for_tag_set(@tag_set).where(type: "#{tag_type.classify}Nomination", tagname: oldname).pluck(:synonym).first + unless TagNomination.change_tagname!(@tag_set, oldname, synonym) + flash[:error] = ts("Oh no! We ran into a problem partway through saving your updates, changing %{oldname} to %{newname} -- please check over your tag set closely!", + oldname: oldname, newname: synonym) + render_index_on_error and return + end + end + end + + # do the name changes + @change[tag_type].each do |oldname, newname| + if TagNomination.change_tagname!(@tag_set, oldname, newname) + @tagnames_to_add << newname + else + # ughhhh + flash[:error] = ts("Oh no! We ran into a problem partway through saving your updates, changing %{oldname} to %{newname} -- please check over your tag set closely!", + oldname: oldname, newname: newname) + render_index_on_error and return + end + end + + # update the tag set + unless @tag_set.add_tagnames(tag_type, @tagnames_to_add) && @tag_set.remove_tagnames(tag_type, @tagnames_to_remove) + @errors = @tag_set.errors.full_messages + flash[:error] = ts("Oh no! We ran into a problem partway through saving your updates -- please check over your tag set closely!") + render_index_on_error and return + end + + @notice ||= [] + @notice << ts("Successfully added to set: %{approved}", approved: @tagnames_to_add.join(', ')) unless @tagnames_to_add.empty? + @notice << ts("Successfully rejected: %{rejected}", rejected: @tagnames_to_remove.join(', ')) unless @tagnames_to_remove.empty? + end + + # If we got here we made it through, YAY + flash[:notice] = @notice + if @tag_set.tag_nominations.unreviewed.empty? + flash[:notice] << ts("All nominations reviewed, yay!") + redirect_to tag_set_path(@tag_set) + else + flash[:notice] << ts("Still some nominations left to review!") + redirect_to tag_set_nominations_path(@tag_set) and return + end + end + + protected + + def render_index_on_error + setup_for_review + render action: "index" + end + + # gathers up the data for all the tag types + def collect_update_multiple_results + TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| + @approve[tag_type] = [] + @synonym[tag_type] = [] + @reject[tag_type] = [] + @change[tag_type] = [] + end + + params.each_pair do |key, val| + next unless val.present? + if key.match(/^([a-z]+)_(approve|reject|synonym|change)_(.*)$/) + type = $1 + action = $2 + name = $3 + # fix back the tagname if it has [] brackets -- see _review_individual_nom for details + name = name.gsub('#LBRACKET', '[').gsub('#RBRACKET', ']') + if TagSet::TAG_TYPES_INITIALIZABLE.include?(type) + # we're safe + case action + when "reject" + @reject[type] << name + when "approve" + @approve[type] << name unless params["#{type}_change_#{name}"].present? && (params["#{type}_change_#{name}"] != name) + when "synonym", "change" + next if val == name + # this is the tricky one: make sure we can do this name change + tagnom = TagNomination.for_tag_set(@tag_set).where(type: "#{type.classify}Nomination", tagname: name).first + if !tagnom + @errors << ts("Couldn't find a #{type} nomination for %{name}", name: name) + @force_expand[type] = true + elsif !tagnom.change_tagname?(val) + @errors << ts("Invalid name change for %{name} to %{val}: %{msg}", name: name, val: val, msg: tagnom.errors.full_messages.join(", ")) + @force_expand[type] = true + elsif action == "synonym" + @synonym[type] << val + else + @change[type] << [name, val] + end + end + end + end + end + + TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| + unless (intersect = @approve[tag_type] & @reject[tag_type]).empty? + @errors << ts("You have both approved and rejected the following %{type} tags: %{intersect}", type: tag_type, intersect: intersect.join(", ")) + @force_expand[tag_type] = true + end + end + end + + private + + def tag_set_nomination_params + params.require(:tag_set_nomination).permit( + :pseud_id, + fandom_nominations_attributes: [ + :id, + :tagname, + character_nominations_attributes: [ + :id, :tagname, :from_fandom_nomination + ], + relationship_nominations_attributes: [ + :id, :tagname, :from_fandom_nomination + ], + ], + freeform_nominations_attributes: [ + :id, :tagname + ], + character_nominations_attributes: [ + :id, :tagname, :parent_tagname + ], + relationship_nominations_attributes: [ + :id, :tagname, :parent_tagname + ] + ) + end + +end diff --git a/app/controllers/tag_wranglers_controller.rb b/app/controllers/tag_wranglers_controller.rb new file mode 100755 index 0000000..9722cbb --- /dev/null +++ b/app/controllers/tag_wranglers_controller.rb @@ -0,0 +1,112 @@ +class TagWranglersController < ApplicationController + include ExportsHelper + include WranglingHelper + + before_action :check_user_status + before_action :check_permission_to_wrangle, except: [:report_csv] + + def index + authorize :wrangling, :full_access? if logged_in_as_admin? + + @wranglers = Role.find_by(name: "tag_wrangler").users.alphabetical + conditions = ["canonical = 1"] + joins = "LEFT JOIN wrangling_assignments ON (wrangling_assignments.fandom_id = tags.id) + LEFT JOIN users ON (users.id = wrangling_assignments.user_id)" + unless params[:fandom_string].blank? + conditions.first << " AND name LIKE ?" + conditions << params[:fandom_string] + "%" + end + unless params[:wrangler_id].blank? + if params[:wrangler_id] == "No Wrangler" + conditions.first << " AND users.id IS NULL" + else + @wrangler = User.find_by(login: params[:wrangler_id]) + if @wrangler + conditions.first << " AND users.id = #{@wrangler.id}" + end + end + end + unless params[:media_id].blank? + @media = Media.find_by_name(params[:media_id]) + if @media + joins << " INNER JOIN common_taggings ON (tags.id = common_taggings.common_tag_id)" + conditions.first << " AND common_taggings.filterable_id = #{@media.id} AND common_taggings.filterable_type = 'Tag'" + end + end + @assignments = Fandom.in_use.joins(joins) + .select('tags.*, users.login AS wrangler') + .where(conditions) + .order(:name) + .paginate(page: params[:page], per_page: 50) + end + + def show + authorize :wrangling if logged_in_as_admin? + + @wrangler = User.find_by!(login: params[:id]) + @page_subtitle = @wrangler.login + @fandoms = @wrangler.fandoms.by_name + @counts = tag_counts_per_category + end + + def report_csv + authorize :wrangling + + wrangler = User.find_by!(login: params[:id]) + wrangled_tags = Tag + .where(last_wrangler: wrangler) + .limit(ArchiveConfig.WRANGLING_REPORT_LIMIT) + .includes(:merger, :parents) + results = [%w[Name Last\ Updated Type Merger Fandoms Unwrangleable]] + wrangled_tags.find_each(order: :desc) do |tag| + merger = tag.merger&.name || "" + fandoms = tag.parents.filter_map { |parent| parent.name if parent.is_a?(Fandom) }.join(", ") + results << [tag.name, tag.updated_at, tag.type, merger, fandoms, tag.unwrangleable] + end + filename = "wrangled_tags_#{wrangler.login}_#{Time.now.utc.strftime('%Y-%m-%d-%H%M')}.csv" + send_csv_data(results, filename) + end + + def create + authorize :wrangling if logged_in_as_admin? + + unless params[:tag_fandom_string].blank? + names = params[:tag_fandom_string].gsub(/$/, ',').split(',').map(&:strip) + fandoms = Fandom.where('name IN (?)', names) + unless fandoms.blank? + for fandom in fandoms + unless !current_user.respond_to?(:fandoms) || current_user.fandoms.include?(fandom) + assignment = current_user.wrangling_assignments.build(fandom_id: fandom.id) + assignment.save! + end + end + end + end + unless params[:assignments].blank? + params[:assignments].each_pair do |fandom_id, user_logins| + fandom = Fandom.find(fandom_id) + user_logins.uniq.each do |login| + unless login.blank? + user = User.find_by(login: login) + unless user.nil? || user.fandoms.include?(fandom) + assignment = user.wrangling_assignments.build(fandom_id: fandom.id) + assignment.save! + end + end + end + end + flash[:notice] = "Wranglers were successfully assigned!" + end + redirect_to tag_wranglers_path(media_id: params[:media_id], fandom_string: params[:fandom_string], wrangler_id: params[:wrangler_id]) + end + + def destroy + authorize :wrangling if logged_in_as_admin? + + wrangler = User.find_by(login: params[:id]) + assignment = WranglingAssignment.where(user_id: wrangler.id, fandom_id: params[:fandom_id]).first + assignment.destroy + flash[:notice] = "Wranglers were successfully unassigned!" + redirect_to tag_wranglers_path(media_id: params[:media_id], fandom_string: params[:fandom_string], wrangler_id: params[:wrangler_id]) + end +end diff --git a/app/controllers/tag_wranglings_controller.rb b/app/controllers/tag_wranglings_controller.rb new file mode 100755 index 0000000..c3068d9 --- /dev/null +++ b/app/controllers/tag_wranglings_controller.rb @@ -0,0 +1,108 @@ +class TagWranglingsController < ApplicationController + include TagWrangling + include WranglingHelper + + before_action :check_user_status + before_action :check_permission_to_wrangle + around_action :record_wrangling_activity, only: [:wrangle] + + def index + @counts = tag_counts_per_category + authorize :wrangling, :read_access? if logged_in_as_admin? + return if params[:show].blank? + + raise "Redshirt: Attempted to constantize invalid class initialize tag_wranglings_controller_index #{params[:show].classify}" unless Tag::USER_DEFINED.include?(params[:show].classify) + + params[:sort_column] = "created_at" unless valid_sort_column(params[:sort_column], "tag") + params[:sort_direction] = "ASC" unless valid_sort_direction(params[:sort_direction]) + + if params[:show] == "fandoms" + @media_names = Media.by_name.pluck(:name) + @page_subtitle = t(".page_subtitle") + end + + type = params[:show].singularize.capitalize + @tags = TagQuery.new({ + type: type, + in_use: true, + unwrangleable: false, + unwrangled: true, + has_posted_works: true, + sort_column: params[:sort_column], + sort_direction: params[:sort_direction], + page: params[:page], + per_page: ArchiveConfig.ITEMS_PER_PAGE + }).search_results + end + + def wrangle + authorize :wrangling, :full_access? if logged_in_as_admin? + + params[:page] = '1' if params[:page].blank? + params[:sort_column] = 'name' if !valid_sort_column(params[:sort_column], 'tag') + params[:sort_direction] = 'ASC' if !valid_sort_direction(params[:sort_direction]) + options = {show: params[:show], page: params[:page], sort_column: params[:sort_column], sort_direction: params[:sort_direction]} + + error_messages, notice_messages = [], [] + + # make tags canonical if allowed + if params[:canonicals].present? && params[:canonicals].is_a?(Array) + saved_canonicals, not_saved_canonicals = [], [] + tags = Tag.where(id: params[:canonicals]) + + tags.each do |tag_to_canonicalize| + if tag_to_canonicalize.update(canonical: true) + saved_canonicals << tag_to_canonicalize + else + not_saved_canonicals << tag_to_canonicalize + end + end + + error_messages << ts('The following tags couldn\'t be made canonical: %{tags_not_saved}', tags_not_saved: not_saved_canonicals.collect(&:name).join(', ')) unless not_saved_canonicals.empty? + notice_messages << ts('The following tags were successfully made canonical: %{tags_saved}', tags_saved: saved_canonicals.collect(&:name).join(', ')) unless saved_canonicals.empty? + end + + if params[:media] && !params[:selected_tags].blank? + options.merge!(media: params[:media]) + @media = Media.find_by_name(params[:media]) + @fandoms = Fandom.find(params[:selected_tags]) + @fandoms.each { |fandom| fandom.add_association(@media) } + elsif params[:fandom_string].blank? && params[:selected_tags].is_a?(Array) && !params[:selected_tags].empty? + error_messages << ts('There were no Fandom tags!') + elsif params[:fandom_string].present? && params[:selected_tags].is_a?(Array) && !params[:selected_tags].empty? + canonical_fandoms, noncanonical_fandom_names = [], [] + fandom_names = params[:fandom_string].split(',').map(&:squish) + + fandom_names.each do |fandom_name| + if (fandom = Fandom.find_by_name(fandom_name)).try(:canonical?) + canonical_fandoms << fandom + else + noncanonical_fandom_names << fandom_name + end + end + + if canonical_fandoms.present? + saved_to_fandoms = Tag.where(id: params[:selected_tags]) + + saved_to_fandoms.each do |tag_to_wrangle| + canonical_fandoms.each do |fandom| + tag_to_wrangle.add_association(fandom) + end + end + + canonical_fandom_names = canonical_fandoms.collect(&:name) + options.merge!(fandom_string: canonical_fandom_names.join(',')) + notice_messages << ts('The following tags were successfully wrangled to %{canonical_fandoms}: %{tags_saved}', canonical_fandoms: canonical_fandom_names.join(', '), tags_saved: saved_to_fandoms.collect(&:name).join(', ')) unless saved_to_fandoms.empty? + end + + if noncanonical_fandom_names.present? + error_messages << ts('The following names are not canonical fandoms: %{noncanonical_fandom_names}.', noncanonical_fandom_names: noncanonical_fandom_names.join(', ')) + end + end + + flash[:notice] = notice_messages.join('
').html_safe unless notice_messages.empty? + flash[:error] = error_messages.join('
').html_safe unless error_messages.empty? + + redirect_to tag_wranglings_path(options) + end +end diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb new file mode 100755 index 0000000..6d9c2fd --- /dev/null +++ b/app/controllers/tags_controller.rb @@ -0,0 +1,427 @@ +class TagsController < ApplicationController + include TagWrangling + + before_action :load_collection + before_action :check_user_status, except: [:show, :index, :show_hidden, :search, :feed] + before_action :check_permission_to_wrangle, except: [:show, :index, :show_hidden, :search, :feed] + before_action :load_tag, only: [:edit, :update, :wrangle, :mass_update] + before_action :load_tag_and_subtags, only: [:show] + around_action :record_wrangling_activity, only: [:create, :update, :mass_update] + + caches_page :feed + + def load_tag + @tag = Tag.find_by_name(params[:id]) + unless @tag && @tag.is_a?(Tag) + raise ActiveRecord::RecordNotFound, "Couldn't find tag named '#{params[:id]}'" + end + end + + # improved performance for show page + def load_tag_and_subtags + @tag = Tag.includes(:direct_sub_tags).find_by_name(params[:id]) + unless @tag && @tag.is_a?(Tag) + raise ActiveRecord::RecordNotFound, "Couldn't find tag named '#{params[:id]}'" + end + end + + # GET /tags + def index + if @collection + @tags = Freeform.canonical.for_collections_with_count([@collection] + @collection.children) + @page_subtitle = t(".collection_page_title", collection_title: @collection.title) + else + no_fandom = Fandom.find_by_name(ArchiveConfig.FANDOM_NO_TAG_NAME) + if no_fandom + @tags = no_fandom.children.by_type("Freeform").first_class.limit(ArchiveConfig.TAGS_IN_CLOUD) + # have to put canonical at the end so that it doesn't overwrite sort order for random and popular + # and then sort again at the very end to make it alphabetic + @tags = if params[:show] == "random" + @tags.random.canonical.sort + else + @tags.popular.canonical.sort + end + else + @tags = [] + end + end + end + + def search + options = params[:tag_search].present? ? tag_search_params : {} + options.merge!(page: params[:page]) if params[:page].present? + @search = TagSearchForm.new(options) + @page_subtitle = ts("Search Tags") + + return if params[:tag_search].blank? + + @page_subtitle = ts("Tags Matching '%{query}'", query: options[:name]) if options[:name].present? + + @tags = @search.search_results + flash_search_warnings(@tags) + end + + def show + @page_subtitle = @tag.name + if @tag.is_a?(Banned) && !logged_in_as_admin? + flash[:error] = t("admin.access.not_admin_denied") + redirect_to(tag_wranglings_path) && return + end + # if tag is NOT wrangled, prepare to show works and bookmarks that are using it + if !@tag.canonical && !@tag.merger + @works = if logged_in? # current_user.is_a?User + @tag.works.visible_to_registered_user.paginate(page: params[:page]) + elsif logged_in_as_admin? + @tag.works.visible_to_admin.paginate(page: params[:page]) + else + @tag.works.visible_to_all.paginate(page: params[:page]) + end + @bookmarks = @tag.bookmarks.visible.paginate(page: params[:page]) + end + # cache the children, since it's a possibly massive query + @tag_children = Rails.cache.fetch "views/tags/#{@tag.cache_key}/children" do + children = {} + (@tag.child_types - %w(SubTag)).each do |child_type| + tags = @tag.send(child_type.underscore.pluralize).order('taggings_count_cache DESC').limit(ArchiveConfig.TAG_LIST_LIMIT + 1) + children[child_type] = tags.to_a.uniq unless tags.blank? + end + children + end + end + + def feed + begin + @tag = Tag.find(params[:id]) + rescue ActiveRecord::RecordNotFound + raise ActiveRecord::RecordNotFound, "Couldn't find tag with id '#{params[:id]}'" + end + @tag = @tag.merger if !@tag.canonical? && @tag.merger + # Temp for testing + if %w(Fandom Character Relationship).include?(@tag.type.to_s) || @tag.name == 'F/F' + if @tag.canonical? + @works = @tag.filtered_works.visible_to_all.order('created_at DESC').limit(25) + else + @works = @tag.works.visible_to_all.order('created_at DESC').limit(25) + end + else + redirect_to(tag_works_path(tag_id: @tag.to_param)) && return + end + + respond_to do |format| + format.html + format.atom + end + end + + def show_hidden + unless params[:creation_id].blank? || params[:creation_type].blank? || params[:tag_type].blank? + model = case params[:creation_type].downcase + when "series" + Series + when "work" + Work + when "chapter" + Chapter + end + @display_creation = model.find(params[:creation_id]) if model.is_a? Class + + # Tags aren't directly on series, so we need to handle them differently + if params[:creation_type] == 'Series' + if params[:tag_type] == 'warnings' + @display_tags = @display_creation.works.visible.collect(&:archive_warnings).flatten.compact.uniq.sort + else + @display_tags = @display_creation.works.visible.collect(&:freeforms).flatten.compact.uniq.sort + end + else + @display_tags = case params[:tag_type] + when 'warnings' + @display_creation.archive_warnings + when 'freeforms' + @display_creation.freeforms + end + end + + # The string used in views/tags/show_hidden.js.erb + if params[:tag_type] == 'warnings' + @display_category = 'warnings' + else + @display_category = @display_tags.first.class.name.tableize + end + end + + respond_to do |format| + format.html do + # This is just a quick fix to avoid script barf if JavaScript is disabled + flash[:error] = ts('Sorry, you need to have JavaScript enabled for this.') + if request.env['HTTP_REFERER'] + redirect_to(request.env['HTTP_REFERER'] || root_path) + else + # else branch needed to deal with bots, which don't have a referer + redirect_to '/' + end + end + format.js + end + end + + # GET /tags/new + def new + authorize :wrangling if logged_in_as_admin? + + @tag = Tag.new + + respond_to do |format| + format.html # new.html.erb + end + end + + # POST /tags + def create + type = tag_params[:type] if params[:tag] + + unless type + flash[:error] = ts("Please provide a category.") + @tag = Tag.new(name: tag_params[:name]) + render(action: "new") + return + end + + raise "Redshirt: Attempted to constantize invalid class initialize create #{type.classify}" unless Tag::TYPES.include?(type.classify) + + model = begin + type.classify.constantize + rescue StandardError + nil + end + @tag = model.find_or_create_by_name(tag_params[:name]) if model.is_a? Class + + unless @tag&.valid? + render(action: "new") + return + end + + if @tag.id_previously_changed? # i.e. tag is new + @tag.update_attribute(:canonical, tag_params[:canonical]) + flash[:notice] = ts("Tag was successfully created.") + else + flash[:notice] = ts("Tag already existed and was not modified.") + end + + redirect_to edit_tag_path(@tag) + end + + def edit + authorize :wrangling, :read_access? if logged_in_as_admin? + + @page_subtitle = ts('%{tag_name} - Edit', tag_name: @tag.name) + + if @tag.is_a?(Banned) && !logged_in_as_admin? + flash[:error] = ts('Please log in as admin') + + redirect_to(tag_wranglings_path) && return + end + + @counts = {} + @uses = ['Works', 'Drafts', 'Bookmarks', 'Private Bookmarks', 'External Works', 'Taggings Count'] + @counts['Works'] = @tag.visible_works_count + @counts['Drafts'] = @tag.works.unposted.count + @counts['Bookmarks'] = @tag.visible_bookmarks_count + @counts['Private Bookmarks'] = @tag.bookmarks.not_public.count + @counts['External Works'] = @tag.visible_external_works_count + @counts['Taggings Count'] = @tag.taggings_count + + @parents = @tag.parents.order(:name).group_by { |tag| tag[:type] } + @parents['MetaTag'] = @tag.direct_meta_tags.by_name + @children = @tag.children.order(:name).group_by { |tag| tag[:type] } + @children['SubTag'] = @tag.direct_sub_tags.by_name + @children['Merger'] = @tag.mergers.by_name + + if @tag.respond_to?(:wranglers) + @wranglers = @tag.canonical ? @tag.wranglers : (@tag.merger ? @tag.merger.wranglers : []) + elsif @tag.respond_to?(:fandoms) && !@tag.fandoms.empty? + @wranglers = @tag.fandoms.collect(&:wranglers).flatten.uniq + end + @suggested_fandoms = @tag.suggested_parent_tags("Fandom") - @tag.fandoms if @tag.respond_to?(:fandoms) + end + + def update + authorize :wrangling if logged_in_as_admin? + + # update everything except for the synonym, + # so that the associations are there to move when the synonym is created + syn_string = params[:tag].delete(:syn_string) + new_tag_type = params[:tag].delete(:type) + + # Limiting the conditions under which you can update the tag type + types = logged_in_as_admin? ? (Tag::USER_DEFINED + %w[Media]) : Tag::USER_DEFINED + @tag = @tag.recategorize(new_tag_type) if @tag.can_change_type? && (types + %w[UnsortedTag]).include?(new_tag_type) + + unless params[:tag].empty? + @tag.attributes = tag_params + end + + @tag.syn_string = syn_string if @tag.errors.empty? && @tag.save + + if @tag.errors.empty? && @tag.save + flash[:notice] = ts('Tag was updated.') + redirect_to edit_tag_path(@tag) + else + @parents = @tag.parents.order(:name).group_by { |tag| tag[:type] } + @parents['MetaTag'] = @tag.direct_meta_tags.by_name + @children = @tag.children.order(:name).group_by { |tag| tag[:type] } + @children['SubTag'] = @tag.direct_sub_tags.by_name + @children['Merger'] = @tag.mergers.by_name + + render :edit + end + end + + def wrangle + authorize :wrangling, :read_access? if logged_in_as_admin? + + @page_subtitle = ts('%{tag_name} - Wrangle', tag_name: @tag.name) + @counts = {} + @tag.child_types.map { |t| t.underscore.pluralize.to_sym }.each do |tag_type| + @counts[tag_type] = @tag.send(tag_type).count + end + + show = params[:show] + if %w(fandoms characters relationships freeforms sub_tags mergers).include?(show) + params[:sort_column] = 'name' unless valid_sort_column(params[:sort_column], 'tag') + params[:sort_direction] = 'ASC' unless valid_sort_direction(params[:sort_direction]) + sort = params[:sort_column] + ' ' + params[:sort_direction] + # add a secondary sorting key when the main one is not discerning enough + if sort.include?('suggested') || sort.include?('taggings_count_cache') + sort += ', name ASC' + end + # this makes sure params[:status] is safe + status = params[:status] + @tags = if %w[unfilterable canonical synonymous unwrangleable].include?(status) + @tag.send(show).reorder(sort).send(status).paginate(page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE) + elsif status == "unwrangled" + @tag.unwrangled_tags( + params[:show].singularize.camelize, + params.permit!.slice(:sort_column, :sort_direction, :page) + ) + else + @tag.send(show).reorder(sort).paginate(page: params[:page], per_page: ArchiveConfig.ITEMS_PER_PAGE) + end + end + end + + def mass_update + authorize :wrangling if logged_in_as_admin? + + params[:page] = '1' if params[:page].blank? + params[:sort_column] = 'name' unless valid_sort_column(params[:sort_column], 'tag') + params[:sort_direction] = 'ASC' unless valid_sort_direction(params[:sort_direction]) + options = { show: params[:show], page: params[:page], sort_column: params[:sort_column], sort_direction: params[:sort_direction], status: params[:status] } + + error_messages = [] + notice_messages = [] + + # make tags canonical if allowed + if params[:canonicals].present? && params[:canonicals].is_a?(Array) + saved_canonicals = [] + not_saved_canonicals = [] + tags = Tag.where(id: params[:canonicals]) + + tags.each do |tag_to_canonicalize| + if tag_to_canonicalize.update(canonical: true) + saved_canonicals << tag_to_canonicalize + else + not_saved_canonicals << tag_to_canonicalize + end + end + + error_messages << ts('The following tags couldn\'t be made canonical: %{tags_not_saved}', tags_not_saved: not_saved_canonicals.collect(&:name).join(', ')) unless not_saved_canonicals.empty? + notice_messages << ts('The following tags were successfully made canonical: %{tags_saved}', tags_saved: saved_canonicals.collect(&:name).join(', ')) unless saved_canonicals.empty? + end + + # remove associated tags + if params[:remove_associated].present? && params[:remove_associated].is_a?(Array) + saved_removed_associateds = [] + not_saved_removed_associateds = [] + tags = Tag.where(id: params[:remove_associated]) + + tags.each do |tag_to_remove| + if @tag.remove_association(tag_to_remove.id) + saved_removed_associateds << tag_to_remove + else + not_saved_removed_associateds << tag_to_remove + end + end + + error_messages << ts('The following tags couldn\'t be removed: %{tags_not_saved}', tags_not_saved: not_saved_removed_associateds.collect(&:name).join(', ')) unless not_saved_removed_associateds.empty? + notice_messages << ts('The following tags were successfully removed: %{tags_saved}', tags_saved: saved_removed_associateds.collect(&:name).join(', ')) unless saved_removed_associateds.empty? + end + + # wrangle to fandom(s) + if params[:fandom_string].blank? && params[:selected_tags].is_a?(Array) && !params[:selected_tags].empty? + error_messages << ts('There were no Fandom tags!') + end + if params[:fandom_string].present? && params[:selected_tags].is_a?(Array) && !params[:selected_tags].empty? + canonical_fandoms = [] + noncanonical_fandom_names = [] + fandom_names = params[:fandom_string].split(',').map(&:squish) + + fandom_names.each do |fandom_name| + if (fandom = Fandom.find_by_name(fandom_name)).try(:canonical?) + canonical_fandoms << fandom + else + noncanonical_fandom_names << fandom_name + end + end + + if canonical_fandoms.present? + saved_to_fandoms = Tag.where(id: params[:selected_tags]) + + saved_to_fandoms.each do |tag_to_wrangle| + canonical_fandoms.each do |fandom| + tag_to_wrangle.add_association(fandom) + end + end + + canonical_fandom_names = canonical_fandoms.collect(&:name) + options[:fandom_string] = canonical_fandom_names.join(',') + notice_messages << ts('The following tags were successfully wrangled to %{canonical_fandoms}: %{tags_saved}', canonical_fandoms: canonical_fandom_names.join(', '), tags_saved: saved_to_fandoms.collect(&:name).join(', ')) unless saved_to_fandoms.empty? + end + + if noncanonical_fandom_names.present? + error_messages << ts('The following names are not canonical fandoms: %{noncanonical_fandom_names}.', noncanonical_fandom_names: noncanonical_fandom_names.join(', ')) + end + end + + flash[:notice] = notice_messages.join('
').html_safe unless notice_messages.empty? + flash[:error] = error_messages.join('
').html_safe unless error_messages.empty? + + redirect_to url_for({ controller: :tags, action: :wrangle, id: params[:id] }.merge(options)) + end + + private + + def tag_params + params.require(:tag).permit( + :name, :type, :canonical, :unwrangleable, :adult, :sortable_name, + :meta_tag_string, :sub_tag_string, :merger_string, :syn_string, + :media_string, :fandom_string, :character_string, :relationship_string, + :freeform_string, + associations_to_remove: [] + ) + end + + def tag_search_params + params.require(:tag_search).permit( + :query, + :name, + :fandoms, + :type, + :canonical, + :wrangling_status, + :created_at, + :uses, + :sort_column, + :sort_direction + ) + end +end diff --git a/app/controllers/troubleshooting_controller.rb b/app/controllers/troubleshooting_controller.rb new file mode 100755 index 0000000..f1eb0ff --- /dev/null +++ b/app/controllers/troubleshooting_controller.rb @@ -0,0 +1,197 @@ +# frozen_string_literal: true + +# A controller used to let admins and tag wranglers perform some +# troubleshooting on tags and works. +class TroubleshootingController < ApplicationController + before_action :check_permission_to_wrangle + before_action :load_item + before_action :check_visibility + + # Display options for troubleshooting. + def show + @item_type = @item.class.base_class.to_s.underscore + @page_subtitle = t(".page_title.#{@item_type}") + end + + # Perform the desired troubleshooting actions. + def update + actions = params.fetch(:actions, []).map(&:to_s).reject(&:blank?) + + disallowed = actions - @allowed_actions + + if disallowed.any? + disallowed_names = disallowed.map do |action| + t("troubleshooting.show.#{action}.title", default: action.titleize) + end + + flash[:error] = + ts("The following actions aren't allowed: %{actions}.", + actions: disallowed_names.to_sentence) + + redirect_to troubleshooting_path + return + end + + flash[:notice] = [] + flash[:error] = [] + + (@allowed_actions & actions).each do |action| + send(action) + end + + # Make sure that we don't show blank errors. + flash[:notice] = nil if flash[:notice].blank? + flash[:error] = nil if flash[:error].blank? + + redirect_to item_path + end + + protected + + # Calculate the permitted actions based on the item type and whether the + # current user is an admin. This is used in the show action to figure out + # which options to display, and in the update action to figure out which + # actions to perform. + # + # In order to work properly, this needs to return a list of strings, and each + # string needs to be the name of an instance method in this class. To make + # the list of options display properly (with a name and a description), each + # of these names also needs a corresponding title and description entry in + # the i18n scope en.troubleshooting.show. + def allowed_actions + if @item.is_a?(Tag) + allowed_actions_for_tag + elsif @item.is_a?(Work) + allowed_actions_for_work + end + end + + # Decide which options should be available when we're troubleshooting a tag. + def allowed_actions_for_tag + if logged_in_as_admin? + %w[fix_associations fix_counts fix_meta_tags update_tag_filters reindex_tag] + else + %w[fix_associations fix_counts fix_meta_tags] + end + end + + # Decide which options should be available when we're troubleshooting a work. + def allowed_actions_for_work + if logged_in_as_admin? + %w[update_work_filters reindex_work] + else + %w[update_work_filters] + end + end + + # Let the views use these two path methods. + helper_method :item_path, :troubleshooting_path + + # The path to view the item. Ideally we could just do redirect_to @item, but + # unfortunately we're dealing with tags, which have numerous subclasses. + def item_path + if @item.is_a?(Tag) + tag_path(@item) + else + polymorphic_path(@item) + end + end + + # The path to view the troubleshooting page for this item. Again, this is + # necessary because tags have a lot of subclasses and need special handling. + def troubleshooting_path + if @item.is_a?(Tag) + tag_troubleshooting_path(@item) + else + polymorphic_path([@item, :troubleshooting]) + end + end + + # Load the @item based on params. Results in a 404 error if the item in + # question can't be found, and a 500 error if there's an unknown type. Also + # sets the variable @allowed_actions. + def load_item + if params[:tag_id] + @item = Tag.find_by_name(params[:tag_id]) + + if @item.nil? + raise ActiveRecord::RecordNotFound, + ts("Could not find tag with name '%{name}'", + name: params[:tag_id]) + end + elsif params[:work_id] + @item = Work.find(params[:work_id]) + else + raise "Unknown item type!" + end + + @check_visibility_of = @item + @allowed_actions = allowed_actions + end + + ######################################## + # AVAILABLE ACTIONS + ######################################## + + # An action allowing the user to reindex a work. + def reindex_work + @item.enqueue_to_index + flash[:notice] << ts("Work sent to be reindexed.") + end + + # An action allowing the user to reindex a tag (and everything related to it). + def reindex_tag + @item.async(:reindex_associated, true) + flash[:notice] << ts("Tag reindex job added to queue.") + end + + # An action allowing the user to try to fix the filters for this tag and all + # of its synonyms. + def update_tag_filters + @item.async(:update_filters_for_taggables) + + @item.mergers.find_each do |syn| + syn.async(:update_filters_for_taggables) + end + + flash[:notice] << ts("Tagged items enqueued for filter updates.") + end + + # An action allowing the user to try to fix a single work's filters. + def update_work_filters + @item.update_filters + flash[:notice] << ts("Work filters updated.") + end + + # An action allowing the user to try to fix the filter count and taggings + # count. + def fix_counts + @item.filter_count&.update_counts + @item.update(taggings_count: @item.taggings.count) + flash[:notice] << ts("Tag counts updated.") + end + + # An action allowing the user to try to fix the inherited metatags. + def fix_meta_tags + modified = MetaTagging.transaction do + InheritedMetaTagUpdater.new(@item).update + end + + if modified + # Fixing the meta taggings is all well and good, but unless the filters + # are adjusted too, this will have no immediate effects. + @item.async(:update_filters_for_filterables) + flash[:notice] << ts("Inherited metatags recalculated. This tag has " \ + "also been enqueued to have its filters fixed.") + else + flash[:notice] << ts("Inherited metatags recalculated. No incorrect " \ + "metatags found.") + end + end + + # An action allowing the user to try to delete invalid associations. + def fix_associations + @item.async(:destroy_invalid_associations) + flash[:notice] << ts("Tag association job enqueued.") + end +end diff --git a/app/controllers/unsorted_tags_controller.rb b/app/controllers/unsorted_tags_controller.rb new file mode 100755 index 0000000..cf8afdd --- /dev/null +++ b/app/controllers/unsorted_tags_controller.rb @@ -0,0 +1,31 @@ +class UnsortedTagsController < ApplicationController + include WranglingHelper + + before_action :check_user_status + before_action :check_permission_to_wrangle + + def index + authorize :wrangling, :read_access? if logged_in_as_admin? + + @tags = UnsortedTag.page(params[:page]) + @counts = tag_counts_per_category + end + + def mass_update + authorize :wrangling if logged_in_as_admin? + + if params[:tags].present? + params[:tags].delete_if { |_, tag_type| tag_type.blank? } + tags = UnsortedTag.where(id: params[:tags].keys) + tags.each do |tag| + new_type = params[:tags][tag.id.to_s] + raise "#{new_type} is not a valid tag type" unless Tag::USER_DEFINED.include?(new_type) + + tag.update_attribute(:type, new_type) + end + flash[:notice] = ts("Tags were successfully sorted.") + end + redirect_to unsorted_tags_path(page: params[:page]) + end + +end diff --git a/app/controllers/user_invite_requests_controller.rb b/app/controllers/user_invite_requests_controller.rb new file mode 100755 index 0000000..d4f2695 --- /dev/null +++ b/app/controllers/user_invite_requests_controller.rb @@ -0,0 +1,86 @@ +class UserInviteRequestsController < ApplicationController + before_action :admin_only, except: [:new, :create] + before_action :check_user_status, only: [:new, :create] + + # GET /user_invite_requests + # GET /user_invite_requests.xml + def index + @user_invite_requests = UserInviteRequest.not_handled.page(params[:page]) + end + + # GET /user_invite_requests/new + # GET /user_invite_requests/new.xml + def new + @page_title = ts('New User Invitation Request') + if AdminSetting.request_invite_enabled? + if logged_in? + @user = current_user + @user_invite_request = @user.user_invite_requests.build + else + flash[:error] = ts("Please log in.") + redirect_to new_user_session_path + end + else + flash[:error] = ts("Sorry, additional invitations are unavailable. Please use the queue! If you are the mod of a challenge currently being run on the Archive, please contact Support. If you are the maintainer of an at-risk archive, please contact Open Doors.".html_safe) + redirect_to root_path + end + end + # POST /user_invite_requests + # POST /user_invite_requests.xml + def create + if AdminSetting.request_invite_enabled? + if logged_in? + @user = current_user + @user_invite_request = @user.user_invite_requests.build(user_invite_request_params) + else + flash[:error] = "Please log in." + redirect_to new_user_session_path + end + if @user_invite_request.save + flash[:notice] = 'Request was successfully created.' + redirect_to(@user) + else + render action: "new" + end + else + flash[:error] = ts("Sorry, new invitations are temporarily unavailable. If you are the mod of a challenge currently being run on the Archive, please contact Support. If you are the maintainer of an at-risk archive, please contact Open Doors".html_safe) + redirect_to root_path + end + end + + # PUT /user_invite_requests/1 + # PUT /user_invite_requests/1.xml + def update + if params[:decline_all] + params[:requests].each_pair do |id, quantity| + unless quantity.blank? + request = UserInviteRequest.find(id) + user = User.find(request.user_id) + requested_total = request.quantity.to_i + request.quantity = 0 + request.save! + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.invite_request_declined(request.user_id, requested_total, request.reason).deliver_later + end + end + end + flash[:notice] = 'All Requests were declined.' + redirect_to user_invite_requests_path and return + end + params[:requests].each_pair do |id, quantity| + unless quantity.blank? + request = UserInviteRequest.find(id) + request.quantity = quantity.to_i + request.save! + end + end + flash[:notice] = ts("Requests were successfully updated.") + redirect_to user_invite_requests_path + end + + private + + def user_invite_request_params + params.require(:user_invite_request).permit(:quantity, :reason) + end +end diff --git a/app/controllers/users/passwords_controller.rb b/app/controllers/users/passwords_controller.rb new file mode 100755 index 0000000..6c05174 --- /dev/null +++ b/app/controllers/users/passwords_controller.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# Use for resetting lost passwords +class Users::PasswordsController < Devise::PasswordsController + before_action :admin_logout_required + skip_before_action :store_location + layout "session" + + def create + user = User.find_for_authentication(resource_params.permit(:login)) + if user.nil? || user.new_record? + flash[:error] = t(".user_not_found") + redirect_to new_user_password_path and return + end + + if user.prevent_password_resets? + flash[:error] = t(".reset_blocked_html", contact_abuse_link: view_context.link_to(t(".contact_abuse"), new_abuse_report_path)) + redirect_to root_path and return + elsif user.password_resets_limit_reached? + available_time = ApplicationController.helpers.time_in_zone( + user.password_resets_available_time, nil, user + ) + + flash[:error] = t(".reset_cooldown_html", reset_available_time: available_time) + redirect_to root_path and return + end + + user.update_password_resets_requested + user.save + + super + end + + protected + + # We need to include information about the user (the remaining reset attempts) + # in addition to the configured reset cooldown in the success message. + # Otherwise, we would just override `devise_i18n_options` instead of this method. + def successfully_sent?(resource) + return super if Devise.paranoid + return unless resource.errors.empty? + + flash[:notice] = t("users.passwords.create.send_instructions", + send_times_remaining: t("users.passwords.create.send_times_remaining", + count: resource.password_resets_remaining), + send_cooldown_period: t("users.passwords.create.send_cooldown_period", + count: ArchiveConfig.PASSWORD_RESET_COOLDOWN_HOURS)) + end + + def after_resetting_password_path_for(resource) + resource.create_log_item(action: ArchiveConfig.ACTION_PASSWORD_RESET) + super + end +end diff --git a/app/controllers/users/registrations_controller.rb b/app/controllers/users/registrations_controller.rb new file mode 100755 index 0000000..4a0ca27 --- /dev/null +++ b/app/controllers/users/registrations_controller.rb @@ -0,0 +1,98 @@ +class Users::RegistrationsController < Devise::RegistrationsController + before_action :check_account_creation_status + before_action :configure_permitted_parameters + + def new + @page_subtitle = t(".page_title") + super do |resource| + if params[:invitation_token] + @invitation = Invitation.find_by(token: params[:invitation_token]) + resource.invitation_token = @invitation.token + resource.email = @invitation.invitee_email + end + + @hide_dashboard = true + end + end + + def create + @page_subtitle = t(".page_title") + @hide_dashboard = true + build_resource(sign_up_params) + + resource.transaction do + # skip sending the Devise confirmation notification + resource.skip_confirmation_notification! + resource.invitation_token = params[:invitation_token] + if resource.save + notify_and_show_confirmation_screen + else + render action: "new" + end + end + end + + private + + def notify_and_show_confirmation_screen + # deliver synchronously to avoid getting caught in backed-up mail queue + UserMailer.signup_notification(resource.id).deliver_now + + flash[:notice] = ts("During testing you can activate via your activation url.", + activation_url: activate_path(resource.confirmation_token)).html_safe if Rails.env.development? + + render 'users/confirmation' + end + + def configure_permitted_parameters + params[:user] = params[:user_registration]&.merge( + accepted_tos_version: @current_tos_version + ) + devise_parameter_sanitizer.permit( + :sign_up, + keys: [ + :password_confirmation, :email, :age_over_13, :data_processing, :terms_of_service, :accepted_tos_version + ] + ) + end + + def check_account_creation_status + if is_registered_user? + flash[:error] = ts('You are already logged in!') + redirect_to root_path and return + end + + token = params[:invitation_token] + + if !AdminSetting.current.account_creation_enabled? + flash[:error] = ts('Account creation is suspended at the moment. Please check back with us later.') + redirect_to root_path and return + else + check_account_creation_invite(token) if AdminSetting.current.creation_requires_invite? + end + end + + def check_account_creation_invite(token) + unless token.blank? + invitation = Invitation.find_by(token: token) + + if !invitation + flash[:error] = ts('There was an error with your invitation token, please contact support') + redirect_to new_feedback_report_path + elsif invitation.redeemed_at + flash[:error] = ts('This invitation has already been used to create an account, sorry!') + redirect_to root_path + end + + return + end + + if !AdminSetting.current.invite_from_queue_enabled? + flash[:error] = ts('Account creation currently requires an invitation. We are unable to give out additional invitations at present, but existing invitations can still be used to create an account.') + redirect_to root_path + else + flash[:error] = ts("To create an account, you'll need an invitation. One option is to add your name to the automatic queue below.") + redirect_to invite_requests_path + end + end +end diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb new file mode 100755 index 0000000..d44bb62 --- /dev/null +++ b/app/controllers/users/sessions_controller.rb @@ -0,0 +1,36 @@ +class Users::SessionsController < Devise::SessionsController + + layout "session" + before_action :admin_logout_required + skip_before_action :store_location + + # POST /users/login + def create + super do |resource| + unless resource.remember_me + message = ts(" You'll stay logged in for %{number} weeks even if you close your browser, so make sure to log out if you're using a public or shared computer.", number: ArchiveConfig.DEFAULT_SESSION_LENGTH_IN_WEEKS) + end + flash[:notice] += message unless message.nil? + flash[:notice] = flash[:notice].html_safe + end + end + + # GET /users/logout + def confirm_logout + # If the user is already logged out, we just redirect to the front page. + redirect_to root_path unless user_signed_in? + end + + # DELETE /users/logout + def destroy + # signed_out clears the session + return_to = session[:return_to] + + signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)) + set_flash_message! :notice, :signed_out if signed_out + + session[:return_to] = return_to + + redirect_back_or_default root_path + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100755 index 0000000..4cf17c4 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,418 @@ +class UsersController < ApplicationController + cache_sweeper :pseud_sweeper + + before_action :check_user_status, only: [:edit, :update, :change_username, :changed_username] + before_action :load_user, except: [:activate, :delete_confirmation, :index] + before_action :check_ownership, except: [:activate, :change_username, :changed_username, :delete_confirmation, :edit, :index, :show, :update] + before_action :check_ownership_or_admin, only: [:change_username, :changed_username, :edit, :update] + skip_before_action :store_location, only: [:end_first_login] + + def load_user + @user = User.find_by!(login: params[:id]) + @check_ownership_of = @user + end + + def index + flash.keep + redirect_to controller: :people, action: :index + end + + # GET /users/1 + def show + @page_subtitle = @user.login + @status = @user.statuses.last + visible = visible_items(current_user) + + @works = visible[:works].order('revised_at DESC').limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) + @series = visible[:series].order('updated_at DESC').limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) + @bookmarks = visible[:bookmarks].order('updated_at DESC').limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD) + if current_user.respond_to?(:subscriptions) + @subscription = current_user.subscriptions.where(subscribable_id: @user.id, + subscribable_type: 'User').first || + current_user.subscriptions.build(subscribable: @user) + end + end + + # GET /users/1/edit + def edit + @page_subtitle = t(".browser_title") + authorize @user.profile if logged_in_as_admin? + end + + def change_email + @page_subtitle = t(".page_title") + end + + def change_password + @page_subtitle = t(".page_title") + end + + def change_username + authorize @user if logged_in_as_admin? + @page_subtitle = t(".page_title") + end + + def changed_password + unless params[:password] && reauthenticate + render(:change_password) && return + end + + @user.password = params[:password] + @user.password_confirmation = params[:password_confirmation] + + if @user.save + flash[:notice] = ts("Your password has been changed. To protect your account, you have been logged out of all active sessions. Please log in with your new password.") + @user.create_log_item(action: ArchiveConfig.ACTION_PASSWORD_CHANGE) + + redirect_to(user_profile_path(@user)) && return + else + render(:change_password) && return + end + end + + def changed_username + authorize @user if logged_in_as_admin? + render(:change_username) && return if params[:new_login].blank? + + @new_login = params[:new_login] + + unless logged_in_as_admin? || @user.valid_password?(params[:password]) + flash[:error] = t(".user.incorrect_password") + render(:change_username) && return + end + + if @new_login == @user.login + flash.now[:error] = t(".new_username_must_be_different") + render :change_username and return + end + + old_login = @user.login + @user.login = @new_login + @user.ticket_number = params[:ticket_number] + + if @user.save + if logged_in_as_admin? + flash[:notice] = t(".admin.successfully_updated") + redirect_to admin_user_path(@user) + else + I18n.with_locale(@user.preference.locale_for_mails) do + UserMailer.change_username(@user, old_login).deliver_later + end + + flash[:notice] = t(".user.successfully_updated") + redirect_to @user + end + else + @user.reload + render :change_username + end + end + + def activate + if params[:id].blank? + flash[:error] = ts('Your activation key is missing.') + redirect_to root_path + + return + end + + @user = User.find_by(confirmation_token: params[:id]) + + unless @user + flash[:error] = ts("Your activation key is invalid. If you didn't activate within #{AdminSetting.current.days_to_purge_unactivated * 7} days, your account was deleted. Please sign up again, or contact support via the link in our footer for more help.").html_safe + redirect_to root_path + + return + end + + if @user.active? + flash[:error] = ts("Your account has already been activated.") + redirect_to @user + + return + end + + @user.activate + + flash[:notice] = ts("Account activation complete! Please log in.") + + @user.create_log_item(action: ArchiveConfig.ACTION_ACTIVATE) + + # assign over any external authors that belong to this user + external_authors = [] + external_authors << ExternalAuthor.find_by(email: @user.email) + @invitation = @user.invitation + external_authors << @invitation.external_author if @invitation + external_authors.compact! + + unless external_authors.empty? + external_authors.each do |external_author| + external_author.claim!(@user) + end + + flash[:notice] += ts(" We found some works already uploaded to the Archive of Our Own that we think belong to you! You'll see them on your homepage when you've logged in.") + end + + redirect_to(new_user_session_path) + end + + def update + authorize @user.profile if logged_in_as_admin? + if @user.profile.update(profile_params) + if logged_in_as_admin? && @user.profile.ticket_url.present? + link = view_context.link_to("Ticket ##{@user.profile.ticket_number}", @user.profile.ticket_url) + AdminActivity.log_action(current_admin, @user, action: "edit profile", summary: link) + end + flash[:notice] = ts('Your profile has been successfully updated') + redirect_to user_profile_path(@user) + else + render :edit + end + end + + def confirm_change_email + @page_subtitle = t(".browser_title") + + render :change_email and return unless reauthenticate + + if params[:new_email].blank? + flash.now[:error] = t("users.confirm_change_email.blank_email") + render :change_email and return + end + + @new_email = params[:new_email] + + # Please note: This comparison is not technically correct. According to + # RFC 5321, the local part of an email address is case sensitive, while the + # domain is case insensitive. That said, all major email providers treat + # the local part as case insensitive, so it would probably cause more + # confusion if we did this correctly. + # + # Also, email addresses are validated on the client, and will only contain + # a limited subset of ASCII, so we don't need to do a unicode casefolding pass. + if @new_email.downcase == @user.email.downcase + flash.now[:error] = t("users.confirm_change_email.same_as_current") + render :change_email and return + end + + if @new_email.downcase != params[:email_confirmation].downcase + flash.now[:error] = t("users.confirm_change_email.nonmatching_email") + render :change_email and return + end + + old_email = @user.email + @user.email = @new_email + return if @user.valid?(:update) + + # Make sure that on failure, the form doesn't show the new invalid email as the current one + @user.email = old_email + render :change_email + end + + def changed_email + new_email = params[:new_email] + + old_email = @user.email + @user.email = new_email + + if @user.save + I18n.with_locale(@user.preference.locale_for_mails) do + UserMailer.change_email(@user.id, old_email, new_email).deliver_later + end + else + # Make sure that on failure, the form still shows the old email as the "current" one. + @user.email = old_email + end + + render :change_email + end + + # GET /users/1/reconfirm_email?confirmation_token=abcdef + def reconfirm_email + confirmed_user = User.confirm_by_token(params[:confirmation_token]) + + if confirmed_user.errors.empty? + flash[:notice] = t(".success") + else + flash[:error] = t(".invalid_token") + end + + redirect_to change_email_user_path(@user) + end + + # DELETE /users/1 + # DELETE /users/1.xml + def destroy + @hide_dashboard = true + @works = @user.works.where(posted: true) + @sole_owned_collections = @user.sole_owned_collections + + if @works.empty? && @sole_owned_collections.empty? + @user.wipeout_unposted_works + @user.destroy_empty_series + + @user.destroy + flash[:notice] = ts('You have successfully deleted your account.') + + redirect_to(delete_confirmation_path) + elsif params[:coauthor].blank? && params[:sole_author].blank? + @sole_authored_works = @user.sole_authored_works + @coauthored_works = @user.coauthored_works + + render('delete_preview') && return + elsif params[:coauthor] || params[:sole_author] + destroy_author + end + end + + def delete_confirmation + end + + def end_first_login + @user.preference.update_attribute(:first_login, false) + + respond_to do |format| + format.html { redirect_to(@user) && return } + format.js + end + end + + def end_banner + @user.preference.update_attribute(:banner_seen, true) + + respond_to do |format| + format.html { redirect_to(request.env['HTTP_REFERER'] || root_path) && return } + format.js + end + end + + def end_tos_prompt + @user.update_attribute(:accepted_tos_version, @current_tos_version) + head :no_content + end + + private + + def reauthenticate + if params[:password_check].blank? + return wrong_password!(params[:new_email], + t("users.confirm_change_email.blank_password"), + t("users.changed_password.blank_password")) + end + + if @user.valid_password?(params[:password_check]) + true + else + wrong_password!(params[:new_email], + t("users.confirm_change_email.wrong_password_html", contact_support_link: helpers.link_to(t("users.confirm_change_email.contact_support"), new_feedback_report_path)), + t("users.changed_password.wrong_password")) + end + end + + def wrong_password!(condition, if_true, if_false) + flash.now[:error] = condition ? if_true : if_false + @wrong_password = true + + false + end + + def visible_items(current_user) + # NOTE: When current_user is nil, we use .visible_to_all, otherwise we use + # .visible_to_registered_user. + visible_method = current_user.nil? && current_admin.nil? ? :visible_to_all : :visible_to_registered_user + + visible_works = @user.works.send(visible_method) + visible_series = @user.series.send(visible_method) + visible_bookmarks = @user.bookmarks.send(visible_method) + + visible_works = visible_works.revealed.non_anon + visible_series = visible_series.exclude_anonymous + @fandoms = if @user == User.orphan_account + [] + else + Fandom.select("tags.*, count(DISTINCT works.id) as work_count"). + joins(:filtered_works).group("tags.id").merge(visible_works). + where(filter_taggings: { inherited: false }). + order('work_count DESC').load + end + + { + works: visible_works, + series: visible_series, + bookmarks: visible_bookmarks + } + end + + def destroy_author + @sole_authored_works = @user.sole_authored_works + @coauthored_works = @user.coauthored_works + + if params[:cancel_button] + flash[:notice] = ts('Account deletion canceled.') + redirect_to user_profile_path(@user) + + return + end + + if params[:coauthor] == 'keep_pseud' || params[:coauthor] == 'orphan_pseud' + # Orphans co-authored works. + + pseuds = @user.pseuds + works = @coauthored_works + + # We change the pseud to the default orphan pseud if use_default is true. + use_default = params[:use_default] == 'true' || params[:coauthor] == 'orphan_pseud' + + Creatorship.orphan(pseuds, works, use_default) + + elsif params[:coauthor] == 'remove' + # Removes user as an author from co-authored works + + @coauthored_works.each do |w| + w.remove_author(@user) + end + end + + if params[:sole_author] == 'keep_pseud' || params[:sole_author] == 'orphan_pseud' + # Orphans works where user is the sole author. + + pseuds = @user.pseuds + works = @sole_authored_works + + # We change the pseud to default orphan pseud if use_default is true. + use_default = params[:use_default] == 'true' || params[:sole_author] == 'orphan_pseud' + + Creatorship.orphan(pseuds, works, use_default) + Collection.orphan(pseuds, @sole_owned_collections, default: use_default) + elsif params[:sole_author] == 'delete' + # Deletes works where user is sole author + @sole_authored_works.each(&:destroy) + + # Deletes collections where user is sole author + @sole_owned_collections.each(&:destroy) + end + + @works = @user.works.where(posted: true) + + if @works.blank? + @user.wipeout_unposted_works + @user.destroy_empty_series + + @user.destroy + + flash[:notice] = ts('You have successfully deleted your account.') + redirect_to(delete_confirmation_path) + else + flash[:error] = ts('Sorry, something went wrong! Please try again.') + redirect_to(@user) + end + end + + private + + def profile_params + params.require(:profile_attributes).permit( + :title, :about_me, :ticket_number + ) + end +end diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb new file mode 100755 index 0000000..ec65bdc --- /dev/null +++ b/app/controllers/works_controller.rb @@ -0,0 +1,984 @@ +# encoding=utf-8 + +class WorksController < ApplicationController + # only registered users and NOT admin should be able to create new works + before_action :load_collection + before_action :load_owner, only: [:index] + before_action :users_only, except: [:index, :show, :navigate, :search, :collected, :edit_tags, :update_tags, :drafts, :share] + before_action :check_user_status, except: [:index, :edit, :edit_multiple, :confirm_delete_multiple, :delete_multiple, :confirm_delete, :destroy, :show, :show_multiple, :navigate, :search, :collected, :share] + before_action :check_user_not_suspended, only: [:edit, :confirm_delete, :destroy, :show_multiple, :edit_multiple, :confirm_delete_multiple, :delete_multiple] + before_action :load_work, except: [:new, :create, :import, :index, :show_multiple, :edit_multiple, :update_multiple, :delete_multiple, :search, :drafts, :collected] + # this only works to check ownership of a SINGLE item and only if load_work has happened beforehand + before_action :check_ownership, except: [:index, :show, :navigate, :new, :create, :import, :show_multiple, :edit_multiple, :edit_tags, :update_tags, :update_multiple, :delete_multiple, :search, :mark_for_later, :mark_as_read, :drafts, :collected, :share] + # admins should have the ability to edit tags (:edit_tags, :update_tags) as per our ToS + before_action :check_ownership_or_admin, only: [:edit_tags, :update_tags] + before_action :log_admin_activity, only: [:update_tags] + before_action :check_parent_visible, only: [:navigate] + before_action :check_visibility, only: [:show, :navigate, :share, :mark_for_later, :mark_as_read] + + before_action :load_first_chapter, only: [:show, :edit, :update, :preview] + + cache_sweeper :collection_sweeper + cache_sweeper :feed_sweeper + + skip_before_action :store_location, only: [:share] + + # we want to extract the countable params from work_search and move them into their fields + def clean_work_search_params + QueryCleaner.new(work_search_params || {}).clean + end + + def search + @languages = Language.default_order + options = params[:work_search].present? ? clean_work_search_params : {} + options[:page] = params[:page] if params[:page].present? + options[:show_restricted] = current_user.present? || logged_in_as_admin? + @search = WorkSearchForm.new(options) + @page_subtitle = ts("Search Works") + + if params[:work_search].present? && params[:edit_search].blank? + if @search.query.present? + @page_subtitle = ts("Works Matching '%{query}'", query: @search.query) + end + + @works = @search.search_results.scope(:for_blurb) + set_own_works + flash_search_warnings(@works) + render 'search_results' + end + end + + # GET /works + def index + base_options = { + page: params[:page] || 1, + show_restricted: current_user.present? || logged_in_as_admin? + } + + options = params[:work_search].present? ? clean_work_search_params : {} + + if params[:fandom_id].present? || (@collection.present? && @tag.present?) + @fandom = Fandom.find(params[:fandom_id]) if params[:fandom_id] + + tag = @fandom || @tag + + options[:filter_ids] ||= [] + options[:filter_ids] << tag.id + end + + if params[:include_work_search].present? + params[:include_work_search].keys.each do |key| + options[key] ||= [] + options[key] << params[:include_work_search][key] + options[key].flatten! + end + end + + if params[:exclude_work_search].present? + params[:exclude_work_search].keys.each do |key| + options[:excluded_tag_ids] ||= [] + options[:excluded_tag_ids] << params[:exclude_work_search][key] + options[:excluded_tag_ids].flatten! + end + end + + options.merge!(base_options) + @page_subtitle = index_page_title + + if logged_in? && @tag + @favorite_tag = @current_user.favorite_tags + .where(tag_id: @tag.id).first || + FavoriteTag + .new(tag_id: @tag.id, user_id: @current_user.id) + end + + if @owner.present? + @search = WorkSearchForm.new(options.merge(faceted: true, works_parent: @owner)) + # If we're using caching we'll try to get the results from cache + # Note: we only cache some first initial number of pages since those are biggest bang for + # the buck -- users don't often go past them + if use_caching? && params[:work_search].blank? && params[:fandom_id].blank? && + params[:include_work_search].blank? && params[:exclude_work_search].blank? && + (params[:page].blank? || params[:page].to_i <= ArchiveConfig.PAGES_TO_CACHE) + # the subtag is for eg collections/COLL/tags/TAG + subtag = @tag.present? && @tag != @owner ? @tag : nil + user = logged_in? || logged_in_as_admin? ? 'logged_in' : 'logged_out' + @works = Rails.cache.fetch("#{@owner.works_index_cache_key(subtag)}_#{user}_page#{params[:page]}_true", expires_in: ArchiveConfig.SECONDS_UNTIL_WORK_INDEX_EXPIRE.seconds) do + results = @search.search_results.scope(:for_blurb) + # calling this here to avoid frozen object errors + results.items + results.facets + results + end + else + @works = @search.search_results.scope(:for_blurb) + end + + flash_search_warnings(@works) + + @facets = @works.facets + if @search.options[:excluded_tag_ids].present? && @facets + tags = Tag.where(id: @search.options[:excluded_tag_ids]) + tags.each do |tag| + @facets[tag.class.to_s.underscore] ||= [] + @facets[tag.class.to_s.underscore] << QueryFacet.new(tag.id, tag.name, 0) + end + end + elsif use_caching? + @works = Rails.cache.fetch('works/index/latest/v1', expires_in: ArchiveConfig.SECONDS_UNTIL_WORK_INDEX_EXPIRE.seconds) do + Work.latest.for_blurb.to_a + end + else + @works = Work.latest.for_blurb.to_a + end + set_own_works + + @pagy = pagy_query_result(@works) if @works.respond_to?(:total_pages) + end + + def collected + options = params[:work_search].present? ? clean_work_search_params : {} + options[:page] = params[:page] || 1 + options[:show_restricted] = current_user.present? || logged_in_as_admin? + + @user = User.find_by!(login: params[:user_id]) + @search = WorkSearchForm.new(options.merge(works_parent: @user, collected: true)) + @works = @search.search_results.scope(:for_blurb) + flash_search_warnings(@works) + @facets = @works.facets + set_own_works + @page_subtitle = ts('%{username} - Collected Works', username: @user.login) + end + + def drafts + unless params[:user_id] && (@user = User.find_by(login: params[:user_id])) + flash[:error] = ts('Whose drafts did you want to look at?') + redirect_to users_path + return + end + + unless current_user == @user || logged_in_as_admin? + flash[:error] = ts('You can only see your own drafts, sorry!') + redirect_to logged_in? ? user_path(current_user) : new_user_session_path + return + end + + @page_subtitle = t(".page_title", username: @user.login) + + if params[:pseud_id] + @pseud = @user.pseuds.find_by(name: params[:pseud_id]) + @works = @pseud.unposted_works.for_blurb.paginate(page: params[:page]) + else + @works = @user.unposted_works.for_blurb.paginate(page: params[:page]) + end + end + + # GET /works/1 + # GET /works/1.xml + def show + @tag_groups = @work.tag_groups + if @work.unrevealed? + @page_subtitle = t(".page_title.unrevealed") + else + page_creator = if @work.anonymous? + ts("Anonymous") + else + @work.pseuds.map(&:byline).sort.join(", ") + end + fandoms = @tag_groups["Fandom"] + page_title_inner = if fandoms.size > 3 + ts("Multifandom") + else + fandoms.empty? ? ts("No fandom specified") : fandoms[0].name + end + @page_title = get_page_title(page_title_inner, page_creator, @work.title) + end + + # Users must explicitly okay viewing of adult content + if params[:view_adult] + cookies[:view_adult] = "true" + elsif @work.adult? && !see_adult? + render('_adult', layout: 'application') && return + end + + # Users must explicitly okay viewing of entire work + if @work.chaptered? + if params[:view_full_work] || (logged_in? && current_user.preference.try(:view_full_works)) + @chapters = @work.chapters_in_order( + include_drafts: (logged_in_as_admin? || + @work.user_is_owner_or_invited?(current_user)) + ) + else + flash.keep + redirect_to([@work, @chapter, { only_path: true }]) && return + end + end + + @tag_categories_limited = Tag::VISIBLE - ['ArchiveWarning'] + @kudos = @work.kudos.with_user.includes(:user) + + if current_user.respond_to?(:subscriptions) + @subscription = current_user.subscriptions.where(subscribable_id: @work.id, + subscribable_type: 'Work').first || + current_user.subscriptions.build(subscribable: @work) + end + + render :show + Reading.update_or_create(@work, current_user) if current_user + end + + # GET /works/1/share + def share + if request.xhr? + if @work.unrevealed? + render template: "errors/404", status: :not_found + else + render layout: false + end + else + # Avoid getting an unstyled page if JavaScript is disabled + flash[:error] = ts("Sorry, you need to have JavaScript enabled for this.") + if request.env["HTTP_REFERER"] + redirect_to(request.env["HTTP_REFERER"] || root_path) + else + # else branch needed to deal with bots, which don't have a referer + redirect_to root_path + end + end + end + + def navigate + @chapters = @work.chapters_in_order( + include_content: false, + include_drafts: (logged_in_as_admin? || + @work.user_is_owner_or_invited?(current_user)) + ) + end + + # GET /works/new + def new + @hide_dashboard = true + @unposted = current_user.unposted_work + + if params[:load_unposted] && @unposted + @work = @unposted + @chapter = @work.first_chapter + else + @work = Work.new + @chapter = @work.chapters.build + end + + # for clarity, add the collection and recipient + if params[:assignment_id] && (@challenge_assignment = ChallengeAssignment.find(params[:assignment_id])) && @challenge_assignment.offering_user == current_user + @work.challenge_assignments << @challenge_assignment + end + + if params[:claim_id] && (@challenge_claim = ChallengeClaim.find(params[:claim_id])) && User.find(@challenge_claim.claiming_user_id) == current_user + @work.challenge_claims << @challenge_claim + end + + if @collection + @work.add_to_collection(@collection) + end + + @work.set_challenge_info + @work.set_challenge_claim_info + set_work_form_fields + + if params[:import] + @page_subtitle = ts("Import New Work") + render(:new_import) + elsif @work.persisted? + render(:edit) + else + render(:new) + end + end + + # POST /works + def create + if params[:cancel_button] + flash[:notice] = ts('New work posting canceled.') + redirect_to current_user + return + end + + @work = Work.new(work_params) + + @chapter = @work.first_chapter + @chapter.attributes = work_params[:chapter_attributes] if work_params[:chapter_attributes] + @work.ip_address = request.remote_ip + + @work.set_challenge_info + @work.set_challenge_claim_info + set_work_form_fields + + if work_cannot_be_saved? + render :new + else + @work.posted = @chapter.posted = true if params[:post_button] + @work.set_revised_at_by_chapter(@chapter) + + if @work.save + if params[:preview_button] + flash[:notice] = ts("Draft was successfully created. It will be scheduled for deletion on %{deletion_date}.", deletion_date: view_context.date_in_zone(@work.created_at + 29.days)).html_safe + in_moderated_collection + redirect_to preview_work_path(@work) + else + # We check here to see if we are attempting to post to moderated collection + flash[:notice] = ts("Work was successfully posted. It should appear in work listings within the next few minutes.") + in_moderated_collection + redirect_to work_path(@work) + end + else + render :new + end + end + end + + # GET /works/1/edit + def edit + @hide_dashboard = true + if @work.number_of_chapters > 1 + @chapters = @work.chapters_in_order(include_content: false, + include_drafts: true) + end + set_work_form_fields + end + + def remove_user_creatorship + pseuds_with_author_removed = @work.pseuds - current_user.pseuds + + if pseuds_with_author_removed.empty? + redirect_to controller: 'orphans', action: 'new', work_id: @work.id + else + @work.remove_author(current_user) + flash[:notice] = ts("You have been removed as a creator from the work.") + redirect_to current_user + end + end + + # GET /works/1/edit_tags + def edit_tags + authorize @work if logged_in_as_admin? + @page_subtitle = ts("Edit Work Tags") + end + + # PUT /works/1 + def update + if params[:cancel_button] + return cancel_posting_and_redirect + end + + @work.preview_mode = !!(params[:preview_button] || params[:edit_button]) + @work.attributes = work_params + @chapter.attributes = work_params[:chapter_attributes] if work_params[:chapter_attributes] + @work.ip_address = request.remote_ip + @work.set_word_count(@work.preview_mode) + + @work.set_challenge_info + @work.set_challenge_claim_info + set_work_form_fields + + if params[:edit_button] || work_cannot_be_saved? + render :edit + elsif params[:preview_button] + unless @work.posted? + flash[:notice] = ts("Your changes have not been saved. Please post your work or save as draft if you want to keep them.") + end + + in_moderated_collection + @preview_mode = true + render :preview + else + @work.posted = @chapter.posted = true if params[:post_button] + @work.set_revised_at_by_chapter(@chapter) + posted_changed = @work.posted_changed? + + if @chapter.save && @work.save + flash[:notice] = ts("Work was successfully #{posted_changed ? 'posted' : 'updated'}.") + if posted_changed + flash[:notice] << ts(" It should appear in work listings within the next few minutes.") + end + in_moderated_collection + redirect_to work_path(@work) + else + @chapter.errors.full_messages.each { |err| @work.errors.add(:base, err) } + render :edit + end + end + end + + def update_tags + authorize @work if logged_in_as_admin? + if params[:cancel_button] + return cancel_posting_and_redirect + end + + @work.preview_mode = !!(params[:preview_button] || params[:edit_button]) + @work.attributes = work_tag_params + + if params[:edit_button] || work_cannot_be_saved? + render :edit_tags + elsif params[:preview_button] + @preview_mode = true + render :preview_tags + elsif params[:save_button] + @work.save + flash[:notice] = ts('Tags were successfully updated.') + redirect_to(@work) + else # Save As Draft + @work.posted = true + @work.minor_version = @work.minor_version + 1 + @work.save + flash[:notice] = ts('Work was successfully updated.') + redirect_to(@work) + end + end + + # GET /works/1/preview + def preview + @preview_mode = true + end + + def preview_tags + @preview_mode = true + end + + def confirm_delete + end + + # DELETE /works/1 + def destroy + @work = Work.find(params[:id]) + + begin + was_draft = !@work.posted? + title = @work.title + @work.destroy + flash[:notice] = ts("Your work %{title} was deleted.", title: title).html_safe + rescue + flash[:error] = ts("We couldn't delete that right now, sorry! Please try again later.") + end + + if was_draft + redirect_to drafts_user_works_path(current_user) + else + redirect_to user_works_path(current_user) + end + end + + # POST /works/import + def import + # check to make sure we have some urls to work with + @urls = params[:urls].split + if @urls.empty? + flash.now[:error] = ts('Did you want to enter a URL?') + render(:new_import) && return + end + + @language_id = params[:language_id] + if @language_id.empty? + flash.now[:error] = ts("Language cannot be blank.") + render(:new_import) && return + end + + importing_for_others = params[:importing_for_others] != "false" && params[:importing_for_others] + + # is external author information entered when import for others is not checked? + if (params[:external_author_name].present? || params[:external_author_email].present?) && !importing_for_others + flash.now[:error] = ts('You have entered an external author name or e-mail address but did not select "Import for others." Please select the "Import for others" option or remove the external author information to continue.') + render(:new_import) && return + end + + # is this an archivist importing? + if importing_for_others && !current_user.archivist + flash.now[:error] = ts('You may not import stories by other users unless you are an approved archivist.') + render(:new_import) && return + end + + # make sure we're not importing too many at once + if params[:import_multiple] == 'works' && (!current_user.archivist && @urls.length > ArchiveConfig.IMPORT_MAX_WORKS || @urls.length > ArchiveConfig.IMPORT_MAX_WORKS_BY_ARCHIVIST) + flash.now[:error] = ts('You cannot import more than %{max} works at a time.', max: current_user.archivist ? ArchiveConfig.IMPORT_MAX_WORKS_BY_ARCHIVIST : ArchiveConfig.IMPORT_MAX_WORKS) + render(:new_import) && return + elsif params[:import_multiple] == 'chapters' && @urls.length > ArchiveConfig.IMPORT_MAX_CHAPTERS + flash.now[:error] = ts('You cannot import more than %{max} chapters at a time.', max: ArchiveConfig.IMPORT_MAX_CHAPTERS) + render(:new_import) && return + end + + options = build_options(params) + options[:ip_address] = request.remote_ip + + # now let's do the import + if params[:import_multiple] == 'works' && @urls.length > 1 + import_multiple(@urls, options) + else # a single work possibly with multiple chapters + import_single(@urls, options) + end + end + + protected + + # import a single work (possibly with multiple chapters) + def import_single(urls, options) + # try the import + storyparser = StoryParser.new + + begin + @work = if urls.size == 1 + storyparser.download_and_parse_story(urls.first, options) + else + storyparser.download_and_parse_chapters_into_story(urls, options) + end + rescue Timeout::Error + flash.now[:error] = ts('Import has timed out. This may be due to connectivity problems with the source site. Please try again in a few minutes, or check Known Issues to see if there are import problems with this site.') + render(:new_import) && return + rescue StoryParser::Error => exception + flash.now[:error] = ts("We couldn't successfully import that work, sorry: %{message}", message: exception.message) + render(:new_import) && return + end + + unless @work && @work.save + flash.now[:error] = ts("We were only partially able to import this work and couldn't save it. Please review below!") + @chapter = @work.chapters.first + @series = current_user.series.distinct + render(:new) && return + end + + # Otherwise, we have a saved work, go us + send_external_invites([@work]) + @chapter = @work.first_chapter if @work + if @work.posted + redirect_to(work_path(@work)) && return + else + redirect_to(preview_work_path(@work)) && return + end + end + + # import multiple works + def import_multiple(urls, options) + # try a multiple import + storyparser = StoryParser.new + @works, failed_urls, errors = storyparser.import_from_urls(urls, options) + + # collect the errors neatly, matching each error to the failed url + unless failed_urls.empty? + error_msgs = 0.upto(failed_urls.length).map { |index| "
#{failed_urls[index]}
#{errors[index]}
" }.join("\n") + flash.now[:error] = "

#{ts('Failed Imports')}

#{error_msgs}
".html_safe + end + + # if EVERYTHING failed, boo. :( Go back to the import form. + render(:new_import) && return if @works.empty? + + # if we got here, we have at least some successfully imported works + flash[:notice] = ts('Importing completed successfully for the following works! (But please check the results over carefully!)') + send_external_invites(@works) + + # fall through to import template + end + + # if we are importing for others, we need to send invitations + def send_external_invites(works) + return unless params[:importing_for_others] + + @external_authors = works.collect(&:external_authors).flatten.uniq + unless @external_authors.empty? + @external_authors.each do |external_author| + external_author.find_or_invite(current_user) + end + message = ' ' + ts('We have notified the author(s) you imported works for. If any were missed, you can also add co-authors manually.') + flash[:notice] ? flash[:notice] += message : flash[:notice] = message + end + end + + # check to see if the work is being added / has been added to a moderated collection, then let user know that + def in_moderated_collection + moderated_collections = [] + @work.collections.each do |collection| + next unless !collection.nil? && collection.moderated? && !collection.user_is_posting_participant?(current_user) + next unless @work.collection_items.present? + @work.collection_items.each do |collection_item| + next unless collection_item.collection == collection + if collection_item.approved_by_user? && collection_item.unreviewed_by_collection? + moderated_collections << collection + end + end + end + if moderated_collections.present? + flash[:notice] ||= '' + flash[:notice] += ts(" You have submitted your work to #{moderated_collections.size > 1 ? 'moderated collections (%{all_collections}). It will not become a part of those collections' : "the moderated collection '%{all_collections}'. It will not become a part of the collection"} until it has been approved by a moderator.", all_collections: moderated_collections.map(&:title).join(', ')) + end + end + + public + + def post_draft + @user = current_user + @work = Work.find(params[:id]) + + unless @user.is_author_of?(@work) + flash[:error] = ts('You can only post your own works.') + redirect_to(current_user) && return + end + + if @work.posted + flash[:error] = ts('That work is already posted. Do you want to edit it instead?') + redirect_to(edit_user_work_path(@user, @work)) && return + end + + @work.posted = true + @work.minor_version = @work.minor_version + 1 + + unless @work.valid? && @work.save + flash[:error] = ts('There were problems posting your work.') + redirect_to(edit_user_work_path(@user, @work)) && return + end + + # AO3-3498: since a work's word count is calculated in a before_save and the chapter is posted in an after_save, + # work's word count needs to be updated with the chapter's word count after the chapter is posted + # AO3-6273 Cannot rely on set_word_count here in a production environment, as it might query an older version of the database + # Instead, as the work in this context is reduced its first chapter, we copy the value directly + @work.word_count = @work.first_chapter.word_count + @work.save + + if !@collection.nil? && @collection.moderated? + redirect_to work_path(@work), notice: ts('Work was submitted to a moderated collection. It will show up in the collection once approved.') + else + flash[:notice] = ts('Your work was successfully posted.') + redirect_to @work + end + end + + # WORK ON MULTIPLE WORKS + + def show_multiple + @page_subtitle = ts("Edit Multiple Works") + @user = current_user + + @works = Work.joins(pseuds: :user).where(users: { id: @user.id }) + + @works = @works.where(id: params[:work_ids]) if params[:work_ids] + + @works_by_fandom = @works.joins(:taggings) + .joins("inner join tags on taggings.tagger_id = tags.id AND tags.type = 'Fandom'") + .select('distinct tags.name as fandom, works.id, works.title, works.posted').group_by(&:fandom) + end + + def edit_multiple + if params[:commit] == 'Orphan' + redirect_to(new_orphan_path(work_ids: params[:work_ids])) && return + end + + @page_subtitle = ts("Edit Multiple Works") + @user = current_user + @works = Work.select('distinct works.*').joins(pseuds: :user).where('users.id = ?', @user.id).where(id: params[:work_ids]) + + render('confirm_delete_multiple') && return if params[:commit] == 'Delete' + end + + def confirm_delete_multiple + @user = current_user + @works = Work.select('distinct works.*').joins(pseuds: :user).where('users.id = ?', @user.id).where(id: params[:work_ids]) + end + + def delete_multiple + @user = current_user + @works = Work.joins(pseuds: :user).where('users.id = ?', @user.id).where(id: params[:work_ids]).readonly(false) + titles = @works.collect(&:title) + + @works.each(&:destroy) + + flash[:notice] = ts('Your works %{titles} were deleted.', titles: titles.join(', ')) + redirect_to show_multiple_user_works_path(@user) + end + + def update_multiple + @user = current_user + @works = Work.joins(pseuds: :user).where('users.id = ?', @user.id).where(id: params[:work_ids]).readonly(false) + @errors = [] + + # To avoid overwriting, we entirely trash any blank fields. + updated_work_params = work_params.reject { |_key, value| value.blank? } + + @works.each do |work| + # now we can just update each work independently, woo! + unless work.update(updated_work_params) + @errors << ts('The work %{title} could not be edited: %{error}', title: work.title, error: work.errors.full_messages.join(" ")).html_safe + end + + if params[:remove_me] + if work.pseuds.where.not(user_id: current_user.id).exists? + work.remove_author(current_user) + else + @errors << ts("You cannot remove yourself as co-creator of the work %{title} because you are the only listed creator. If you have invited another co-creator, you must wait for them to accept before you can remove yourself.", title: work.title) + end + end + end + + if @errors.empty? + flash[:notice] = ts('Your edits were put through! Please check over the works to make sure everything is right.') + else + flash[:error] = @errors + end + + redirect_to show_multiple_user_works_path(@user, work_ids: @works.map(&:id)) + end + + # marks a work to read later + def mark_for_later + @work = Work.find(params[:id]) + Reading.mark_to_read_later(@work, current_user, true) + read_later_path = user_readings_path(current_user, show: 'to-read') + if @work.marked_for_later?(current_user) + flash[:notice] = ts("This work was added to your #{view_context.link_to('Marked for Later list', read_later_path)}.").html_safe + end + redirect_to(request.env['HTTP_REFERER'] || root_path) + end + + def mark_as_read + @work = Work.find(params[:id]) + Reading.mark_to_read_later(@work, current_user, false) + read_later_path = user_readings_path(current_user, show: 'to-read') + unless @work.marked_for_later?(current_user) + flash[:notice] = ts("This work was removed from your #{view_context.link_to('Marked for Later list', read_later_path)}.").html_safe + end + redirect_to(request.env['HTTP_REFERER'] || root_path) + end + + protected + + def load_owner + if params[:user_id].present? + @user = User.find_by!(login: params[:user_id]) + if params[:pseud_id].present? + @pseud = @user.pseuds.find_by(name: params[:pseud_id]) + end + end + if params[:tag_id] + @tag = Tag.find_by_name(params[:tag_id]) + unless @tag && @tag.is_a?(Tag) + raise ActiveRecord::RecordNotFound, "Couldn't find tag named '#{params[:tag_id]}'" + end + unless @tag.canonical? + if @tag.merger.present? + if @collection.present? + redirect_to(collection_tag_works_path(@collection, @tag.merger)) && return + else + redirect_to(tag_works_path(@tag.merger)) && return + end + else + redirect_to(tag_path(@tag)) && return + end + end + end + @language = Language.find_by(short: params[:language_id]) if params[:language_id].present? + @owner = @pseud || @user || @collection || @tag || @language + end + + def load_work + @work = Work.find_by(id: params[:id]) + unless @work + raise ActiveRecord::RecordNotFound, "Couldn't find work with id '#{params[:id]}'" + end + if @collection && !@work.collections.include?(@collection) + redirect_to(@work) && return + end + + @check_ownership_of = @work + @check_visibility_of = @work + end + + def check_parent_visible + check_visibility_for(@work) + end + + def load_first_chapter + @chapter = if @work.user_is_owner_or_invited?(current_user) || logged_in_as_admin? + @work.first_chapter + else + @work.chapters.in_order.posted.first + end + end + + # Check whether we should display :new or :edit instead of previewing or + # saving the user's changes. + def work_cannot_be_saved? + !(@work.errors.empty? && @work.valid?) + end + + def set_work_form_fields + @work.reset_published_at(@chapter) + @series = current_user.series.distinct + @serial_works = @work.serial_works + + if @collection.nil? + @collection = @work.approved_collections.first + end + + if params[:claim_id] + @posting_claim = ChallengeClaim.find_by(id: params[:claim_id]) + end + end + + def set_own_works + return unless @works + @own_works = [] + if current_user.is_a?(User) + pseud_ids = current_user.pseuds.pluck(:id) + @own_works = @works.select do |work| + (pseud_ids & work.pseuds.pluck(:id)).present? + end + end + end + + def cancel_posting_and_redirect + if @work && @work.posted + flash[:notice] = ts('The work was not updated.') + redirect_to user_works_path(current_user) + else + flash[:notice] = ts('The work was not posted. It will be saved here in your drafts for one month, then deleted from the Archive.') + redirect_to drafts_user_works_path(current_user) + end + end + + def index_page_title + if @owner.present? + owner_name = + case @owner.class.to_s + when 'Pseud' + @owner.name + when 'User' + @owner.login + when 'Collection' + @owner.title + else + @owner.try(:name) + end + + "#{owner_name} - Works".html_safe + else + 'Latest Works' + end + end + + def log_admin_activity + if logged_in_as_admin? + options = { action: params[:action] } + + if params[:action] == 'update_tags' + summary = "Old tags: #{@work.tags.pluck(:name).join(', ')}" + end + + AdminActivity.log_action(current_admin, @work, action: params[:action], summary: summary) + end + end + + private + + def build_options(params) + pseuds_to_apply = + (Pseud.find_by(name: params[:pseuds_to_apply]) if params[:pseuds_to_apply]) + + { + pseuds: pseuds_to_apply, + post_without_preview: params[:post_without_preview], + importing_for_others: params[:importing_for_others], + restricted: params[:restricted], + moderated_commenting_enabled: params[:moderated_commenting_enabled], + comment_permissions: params[:comment_permissions], + override_tags: params[:override_tags], + detect_tags: params[:detect_tags] == "true", + fandom: params[:work][:fandom_string], + archive_warning: params[:work][:archive_warning_strings], + character: params[:work][:character_string], + rating: params[:work][:rating_string], + relationship: params[:work][:relationship_string], + category: params[:work][:category_strings], + freeform: params[:work][:freeform_string], + notes: params[:notes], + encoding: params[:encoding], + external_author_name: params[:external_author_name], + external_author_email: params[:external_author_email], + external_coauthor_name: params[:external_coauthor_name], + external_coauthor_email: params[:external_coauthor_email], + language_id: params[:language_id] + }.compact_blank! + end + + def work_params + params.require(:work).permit( + :rating_string, :fandom_string, :relationship_string, :character_string, + :archive_warning_string, :category_string, + :freeform_string, :summary, :notes, :endnotes, :collection_names, :recipients, :wip_length, + :backdate, :language_id, :work_skin_id, :restricted, :comment_permissions, + :moderated_commenting_enabled, :title, :pseuds_to_add, :collections_to_add, + current_user_pseud_ids: [], + collections_to_remove: [], + challenge_assignment_ids: [], + challenge_claim_ids: [], + category_strings: [], + archive_warning_strings: [], + author_attributes: [:byline, ids: [], coauthors: []], + series_attributes: [:id, :title], + parent_work_relationships_attributes: [ + :url, :title, :author, :language_id, :translation + ], + chapter_attributes: [ + :title, :"published_at(3i)", :"published_at(2i)", :"published_at(1i)", + :published_at, :content + ] + ) + end + + def work_tag_params + params.require(:work).permit( + :rating_string, :fandom_string, :relationship_string, :character_string, + :archive_warning_string, :category_string, :freeform_string, :language_id, + category_strings: [], + archive_warning_strings: [] + ) + end + + def work_search_params + params.require(:work_search).permit( + :query, + :title, + :creators, + :revised_at, + :complete, + :single_chapter, + :word_count, + :language_id, + :fandom_names, + :rating_ids, + :character_names, + :relationship_names, + :freeform_names, + :hits, + :kudos_count, + :comments_count, + :bookmarks_count, + :sort_column, + :sort_direction, + :other_tag_names, + :excluded_tag_names, + :crossover, + :date_from, + :date_to, + :words_from, + :words_to, + + archive_warning_ids: [], + warning_ids: [], # backwards compatibility + category_ids: [], + rating_ids: [], + fandom_ids: [], + character_ids: [], + relationship_ids: [], + freeform_ids: [], + + collection_ids: [] + ) + end + +end diff --git a/app/controllers/wrangling_guidelines_controller.rb b/app/controllers/wrangling_guidelines_controller.rb new file mode 100755 index 0000000..f015a18 --- /dev/null +++ b/app/controllers/wrangling_guidelines_controller.rb @@ -0,0 +1,82 @@ +class WranglingGuidelinesController < ApplicationController + before_action :admin_only, except: [:index, :show] + + # GET /wrangling_guidelines + def index + @wrangling_guidelines = WranglingGuideline.order("position ASC") + end + + # GET /wrangling_guidelines/1 + def show + @wrangling_guideline = WranglingGuideline.find(params[:id]) + end + + # GET /wrangling_guidelines/new + def new + authorize :wrangling + @wrangling_guideline = WranglingGuideline.new + end + + # GET /wrangling_guidelines/1/edit + def edit + authorize :wrangling + @wrangling_guideline = WranglingGuideline.find(params[:id]) + end + + # GET /wrangling_guidelines/manage + def manage + authorize :wrangling + @wrangling_guidelines = WranglingGuideline.order("position ASC") + end + + # POST /wrangling_guidelines + def create + authorize :wrangling + @wrangling_guideline = WranglingGuideline.new(wrangling_guideline_params) + + if @wrangling_guideline.save + flash[:notice] = t("wrangling_guidelines.create") + redirect_to(@wrangling_guideline) + else + render action: "new" + end + end + + # PUT /wrangling_guidelines/1 + def update + authorize :wrangling + @wrangling_guideline = WranglingGuideline.find(params[:id]) + + if @wrangling_guideline.update(wrangling_guideline_params) + flash[:notice] = t("wrangling_guidelines.update") + redirect_to(@wrangling_guideline) + else + render action: "edit" + end + end + + # reorder FAQs + def update_positions + authorize :wrangling + if params[:wrangling_guidelines] + @wrangling_guidelines = WranglingGuideline.reorder_list(params[:wrangling_guidelines]) + flash[:notice] = t("wrangling_guidelines.reorder") + end + redirect_to(wrangling_guidelines_path) + end + + # DELETE /wrangling_guidelines/1 + def destroy + authorize :wrangling + @wrangling_guideline = WranglingGuideline.find(params[:id]) + @wrangling_guideline.destroy + flash[:notice] = t("wrangling_guidelines.delete") + redirect_to(wrangling_guidelines_path) + end + + private + + def wrangling_guideline_params + params.require(:wrangling_guideline).permit(:title, :content) + end +end diff --git a/app/decorators/bookmarkable_decorator.rb b/app/decorators/bookmarkable_decorator.rb new file mode 100755 index 0000000..9ac2961 --- /dev/null +++ b/app/decorators/bookmarkable_decorator.rb @@ -0,0 +1,75 @@ +class BookmarkableDecorator < SimpleDelegator + attr_accessor :inner_hits, :loaded_bookmarks + + # Given a list of bookmarkable objects, with inner bookmark hits, load the + # objects and their bookmarks and wrap everything up in a + # BookmarkableDecorator object. + def self.load_from_elasticsearch(hits, **options) + bookmarks = load_bookmarks(hits, **options) + bookmarkables = load_bookmarkables(hits, **options) + + hits.map do |hit| + id = hit["_id"] + next if bookmarkables[id].blank? + new_with_inner_hits( + bookmarkables[id], + hit.dig("inner_hits", "bookmark"), + bookmarks + ) + end.compact + end + + # Given search results for bookmarkables, with inner_hits for the matching + # bookmarks, load all of the referenced bookmarks and return a hash mapping + # from IDs to bookmarks. + def self.load_bookmarks(hits, **options) + all_bookmark_hits = hits.flat_map do |bookmarkable_item| + bookmarkable_item.dig("inner_hits", "bookmark", "hits", "hits") + end + + Bookmark.load_from_elasticsearch(all_bookmark_hits, **options).group_by(&:id) + end + + # Given search results for bookmarkables, return a hash mapping from IDs to + # Works, Series, or ExternalWorks (depending on which type the ID is marked + # with). + def self.load_bookmarkables(hits, **options) + hits_by_bookmarkable_type = hits.group_by do |item| + item.dig("_source", "bookmarkable_type") + end + + bookmarkables = {} + + [Work, Series, ExternalWork].each do |klass| + hits_for_klass = hits_by_bookmarkable_type[klass.to_s] + next if hits_for_klass.blank? + type = klass.to_s.underscore + klass.load_from_elasticsearch(hits_for_klass, **options).each do |item| + bookmarkables["#{item.id}-#{type}"] = item + end + end + + bookmarkables + end + + # Create a new bookmarkable decorator with information about this + # bookmarkable's inner hits, and a hash of pre-loaded bookmarks. + def self.new_with_inner_hits(bookmarkable, inner_hits, bookmarks) + new(bookmarkable).tap do |decorator| + decorator.inner_hits = inner_hits + decorator.loaded_bookmarks = bookmarks + end + end + + # Return the number of inner bookmarks matching the query. + def matching_bookmark_count + @matching_bookmark_count ||= inner_hits.dig("hits", "total") + end + + # Return a small sampling of inner bookmarks matching the query. + def matching_bookmarks + @matching_bookmarks = inner_hits.dig("hits", "hits").flat_map do |hit| + loaded_bookmarks[hit["_id"].to_i] + end.compact + end +end diff --git a/app/decorators/comment_decorator.rb b/app/decorators/comment_decorator.rb new file mode 100755 index 0000000..5843112 --- /dev/null +++ b/app/decorators/comment_decorator.rb @@ -0,0 +1,68 @@ +class CommentDecorator < SimpleDelegator + # Given an array of thread IDs, loads all comments in those threads, wraps + # all of them in CommentDecorators, and sets up reviewed_replies for all + # comments. Returns a hash mapping from comment IDs to CommentDecorators. + def self.from_thread_ids(thread_ids) + wrapped_by_id = {} + + # Order by [thread, id] so that the comments in a thread are processed in + # the order they were posted. This will ensure that when we process a + # reply, its commentable has already been processed, and will also ensure + # that the replies to a comment are displayed in the correct order: + Comment.for_display.where(thread: thread_ids).order(:thread, :id).each do |comment| + wrapped = CommentDecorator.new(comment) + wrapped_by_id[comment.id] = wrapped + + next unless comment.reply_comment? + + wrapped_by_id[comment.commentable_id].comments << wrapped + end + + wrapped_by_id + end + + # Given an array of thread IDs, loads them with from_thread_ids, and then + # replaces the contents of the array with the CommentDecorators for each + # thread root. + def self.wrap_thread_ids(thread_ids) + comments_by_id = from_thread_ids(thread_ids) + + wrapped = thread_ids.map do |id| + comments_by_id[id] + end + + thread_ids.replace(wrapped) + end + + # Given an array of comments, loads the threads associated with those + # comments using from_thread_ids, and then replaces the contents of the array + # with the decorated version of those comments. + def self.wrap_comments(comments) + comments_by_id = from_thread_ids(comments.map(&:thread)) + + wrapped = comments.map do |comment| + comments_by_id[comment.id] + end + + comments.replace(wrapped) + end + + # Given a commentable, gets the desired page of threads for that commentable, + # and then loads all of the comments for those threads using wrap_thread_ids. + def self.for_commentable(commentable, page:) + thread_ids = commentable.comments.reviewed.pluck(:thread) + .paginate(page: page, per_page: Comment.per_page) + + wrap_thread_ids(thread_ids) + end + + # Override the comments association. + def comments + @comments ||= [] + end + + # Override the reviewed_replies association. + def reviewed_replies + @reviewed_replies ||= comments.reject(&:unreviewed?) + end +end diff --git a/app/decorators/homepage.rb b/app/decorators/homepage.rb new file mode 100755 index 0000000..312ebfd --- /dev/null +++ b/app/decorators/homepage.rb @@ -0,0 +1,70 @@ +class Homepage + include NumberHelper + + def initialize(user) + @user = user + end + + def rounded_counts + @user_count = Rails.cache.fetch("/v1/home/counts/user", expires_in: 40.minutes) do + estimate_number(User.count) + end + @work_count = Rails.cache.fetch("/v1/home/counts/works", expires_in: 40.minutes) do + estimate_number(Work.posted.count) + end + @fandom_count = Rails.cache.fetch("/v1/home/counts/fandom", expires_in: 40.minutes) do + estimate_number(Fandom.canonical.count) + end + [@user_count, @work_count, @fandom_count] + end + + def logged_in? + @user.present? + end + + def admin_posts + @admin_posts = if Rails.env.development? + AdminPost.non_translated.for_homepage.all + else + Rails.cache.fetch("home/index/home_admin_posts", expires_in: 20.minutes) do + AdminPost.non_translated.for_homepage.to_a + end + end + end + + def favorite_tags + return unless logged_in? + + @favorite_tags ||= if Rails.env.development? + @user.favorite_tags.to_a.sort_by { |favorite_tag| favorite_tag.tag.sortable_name.downcase } + else + Rails.cache.fetch("home/index/#{@user.id}/home_favorite_tags") do + @user.favorite_tags.to_a.sort_by { |favorite_tag| favorite_tag.tag.sortable_name.downcase } + end + end + end + + def readings + return unless logged_in? && @user.preference.try(:history_enabled?) + + @readings ||= if Rails.env.development? + @user.readings.visible.random_order + .limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) + .where(toread: true) + .all + else + Rails.cache.fetch("home/index/#{@user.id}/home_marked_for_later") do + @user.readings.visible.random_order + .limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) + .where(toread: true) + .to_a + end + end + end + + def inbox_comments + return unless logged_in? + + @inbox_comments ||= @user.inbox_comments.with_bad_comments_removed.for_homepage + end +end diff --git a/app/decorators/pseud_decorator.rb b/app/decorators/pseud_decorator.rb new file mode 100755 index 0000000..a3867aa --- /dev/null +++ b/app/decorators/pseud_decorator.rb @@ -0,0 +1,126 @@ +class PseudDecorator < SimpleDelegator + + attr_reader :data + + # Pseuds need to be decorated with various stats from the "_source" when + # viewing search results, so we first load the pseuds with the base search + # class, and then decorate them with the data. + def self.load_from_elasticsearch(hits, **options) + items = Pseud.load_from_elasticsearch(hits, **options) + decorate_from_search(items, hits) + end + + # TODO: pull this out into a reusable module + def self.decorate_from_search(results, search_hits) + search_data = search_hits.group_by { |doc| doc["_id"] } + results.map do |result| + data = search_data[result.id.to_s].first&.dig('_source') || {} + new_with_data(result, data) + end + end + + # TODO: Either eliminate this function or add definitions for work_counts and + # bookmark_counts (and possibly fandom information, as well?). The NameError + # that this causes isn't a problem at the moment because the function isn't + # being called from anywhere, but it needs to be fixed before it can be used. + def self.decorate(pseuds) + users = User.where(id: pseuds.map(&:user_id)).group_by(&:id) + work_counts + bookmark_counts + work_key = User.current_user.present? ? :general_works_count : :public_works_count + bookmark_key = User.current_user.present? ? :general_bookmarks_count : :public_bookmarks_count + pseuds.map do |pseud| + data = { + user_login: users[user_id].login, + bookmark_key => bookmark_counts[id], + work_key => work_counts[id] + } + new_with_data(pseud, data) + end + end + + def self.new_with_data(pseud, data) + new(pseud).tap do |decorator| + decorator.data = data + end + end + + def data=(info) + @data = HashWithIndifferentAccess.new(info) + end + + def works_count + count = User.current_user.present? ? data[:general_works_count] : data[:public_works_count] + count || 0 + end + + def bookmarks_count + User.current_user.present? ? data[:general_bookmarks_count] : data[:public_bookmarks_count] + end + + def byline + data[:byline] ||= constructed_byline + end + + def user_login + data[:user_login] + end + + def pseud_path + "/users/#{user_login}/pseuds/#{name}" + end + + def works_path + "#{pseud_path}/works" + end + + def works_link + return unless works_count > 0 + text = ActionController::Base.helpers.pluralize(works_count, "works") + "#{text}" + end + + def bookmarks_path + "#{pseud_path}/bookmarks" + end + + def bookmarks_link + return unless bookmarks_count > 0 + text = ActionController::Base.helpers.pluralize(bookmarks_count, "bookmarks") + "#{text}" + end + + def fandom_path(id) + return unless id + "#{works_path}?fandom_id=#{id}" + end + + def fandom_link(fandom_id) + fandom = fandom_stats(fandom_id) + return unless fandom.present? + text = ActionController::Base.helpers.pluralize(fandom[:count], "work") + " in #{fandom[:name]}" + "#{text}" + end + + def authored_items_links(options = {}) + general_links = [works_link, bookmarks_link].compact.join(", ") + if options[:fandom_id].present? + # This can potentially be an array + fandom_links = [options[:fandom_id]].flatten.map do |fandom_id| + fandom_link(fandom_id) + end + general_links + " | " + fandom_links.compact.join(", ") + else + general_links + end + end + + def constructed_byline + name == user_login ? name : "#{name} (#{user_login})" + end + + def fandom_stats(id) + key = User.current_user.present? ? "id" : "id_for_public" + data[:fandoms]&.detect { |fandom| fandom[key].to_s == id.to_s } + end +end diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb new file mode 100755 index 0000000..1b085c2 --- /dev/null +++ b/app/helpers/admin_helper.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module AdminHelper + def admin_activity_login_string(activity) + activity.admin.nil? ? ts("Admin deleted") : activity.admin_login + end + + def admin_activity_target_link(activity) + url = if activity.target.is_a?(Pseud) + user_pseuds_path(activity.target.user) + else + activity.target + end + link_to(activity.target_name, url) + end + + # Summaries for profile and pseud edits, which contain links, need to be + # handled differently from summaries that use item.inspect (and thus contain + # angle brackets). + def admin_activity_summary(activity) + if activity.action == "edit pseud" || activity.action == "edit profile" + raw sanitize_field(activity, :summary) + else + activity.summary + end + end + + def admin_setting_disabled?(field) + return unless logged_in_as_admin? + + !policy(AdminSetting).permitted_attributes.include?(field) + end + + def admin_setting_checkbox(form, field_name) + form.check_box(field_name, disabled: admin_setting_disabled?(field_name)) + end + + def admin_setting_text_field(form, field_name, options = {}) + options[:disabled] = admin_setting_disabled?(field_name) + form.text_field(field_name, options) + end + + def admin_can_update_user_roles? + return unless logged_in_as_admin? + + policy(User).permitted_attributes.include?(roles: []) + end + + def admin_can_update_user_email? + return unless logged_in_as_admin? + + policy(User).permitted_attributes.include?(:email) + end +end diff --git a/app/helpers/admin_post_helper.rb b/app/helpers/admin_post_helper.rb new file mode 100755 index 0000000..e167de6 --- /dev/null +++ b/app/helpers/admin_post_helper.rb @@ -0,0 +1,8 @@ +module AdminPostHelper + def sorted_translations(admin_post) + admin_post.translations.sort_by do |translation| + language = translation.language + language.sortable_name.blank? ? language.short : language.sortable_name + end + end +end diff --git a/app/helpers/advanced_search_helper.rb b/app/helpers/advanced_search_helper.rb new file mode 100755 index 0000000..5a36a10 --- /dev/null +++ b/app/helpers/advanced_search_helper.rb @@ -0,0 +1,16 @@ +module AdvancedSearchHelper + + def filter_boolean_value(filter_action, tag_type, tag_id) + if filter_action == "include" + @search.send("#{tag_type}_ids").present? && + @search.send("#{tag_type}_ids").include?(tag_id) + elsif tag_type == "tag" && @search.respond_to?(:excluded_bookmark_tag_ids) + # Bookmarker's tag exclude checkboxes on bookmark filters + @search.excluded_bookmark_tag_ids.present? && @search.excluded_bookmark_tag_ids.include?(tag_id) + else + # Work tag exclude checkboxes on bookmark filters, + # or exclude checkboxes on work filters + @search.excluded_tag_ids.present? && @search.excluded_tag_ids.include?(tag_id) + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb new file mode 100755 index 0000000..80a574a --- /dev/null +++ b/app/helpers/application_helper.rb @@ -0,0 +1,654 @@ +# Methods added to this helper will be available to all templates in the application. +module ApplicationHelper + include HtmlCleaner + + # TODO: Official recommendation from Rails indicates we should switch to + # unobtrusive JavaScript instead of using anything like `link_to_function` + def link_to_function(name, *args, &block) + html_options = args.extract_options!.symbolize_keys + + function = block_given? ? update_page(&block) : args[0] || '' + + onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;" + href = html_options[:href] || 'javascript:void(0)' + + content_tag(:a, name, html_options.merge(href: href, onclick: onclick)) + end + + # Generates class names for the main div in the application layout + def classes_for_main + class_names = controller.controller_name + '-' + controller.action_name + + show_sidebar = ((@user || @admin_posts || @collection || show_wrangling_dashboard) && !@hide_dashboard) + class_names += " dashboard" if show_sidebar + + class_names += " filtered" if page_has_filters? + + case controller.controller_name + when "abuse_reports", "feedbacks", "known_issues" + class_names = "system support #{controller.controller_name} #{controller.action_name}" + when "archive_faqs" + class_names = "system docs support faq #{controller.action_name}" + when "wrangling_guidelines" + class_names = "system docs guideline #{controller.action_name}" + when "home" + class_names = if %w(content privacy).include?(controller.action_name) + "system docs tos tos-#{controller.action_name}" + else + "system docs #{controller.action_name}" + end + when "errors" + class_names = "system #{controller.controller_name} error-#{controller.action_name}" + end + + class_names + end + + def page_has_filters? + @facets.present? || (controller.action_name == 'index' && controller.controller_name == 'collections') || (controller.action_name == 'unassigned' && controller.controller_name == 'fandoms') + end + + # This is used to make the current page we're on (determined by the path or by the specified condition) a span with class "current" and it allows us to add a title attribute to the link or the span + def span_if_current(link_to_default_text, path, condition=nil, title_attribute_default_text=nil) + is_current = condition.nil? ? current_page?(path) : condition + span_tag = title_attribute_default_text.nil? ? "#{link_to_default_text}" : "#{link_to_default_text}" + link_code = title_attribute_default_text.nil? ? link_to(link_to_default_text, path) : link_to(link_to_default_text, path, title: "#{title_attribute_default_text}") + is_current ? span_tag.html_safe : link_code + end + + def link_to_rss(link_to_feed) + link_to content_tag(:span, ts("RSS Feed")), link_to_feed, title: ts("RSS Feed"), class: "rss" + end + + # 1: default shows just the link to help + # 2: show_text = true: shows "plain text with limited html" and link to help + def allowed_html_instructions(show_text = true) + (show_text ? h(ts("Plain text with limited HTML")) : "".html_safe) + + link_to_help("html-help") + end + + # Byline helpers + def byline(creation, options={}) + if creation.respond_to?(:anonymous?) && creation.anonymous? + anon_byline = ts("Anonymous").html_safe + if options[:visibility] != "public" && (logged_in_as_admin? || is_author_of?(creation)) + anon_byline += " [#{non_anonymous_byline(creation, options[:only_path])}]".html_safe + end + return anon_byline + end + non_anonymous_byline(creation, options[:only_path]) + end + + def non_anonymous_byline(creation, url_path = nil) + only_path = url_path.nil? ? true : url_path + + if @preview_mode + # Skip cache in preview mode + return byline_text(creation, only_path) + end + + Rails.cache.fetch("#{creation.cache_key}/byline-nonanon/#{only_path.to_s}") do + byline_text(creation, only_path) + end + end + + def byline_text(creation, only_path, text_only = false) + if creation.respond_to?(:author) + creation.author + else + pseuds = @preview_mode ? creation.pseuds_after_saving : creation.pseuds.to_a + pseuds = pseuds.flatten.uniq.sort + + archivists = Hash.new [] + if creation.is_a?(Work) + external_creatorships = creation.external_creatorships.select { |ec| !ec.claimed? } + external_creatorships.each do |ec| + archivist_pseud = pseuds.select { |p| ec.archivist.pseuds.include?(p) }.first + archivists[archivist_pseud] += [ec.author_name] + end + end + + pseuds.map { |pseud| + pseud_byline = text_only ? pseud.byline : pseud_link(pseud, only_path) + if archivists[pseud].empty? + pseud_byline + else + archivists[pseud].map { |ext_author| + ts("%{ext_author} [archived by %{name}]", ext_author: ext_author, name: pseud_byline) + }.join(', ') + end + }.join(', ').html_safe + end + end + + def pseud_link(pseud, only_path = true) + if only_path + link_to(pseud.byline, user_pseud_path(pseud.user, pseud), rel: "author") + else + link_to(pseud.byline, user_pseud_url(pseud.user, pseud), rel: "author") + end + end + + # A plain text version of the byline, for when we don't want to deliver a linkified version. + def text_byline(creation, options={}) + if creation.respond_to?(:anonymous?) && creation.anonymous? + anon_byline = ts("Anonymous") + if (logged_in_as_admin? || is_author_of?(creation)) && options[:visibility] != 'public' + anon_byline += " [#{non_anonymous_byline(creation)}]".html_safe + end + anon_byline + else + only_path = false + text_only = true + byline_text(creation, only_path, text_only) + end + end + + def link_to_modal(content = "", options = {}) + options[:class] ||= "" + options[:for] ||= "" + options[:title] ||= options[:for] + + html_options = { class: "#{options[:class]} modal", title: options[:title] } + link_to content, options[:for], html_options + end + + # Currently, help files are static. We may eventually want to make these dynamic? + def link_to_help(help_entry, link = '?'.html_safe) + help_file = "" + #if Locale.active && Locale.active.language + # help_file = "#{ArchiveConfig.HELP_DIRECTORY}/#{Locale.active.language.code}/#{help_entry}.html" + #end + + unless !help_file.blank? && File.exists?("#{Rails.root}/public/#{help_file}") + help_file = "#{ArchiveConfig.HELP_DIRECTORY}/#{help_entry}.html" + end + + " ".html_safe + link_to_modal(link, for: help_file, title: help_entry.split('-').join(' ').capitalize, class: "help symbol question").html_safe + end + + # Inserts the flash alert messages for flash[:key] wherever + # <%= flash_div :key %> + # is placed in the views. That is, if a controller or model sets + # flash[:error] = "OMG ERRORZ AIE" + # or + # flash.now[:error] = "OMG ERRORZ AIE" + # + # then that error will appear in the view where you have + # <%= flash_div :error %> + # + # The resulting HTML will look like this: + #
OMG ERRORZ AIE
+ # + # The CSS classes are specified in system-messages.css. + # + # You can also have multiple possible flash alerts in a single location with: + # <%= flash_div :error, :caution, :notice %> + # (These are the three varieties currently defined.) + # + def flash_div *keys + keys.collect { |key| + if flash[key] + if flash[key].is_a?(Array) + content_tag(:div, + content_tag(:ul, + safe_join(flash[key].map do |flash_item| + content_tag(:li, sanitize(flash_item)) + end), "\n"), + class: "flash #{key}") + else + content_tag(:div, sanitize(flash[key]), class: "flash #{key}") + end + end + }.join.html_safe + end + + # Generates sorting links for index pages, with column names and directions + def sort_link(title, column=nil, options = {}) + condition = options[:unless] if options.has_key?(:unless) + + unless column.nil? + current_column = (params[:sort_column] == column.to_s) || params[:sort_column].blank? && options[:sort_default] + css_class = current_column ? "current" : nil + if current_column # explicitly or implicitly doing the existing sorting, so we need to toggle + if params[:sort_direction] + direction = params[:sort_direction].to_s.upcase == 'ASC' ? 'DESC' : 'ASC' + else + direction = options[:desc_default] ? 'ASC' : 'DESC' + end + else + direction = options[:desc_default] ? 'DESC' : 'ASC' + end + link_to_unless condition, ((direction == 'ASC' ? '↑ ' : '↓ ') + title).html_safe, + current_path_with(sort_column: column, sort_direction: direction), {class: css_class, title: (direction == 'ASC' ? ts('sort up') : ts('sort down'))} + else + link_to_unless params[:sort_column].nil?, title, current_path_with(sort_column: nil, sort_direction: nil) + end + end + + ## Allow use of tiny_mce WYSIWYG editor + def use_tinymce + @content_for_tinymce = "" + content_for :tinymce do + javascript_include_tag "tinymce/tinymce.min.js", skip_pipeline: true + end + @content_for_tinymce_init = "" + content_for :tinymce_init do + javascript_include_tag "mce_editor.min.js", skip_pipeline: true + end + end + + # check for pages that allow tiny_mce before loading the massive javascript + def allow_tinymce?(controller) + %w(admin_posts archive_faqs known_issues chapters works wrangling_guidelines).include?(controller.controller_name) && + %w(new create edit update).include?(controller.action_name) + end + + # see: http://www.w3.org/TR/wai-aria/states_and_properties#aria-valuenow + def generate_countdown_html(field_id, max) + max = max.to_s + span = content_tag(:span, max, id: "#{field_id}_counter", class: "value", "data-maxlength" => max) + content_tag(:p, span + ts(' characters left'), class: "character_counter", "tabindex" => 0) + end + + # expand/contracts all expand/contract targets inside its nearest parent with the target class (usually index or listbox etc) + def expand_contract_all(target = "listbox") + expand_all = button_tag(ts("Expand All"), class: "expand_all", data: { target_class: target }) + contract_all = button_tag(ts("Contract All"), class: "contract_all", data: { target_class: target }) + + expand_all + contract_all + end + + # Sets up expand/contract/shuffle buttons for any list whose id is passed in + # See the jquery code in application.js + # Note that these start hidden because if javascript is not available, we + # don't want to show the user the buttons at all. + def expand_contract_shuffle(list_id, shuffle: true) + target = "##{list_id}" + expander = button_tag("↓".html_safe, class: "expand hidden", title: "expand", data: { action_target: target }) + contractor = button_tag("↑".html_safe, class: "contract hidden", title: "contract", data: { action_target: target }) + shuffler = button_tag("⇆".html_safe, class: "shuffle hidden", title: "shuffle", data: { action_target: target }) if shuffle + + expander + contractor + shuffler + end + + # returns the default autocomplete attributes, all of which can be overridden + # note: we do this and put the message defaults here so we can use translation on them + def autocomplete_options(method, options={}) + { + class: "autocomplete", + data: { + autocomplete_method: (method.is_a?(Array) ? method.to_json : "/autocomplete/#{method}"), + autocomplete_hint_text: ts("Start typing for suggestions!"), + autocomplete_no_results_text: ts("(No suggestions found)"), + autocomplete_min_chars: 1, + autocomplete_searching_text: ts("Searching...") + } + }.deep_merge(options) + end + + # see http://asciicasts.com/episodes/197-nested-model-form-part-2 + def link_to_add_section(linktext, form, nested_model_name, partial_to_render, locals = {}) + new_nested_model = form.object.class.reflect_on_association(nested_model_name).klass.new + child_index = "new_#{nested_model_name}" + rendered_partial_to_add = + form.fields_for(nested_model_name, new_nested_model, child_index: child_index) {|child_form| + render(partial: partial_to_render, locals: {form: child_form, index: child_index}.merge(locals)) + } + link_to_function(linktext, "add_section(this, \"#{nested_model_name}\", \"#{escape_javascript(rendered_partial_to_add)}\")", class: "hidden showme") + end + + # see above + def link_to_remove_section(linktext, form, class_of_section_to_remove="removeme") + form.hidden_field(:_destroy) + "\n" + + link_to_function(linktext, "remove_section(this, \"#{class_of_section_to_remove}\")", class: "hidden showme") + end + + # show time in the time zone specified by the first argument + # add the user's time when specified in preferences + def time_in_zone(time, zone = nil, user = User.current_user) + return ts("(no time specified)") if time.blank? + + zone ||= (user&.is_a?(User) && user.preference.time_zone) ? user.preference.time_zone : Time.zone.name + time_in_zone = time.in_time_zone(zone) + time_in_zone_string = time_in_zone.strftime('%a %d + %b %Y + %I:%M%p') + + " #{time_in_zone.zone} " + + user_time_string = "" + if user.is_a?(User) && user.preference.time_zone + if user.preference.time_zone != zone + user_time = time.in_time_zone(user.preference.time_zone) + user_time_string = "(" + user_time.strftime('%I:%M%p') + + " #{user_time.zone})" + elsif !user.preference.time_zone + user_time_string = link_to ts("(set timezone)"), user_preferences_path(user) + end + end + + (time_in_zone_string + user_time_string).strip.html_safe + end + + def mailto_link(user, options={}) + " + \"email + ".html_safe + end + + # these two handy methods will take a form object (eg from form_for) and an attribute (eg :title or '_destroy') + # and generate the id or name that Rails will output for that object + def field_attribute(attribute) + attribute.to_s.sub(/\?$/,"") + end + + def name_to_id(name) + name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "") + end + + def field_id(form_or_object_name, attribute, index: nil, **_kwargs) + name_to_id(field_name(form_or_object_name, attribute, index: index)) + end + + # This is a partial re-implementation of ActionView::Helpers::FormTagHelper#field_name. + # The method contract changed in Rails 7.0, but we can't use the default because it sometimes + # includes other information that -- at a minimum -- wreaks havoc on the Cucumber feature tests. + # It is used in when constructing forms, like in app/views/tags/new.html.erb. + def field_name(form_or_object_name, attribute, *_method_names, multiple: false, index: nil) + object_name = if form_or_object_name.respond_to?(:object_name) + form_or_object_name.object_name + else + form_or_object_name + end + if object_name.blank? + "#{field_attribute(attribute)}#{multiple ? '[]' : ''}" + elsif index + "#{object_name}[#{index}][#{field_attribute(attribute)}]#{multiple ? '[]' : ''}" + else + "#{object_name}[#{field_attribute(attribute)}]#{multiple ? '[]' : ''}" + end + end + + # toggle an checkboxes (scrollable checkboxes) section of a form to show all of the checkboxes + def checkbox_section_toggle(checkboxes_id, checkboxes_size, options = {}) + toggle_show = content_tag(:a, ts("Expand %{checkboxes_size} Checkboxes", checkboxes_size: checkboxes_size), + class: "toggle #{checkboxes_id}_show") + "\n".html_safe + + toggle_hide = content_tag(:a, ts("Collapse Checkboxes"), + style: "display: none;", + class: "toggle #{checkboxes_id}_hide", + href: "##{checkboxes_id}") + "\n".html_safe + + css_class = checkbox_section_css_class(checkboxes_size) + + javascript_bits = content_for(:footer_js) { + javascript_tag("$j(document).ready(function(){\n" + + "$j('##{checkboxes_id}').find('.actions').show();\n" + + "$j('.#{checkboxes_id}_show').click(function() {\n" + + "$j('##{checkboxes_id}').find('.index').attr('class', 'options index all');\n" + + "$j('.#{checkboxes_id}_hide').show();\n" + + "$j('.#{checkboxes_id}_show').hide();\n" + + "});" + "\n" + + "$j('.#{checkboxes_id}_hide').click(function() {\n" + + "$j('##{checkboxes_id}').find('.index').attr('class', '#{css_class}');\n" + + "$j('.#{checkboxes_id}_show').show();\n" + + "$j('.#{checkboxes_id}_hide').hide();\n" + + "});\n" + + "})") + } + + toggle = content_tag(:p, + (options[:no_show] ? "".html_safe : toggle_show) + + toggle_hide + + (options[:no_js] ? "".html_safe : javascript_bits), class: "actions", style: "display: none;") + end + + # create a scrollable checkboxes section for a form that can be toggled open/closed + # form: the form this is being created in + # attribute: the attribute being set + # choices: the array of options (which should be objects of some sort) + # checked_method: a method that can be run on the object of the form to get back a list + # of currently-set options + # name_method: a method that can be run on each individual option to get its pretty name for labelling (typically just "name") + # value_method: a value that can be run to get the value of each individual option + # + # + # See the prompt_form in challenge signups for example of usage + def checkbox_section(form, attribute, choices, options = {}) + options = { + checked_method: nil, + name_method: "name", + name_helper_method: nil, # alternative: pass a helper method that gets passed the choice + extra_info_method: nil, # helper method that gets passed the choice, for any extra information that gets attached to the label + value_method: "id", + disabled: false, + include_toggle: true, + checkbox_side: "left", + include_blank: true, + concise: false # specify concise to invoke alternate formatting for skimmable lists (two-column in default layout) + }.merge(options) + + field_name = options[:field_name] || field_name(form, attribute) + field_name += '[]' + base_id = options[:field_id] || field_id(form, attribute) + checkboxes_id = "#{base_id}_checkboxes" + opts = options[:disabled] ? {disabled: "true"} : {} + already_checked = case + when options[:checked_method].is_a?(Array) + options[:checked_method] + when options[:checked_method].nil? + [] + else + form.object.send(options[:checked_method]) || [] + end + + checkboxes = choices.map do |choice| + is_checked = !options[:checked_method] || already_checked.empty? ? false : already_checked.include?(choice) + display_name = case + when options[:name_helper_method] + eval("#{options[:name_helper_method]}(choice)") + else + choice.send(options[:name_method]).html_safe + end + value = choice.send(options[:value_method]) + checkbox_id = "#{base_id}_#{name_to_id(value)}" + checkbox = check_box_tag(field_name, value, is_checked, opts.merge({id: checkbox_id})) + checkbox_and_label = label_tag checkbox_id, class: "action" do + options[:checkbox_side] == "left" ? checkbox + display_name : display_name + checkbox + end + if options[:extra_info_method] + checkbox_and_label = options[:checkbox_side] == "left" ? checkbox_and_label + eval("#{options[:extra_info_method]}(choice)") : eval("#{options[:extra_info_method]}(choice)") + checkbox_and_label + end + content_tag(:li, checkbox_and_label) + end.join("\n").html_safe + + # if there are only a few choices, don't show the scrolling and the toggle + size = choices.size + css_class = checkbox_section_css_class(size, options[:concise]) + checkboxes_ul = content_tag(:ul, checkboxes, class: css_class) + + toggle = "".html_safe + if options[:include_toggle] && !options[:concise] && size > (ArchiveConfig.OPTIONS_TO_SHOW * 6) + toggle = checkbox_section_toggle(checkboxes_id, size) + end + + # We wrap the whole thing in a div + return content_tag(:div, checkboxes_ul + toggle + (options[:include_blank] ? hidden_field_tag(field_name, " ") : ''.html_safe), id: checkboxes_id) + end + + def checkbox_section_css_class(size, concise=false) + css_class = "options index group" + + if concise + css_class += " concise lots" if size > ArchiveConfig.OPTIONS_TO_SHOW + else + css_class += " many" if size > ArchiveConfig.OPTIONS_TO_SHOW + css_class += " lots" if size > (ArchiveConfig.OPTIONS_TO_SHOW * 6) + end + + css_class + end + + def check_all_none(all_text="All", none_text="None", id_filter=nil) + filter_attrib = (id_filter ? " data-checkbox-id-filter=\"#{id_filter}\"" : '') + ('").html_safe + end + + def submit_button(form=nil, button_text=nil) + button_text ||= (form.nil? || form.object.nil? || form.object.new_record?) ? ts("Submit") : ts("Update") + content_tag(:p, (form.nil? ? submit_tag(button_text) : form.submit(button_text)), class: "submit") + end + + def submit_fieldset(form=nil, button_text=nil) + content_tag(:fieldset, content_tag(:legend, ts("Actions")) + submit_button(form, button_text)) + end + + def first_paragraph(full_text, placeholder_text = 'No preview available.') + # is there a paragraph that does not have a child image? + paragraph = Nokogiri::HTML5.parse(full_text).at_xpath("//p[not(img)]") + if paragraph.present? + # if so, get its text and put it in a fresh p tag + paragraph_text = paragraph.text + return content_tag(:p, paragraph_text) + else + # if not, put the placeholder text in a p tag with the placeholder class + return content_tag(:p, ts(placeholder_text), class: 'placeholder') + end + end + + # spans for nesting a checkbox or radio button inside its label to make custom + # checkbox or radio designs + def label_indicator_and_text(text) + content_tag(:span, "", class: "indicator", "aria-hidden": "true") + content_tag(:span, text) + end + + # Display a collection of radio buttons, wrapped in an unordered list. + # + # The parameter option_array should be a list of pairs, where the first + # element in each pair is the radio button's value, and the second element in + # each pair is the radio button's label. + def radio_button_list(form, field_name, option_array) + content_tag(:ul) do + form.collection_radio_buttons(field_name, option_array, :first, :second, + include_hidden: false) do |builder| + content_tag(:li, builder.label { builder.radio_button + builder.text }) + end + end + end + + # Identifier for creation, formatted external-work-12, series-12, work-12. + def creation_id_for_css_classes(creation) + return unless %w[ExternalWork Series Work].include?(creation.class.name) + + "#{creation.class.name.underscore.dasherize}-#{creation.id}" + end + + # Array of creator ids, formatted user-123, user-126. + # External works are not created by users, so we can skip this. + def creator_ids_for_css_classes(creation) + return [] unless %w[Series Work].include?(creation.class.name) + return [] if creation.anonymous? + # Although series.unrevealed? can be true, the creators are not concealed + # in the blurb. Therefore, we do not need special handling for unrevealed + # series. + return [] if creation.is_a?(Work) && creation.unrevealed? + + creation.pseuds.pluck(:user_id).uniq.map { |id| "user-#{id}" } + end + + def css_classes_for_creation_blurb(creation) + return if creation.nil? + + Rails.cache.fetch("#{creation.cache_key_with_version}/blurb_css_classes-v2") do + creation_id = creation_id_for_css_classes(creation) + creator_ids = creator_ids_for_css_classes(creation).join(" ") + "blurb group #{creation_id} #{creator_ids}".strip + end + end + + # Returns the current path, with some modified parameters. Modeled after + # WillPaginate::ActionView::LinkRenderer to try to prevent any additional + # security risks. + def current_path_with(**kwargs) + # Only throw in the query params if this is a GET request, because POST and + # such don't pass their params in the URL. + path_params = if request.get? || request.head? + permit_all_except(params, [:script_name, :original_script_name]) + else + {} + end + + path_params.deep_merge!(kwargs) + path_params[:only_path] = true # prevent shenanigans + + url_for(path_params) + end + + # Creates a new hash with all keys except those marked as blocked. + # + # This is a bit of a hack, but without this we'd have to either (a) make a + # list of all permitted params each time current_path_with is called, or (b) + # call params.permit! and effectively disable strong parameters for any code + # called after current_path_with. + def permit_all_except(params, blocked_keys) + if params.respond_to?(:each_pair) + {}.tap do |result| + params.each_pair do |key, value| + key = key.to_sym + next if blocked_keys.include?(key) + + result[key] = permit_all_except(value, blocked_keys) + end + end + elsif params.respond_to?(:map) + params.map do |entry| + permit_all_except(entry, blocked_keys) + end + else # not a hash or an array, just a flat value + params + end + end + + def disallow_robots?(item) + return unless item + + if item.is_a?(User) + item.preference&.minimize_search_engines? + elsif item.respond_to?(:users) + item.users.all? { |u| u&.preference&.minimize_search_engines? } + end + end + + # Determines if the page (controller and action combination) does not need + # to show the ToS (Terms of Service) popup. + def tos_exempt_page? + case params[:controller] + when "home" + %w[index content dmca privacy tos tos_faq].include?(params[:action]) + when "abuse_reports", "feedbacks", "users/sessions" + %w[new create].include?(params[:action]) + when "archive_faqs" + %w[index show].include?(params[:action]) + end + end + + def browser_page_title(page_title, page_subtitle) + return page_title if page_title + + page = if page_subtitle + page_subtitle + elsif controller.action_name == "index" + process_title(controller.controller_name) + else + "#{process_title(controller.action_name)} #{process_title(controller.controller_name.singularize)}" + end + # page_subtitle sometimes contains user (including admin) content, so let's + # not html_safe the entire string. Let's require html_safe be called when + # we set @page_subtitle, so we're conscious of what we're doing. + page + " | #{ArchiveConfig.APP_NAME}" + end +end diff --git a/app/helpers/block_helper.rb b/app/helpers/block_helper.rb new file mode 100755 index 0000000..21753c2 --- /dev/null +++ b/app/helpers/block_helper.rb @@ -0,0 +1,46 @@ +module BlockHelper + def block_link(user, block: nil) + if block.nil? + block = user.block_by_current_user + blocking_user = current_user + else + blocking_user = block.blocker + end + + if block + link_to(t("blocked.unblock"), confirm_unblock_user_blocked_user_path(blocking_user, block)) + else + link_to(t("blocked.block"), confirm_block_user_blocked_users_path(blocking_user, blocked_id: user)) + end + end + + def blocked_by?(object) + return false unless current_user + + blocker = users_for(object) + + # Users can't be blocked by their own creations, even if one of their + # co-creators has blocked them: + return false if blocker.include?(current_user) + + blocker.any?(&:block_of_current_user) + end + + def blocked_by_comment?(comment) + (comment.is_a?(Comment) || comment.is_a?(CommentDecorator)) && + comment.parent_type != "Tag" && + blocked_by?(comment) + end + + def users_for(object) + if object.is_a?(User) + [object] + elsif object.respond_to?(:user) + [object.user].compact + elsif object.respond_to?(:users) + object.users + else + [] + end + end +end diff --git a/app/helpers/bookmarks_helper.rb b/app/helpers/bookmarks_helper.rb new file mode 100755 index 0000000..c16587a --- /dev/null +++ b/app/helpers/bookmarks_helper.rb @@ -0,0 +1,130 @@ +module BookmarksHelper + # if the current user has the current object bookmarked return the existing bookmark + # since the user may have multiple bookmarks for different pseuds we prioritize by current default pseud if more than one bookmark exists + def bookmark_if_exists(bookmarkable) + return nil unless logged_in? + + bookmarkable = bookmarkable.work if bookmarkable.class == Chapter + + current_user.bookmarks.where(bookmarkable: bookmarkable) + .reorder("pseuds.is_default", "bookmarks.id").last + end + + # returns just a url to the new bookmark form + def get_new_bookmark_path(bookmarkable) + return case bookmarkable.class.to_s + when "Chapter" + new_work_bookmark_path(bookmarkable.work) + when "Work" + new_work_bookmark_path(bookmarkable) + when "ExternalWork" + new_external_work_bookmark_path(bookmarkable) + when "Series" + new_series_bookmark_path(bookmarkable) + end + end + + def link_to_bookmarkable_bookmarks(bookmarkable, link_text='') + if link_text.blank? + link_text = number_with_delimiter(Bookmark.count_visible_bookmarks(bookmarkable, current_user)) + end + path = case bookmarkable.class.name + when "Work" + then work_bookmarks_path(bookmarkable) + when "ExternalWork" + then external_work_bookmarks_path(bookmarkable) + when "Series" + then series_bookmarks_path(bookmarkable) + end + link_to link_text, path + end + + # returns the appropriate small single icon for a bookmark -- not hardcoded, these are in css so they are skinnable + def get_symbol_for_bookmark(bookmark) + if bookmark.private? + css_class = "private" + title_string = "Private Bookmark" + elsif bookmark.hidden_by_admin? + css_class = "hidden" + title_string = "Bookmark Hidden by Admin" + elsif bookmark.rec? + css_class = "rec" + title_string = "Rec" + else + css_class = "public" + title_string = "Public Bookmark" + end + link_to_help('bookmark-symbols-key', content_tag(:span, content_tag(:span, title_string, class: "text"), class: css_class, title: title_string)) + end + + def bookmark_form_path(bookmark, bookmarkable) + if bookmark.new_record? + if bookmarkable.new_record? + bookmarks_path + else + polymorphic_path([bookmarkable, bookmark]) + end + else + bookmark_path(bookmark) + end + end + + def get_count_for_bookmark_blurb(bookmarkable) + count = bookmarkable.public_bookmark_count + link = link_to (count < 100 ? count.to_s : "*"), + polymorphic_path([bookmarkable, Bookmark]) + content_tag(:span, link, class: "count") + end + + # Bookmark blurbs contain a single bookmark from a single user. + # bookmark blurb group creation-id [creator-ids bookmarker-id].uniq + def css_classes_for_bookmark_blurb(bookmark) + return if bookmark.nil? + + creation = bookmark.bookmarkable + if creation.nil? + "bookmark blurb group #{bookmarker_id_for_css_classes(bookmark)}" + else + Rails.cache.fetch("#{creation.cache_key_with_version}_#{bookmark.cache_key}/blurb_css_classes") do + creation_id = creation_id_for_css_classes(creation) + user_ids = user_ids_for_bookmark_blurb(bookmark).join(" ") + "bookmark blurb group #{creation_id} #{user_ids}".squish + end + end + end + + # Bookmarkable blurbs contain multiple short blurbs from different users. + # Bookmarker ids are applied to the individual short blurbs. + # Note that creation blurb classes are cached. + # bookmark blurb group creation-id creator-ids + def css_classes_for_bookmarkable_blurb(bookmarkable) + return "bookmark blurb group" if bookmarkable.nil? + + creation_classes = css_classes_for_creation_blurb(bookmarkable) + "bookmark #{creation_classes}".strip + end + + def css_classes_for_bookmark_blurb_short(bookmark) + return if bookmark.nil? + + own = "own" if is_author_of?(bookmark) + bookmarker_id = bookmarker_id_for_css_classes(bookmark) + "#{own} user short blurb group #{bookmarker_id}".squish + end + + private + + def bookmarker_id_for_css_classes(bookmark) + return if bookmark.nil? + + "user-#{bookmark.pseud.user_id}" + end + + # Array of unique creator and bookmarker ids, formatted user-123, user-126. + # If the user has bookmarked their own work, we don't need their id twice. + def user_ids_for_bookmark_blurb(bookmark) + user_ids = creator_ids_for_css_classes(bookmark.bookmarkable) + user_ids << bookmarker_id_for_css_classes(bookmark) + user_ids.uniq + end +end diff --git a/app/helpers/challenge_helper.rb b/app/helpers/challenge_helper.rb new file mode 100755 index 0000000..5ba2608 --- /dev/null +++ b/app/helpers/challenge_helper.rb @@ -0,0 +1,48 @@ +module ChallengeHelper + def prompt_tags(prompt) + details = content_tag(:h6, ts("Tags"), class: "landmark heading") + TagSet::TAG_TYPES.each do |type| + if prompt && prompt.tag_set && !prompt.tag_set.with_type(type).empty? + details += content_tag(:ul, tag_link_list(prompt.tag_set.with_type(type), link_to_works=true), class: "#{type} type tags commas") + end + end + details + end + + # generate the display value for the claim + def claim_title(claim) + claim.title.html_safe + link_to(ts(" (Details)"), collection_prompt_path(claim.collection, claim.request_prompt), target: "_blank", class: "toggle") + end + + # count the number of tag sets used in a challenge + def tag_set_count(collection) + if challenge_type_present?(collection) + tag_sets = determine_tag_sets(collection.challenge) + + # use `blank?` instead of `empty?` since there is the possibility that + # `tag_sets` will be nil, and nil does not respond to `blank?` + tag_sets.size unless tag_sets.blank? + end + end + + private + + # Private: Determines whether a collection has a challenge type + # + # Returns a boolean + def challenge_type_present?(collection) + collection && collection.challenge_type.present? + end + + # Private: Determines the collection of owned_tag_sets based on a given + # challenge's class + # + # Returns an ActiveRecord Collection object or nil + def determine_tag_sets(challenge) + if challenge.class.name == 'GiftExchange' + challenge.offer_restriction.owned_tag_sets + elsif challenge.class.name == 'PromptMeme' + challenge.request_restriction.owned_tag_sets + end + end +end diff --git a/app/helpers/collections_helper.rb b/app/helpers/collections_helper.rb new file mode 100755 index 0000000..d1c8af1 --- /dev/null +++ b/app/helpers/collections_helper.rb @@ -0,0 +1,138 @@ +module CollectionsHelper + + # Generates a draggable, pop-up div which contains the add-to-collection form + def collection_link(item) + if item.class == Chapter + item = item.work + end + if logged_in? + if item.class == Work + link_to ts("Add To Collection"), new_work_collection_item_path(item), remote: true + elsif item.class == Bookmark + link_to ts("Add To Collection"), new_bookmark_collection_item_path(item) + end + end + end + + # show a section if it's not empty or if the parent collection has it + def show_collection_section(collection, section) + if ["intro", "faq", "rules"].include?(section) # just a check that we're not using a bogus section string + !collection.collection_profile.send(section).blank? || collection.parent && !collection.parent.collection_profile.send(section).blank? + end + end + + # show collection preface if at least one section of the profile (or the parent collection's profile) is not empty + def show_collection_preface(collection) + show_collection_section(collection, "intro") || show_collection_section(collection, "faq") || show_collection_section(collection, "rules") + end + + # show navigation to relevant sections of the profile if needed + def show_collection_profile_navigation(collection, section) + ["intro", "faq", "rules"].each do |s| + if show_collection_section(collection, s) && s != section + return true # if at least one other section than the current one is not blank, we need the navigation; break out of the each...do + end + end + return false # if it passed through all tests above and not found a match, then we don't need the navigation + end + + def challenge_class_name(collection) + collection.challenge.class.name.demodulize.tableize.singularize + end + + def show_collections_data(collections) + collections.collect { |coll| link_to coll.title, collection_path(coll) }.join(ArchiveConfig.DELIMITER_FOR_OUTPUT).html_safe + end + + def challenge_assignment_byline(assignment) + if assignment.offer_signup && assignment.offer_signup.pseud + assignment.offer_signup.pseud.byline + elsif assignment.pinch_hitter + assignment.pinch_hitter.byline + "* (pinch hitter)" + else + "" + end + end + + def challenge_assignment_email(assignment) + if assignment.offer_signup && assignment.offer_signup.pseud + user = assignment.offer_signup.pseud.user + elsif assignment.pinch_hitter + user = assignment.pinch_hitter.user + else + user = nil + end + if user + mailto_link user, subject: "[#{(@collection.title)}] Message from Collection Maintainer" + end + end + + def collection_item_display_title(collection_item) + item = collection_item.item + item_type = collection_item.item_type + if item_type == 'Bookmark' && item.present? && item.bookmarkable.present? + # .html_safe is necessary for titles with ampersands etc when inside ts() + ts('Bookmark for %{title}', title: item.bookmarkable.title).html_safe + elsif item_type == 'Bookmark' + ts('Bookmark of deleted item') + elsif item_type == 'Work' && item.posted? + item.title + elsif item_type == 'Work' && !item.posted? + ts('%{title} (Draft)', title: item.title).html_safe + # Prevent 500 error if collection_item is not destroyed when collection_item.item is + else + ts('Deleted or unknown item') + end + end + + def collection_item_approval_options_label(actor:, item_type:) + item_type = item_type.downcase + actor = actor.downcase + + case actor + when "user" + t("collections_helper.collection_item_approval_options_label.user.#{item_type}") + when "collection" + t("collections_helper.collection_item_approval_options_label.collection") + end + end + + # i18n-tasks-use t('collections_helper.collection_item_approval_options.collection.approved') + # i18n-tasks-use t('collections_helper.collection_item_approval_options.collection.rejected') + # i18n-tasks-use t('collections_helper.collection_item_approval_options.collection.unreviewed') + # i18n-tasks-use t('collections_helper.collection_item_approval_options.user.bookmark.approved') + # i18n-tasks-use t('collections_helper.collection_item_approval_options.user.bookmark.rejected') + # i18n-tasks-use t('collections_helper.collection_item_approval_options.user.bookmark.unreviewed') + # i18n-tasks-use t('collections_helper.collection_item_approval_options.user.work.approved') + # i18n-tasks-use t('collections_helper.collection_item_approval_options.user.work.rejected') + # i18n-tasks-use t('collections_helper.collection_item_approval_options.user.work.unreviewed') + def collection_item_approval_options(actor:, item_type:) + item_type = item_type.downcase + actor = actor.downcase + + key = case actor + when "user" + "collections_helper.collection_item_approval_options.user.#{item_type}" + when "collection" + "collections_helper.collection_item_approval_options.collection" + end + + [ + [t("#{key}.unreviewed"), :unreviewed], + [t("#{key}.approved"), :approved], + [t("#{key}.rejected"), :rejected] + ] + end + + # Fetches the icon URL for the given collection, using the standard (100x100) variant. + def standard_icon_url(collection) + return "/images/skins/iconsets/default/icon_collection.png" unless collection.icon.attached? + + rails_blob_url(collection.icon.variant(:standard)) + end + + # Wraps the collection's standard_icon_url in an image tag + def collection_icon_display(collection) + image_tag(standard_icon_url(collection), size: "100x100", alt: collection.icon_alt_text, class: "icon", skip_pipeline: true) + end +end diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb new file mode 100755 index 0000000..3cba368 --- /dev/null +++ b/app/helpers/comments_helper.rb @@ -0,0 +1,404 @@ +module CommentsHelper + def value_for_comment_form(commentable, comment) + commentable.is_a?(Tag) ? comment : [commentable, comment] + end + + def title_for_comment_page(commentable) + if commentable.commentable_name.blank? + title = "" + elsif commentable.is_a?(Tag) + title = link_to_tag(commentable) + else + title = link_to(commentable.commentable_name, commentable) + end + (ts('Reading Comments on ') + title).html_safe + end + + def link_to_comment_ultimate_parent(comment) + ultimate = comment.ultimate_parent + case ultimate.class.to_s + when 'Work' then + link_to ultimate.title, ultimate + when 'Pseud' then + link_to ultimate.name, ultimate + when 'AdminPost' then + link_to ultimate.title, ultimate + else + if ultimate.is_a?(Tag) + link_to_tag(ultimate) + else + link_to 'Something Interesting', ultimate + end + end + end + + def comment_link_with_commentable_name(comment) + ultimate_parent = comment.ultimate_parent + commentable_name = ultimate_parent&.commentable_name + text = case ultimate_parent.class.to_s + when "Work" + t("comments_helper.comment_link_with_commentable_name.on_work_html", title: commentable_name) + when "AdminPost" + t("comments_helper.comment_link_with_commentable_name.on_admin_post_html", title: commentable_name) + else + if ultimate_parent.is_a?(Tag) + t("comments_helper.comment_link_with_commentable_name.on_tag_html", name: commentable_name) + else + t("comments_helper.comment_link_with_commentable_name.on_unknown") + end + end + link_to(text, comment_path(comment)) + end + + # return pseudname or name for comment + def get_commenter_pseud_or_name(comment) + if comment.pseud_id + if comment.pseud.nil? + ts("Account Deleted") + elsif comment.pseud.user.official + (link_to comment.pseud.byline, [comment.pseud.user, comment.pseud]) + content_tag(:span, " " + ts("(Official)"), class: "role") + else + link_to comment.pseud.byline, [comment.pseud.user, comment.pseud] + end + else + content_tag(:span, comment.name) + content_tag(:span, " #{ts('(Guest)')}", class: "role") + end + end + + def chapter_description_link(comment) + link_to t("comments_helper.chapter_link_html", position: comment.parent.position), work_chapter_path(comment.parent.work, comment.parent) + end + + def image_safety_mode_cache_key(comment) + "image-safety-mode" if comment.use_image_safety_mode? + end + + #### + ## Mar 4 2009 Enigel: the below shouldn't happen anymore, please test + #### + ## Note: there is a small but interesting bug here. If you first use javascript to open + ## up the comments, the various url_for(:overwrite_params) arguments used below as the + ## non-javascript fallbacks will end up with the wrong code, and so if you then turn + ## off Javascript and try to use the links, you will get weirdo results. I think this + ## is a bug we can live with for the moment; someone consistently browsing without + ## javascript shouldn't have problems. + ## -- Naomi, 9/2/2008 + #### + + #### Helpers for _commentable.html.erb #### + + # return link to show or hide comments + def show_hide_comments_link(commentable, options={}) + options[:link_type] ||= "show" + options[:show_count] ||= false + + commentable_id = commentable.is_a?(Tag) ? + :tag_id : + "#{commentable.class.to_s.underscore}_id".to_sym + commentable_value = commentable.is_a?(Tag) ? + commentable.name : + commentable.id + + comment_count = commentable.count_visible_comments.to_s + + link_action = options[:link_type] == "hide" || params[:show_comments] ? + :hide_comments : + :show_comments + + link_text = ts("%{words} %{count}", + words: options[:link_type] == "hide" || params[:show_comments] ? + "Hide Comments" : + "Comments", + count: options[:show_count] ? + "(" +comment_count+ ")" : + "") + + link_to( + link_text, + url_for(controller: :comments, + action: link_action, + commentable_id => commentable_value, + view_full_work: params[:view_full_work]), + remote: true) + end + + #### HELPERS FOR CHECKING WHICH BUTTONS/FORMS TO DISPLAY ##### + + def can_reply_to_comment?(comment) + admin_settings = AdminSetting.current + + return false if comment.unreviewed? + return false if comment.iced? + return false if comment.hidden_by_admin? + return false if parent_disallows_comments?(comment) + return false if comment_parent_hidden?(comment) + return false if blocked_by_comment?(comment) + return false if blocked_by?(comment.ultimate_parent) + return false if logged_in_as_admin? + + return true unless guest? + + !(admin_settings.guest_comments_off? || comment.guest_replies_disallowed?) + end + + def can_edit_comment?(comment) + is_author_of?(comment) && + !comment.iced? && + comment.count_all_comments.zero? && + !comment_parent_hidden?(comment) && + !blocked_by_comment?(comment.commentable) && + !blocked_by?(comment.ultimate_parent) + end + + # Only an admin with proper authorization can mark a spam comment ham. + def can_mark_comment_ham?(comment) + return unless comment.pseud.nil? && !comment.approved? + + policy(comment).can_mark_comment_spam? + end + + # An admin with proper authorization or a creator of the comment's ultimate + # parent (i.e. the work) can mark an approved comment as spam. + def can_mark_comment_spam?(comment) + return unless comment.pseud.nil? && comment.approved? + + policy(comment).can_mark_comment_spam? || is_author_of?(comment.ultimate_parent) + end + + # Comments can be deleted by admins with proper authorization, their creator + # (if the creator is a registered user), or the creator of the comment's + # ultimate parent. + def can_destroy_comment?(comment) + policy(comment).can_destroy_comment? || + is_author_of?(comment) || + is_author_of?(comment.ultimate_parent) + end + + # Comments on works can be frozen by admins with proper authorization or the + # work creator. + # Comments on tags can be frozen by admins with proper authorization. + # Comments on admin posts can be frozen by any admin. + def can_freeze_comment?(comment) + policy(comment).can_freeze_comment? || + comment.ultimate_parent.is_a?(Work) && + is_author_of?(comment.ultimate_parent) + end + + def can_hide_comment?(comment) + policy(comment).can_hide_comment? + end + + def can_see_hidden_comment?(comment) + !comment.hidden_by_admin? || + is_author_of?(comment) || + can_hide_comment?(comment) + end + + def comment_parent_hidden?(comment) + parent = comment.ultimate_parent + (parent.respond_to?(:hidden_by_admin) && parent.hidden_by_admin) || + (parent.respond_to?(:in_unrevealed_collection) && parent.in_unrevealed_collection) + end + + def parent_disallows_comments?(comment) + parent = comment.ultimate_parent + return false unless parent.is_a?(Work) || parent.is_a?(AdminPost) + + parent.disable_all_comments? || + parent.disable_anon_comments? && !logged_in? + end + + def can_review_comment?(comment) + return false unless comment.unreviewed? + + is_author_of?(comment.ultimate_parent) || policy(comment).can_review_comment? + end + + def can_review_all_comments?(commentable) + commentable.is_a?(AdminPost) || is_author_of?(commentable) + end + + #### HELPERS FOR REPLYING TO COMMENTS ##### + + # return link to add new reply to a comment + def add_comment_reply_link(comment) + commentable_id = comment.ultimate_parent.is_a?(Tag) ? + :tag_id : + comment.parent.class.name.foreign_key.to_sym # :chapter_id, :admin_post_id etc. + commentable_value = comment.ultimate_parent.is_a?(Tag) ? + comment.ultimate_parent.name : + comment.parent.id + link_to( + ts("Reply"), + url_for(controller: :comments, + action: :add_comment_reply, + id: comment.id, + comment_id: params[:comment_id], + commentable_id => commentable_value, + view_full_work: params[:view_full_work], + page: params[:page]), + remote: true) + end + + # return link to cancel new reply to a comment + def cancel_comment_reply_link(comment) + commentable_id = comment.ultimate_parent.is_a?(Tag) ? + :tag_id : + comment.parent.class.name.foreign_key.to_sym + commentable_value = comment.ultimate_parent.is_a?(Tag) ? + comment.ultimate_parent.name : + comment.parent.id + link_to( + ts("Cancel"), + url_for( + controller: :comments, + action: :cancel_comment_reply, + id: comment.id, + comment_id: params[:comment_id], + commentable_id => commentable_value, + view_full_work: params[:view_full_work], + page: params[:page] + ), + remote: true + ) + end + + # canceling an edit + def cancel_edit_comment_link(comment) + link_to(ts("Cancel"), + url_for(controller: :comments, + action: :cancel_comment_edit, + id: comment.id, + comment_id: params[:comment_id]), + remote: true) + end + + # return html link to edit comment + def edit_comment_link(comment) + link_to(ts("Edit"), + url_for(controller: :comments, + action: :edit, + id: comment, + comment_id: params[:comment_id]), + remote: true) + end + + def do_cancel_delete_comment_link(comment) + if params[:delete_comment_id] && params[:delete_comment_id] == comment.id.to_s + cancel_delete_comment_link(comment) + else + delete_comment_link(comment) + end + end + + def freeze_comment_button(comment) + if comment.iced? + button_to ts("Unfreeze Thread"), unfreeze_comment_path(comment), method: :put + else + button_to ts("Freeze Thread"), freeze_comment_path(comment), method: :put + end + end + + def hide_comment_button(comment) + if comment.hidden_by_admin? + button_to ts("Make Comment Visible"), unhide_comment_path(comment), method: :put + else + button_to ts("Hide Comment"), hide_comment_path(comment), method: :put + end + end + + # Not a link or button, but included with them. + def frozen_comment_indicator + content_tag(:span, ts("Frozen"), class: "frozen current") + end + + # return html link to delete comments + def delete_comment_link(comment) + link_to( + ts("Delete"), + url_for(controller: :comments, + action: :delete_comment, + id: comment, + comment_id: params[:comment_id]), + remote: true) + end + + # return link to cancel new reply to a comment + def cancel_delete_comment_link(comment) + link_to( + ts("Cancel"), + url_for(controller: :comments, + action: :cancel_comment_delete, + id: comment, + comment_id: params[:comment_id]), + remote: true) + end + + # return html link to mark/unmark comment as spam + def tag_comment_as_spam_link(comment) + if comment.approved + link_to(ts("Spam"), reject_comment_path(comment), method: :put, data: { confirm: "Are you sure you want to mark this as spam?" }) + else + link_to(ts("Not Spam"), approve_comment_path(comment), method: :put) + end + end + + # gets the css user- class name for the comment + def commenter_id_for_css_classes(comment) + return if comment.pseud.nil? + return if comment.by_anonymous_creator? + return if comment.is_deleted + return if comment.hidden_by_admin + + "user-#{comment.pseud.user_id}" + end + + def css_classes_for_comment(comment) + return if comment.nil? + + unavailable = "unavailable" if comment.hidden_by_admin + unreviewed = "unreviewed" if comment.unreviewed? + commenter = commenter_id_for_css_classes(comment) + official = "official" if commenter && comment&.pseud&.user&.official + guest = "guest" unless comment.pseud_id + + "#{unavailable} #{official} #{guest} #{unreviewed} comment group #{commenter}".squish + end + + # find the parent of the commentable + def find_parent(commentable) + if commentable.respond_to?(:ultimate_parent) + commentable.ultimate_parent + elsif commentable.respond_to?(:work) + commentable.work + else + commentable + end + end + + # if parent commentable is a work, determine if current user created it + def current_user_is_work_creator(commentable) + if logged_in? + parent = find_parent(commentable) + parent.is_a?(Work) && current_user.is_author_of?(parent) + end + end + + # if parent commentable is an anonymous work, determine if current user created it + def current_user_is_anonymous_creator(commentable) + if logged_in? + parent = find_parent(commentable) + parent.is_a?(Work) && parent.anonymous? && current_user.is_author_of?(parent) + end + end + + # determine if the parent has its comments set to moderated + def comments_are_moderated(commentable) + parent = find_parent(commentable) + parent.respond_to?(:moderated_commenting_enabled) && parent.moderated_commenting_enabled? + end + + def focused_on_comment(commentable) + params[:add_comment_reply_id] && params[:add_comment_reply_id] == commentable.id.to_s + end +end diff --git a/app/helpers/date_helper.rb b/app/helpers/date_helper.rb new file mode 100755 index 0000000..ac6d502 --- /dev/null +++ b/app/helpers/date_helper.rb @@ -0,0 +1,36 @@ +module DateHelper + + # Use time_ago_in_words if less than a month ago, otherwise display date + def set_format_for_date(datetime) + return "" unless datetime.is_a? Time + if datetime > 30.days.ago && !AdminSetting.enable_test_caching? + time_ago_in_words(datetime) + else + date_in_user_time_zone(datetime).to_date.to_formatted_s(:rfc822) + end + end + + def date_in_user_time_zone(datetime) + if logged_in? && current_user.preference.time_zone + zone = current_user.preference.time_zone + begin + date_in_user_time_zone = datetime.in_time_zone(current_user.preference.time_zone) + rescue + datetime + end + else + date_in_user_time_zone = datetime + end + end + + # show date in the time zone specified + # note: this does *not* append timezone and does *not* reflect user preferences + def date_in_zone(time, zone = nil) + zone ||= Time.zone.name + return nil if time.blank? + + time_in_zone = time.in_time_zone(zone) + I18n.l(time_in_zone, format: :date_short_html).html_safe + # i18n-tasks-use t('time.formats.date_short_html') + end +end diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb new file mode 100755 index 0000000..08131f1 --- /dev/null +++ b/app/helpers/exports_helper.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +module ExportsHelper + + def send_csv_data(content_array, filename) + send_data(export_csv(content_array), filename: filename, type: :csv) + end + + # Tab-separated CSV with utf-16le encoding (unicode) and byte order + # mark. This seems to be the only variant Excel can get + # automatically into proper table format. OpenOffice handles it + # well, too. + def export_csv(content_array) + csv_data = content_array.map { |x| x.to_csv(col_sep: "\t", encoding: "utf-8") }.join + byte_order_mark = "\uFEFF" + (byte_order_mark + csv_data).encode("utf-16le", "utf-8", invalid: :replace, undef: :replace, replace: "") + end +end diff --git a/app/helpers/external_authors_helper.rb b/app/helpers/external_authors_helper.rb new file mode 100755 index 0000000..a4e8075 --- /dev/null +++ b/app/helpers/external_authors_helper.rb @@ -0,0 +1,26 @@ +module ExternalAuthorsHelper + + def add_name_link(form_builder) + link_to_function 'add name' do |page| + form_builder.fields_for :external_author_names, ExternalAuthorName.new, child_index: 'NEW_RECORD' do |f| + html = render(partial: 'external_author_name', locals: { form: f }) + page << "$('external_author_names').insert({ bottom: '#{escape_javascript(html)}'.replace(/NEW_RECORD/g, new Date().getTime()) });" + end + end + end + + + def remove_name_link(form_builder) + if form_builder.object.new_record? + # If the task is a new record, we can just remove the div from the dom + link_to_function("remove", "$(this).up('.external_author_name').remove();"); + else + # However if it's a "real" record it has to be deleted from the database, + # for this reason the new fields_for, accept_nested_attributes helpers give us _delete, + # a virtual attribute that tells rails to delete the child record. + form_builder.hidden_field("_destroy") + + link_to_function("remove", "$(this).up('.external_author_name').hide(); $(this).previous().value = '1'") + end + end + +end diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb new file mode 100755 index 0000000..55e91cd --- /dev/null +++ b/app/helpers/home_helper.rb @@ -0,0 +1,114 @@ +module HomeHelper + def html_to_text(string) + string.gsub!(//, "\n") + string.gsub!(/<\/?p>/, "\n\n") + string = strip_tags(string) + string.gsub!(/^[ \t]*/, "") + while !string.gsub!(/\n\s*\n\s*\n/, "\n\n").nil? + # keep going + end + return string + end + + # A TOC section has an h4 header, p with intro link, and ol of subsections. + def tos_table_of_contents_section(action) + return unless %w[content privacy tos].include?(action) + + content = tos_section_header(action) + tos_section_intro_link(action) + tos_subsection_list(action) + # If we're on /tos, /content, or /privacy, use the details tag to make + # sections expandable and collapsable. + if controller.controller_name == "home" + # Use the open attribute to make the page's corresponding section expanded + # by default. + content_tag(:details, content, open: controller.action_name == action) + else + content + end + end + + private + + def tos_section_header(action) + # If we're on /tos, /content, or /privacy, the corresponding section header + # gets extra text indicating it is the current section. + text = if controller.controller_name == "home" && controller.action_name == action + t("home.tos_toc.#{action}.header_current") + else + t("home.tos_toc.#{action}.header") + end + heading = content_tag(:h4, text, class: "heading") + # If we're on /tos, /content, or /privacy, use a summary tag around the h4 + # so it serves as the toggle to expand or collapse its section. + if controller.controller_name == "home" + content_tag(:summary, heading) + else + heading + end + end + + def tos_section_intro_link(action) + content_tag(:p, link_to(t("home.tos_toc.#{action}.intro"), tos_anchor_url(action, action))) + end + + def tos_subsection_list(action) + items = case action + when "content" + content_policy_subsection_items + when "privacy" + privacy_policy_subsection_items + when "tos" + tos_subsection_items + end + content_tag(:ol, items.html_safe, style: "list-style-type: upper-alpha;") + end + + # When we are on the /signup page, the entire TOS is displayed. This lets us + # make sure that page only uses plain anchors in its TOC while the /tos, + # /content, nad /privacy pages (found in the home controller) sometimes + # point to other pages. + def tos_anchor_url(action, anchor) + if controller.controller_name == "home" + url_for(only_path: true, action: action, anchor: anchor) + else + "##{anchor}" + end + end + + def content_policy_subsection_items + content_tag(:li, link_to(t("home.tos_toc.content.offensive_content"), tos_anchor_url("content", "II.A"))) + + content_tag(:li, link_to(t("home.tos_toc.content.fanworks"), tos_anchor_url("content", "II.B"))) + + content_tag(:li, link_to(t("home.tos_toc.content.commercial_promotion"), tos_anchor_url("content", "II.C"))) + + content_tag(:li, link_to(t("home.tos_toc.content.copyright_infringement"), tos_anchor_url("content", "II.D"))) + + content_tag(:li, link_to(t("home.tos_toc.content.plagiarism"), tos_anchor_url("content", "II.E"))) + + content_tag(:li, link_to(t("home.tos_toc.content.personal_information_and_fannish_identities"), tos_anchor_url("content", "II.F"))) + + content_tag(:li, link_to(t("home.tos_toc.content.impersonation"), tos_anchor_url("content", "II.G"))) + + content_tag(:li, link_to(t("home.tos_toc.content.harassment"), tos_anchor_url("content", "II.H"))) + + content_tag(:li, link_to(t("home.tos_toc.content.user_icons"), tos_anchor_url("content", "II.I"))) + + content_tag(:li, link_to(t("home.tos_toc.content.mandatory_tags"), tos_anchor_url("content", "II.J"))) + + content_tag(:li, link_to(t("home.tos_toc.content.illegal_and_inappropriate_content"), tos_anchor_url("content", "II.K"))) + end + + def privacy_policy_subsection_items + content_tag(:li, link_to(t("home.tos_toc.privacy.applicability"), tos_anchor_url("privacy", "III.A"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.scope_of_personal_information_we_process"), tos_anchor_url("privacy", "III.B"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.types_of_personal_information_we_collect_and_process"), tos_anchor_url("privacy", "III.C"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.aggregate_and_anonymous_information"), tos_anchor_url("privacy", "III.D"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.your_rights_under_applicable_data_privacy_laws"), tos_anchor_url("privacy", "III.E"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.information_shared_with_third_parties"), tos_anchor_url("privacy", "III.F"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.termination_of_account"), tos_anchor_url("privacy", "III.G"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.retention_of_personal_information"), tos_anchor_url("privacy", "III.H"))) + + content_tag(:li, link_to(t("home.tos_toc.privacy.contact_us"), tos_anchor_url("privacy", "III.I"))) + end + + def tos_subsection_items + content_tag(:li, link_to(t("home.tos_toc.tos.general_terms"), tos_anchor_url("tos", "I.A"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.updates_to_the_tos"), tos_anchor_url("tos", "I.B"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.potential_problems"), tos_anchor_url("tos", "I.C"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.content_you_access"), tos_anchor_url("tos", "I.D"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.what_we_do_with_content"), tos_anchor_url("tos", "I.E"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.what_you_cant_do"), tos_anchor_url("tos", "I.F"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.registration_and_email_addresses"), tos_anchor_url("tos", "I.G"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.age_policy"), tos_anchor_url("tos", "I.H"))) + + content_tag(:li, link_to(t("home.tos_toc.tos.abuse_policy"), tos_anchor_url("tos", "I.I"))) + end +end diff --git a/app/helpers/inbox_helper.rb b/app/helpers/inbox_helper.rb new file mode 100755 index 0000000..d19915c --- /dev/null +++ b/app/helpers/inbox_helper.rb @@ -0,0 +1,20 @@ +module InboxHelper + # Describes commentable - used on inbox show page + def commentable_description_link(comment) + commentable = comment.ultimate_parent + return ts("Deleted Object") if commentable.blank? + + if commentable.is_a?(Tag) + link_to commentable.name, tag_comment_path(commentable, comment) + elsif commentable.is_a?(AdminPost) + link_to commentable.title, admin_post_comment_path(commentable, comment) + elsif commentable.chaptered? + link_to t("inbox_helper.comment_link_with_chapter_number", position: comment.parent.position, title: commentable.title), work_comment_path(commentable, comment) + else + link_to commentable.title, work_comment_path(commentable, comment) + end + end + + # get_commenter_pseud_or_name can be found in comments_helper + +end diff --git a/app/helpers/invitations_helper.rb b/app/helpers/invitations_helper.rb new file mode 100755 index 0000000..3d30d9b --- /dev/null +++ b/app/helpers/invitations_helper.rb @@ -0,0 +1,26 @@ +module InvitationsHelper + def creator_link(invitation) + case invitation.creator + when User + link_to(invitation.creator.login, invitation.creator) + when Admin + invitation.creator.login + else + t("invitations.invitation.queue") + end + end + + def invitee_link(invitation) + return unless invitation.invitee_type == "User" + + if User.current_user.is_a?(Admin) && policy(invitation).access_invitee_details? + return t("invitations.invitation.user_id_deleted", user_id: invitation.invitee_id) if invitation.invitee.blank? + + return link_to(invitation.invitee.login, admin_user_path(invitation.invitee)) + end + + return t("invitations.invitation.deleted_user") if invitation.invitee.blank? + + link_to(invitation.invitee.login, invitation.invitee) if invitation.invitee.present? + end +end diff --git a/app/helpers/kudos_helper.rb b/app/helpers/kudos_helper.rb new file mode 100755 index 0000000..dd1c01b --- /dev/null +++ b/app/helpers/kudos_helper.rb @@ -0,0 +1,52 @@ +module KudosHelper + # Returns a comma-separated list of kudos. Restricts the list to the first + # ArchiveConfig.MAX_KUDOS_TO_SHOW entries, with a link to view more. + # + # When showing_more is true, returns a list with a connector at the front, + # so that it can be appended to an existing list to make a longer list. + # Otherwise, returns a normal-looking list. + def kudos_user_links(commentable, kudos, showing_more: true) + kudos = kudos.order(id: :desc) + + total_count = kudos.count + collapsed_count = total_count - ArchiveConfig.MAX_KUDOS_TO_SHOW + kudos_to_display = kudos.limit(ArchiveConfig.MAX_KUDOS_TO_SHOW).to_a + + kudos_links = kudos_to_display.map do |kudo| + link_to kudo.user.login, kudo.user + end + + # Make sure to duplicate the hash returned by I18n.translate, because + # otherwise I18n will start returning our modified version: + connectors = t("support.array").dup + + if showing_more + # Make a connector appear at the front: + kudos_links.unshift("") + + # Even if it looks like there are only two items, we're actually just + # showing the last part of a longer list, so we should always use the + # last_word_connector instead of the two_words_connector: + connectors[:two_words_connector] = connectors[:last_word_connector] + end + + if collapsed_count.positive? + # Add the link to show more at the end of the list: + kudos_links << link_to( + t("kudos.user_links.more_link", count: collapsed_count), + work_kudos_path(commentable, before: kudos_to_display.last.id), + id: "kudos_more_link", remote: true + ) + + # Regardless of whether we're showing 2 or 3+, we need to wrap the last + # connector in a span with the id "kudos_more_connector" so that we can + # remove/alter it later: + %i[two_words_connector last_word_connector].each do |connector_type| + connectors[connector_type] = tag.span(connectors[connector_type], + id: "kudos_more_connector") + end + end + + kudos_links.to_sentence(connectors).html_safe + end +end diff --git a/app/helpers/language_helper.rb b/app/helpers/language_helper.rb new file mode 100755 index 0000000..d1d036b --- /dev/null +++ b/app/helpers/language_helper.rb @@ -0,0 +1,39 @@ +RTL_LOCALES = %w[ar fa he].freeze + +module LanguageHelper + def available_faq_locales + ArchiveFaq.translated_locales.map { |code| Locale.find_by(iso: code) } + end + + def rtl? + RTL_LOCALES.include?(Globalize.locale.to_s) + end + + def rtl_language?(language) + RTL_LOCALES.include?(language.short) + end + + def english? + params[:language_id] == "en" + end + + def translated_questions(all_questions) + questions = [] + all_questions.each do |question| + question.translations.each do |translation| + if translation.is_translated == "1" && params[:language_id].to_s == translation.locale.to_s + questions << question + end + end + end + questions + end + + def language_options_for_select(languages, value_attribute) + languages.map { |language| [language.name, language[value_attribute], { lang: language.short }] } + end + + def locale_options_for_select(locales, value_attribute) + locales.map { |locale| [locale.name, locale[value_attribute], { lang: locale.language.short }] } + end +end diff --git a/app/helpers/mailer_helper.rb b/app/helpers/mailer_helper.rb new file mode 100755 index 0000000..c656a4e --- /dev/null +++ b/app/helpers/mailer_helper.rb @@ -0,0 +1,311 @@ +module MailerHelper + + def style_bold(text) + ("" + "#{text}".html_safe + "").html_safe + end + + def style_link(body, url, html_options = {}) + html_options[:style] = "color:#990000" + link_to(body.html_safe, url, html_options) + end + + def style_role(text) + tag.em(tag.strong(text)) + end + + # For work, chapter, and series links + def style_creation_link(title, url, html_options = {}) + html_options[:style] = "color:#990000" + ("" + link_to(title.html_safe, url, html_options) + "").html_safe + end + + # For work, chapter, and series titles + def style_creation_title(title) + ("" + title.html_safe + "").html_safe + end + + def style_footer_link(body, url, html_options = {}) + html_options[:style] = "color:#FFFFFF" + link_to(body.html_safe, url, html_options) + end + + def style_email(email, name = nil, html_options = {}) + html_options[:style] = "color:#990000" + mail_to(email, name.nil? ? nil : name.html_safe, html_options) + end + + def style_pseud_link(pseud) + style_link("" + + pseud.byline, user_pseud_url(pseud.user, pseud)) + end + + def text_pseud(pseud) + pseud.byline + " (#{user_pseud_url(pseud.user, pseud)})" + end + + def style_quote(text) + ("
" + text + "
").html_safe + end + + def support_link(text) + style_link(text, root_url + "support") + end + + def abuse_link(text) + style_link(text, root_url + "abuse_reports/new") + end + + def tos_link(text) + style_link(text, tos_url) + end + + def opendoors_link(text) + style_link(text, "https://opendoors.transformativeworks.org/contact-open-doors/") + end + + def styled_divider + ("
" + + "
" + + "
" + + "

").html_safe + end + + def text_divider + "--------------------" + end + + # strip opening paragraph tags, and line breaks or close-pargraphs at the end of the string + # all other close-paragraphs become double line breaks + # line break tags become single line breaks + # bold text is wrapped in * + # italic text is wrapped in / + # underlined text is wrapped in _ + # all other html tags are stripped + def to_plain_text(html) + strip_tags( + html.gsub(/

|<\/p>\z|\z/, "") + .gsub(/<\/p>/, "\n\n") + .gsub(//, "\n") + .gsub(/<\/?(b|em|strong)>/, "*") + .gsub(/<\/?(i|cite)>/, "/") + .gsub(/<\/?u>/, "_") + ) + end + + # Reformat a string as HTML with
tags instead of newlines, but with all + # other HTML escaped. + # This is used for collection.assignment_notification, which already strips + # HTML tags (when saving the collection settings, the params are sanitized), + # but that still leaves other HTML entities. + def escape_html_and_create_linebreaks(html) + # Escape each line with h(), then join with
s and mark as html_safe to + # ensure that the
s aren't escaped. + html.split("\n").map { |line_of_text| h(line_of_text) }.join('
').html_safe + end + + # The title used in creatorship_notification and creatorship_request + # emails. + def creation_title(creation) + if creation.is_a?(Chapter) + t("mailer.general.creation.title_with_chapter_number", + position: creation.position, title: creation.work.title) + else + creation.title + end + end + + # e.g., Title (x words), where Title is a link + def creation_link_with_word_count(creation, creation_url) + title = if creation.is_a?(Chapter) + creation.full_chapter_title.html_safe + else + creation.title.html_safe + end + t("mailer.general.creation.link_with_word_count", + creation_link: style_creation_link(title, creation_url), + word_count: creation_word_count(creation)).html_safe + end + + # e.g., "Title" (x words), where Title is not a link + def creation_title_with_word_count(creation) + title = if creation.is_a?(Chapter) + creation.full_chapter_title.html_safe + else + creation.title.html_safe + end + t("mailer.general.creation.title_with_word_count", + creation_title: title, word_count: creation_word_count(creation)) + end + + # The bylines used in subscription emails to prevent exposing the name(s) of + # anonymous creator(s). + def creator_links(work) + if work.anonymous? + "Anonymous" + else + work.pseuds.map { |p| style_pseud_link(p) }.to_sentence.html_safe + end + end + + def creator_text(work) + if work.anonymous? + "Anonymous" + else + work.pseuds.map { |p| text_pseud(p) }.to_sentence.html_safe + end + end + + def metadata_label(text) + text.html_safe + t("mailer.general.metadata_label_indicator") + end + + # Spacing is dealt with in locale files, e.g. " : " for French. + def work_tag_metadata(tags) + return if tags.empty? + + "#{work_tag_metadata_label(tags)}#{work_tag_metadata_list(tags)}" + end + + def style_metadata_label(text) + style_bold(metadata_label(text)) + end + + # Spacing is dealt with in locale files, e.g. " : " for French. + def style_work_tag_metadata(tags) + return if tags.empty? + + label = style_bold(work_tag_metadata_label(tags)) + "#{label}#{style_work_tag_metadata_list(tags)}".html_safe + end + + def commenter_pseud_or_name_link(comment) + return style_bold(t("roles.anonymous_creator")) if comment.by_anonymous_creator? + + if comment.comment_owner.nil? + t("roles.commenter_name.html", name: style_bold(comment.comment_owner_name), role_with_parens: style_role(t("roles.guest_with_parens"))) + else + role = comment.user.official ? t("roles.official_with_parens") : t("roles.registered_with_parens") + pseud_link = style_link(comment.pseud.byline, user_pseud_url(comment.user, comment.pseud)) + t("roles.commenter_name.html", name: tag.strong(pseud_link), role_with_parens: style_role(role)) + end + end + + def commenter_pseud_or_name_text(comment) + return t("roles.anonymous_creator") if comment.by_anonymous_creator? + + if comment.comment_owner.nil? + t("roles.commenter_name.text", name: comment.comment_owner_name, role_with_parens: t("roles.guest_with_parens")) + else + role = comment.user.official ? t("roles.official_with_parens") : t("roles.registered_with_parens") + t("roles.commenter_name.text", name: text_pseud(comment.pseud), role_with_parens: role) + end + end + + def content_for_commentable_text(comment) + if comment.ultimate_parent.is_a?(Tag) + t(".content.tag.text", + pseud: commenter_pseud_or_name_text(comment), + tag: comment.ultimate_parent.commentable_name, + tag_url: tag_url(comment.ultimate_parent)) + elsif comment.parent.is_a?(Chapter) && comment.ultimate_parent.chaptered? + if comment.parent.title.blank? + t(".content.chapter.untitled_text", + pseud: commenter_pseud_or_name_text(comment), + chapter_position: comment.parent.position, + work: comment.ultimate_parent.commentable_name, + chapter_url: work_chapter_url(comment.parent.work, comment.parent)) + else + t(".content.chapter.titled_text", + pseud: commenter_pseud_or_name_text(comment), + chapter_position: comment.parent.position, + chapter_title: comment.parent.title, + work: comment.ultimate_parent.commentable_name, + chapter_url: work_chapter_url(comment.parent.work, comment.parent)) + end + else + t(".content.other.text", + pseud: commenter_pseud_or_name_text(comment), + title: comment.ultimate_parent.commentable_name, + commentable_url: polymorphic_url(comment.ultimate_parent)) + end + end + + def content_for_commentable_html(comment) + if comment.ultimate_parent.is_a?(Tag) + t(".content.tag.html", + pseud_link: commenter_pseud_or_name_link(comment), + tag_link: style_link(comment.ultimate_parent.commentable_name, tag_url(comment.ultimate_parent))) + elsif comment.parent.is_a?(Chapter) && comment.ultimate_parent.chaptered? + t(".content.chapter.html", + pseud_link: commenter_pseud_or_name_link(comment), + chapter_link: style_link(comment.parent.title.blank? ? t(".chapter.untitled", position: comment.parent.position) : t(".chapter.titled", position: comment.parent.position, title: comment.parent.title), work_chapter_url(comment.parent.work, comment.parent)), + work_link: style_creation_link(comment.ultimate_parent.commentable_name, work_url(comment.parent.work))) + else + t(".content.other.html", + pseud_link: commenter_pseud_or_name_link(comment), + commentable_link: style_creation_link(comment.ultimate_parent.commentable_name, polymorphic_url(comment.ultimate_parent))) + end + end + + def collection_footer_note_html(is_collection_email, collection) + if is_collection_email + t("mailer.collections.why_collection_email.html", + collection_link: style_footer_link(collection.title, collection_url(collection))) + else + t("mailer.collections.why_maintainer.html", + collection_link: style_footer_link(collection.title, collection_url(collection))) + end + end + + def collection_footer_note_text(is_collection_email, collection) + if is_collection_email + t("mailer.collections.why_collection_email.text", + collection_title: collection.title, + collection_url: collection_url(collection)) + else + t("mailer.collections.why_maintainer.text", + collection_title: collection.title, + collection_url: collection_url(collection)) + end + end + + private + + # e.g., 1 word or 50 words + def creation_word_count(creation) + t("mailer.general.creation.word_count", count: creation.word_count) + end + + def work_tag_metadata_label(tags) + return if tags.empty? + + # i18n-tasks-use t('activerecord.models.archive_warning') + # i18n-tasks-use t('activerecord.models.character') + # i18n-tasks-use t('activerecord.models.fandom') + # i18n-tasks-use t('activerecord.models.freeform') + # i18n-tasks-use t('activerecord.models.rating') + # i18n-tasks-use t('activerecord.models.relationship') + type = tags.first.type + t("activerecord.models.#{type.underscore}", count: tags.count) + t("mailer.general.metadata_label_indicator") + end + + # We don't use .to_sentence because these aren't links and we risk making any + # connector word (e.g., "and") look like part of the final tag. + def work_tag_metadata_list(tags) + return if tags.empty? + + tags.pluck(:name).join(t("support.array.words_connector")) + end + + def style_work_tag_metadata_list(tags) + return if tags.empty? + + type = tags.first.type + # Fandom tags are linked and to_sentence'd. + if type == "Fandom" + tags.map { |f| style_link(f.name, fandom_url(f)) }.to_sentence.html_safe + else + work_tag_metadata_list(tags) + end + end +end # end of MailerHelper diff --git a/app/helpers/mute_helper.rb b/app/helpers/mute_helper.rb new file mode 100755 index 0000000..688dc9f --- /dev/null +++ b/app/helpers/mute_helper.rb @@ -0,0 +1,42 @@ +module MuteHelper + def mute_link(user, mute: nil) + if mute.nil? + mute = user.mute_by_current_user + muting_user = current_user + else + muting_user = mute.muter + end + + if mute + link_to(t("muted.unmute"), confirm_unmute_user_muted_user_path(muting_user, mute)) + else + link_to(t("muted.mute"), confirm_mute_user_muted_users_path(muting_user, muted_id: user)) + end + end + + def mute_css + return if current_user.nil? + + Rails.cache.fetch(mute_css_key(current_user)) do + mute_css_uncached(current_user) + end + end + + def mute_css_uncached(user) + user.reload + + return if user.muted_users.empty? + + css_classes = user.muted_users.map { |muted_user| ".user-#{muted_user.id}" }.join(", ") + + "".html_safe + end + + def mute_css_key(user) + "muted/#{user.id}/mute_css" + end + + def user_has_muted_users? + !current_user.muted_users.empty? if current_user + end +end diff --git a/app/helpers/number_helper.rb b/app/helpers/number_helper.rb new file mode 100755 index 0000000..76ab708 --- /dev/null +++ b/app/helpers/number_helper.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module NumberHelper + # Converts a precise number to an approximate with no more than 4 digits. + # + # @example + # estimate_number(2) # 2 + # estimate_number(25) # 25 + # estimate_number(308) # 308 + # estimate_number(1234) # 1234 + # estimate_number(120345) # 120300 + def estimate_number(number) + digits = [(Math.log10([number, 1].max).to_i - 3), 0].max + divide = 10**digits + divide * (number / divide).to_i + end +end diff --git a/app/helpers/orphans_helper.rb b/app/helpers/orphans_helper.rb new file mode 100755 index 0000000..deb3175 --- /dev/null +++ b/app/helpers/orphans_helper.rb @@ -0,0 +1,15 @@ +module OrphansHelper + + # Renders the appropriate partial based on the class of object to be orphaned + def render_orphan_partial(to_be_orphaned) + if to_be_orphaned.is_a?(Series) + render 'orphans/orphan_series', series: to_be_orphaned + elsif to_be_orphaned.is_a?(Pseud) + render 'orphans/orphan_pseud', pseud: to_be_orphaned + elsif to_be_orphaned.is_a?(User) + render 'orphans/orphan_user', user: to_be_orphaned + else # either a single work or an array of works + render 'orphans/orphan_work', works: [to_be_orphaned].flatten + end + end +end diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb new file mode 100755 index 0000000..cee1c0b --- /dev/null +++ b/app/helpers/pagination_helper.rb @@ -0,0 +1,66 @@ +module PaginationHelper + include Pagy::Frontend + + # change the default link renderer for will_paginate + def will_paginate(collection_or_options = nil, options = {}) + if collection_or_options.is_a? Hash + options = collection_or_options + collection_or_options = nil + end + options = options.merge renderer: PaginationListLinkRenderer unless options[:renderer] + super(*[collection_or_options, options].compact) + end + + # Cf https://github.com/ddnexus/pagy/blob/master/gem/lib/pagy/frontend.rb + # i18n-tasks-use t("pagy.prev") + # i18n-tasks-use t("pagy.next") + # i18n-tasks-use t("pagy.aria_label.nav") + def pagy_nav(pagy, id: nil, aria_label: nil, **vars) + return nil unless pagy + + # Keep will_paginate behavior of showing nothing if only one page + return nil if pagy.series.length <= 1 + + id = %( id="#{id}") if id + a = pagy_anchor(pagy, **vars) + + html = %(

#{t('a11y.navigation')}

) + + html << %() + + prev_text = pagy_t("pagy.prev") + prev_a = + if (p_prev = pagy.prev) + a.call(p_prev, prev_text) + else + %(#{prev_text}) + end + html << %() + + pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36] + html << %(
  • ) + html << case item + when Integer + a.call(item) + when String + %(#{pagy.label_for(item)}) + when :gap + %(#{pagy_t('pagy.gap')}) + else + raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}" + end + html << %(
  • ) + end + + next_text = pagy_t("pagy.next") + next_a = + if (p_next = pagy.next) + a.call(p_next, next_text) + else + %(#{next_text}) + end + html << %() + + html << %() + end +end diff --git a/app/helpers/prompt_restrictions_helper.rb b/app/helpers/prompt_restrictions_helper.rb new file mode 100755 index 0000000..947e567 --- /dev/null +++ b/app/helpers/prompt_restrictions_helper.rb @@ -0,0 +1,76 @@ +module PromptRestrictionsHelper + def prompt_restriction_settings(form, include_description = false, allowany, hasprompts) + + result = "".html_safe + result += content_tag(:dt, form.label(:optional_tags_allowed, ts("Optional Tags?")) + + link_to_help("challenge-optional-tags")) + result += content_tag(:dd, form.check_box(:optional_tags_allowed, disabled: (hasprompts ? false : true))) + + result += content_tag(:dt, form.label(:title_allowed, ts("Title:"))) + result += required_and_allowed_boolean(form, "title", hasprompts) + + result += content_tag(:dt, form.label(:description_allowed, ts("Details/Description:"))) + result += required_and_allowed_boolean(form, "description", hasprompts) + + result += content_tag(:dt, form.label(:url_required, ts("URL:"))) + result += required_and_allowed_boolean(form, "url", hasprompts) + + result += content_tag(:dt, form.label(:fandom_num_required, ts("Fandom(s):"))) + result += required_and_allowed(form, "fandom", hasprompts, allowany) + + result += content_tag(:dt, form.label(:character_num_required, ts("Character(s):"))) + result += required_and_allowed(form, "character", hasprompts, allowany) + + result += content_tag(:dt, form.label(:relationship_num_required, ts("Relationship(s):"))) + result += required_and_allowed(form, "relationship", hasprompts, allowany) + + result += content_tag(:dt, form.label(:rating_num_required, ts("Rating(s):"))) + result += required_and_allowed(form, "rating", hasprompts, allowany) + + result += content_tag(:dt, form.label(:category_num_required, ts("Categories:")) + + link_to_help("challenge-category-tags")) + result += required_and_allowed(form, "category", hasprompts, allowany) + + result += content_tag(:dt, form.label(:freeform_num_required, ts("Additional tag(s):"))) + result += required_and_allowed(form, "freeform", hasprompts, allowany) + + result += content_tag(:dt, form.label(:archive_warning_num_required, ts("Archive Warning(s):"))) + result += required_and_allowed(form, "archive_warning", hasprompts, allowany) + end + + def required_and_allowed_boolean(form, fieldname, hasprompts) + content_tag(:dd, ("Required: " + form.check_box( ("#{fieldname}_required").to_sym, disabled: (hasprompts ? false : true)) + + " Allowed: " + form.check_box( ("#{fieldname}_allowed").to_sym, disabled: (hasprompts ? false : true)) ).html_safe ) + end + + def required_and_allowed(form, tag_type, hasprompts, allowany) + fields = "Required: " + form.text_field( ("#{tag_type}_num_required").to_sym, disabled: (hasprompts ? false : true), class: "number" ) + fields += " Allowed: " + form.text_field( ("#{tag_type}_num_allowed").to_sym, disabled: (hasprompts ? false : true), class: "number" ) + if TagSet::TAG_TYPES.include?(tag_type) + if allowany + fields += label_tag field_id(form, "allow_any_#{tag_type}") do + h(ts("Allow Any")) + form.check_box("allow_any_#{tag_type}".to_sym, disabled: (hasprompts ? false : true)) + end + else + form.hidden_field :"allow_any_#{tag_type}".to_sym, value: false + end + fields += label_tag field_id(form, "require_unique_#{tag_type}") do + h(ts("Must Be Unique?")) + form.check_box("require_unique_#{tag_type}".to_sym, disabled: (hasprompts ? false : true)) + end + end + content_tag(:dd, fields.html_safe, class: "complex", title: ts(tag_type_label_name(tag_type).pluralize.downcase.to_s)) + "\n".html_safe + end + + # generate the string to use for the labels on sign-up forms + def challenge_signup_label(tag_name, num_allowed, num_required) + if num_required > 0 && (num_allowed > num_required) + "#{((num_allowed > 1) ? tag_name.pluralize : tag_name).titleize} (#{num_required} - #{num_allowed}): *" + elsif num_required > 0 && (num_allowed == num_required) + "#{((num_allowed > 1) ? tag_name.pluralize : tag_name).titleize} (#{num_required}): *" + elsif num_allowed > 0 + "#{((num_allowed > 1) ? tag_name.pluralize : tag_name).titleize} (#{num_required} - #{num_allowed}):" + else + "#{tag_name.titleize}:" + end + end +end diff --git a/app/helpers/pseuds_helper.rb b/app/helpers/pseuds_helper.rb new file mode 100755 index 0000000..997023d --- /dev/null +++ b/app/helpers/pseuds_helper.rb @@ -0,0 +1,51 @@ +module PseudsHelper + # Returns a list of pseuds, with links to each pseud. + # + # Used on Profile page, and by ProfileController#pseuds. + # + # The pseuds argument should be a single page of the user's pseuds, generated + # by calling user.pseuds.paginate(page: 1) or similar. This allows us to + # insert a remote link to dynamically insert the next page of pseuds. + def print_pseud_list(user, pseuds, first: true) + links = pseuds.map do |pseud| + link_to(pseud.name, [user, pseud]) + end + + difference = pseuds.total_entries - pseuds.length - pseuds.offset + + if difference.positive? + links << link_to( + t("profile.pseud_list.more_pseuds", count: difference), + pseuds_user_profile_path(user, page: pseuds.next_page), + remote: true, id: "more_pseuds" + ) + end + + more_pseuds_connector = tag.span( + t("support.array.last_word_connector"), + id: "more_pseuds_connector" + ) + + if first + to_sentence(links, + last_word_connector: more_pseuds_connector) + else + links.unshift("") + to_sentence(links, + last_word_connector: more_pseuds_connector, + two_words_connector: more_pseuds_connector) + end + end + + def pseuds_for_sidebar(user, pseud) + pseuds = user.pseuds.abbreviated_list - [pseud] + pseuds = pseuds.sort + pseuds = [pseud] + pseuds if pseud && !pseud.new_record? + pseuds + end + + # used in the sidebar + def pseud_selector(pseuds) + pseuds.collect { |pseud| "
  • #{span_if_current(pseud.name, [pseud.user, pseud])}
  • " }.join.html_safe + end +end diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb new file mode 100755 index 0000000..dcb9be9 --- /dev/null +++ b/app/helpers/search_helper.rb @@ -0,0 +1,64 @@ +module SearchHelper + + # modified from mislav-will_paginate-2.3.2/lib/will_paginate/view_helpers.rb + def search_header(collection, search, item_name, parent=nil) + header = [] + if !collection.respond_to?(:total_pages) + header << ts("Recent #{item_name.pluralize}") + elsif collection.total_pages < 2 + header << pluralize(collection.total_entries, item_name) + else + total_entries = collection.total_entries + total_entries = collection.unlimited_total_entries if collection.respond_to?(:unlimited_total_entries) + header << ts(" %{start_number} - %{end_number} of %{total} %{things}", + start_number: number_with_delimiter(collection.offset + 1), + end_number: number_with_delimiter(collection.offset + collection.length), + total: number_with_delimiter(total_entries), + things: item_name.pluralize) + end + header << ts("found") if search.present? && search.query.present? + + case parent + when Collection + header << ts("in %{collection_link}", collection_link: link_to(parent.title, parent)) + when Pseud + header << ts("by %{byline}", byline: parent.byline) + when User + header << ts("by %{username}", username: parent.login) + when Language + header << ts("in %{language}", language: parent.name) + end + + header << ts("in %{tag_link}", tag_link: link_to_tag_with_text(parent, parent.name)) if parent.is_a?(Tag) + # The @fandom version is used when following a fandom link from a user's dashboard, which + # which will take you to a URL like /users/username/works?fandom_id=123. + header << ts("in %{fandom_link}", fandom_link: link_to_tag(@fandom)) if @fandom.present? + header.join(" ").html_safe + end + + def search_results_found(results) + ts("%{count} Found", count: number_with_delimiter(results.unlimited_total_entries)) + end + + def random_search_tip + ArchiveConfig.SEARCH_TIPS[rand(ArchiveConfig.SEARCH_TIPS.size)] + end + + def works_original_path + url_for( + controller: :works, + action: :index, + only_path: true, + **params.slice(:tag_id, :fandom_id, :collection_id, :pseud_id, :user_id).permit! + ) + end + + def bookmarks_original_path + url_for( + controller: :bookmarks, + action: :index, + only_path: true, + **params.slice(:tag_id, :collection_id, :pseud_id, :user_id).permit! + ) + end +end diff --git a/app/helpers/series_helper.rb b/app/helpers/series_helper.rb new file mode 100755 index 0000000..af77855 --- /dev/null +++ b/app/helpers/series_helper.rb @@ -0,0 +1,83 @@ +module SeriesHelper + + def show_series_data(work) + series_data = series_data_for_work(work) + series_data.join(ArchiveConfig.DELIMITER_FOR_OUTPUT).html_safe + end + + # this should only show prev and next works visible to the current user + def series_data_for_work(work) + series = work.serial_works.map(&:series).compact + series.map do |serial| + works_in_series = serial.works_in_order.posted.select( + # Include only the fields needed to calculate visibility: + :id, :restricted, :hidden_by_admin, :posted + ).select(&:visible?) + + visible_position = works_in_series.index(work) || works_in_series.length + unless !visible_position + # Span used at end of previous_link and beginning of next_link to prevent extra + # whitespace around main_link if next or previous link is missing. It also allows + # us to use CSS to insert a decorative divider + divider_span = content_tag(:span, " ", class: "divider") + # This is empty if there is no previous work, otherwise it is + # + # with a left-pointing arrow before "Previous" + previous_link = if visible_position > 0 + link_to(ts("← Previous Work").html_safe, + works_in_series[visible_position - 1], + class: "previous") + divider_span + else + "".html_safe + end + # This part is always included + # Part # of TITLE + main_link = content_tag(:span, + ts("Part %{position} of %{series_title}", + position: (visible_position + 1).to_s, + series_title: link_to(serial.title, serial)).html_safe, + class: "position") + # This is empty if there is no next work, otherwise it is + # + # with a right-pointing arrow after "Work" + next_link = if visible_position < works_in_series.size - 1 + divider_span + link_to(ts("Next Work →").html_safe, + works_in_series[visible_position + 1], + class: "next") + else + "".html_safe + end + # put the parts together and wrap them in + content_tag(:span, previous_link + main_link + next_link, class: "series") + end + end + end + + def work_series_description(work, series) + serial = SerialWork.where(work_id: work.id, series_id: series.id).first + ts("Part %{position} of %{title}".html_safe, position: serial.position, title: link_to(series.title, series)) + end + + def series_list_for_feeds(work) + series = work.series + if series.empty? + return "None" + else + list = [] + for s in series + list << ts("Part %{serial_index} of %{link_to_series}", serial_index: s.serial_works.where(work_id: work.id).select(:position).first.position, link_to_series: link_to(s.title, series_url(s))) + end + return list.join(', ') + end + end + + # Generates confirmation message for "Remove Me As Co-Creator" + def series_removal_confirmation(series, user) + if !(series.work_pseuds & user.pseuds).empty? + ts("You're listed as a creator of works in this series. Do you want to remove yourself as a creator of this series and all of its works?") + else + ts("Are you sure you want to be removed as a creator of this series?") + end + end + +end diff --git a/app/helpers/share_helper.rb b/app/helpers/share_helper.rb new file mode 100755 index 0000000..73a23f8 --- /dev/null +++ b/app/helpers/share_helper.rb @@ -0,0 +1,78 @@ +# Helper for work and bookmark social media sharing code +module ShareHelper + # Get work title, word count, and creators and add app short name, + # but do not add formatting so it can be link text for Tumblr sharing. + def get_tumblr_embed_link_title(work) + title = work.title + " (#{work.word_count} #{ts('words')})" + pseud = text_byline(work) + "#{title} #{ts("by")} #{pseud} #{ts("[#{ArchiveConfig.APP_SHORT_NAME}]")}" + end + + def get_tweet_text(work) + if work.unrevealed? + ts("Mystery Work") + else + names = text_byline(work) + fandoms = short_fandom_string(work) + "#{work.title} by #{names} - #{fandoms}".truncate(95) + end + end + + def get_tweet_text_for_bookmark(bookmark) + return unless bookmark.bookmarkable.is_a?(Work) + + names = bookmark.bookmarkable.creators.to_sentence + fandoms = short_fandom_string(bookmark.bookmarkable) + "Bookmark of #{bookmark.bookmarkable.title} by #{names} - #{fandoms}".truncate(83) + end + + # JavaScript-less share buttons from https://sharingbuttons.io/ + # We use medium, solid, rectangular buttons. + def sharing_button(site, address, text, target: nil) + return unless %w[twitter tumblr].include?(site) + + tag.a( + tag.div( + tag.div( + sharing_svg(site), + class: "resp-sharing-button__icon resp-sharing-button__icon--solid", + aria: { hidden: true } + ) + text, + class: "resp-sharing-button resp-sharing-button--#{site} resp-sharing-button--medium" + ), + href: address, + target: target, + class: "resp-sharing-button__link", + aria: { label: text } + ) + end + + private + + def short_fandom_string(work) + work.fandoms.size > 2 ? ts("Multifandom") : work.fandom_string + end + + # Being able to add line breaks in the sharing templates makes the code + # easier to read and edit, but we don't want them in the sharing code itself + def remove_newlines(html) + html.delete("\n") + end + + def sharing_svg(site) + return unless %w[twitter tumblr].include?(site) + + path = case site + when "twitter" + tag.path d: "M23.44 4.83c-.8.37-1.5.38-2.22.02.93-.56.98-.96 1.32-2.02-.88.52-1.86.9-2.9 1.1-.82-.88-2-1.43-3.3-1.43-2.5 0-4.55 2.04-4.55 4.54 0 .36.03.7.1 1.04-3.77-.2-7.12-2-9.36-4.75-.4.67-.6 1.45-.6 2.3 0 1.56.8 2.95 2 3.77-.74-.03-1.44-.23-2.05-.57v.06c0 2.2 1.56 4.03 3.64 4.44-.67.2-1.37.2-2.06.08.58 1.8 2.26 3.12 4.25 3.16C5.78 18.1 3.37 18.74 1 18.46c2 1.3 4.4 2.04 6.97 2.04 8.35 0 12.92-6.92 12.92-12.93 0-.2 0-.4-.02-.6.9-.63 1.96-1.22 2.56-2.14z" + when "tumblr" + tag.path d: "M13.5.5v5h5v4h-5V15c0 5 3.5 4.4 6 2.8v4.4c-6.7 3.2-12 0-12-4.2V9.5h-3V6.7c1-.3 2.2-.7 3-1.3.5-.5 1-1.2 1.4-2 .3-.7.6-1.7.7-3h3.8z" + end + + tag.svg( + path, + xmlns: "http://www.w3.org/2000/svg", + viewBox: "0 0 24 24" + ) + end +end diff --git a/app/helpers/skin_cache_helper.rb b/app/helpers/skin_cache_helper.rb new file mode 100755 index 0000000..7a9c482 --- /dev/null +++ b/app/helpers/skin_cache_helper.rb @@ -0,0 +1,28 @@ +module SkinCacheHelper + def cache_timestamp + Time.now.utc.to_fs(:usec) + end + + def skin_cache_version_key(skin_id) + skin_id = skin_id.id if skin_id.is_a?(Skin) + [:v1, :site_skin, skin_id, :version_key] + end + + def skin_cache_version(skin_id) + Rails.cache.fetch(skin_cache_version_key(skin_id)) do + cache_timestamp + end + end + + def skin_cache_version_update(skin_id) + Rails.cache.write(skin_cache_version_key(skin_id), cache_timestamp) + end + + def skin_chooser_key + [:v2, :skin_chooser] + end + + def skin_chooser_expire_cache + ActionController::Base.new.expire_fragment(skin_chooser_key) + end +end diff --git a/app/helpers/skins_helper.rb b/app/helpers/skins_helper.rb new file mode 100755 index 0000000..73bd2af --- /dev/null +++ b/app/helpers/skins_helper.rb @@ -0,0 +1,88 @@ +module SkinsHelper + def skin_author_link(skin) + if skin.author.is_a? User + link_to(skin.byline, skin.author) + else + skin.byline + end + end + + # we only actually display an image if there's a file + def skin_preview_display(skin) + return unless skin&.icon&.attached? + + link_to image_tag(rails_blob_url(skin.icon.variant(:standard)), + alt: skin.icon_alt_text, + class: "icon", + skip_pipeline: true), + rails_blob_url(skin.icon) + end + + # Fetches the current skin. This is determined by the following + # 1. Skin ID set by request parameter + # 2. Skin ID set in the current session (if someone, a user or admin, is logged in) + # 3. Current user's skin preference + # 4. The default skin (as set by the active AdminSetting) + def current_skin + skin = Skin.approved_or_owned_by.usable.find_by(id: params[:site_skin]) if params[:site_skin] + skin ||= Skin.approved_or_owned_by.usable.find_by(id: session[:site_skin]) if (logged_in? || logged_in_as_admin?) && session[:site_skin] + skin ||= current_user&.preference&.skin + skin || AdminSetting.default_skin + end + + def skin_tag + roles = if logged_in_as_admin? + Skin::DEFAULT_ROLES_TO_INCLUDE + ["admin"] + else + Skin::DEFAULT_ROLES_TO_INCLUDE + end + + skin = current_skin + return "" unless skin + + # We include the version information for both the skin's id and the + # AdminSetting.default_skin_id because the default skin is used in skins of + # type "user", so we need to regenerate the cache block when it's modified. + # + # We also include the default_skin_id in the version number so that we + # regenerate the cache block when an admin updates the current default + # skin. + Rails.cache.fetch( + [:v1, :site_skin, skin.id, logged_in_as_admin?], + version: [skin_cache_version(skin.id), + AdminSetting.default_skin_id, + skin_cache_version(AdminSetting.default_skin_id)] + ) do + skin.get_style(roles) + end + end + + def show_advanced_skin?(skin) + !skin.new_record? && + (skin.role != Skin::DEFAULT_ROLE || + (skin.media.present? && skin.media != Skin::DEFAULT_MEDIA) || + skin.ie_condition.present? || + skin.unusable? || + !skin.skin_parents.empty?) + end + + def my_site_skins_link(link_text = nil) + link_text ||= "My Site Skins" + span_if_current ts(link_text), user_skins_path(current_user, skin_type: "Site"), current_page?(user_skins_path(current_user)) && (params[:skin_type].blank? || params[:skin_type] == "Site") + end + + def my_work_skins_link(link_text = nil) + link_text ||= "My Work Skins" + span_if_current ts(link_text), user_skins_path(current_user, skin_type: "WorkSkin") + end + + def public_site_skins_link(link_text = nil) + link_text ||= "Public Site Skins" + span_if_current ts(link_text), skins_path(skin_type: "Site"), current_page?(skins_path) && (params[:skin_type].blank? || params[:skin_type] == "Site") + end + + def public_work_skins_link(link_text = nil) + link_text ||= "Public Work Skins" + span_if_current ts(link_text), skins_path(skin_type: "WorkSkin") + end +end diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb new file mode 100644 index 0000000..4b17ed4 --- /dev/null +++ b/app/helpers/statuses_helper.rb @@ -0,0 +1,3 @@ +module StatusesHelper +end + diff --git a/app/helpers/tag_sets_helper.rb b/app/helpers/tag_sets_helper.rb new file mode 100755 index 0000000..35e8329 --- /dev/null +++ b/app/helpers/tag_sets_helper.rb @@ -0,0 +1,105 @@ +# These methods return information about the given TagSetNomination or the +# tags in a a TagSet +module TagSetsHelper + + def nomination_notes(limit) + message = "" + if limit[:fandom] > 0 + if limit[:character] > 0 + if limit[:relationship] > 0 + message = ts("You can nominate up to %{f} fandoms and up to %{c} characters and %{r} relationships for each one.", + f: limit[:fandom], c: limit[:character], r: limit[:relationship]) + else + message = ts("You can nominate up to %{f} fandoms and up to %{c} characters for each one.", f: limit[:fandom], c: limit[:character]) + end + elsif limit[:relationship] > 0 + message = ts("You can nominate up to %{f} fandoms and up to %{r} relationships for each one.", f: limit[:fandom], r: limit[:relationship]) + else + message = ts("You can nominate up to %{f} fandoms.", f: limit[:fandom]) + end + else + if limit[:character] > 0 + if limit[:relationship] > 0 + message = ts("You can nominate up to %{c} characters and %{r} relationships.", c: limit[:character], r: limit[:relationship]) + else + message = ts("You can nominate up to %{c} characters.", c: limit[:character]) + end + elsif limit[:relationship] > 0 + message = ts("You can nominate up to %{r} relationships.", r: limit[:relationship]) + end + end + + if limit[:freeform] > 0 + if message.blank? + message = ts("You can nominate up to %{ff} additional tags.", ff: limit[:freeform]) + else + message += ts(" You can also nominate up to %{ff} additional tags.", ff: limit[:freeform]) + end + end + + message + end + + def nomination_status(nomination=nil) + symbol = "?!" + status = "unreviewed" + tooltip = ts('This nomination has not been reviewed yet.') + if nomination + if nomination.approved + symbol = "✔" + status = "approved" + tooltip = ts('This nomination has been approved!') + elsif nomination.rejected + symbol = "✖" + status = "rejected" + tooltip = ts('This nomination was rejected (but another version may have been approved instead).') + elsif @tag_set.nominated + symbol = "?!" + status = "unreviewed" + tooltip = ts('This nomination has not been reviewed yet and can still be changed.') + end + end + + return content_tag(:span, content_tag(:span, "#{symbol}".html_safe), class: "#{status} symbol", data: {tooltip: "#{tooltip}"}) + end + + def nomination_tag_information(nominated_tag) + tag_object = Tag.find_by(name: nominated_tag.tagname) + status = "nonexistent" + tooltip = ts("This tag has never been used before. Check the spelling!") + title = ts("nonexistent tag") + span_content = nominated_tag.tagname + synonym_for = "" + case + when nominated_tag.canonical + if nominated_tag.parented + status = "canonical" + tooltip = ts("This is a canonical tag.") + title = ts("canonical tag") + span_content = link_to_tag_works(tag_object) + else + status = "unparented" + tooltip = ts("This is a canonical tag but not associated with the specified fandom.") + title = ts("canonical tag without parent") + span_content = link_to_tag_works(tag_object) + end + when nominated_tag.synonym + status = "synonym" + tooltip = ts("This is a synonym of a canonical tag.") + title = ts("tag synonym") + synonym_for = content_tag(:span, " (#{link_to_tag_works(tag_object.merger, class: "canonical")})".html_safe) + when nominated_tag.exists + status = "unwrangled" + tooltip = ts("This is not a canonical tag.") + title = ts("non-canonical tag") + end + + return content_tag(:span, "#{span_content}".html_safe, class: "#{status} nomination", title: "#{title}", data: {tooltip: "#{tooltip}"}) + synonym_for + + end + + def tag_relation_to_list(tag_relation) + tag_relation.by_name_without_articles.pluck(:name).map {|tagname| content_tag(:li, tagname)}.join("\n").html_safe + end + +end diff --git a/app/helpers/tag_type_helper.rb b/app/helpers/tag_type_helper.rb new file mode 100755 index 0000000..282f154 --- /dev/null +++ b/app/helpers/tag_type_helper.rb @@ -0,0 +1,42 @@ +module TagTypeHelper + + # Determines the appropriate CSS class given the tag class name e.g. "Archive" + # + # Examples + # + # tag_type_css_class("ArchiveWarning") + # # => "warning" + def tag_type_css_class(tag_type) + tag_type = tag_type.singularize.classify + case tag_type + when "AdditionalTag" + "freeform" + when "ArchiveWarning" + "warning" + else + tag_type.downcase + end + end + + # Determines the Tag Type labels e.g "Warnings", "Categories", "Fandoms" + # + # Examples + # + # tag_type_label_name("archive_warning") + # # => "Warnings" + # + # Returns String label in singular form + def tag_type_label_name(tag_type) + label = case tag_type.singularize.underscore + when "archive_warning" + ArchiveWarning.label_name + when "freeform" + Freeform.label_name + when "tag" + "Bookmarker's Tag" + else + tag_type.humanize.titleize + end + label.singularize + end +end diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb new file mode 100755 index 0000000..168e778 --- /dev/null +++ b/app/helpers/tags_helper.rb @@ -0,0 +1,355 @@ +module TagsHelper + + # Takes an array of tags and returns a marked-up, comma-separated list of links to them + def tag_link_list(tags, link_to_works=false) + tags = tags.uniq.compact.map {|tag| content_tag(:li, link_to_works ? link_to_tag_works(tag) : link_to_tag(tag))}.join.html_safe + end + + def description(tag) + tag.name + " (" + tag.class.name + ")" + end + + # Adds the appropriate css classes for the tag index page + def tag_cloud(tags, classes) + max, min = -1.0/0, 1.0/0 + tags.each { |t| + next if t.count.to_i == 0 # 0s make log scales sad + max = Math.log(t.count.to_i) if Math.log(t.count.to_i) > max + min = Math.log(t.count.to_i) if Math.log(t.count.to_i) < min + } + + divisor = ((max - min) / classes.size) + tags.each { |t| + if divisor.infinite? + # all counts were 0 + yield t, classes[0] + else + class_idx = ((Math.log(t.count.to_i) - min) / divisor) + # handle lower edge case to prevent OOB access + if class_idx.nan? + class_idx = 0.0 + end + # handle upper edge case to prevent OOB access + if class_idx >= classes.size + class_idx = classes.size - 1 + end + yield t, classes[class_idx.floor] + end + } + end + + def wrangler_list(wranglers, tag) + if wranglers.blank? + if @tag[:type] == 'Fandom' + sign_up_fandoms = tag.name + elsif Tag::USER_DEFINED.include?(@tag.class.name) && !tag.fandoms.blank? + sign_up_fandoms = tag.fandoms.collect(&:name).join(', ') + end + link_to "Sign Up", tag_wranglers_path(sign_up_fandoms: sign_up_fandoms) + else + wranglers.collect(&:login).join(', ') + end + end + + def link_to_tag(tag, options = {}) + link_to_tag_with_text(tag, tag.display_name, options) + end + + def link_to_tag_works(tag, options = {}) + link_to_tag_works_with_text(tag, tag.display_name, options) + end + + def link_to_tag_with_text(tag, link_text, options = {}) + if options[:full_path] + link_to_with_tag_class(tag_url(tag), link_text, options) + else + link_to_with_tag_class(tag_path(tag), link_text, options) + end + end + + def link_to_edit_tag(tag, options = {}) + link_to_with_tag_class(edit_tag_path(tag), tag.name, options) + end + + def link_to_tag_works_with_text(tag, link_text, options = {}) + collection = options[:collection] + if options[:full_path] + link_to_with_tag_class(collection ? collection_tag_works_url(collection, tag) : tag_works_url(tag), link_text, options) + else + link_to_with_tag_class(collection ? collection_tag_works_path(collection, tag) : tag_works_path(tag), link_text, options) + end + end + + # the label on checkboxes to remove tag associations + # currently blank per wrangler request, can be changed to different label as desired + def remove_tag_association_label(tag) + "".html_safe + end + + # Adds the "tag" classname to links (for tag links) + def link_to_with_tag_class(path, text, options) + options[:class] ? options[:class] << " tag" : options[:class] = "tag" + link_to text, path, options + end + + # Used on tag edit page + def tag_category_name(tag_type) + tag_type == "Merger" ? "Synonyms" : tag_type.pluralize + end + + # Should the current user be able to access tag wrangling pages? + def can_wrangle? + logged_in_as_admin? || (current_user.is_a?(User) && current_user.is_tag_wrangler?) + end + + # Determines whether or not to display warnings for a creation + def hide_warnings?(creation) + current_user.is_a?(User) && current_user.preference && current_user.preference.hide_warnings? && !current_user.is_author_of?(creation) + end + + # Determines whether or not to display freeform tags for a creation + def hide_freeform?(creation) + current_user.is_a?(User) && current_user.preference && current_user.preference.hide_freeform? && !current_user.is_author_of?(creation) + end + + # Link to show tags if they're currently hidden + def show_hidden_tags_link(creation, tag_type) + text = ts("Show %{tag_type}", tag_type: (tag_type == 'freeforms' ? "additional tags" : tag_type.humanize.downcase.split.last)) + url = {controller: 'tags', action: 'show_hidden', creation_type: creation.class.to_s, creation_id: creation.id, tag_type: tag_type } + link_to text, url, remote: true + end + + # Makes filters show warnings display name + def label_for_filter(tag_type, tag_info) + name = (tag_type == "archive_warning") ? warning_display_name(tag_info[:name]) : tag_info[:name] + name + " (#{tag_info[:count]})" + end + + # Changes display name of warnings in works blurb + # Used when we don't have an actual tag object + def warning_display_name(name) + ArchiveWarning::DISPLAY_NAME_MAPPING[name] || name + end + + # Individual results for a tag search + def tag_search_result(tag) + if tag + span = tag.canonical? ? "" : "" + span += tag.type + ": " + link_to_tag(tag) + " ‎(#{tag.taggings_count})" + span.html_safe + end + end + + def tag_comment_link(tag) + count = tag.total_comments.count.to_s + if count == "0" + last_comment = "" + else + last_comment = " (last comment: " + tag.total_comments.order('created_at DESC').first.created_at.to_s + ")" + end + link_text = count + " comments" + last_comment + link_to link_text, {controller: :comments, action: :index, tag_id: tag} + end + + def show_wrangling_dashboard + can_wrangle? && + (%w(tags tag_wranglings tag_wranglers tag_wrangling_requests unsorted_tags).include?(controller.controller_name) || + (@tag && controller.controller_name == 'comments')) + end + + # Returns a nested list of meta tags + def meta_tag_tree(tag) + meta_ul = "".html_safe + unless tag.direct_meta_tags.empty? + tag.direct_meta_tags.each do |meta| + meta_ul += content_tag(:li, link_to_tag(meta)) + unless meta.direct_meta_tags.empty? + meta_ul += content_tag(:li, meta_tag_tree(meta)) + end + end + end + content_tag(:ul, meta_ul, class: 'tags tree index') + end + + # Returns a nested list of sub tags + def sub_tag_tree(tag) + sub_ul = "" + unless tag.direct_sub_tags.empty? + sub_ul << "
      " + tag.direct_sub_tags.order(:name).each do |sub| + sub_ul << "
    • " + link_to_tag(sub) + unless sub.direct_sub_tags.empty? + sub_ul << sub_tag_tree(sub) + end + sub_ul << "
    • " + end + sub_ul << "
    " + end + sub_ul.html_safe + end + + def blurb_tag_block(item, tag_groups=nil) + tag_groups ||= item.tag_groups + categories = ['ArchiveWarning', 'Relationship', 'Character', 'Freeform'] + tag_block = "" + + categories.each do |category| + if tags = tag_groups[category] + unless tags.empty? + class_name = tag_block_class_name(category) + if (class_name == "warnings" && hide_warnings?(item)) || (class_name == "freeforms" && hide_freeform?(item)) + tag_block << show_hidden_tag_link_list_item(item, category) + elsif class_name == "warnings" + open_tags = "
  • " + close_tags = "
  • " + link_array = tags.collect{|tag| link_to_tag_works(tag)} + tag_block << open_tags + link_array.join("
  • ") + close_tags + else + link_array = tags.collect{|tag| link_to_tag_works(tag)} + tag_block << "
  • " + link_array.join("
  • ") + '
  • ' + end + end + end + end + tag_block.html_safe + end + + # Takes a tag category class name, e.g. Relationship, and returns a string. + # The returned string is plural and used for more than the HTML class + # attribute, which is why we don't use tag_type_css_class(tag_type). + def tag_block_class_name(category) + if category == "ArchiveWarning" + "warnings" + else + category.downcase.pluralize + end + end + + # Wraps hidden tags toggle in
  • and tags for blurbs and work meta. + # options[:suppress_toggle_class] is used to skip placing an HTML class on the + # toggle in work meta. The class will still be on the tags. + def show_hidden_tag_link_list_item(item, category, options = {}) + item_class = item.class.to_s.underscore + class_name = tag_block_class_name(category) + content_tag(:li, + content_tag(:strong, + show_hidden_tags_link(item, class_name)), + class: options[:suppress_toggle_class] ? nil : class_name, + id: "#{item_class}_#{item.id}_category_#{class_name}") + end + + def get_title_string(tags, category_name = "") + if tags && tags.size > 0 + # We don't use .to_sentence because these aren't links and we risk making any + # connector word (e.g., "and") look like part of the final tag. + tags.map(&:display_name).join(t("support.array.words_connector")) + elsif tags.blank? && category_name.blank? + ArchiveConfig.WARNING_DEFAULT_TAG_DISPLAY_NAME + else + category_name.blank? ? "" : "No" + " " + category_name + end + end + + # produce our spiffy pretty block of tag symbols + def get_symbols_for(item, tag_groups=nil, symbols_only = false) + symbol_block = [] + symbol_block << "
      " unless symbols_only + + # split up the item's tags into groups based on type + tag_groups ||= item.tag_groups + + ratings = tag_groups['Rating'] + symbol_block << get_symbol_link(get_ratings_class(ratings), get_title_string(ratings, "rating")) + + warnings = tag_groups['ArchiveWarning'] + symbol_block << get_symbol_link(get_warnings_class(warnings), get_title_string(warnings)) + + categories = tag_groups['Category'] + symbol_block << get_symbol_link(get_category_class(categories), get_title_string(categories, "category")) + + if [Work, Series].include?(item.class) + if item.complete? + symbol_block << get_symbol_link( "complete-yes iswip" , "Complete #{item.class.to_s}") + else + symbol_block << get_symbol_link( "complete-no iswip", "#{item.class.to_s} in Progress" ) + end + elsif item.class == ExternalWork + symbol_block << get_symbol_link('external-work', "External Work") + elsif item.is_a?(Prompt) + if item.unfulfilled? + symbol_block << get_symbol_link( "complete-no iswip", "#{item.class.to_s} Unfulfilled" ) + else + symbol_block << get_symbol_link("complete-yes iswip", "#{item.class.to_s} Fulfilled" ) + end + end + + symbol_block << "
    " unless symbols_only + return symbol_block.join("\n").html_safe + end + + def get_symbol_link(css_class, title_string) + content_tag(:li, link_to_help('symbols-key', link = ("" + title_string + "").html_safe)) + end + + # return the right warnings class + def get_warnings_class(warning_tags = []) + if warning_tags.blank? # for testing + "warning-choosenotto warnings" + elsif warning_tags.size == 1 && warning_tags.first.name == ArchiveConfig.WARNING_NONE_TAG_NAME + # only one tag and it says "no warnings" + "warning-no warnings" + elsif warning_tags.size == 1 && warning_tags.first.name == ArchiveConfig.WARNING_DEFAULT_TAG_NAME + # only one tag and it says choose not to warn + "warning-choosenotto warnings" + elsif warning_tags.size == 2 && ((warning_tags.first.name == ArchiveConfig.WARNING_DEFAULT_TAG_NAME && warning_tags.second.name == ArchiveConfig.WARNING_NONE_TAG_NAME) || (warning_tags.first.name == ArchiveConfig.WARNING_NONE_TAG_NAME && warning_tags.second.name == ArchiveConfig.WARNING_DEFAULT_TAG_NAME)) + # two tags and they are "choose not to warn" and "no archive warnings apply" in either order + "warning-choosenotto warnings" + else + "warning-yes warnings" + end + end + + def get_ratings_class(rating_tags = []) + if rating_tags.blank? # for testing + "rating-notrated rating" + else + names = rating_tags.collect(&:name) + if names.include?(ArchiveConfig.RATING_EXPLICIT_TAG_NAME) + "rating-explicit rating" + elsif names.include?(ArchiveConfig.RATING_MATURE_TAG_NAME) + "rating-mature rating" + elsif names.include?(ArchiveConfig.RATING_TEEN_TAG_NAME) + "rating-teen rating" + elsif names.include?(ArchiveConfig.RATING_GENERAL_TAG_NAME) + "rating-general-audience rating" + else + "rating-notrated rating" + end + end + end + + def get_category_class(category_tags) + if category_tags.blank? + "category-none category" + elsif category_tags.length > 1 + "category-multi category" + else + case category_tags.first.name + when ArchiveConfig.CATEGORY_GEN_TAG_NAME + "category-gen category" + when ArchiveConfig.CATEGORY_SLASH_TAG_NAME + "category-slash category" + when ArchiveConfig.CATEGORY_HET_TAG_NAME + "category-het category" + when ArchiveConfig.CATEGORY_FEMSLASH_TAG_NAME + "category-femslash category" + when ArchiveConfig.CATEGORY_MULTI_TAG_NAME + "category-multi category" + when ArchiveConfig.CATEGORY_OTHER_TAG_NAME + "category-other category" + else + "category-none category" + end + end + end +end diff --git a/app/helpers/translation_helper.rb b/app/helpers/translation_helper.rb new file mode 100755 index 0000000..2ccc97c --- /dev/null +++ b/app/helpers/translation_helper.rb @@ -0,0 +1,42 @@ +module TranslationHelper + +def time_ago_in_words(from_time, include_seconds = false) + + to_time = Time.now + if from_time.respond_to?(:to_time) + from_time = from_time.to_time + else + return + end + to_time = to_time.to_time if to_time.respond_to?(:to_time) + distance_in_minutes = (((to_time - from_time).abs)/60).round + distance_in_seconds = ((to_time - from_time).abs).round + + case distance_in_minutes + when 0..1 + return (distance_in_minutes==0) ? 'less than 1 minute ago' : '1 minute ago' unless include_seconds + case distance_in_seconds + when 0..5 then "less than 5 seconds ago" + when 6..10 then "less than 10 seconds ago" + when 11..20 then "less than 20 seconds ago" + when 21..40 then "half a minute ago" + when 41..59 then "less than a minute ago" + else "1 minute ago" + end + when 2..45 then "#{distance_in_minutes} minutes ago" + when 46..90 then "1 hour ago" + when 90..1440 then "#{(distance_in_minutes.to_f / 60.0).round} hours ago" + when 1441..2880 then "1 day ago" + else "#{(distance_in_minutes / 1440).round} days ago" + end + end + +alias distance_of_time_in_words_to_now time_ago_in_words + + # Take some text and add whatever punctuation, symbols, and/or spacing + # we use to separate a metadata property from its value, e.g., "Property: ", + # "Propriété : ". + def metadata_property(text) + text.html_safe + t("mailer.general.metadata_label_indicator") + end +end diff --git a/app/helpers/user_invite_requests_helper.rb b/app/helpers/user_invite_requests_helper.rb new file mode 100755 index 0000000..a71ea20 --- /dev/null +++ b/app/helpers/user_invite_requests_helper.rb @@ -0,0 +1,14 @@ +module UserInviteRequestsHelper + + # given a request for invite codes: + # generates a link displaying the number of invite codes previously issued to this + # user; link goes to overview of user's invite codes. + def link_to_previous_invite_requests(request) + if request.user.invitations.count > 0 + link_to request.user.invitations.count, find_admin_invitations_path(user_name: request.user.login) + else + "0" + end + end + +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100755 index 0000000..9e71edb --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,192 @@ +module UsersHelper + # Can be used to check ownership of items + def is_author_of?(item) + if @own_bookmarks && item.is_a?(Bookmark) + @own_bookmarks.include?(item) + elsif @own_works && item.is_a?(Work) + @own_works.include?(item) + else + current_user.is_a?(User) && current_user.is_author_of?(item) + end + end + + # Can be used to check if user is maintainer of any collections + def is_maintainer? + current_user.is_a?(User) ? current_user.maintained_collections.present? : false + end + + # Prints user pseuds with links to anchors for each pseud on the page and the description as the title + def print_pseuds(user) + user.pseuds.collect(&:name).join(', ') + end + + # Determine which icon to show on user pages + def standard_icon(pseud = nil) + return "/images/skins/iconsets/default/icon_user.png" unless pseud&.icon&.attached? + + rails_blob_url(pseud.icon.variant(:standard)) + end + + # no alt text if there isn't specific alt text + def icon_display(user = nil, pseud = nil) + path = user ? (pseud ? user_pseud_path(pseud.user, pseud) : user_path(user)) : nil + pseud ||= user.default_pseud if user + icon = standard_icon(pseud) + alt_text = pseud.try(:icon_alt_text) || nil + + if path + link_to image_tag(icon, alt: alt_text, class: 'icon', skip_pipeline: true), path + else + image_tag(icon, class: 'icon', skip_pipeline: true) + end + end + + # Prints coauthors + def print_coauthors(user) + user.coauthors.collect(&:name).join(', ') + end + + # Prints link to bookmarks page with user-appropriate number of bookmarks + # (The total should reflect the number of bookmarks the user can actually see.) + def bookmarks_link(user, pseud = nil) + return pseud_bookmarks_link(pseud) if pseud.present? && !pseud.new_record? + + total = SearchCounts.bookmark_count_for_user(user) + span_if_current ts('Bookmarks (%{bookmark_number})', bookmark_number: total.to_s), user_bookmarks_path(@user) + end + + def pseud_bookmarks_link(pseud) + total = SearchCounts.bookmark_count_for_pseud(pseud) + span_if_current ts('Bookmarks (%{bookmark_number})', bookmark_number: total.to_s), user_pseud_bookmarks_path(@user, pseud) + end + + # Prints link to works page with user-appropriate number of works + # (The total should reflect the number of works the user can actually see.) + def works_link(user, pseud = nil) + return pseud_works_link(pseud) if pseud.present? && !pseud.new_record? + + total = SearchCounts.work_count_for_user(user) + span_if_current ts('Works (%{works_number})', works_number: total.to_s), user_works_path(@user) + end + + def pseud_works_link(pseud) + total = SearchCounts.work_count_for_pseud(pseud) + span_if_current ts('Works (%{works_number})', works_number: total.to_s), user_pseud_works_path(@user, pseud) + end + + # Prints link to series page with user-appropriate number of series + def series_link(user, pseud = nil) + return pseud_series_link(pseud) if pseud.present? && !pseud.new_record? + + total = if current_user.nil? + Series.visible_to_all.exclude_anonymous.for_user(user).count.size + else + Series.visible_to_registered_user.exclude_anonymous.for_user(user).count.size + end + span_if_current ts("Series (%{series_number})", series_number: total.to_s), user_series_index_path(user) + end + + def pseud_series_link(pseud) + total = if current_user.nil? + Series.visible_to_all.exclude_anonymous.for_pseud(pseud).count.size + else + Series.visible_to_registered_user.exclude_anonymous.for_pseud(pseud).count.size + end + span_if_current ts("Series (%{series_number})", series_number: total.to_s), user_pseud_series_index_path(pseud.user, pseud) + end + + def gifts_link(user) + if current_user.nil? + gift_number = user.gift_works.visible_to_all.distinct.count + else + gift_number = user.gift_works.visible_to_registered_user.distinct.count + end + span_if_current ts('Gifts (%{gift_number})', gift_number: gift_number.to_s), user_gifts_path(user) + end + + def authored_items(pseud, work_counts = {}, rec_counts = {}) + visible_works = pseud.respond_to?(:work_count) ? pseud.work_count.to_i : (work_counts[pseud.id] || 0) + visible_recs = pseud.respond_to?(:rec_count) ? pseud.rec_count.to_i : (rec_counts[pseud.id] || 0) + items = visible_works == 1 ? link_to(visible_works.to_s + ' work', user_pseud_works_path(pseud.user, pseud)) : (visible_works > 1 ? link_to(visible_works.to_s + ' works', user_pseud_works_path(pseud.user, pseud)) : '') + items += ', ' if (visible_works > 0) && (visible_recs > 0) + if visible_recs > 0 + items += visible_recs == 1 ? link_to(visible_recs.to_s + ' rec', user_pseud_bookmarks_path(pseud.user, pseud, recs_only: true)) : link_to(visible_recs.to_s + ' recs', user_pseud_bookmarks_path(pseud.user, pseud, recs_only: true)) + end + items.html_safe + end + + def log_item_action_name(item) + action = item.action + + return fnok_action_name(item) if fnok_action?(action) + + case action + when ArchiveConfig.ACTION_ACTIVATE + t("users_helper.log.validated") + when ArchiveConfig.ACTION_ADD_ROLE + t("users_helper.log.role_added") + when ArchiveConfig.ACTION_REMOVE_ROLE + t("users_helper.log.role_removed") + when ArchiveConfig.ACTION_SUSPEND + t("users_helper.log.suspended") + when ArchiveConfig.ACTION_UNSUSPEND + t("users_helper.log.lift_suspension") + when ArchiveConfig.ACTION_BAN + t("users_helper.log.ban") + when ArchiveConfig.ACTION_WARN + t("users_helper.log.warn") + when ArchiveConfig.ACTION_RENAME + t("users_helper.log.rename") + when ArchiveConfig.ACTION_PASSWORD_CHANGE + t("users_helper.log.password_change") + when ArchiveConfig.ACTION_NEW_EMAIL + t("users_helper.log.email_change") + when ArchiveConfig.ACTION_TROUBLESHOOT + t("users_helper.log.troubleshot") + when ArchiveConfig.ACTION_NOTE + t("users_helper.log.note") + when ArchiveConfig.ACTION_PASSWORD_RESET + t("users_helper.log.password_reset") + end + end + + # Give the TOS field in the new user form a different name in non-production environments + # so that it can be filtered out of the log, for ease of debugging + def tos_field_name + if Rails.env.production? + 'terms_of_service' + else + 'terms_of_service_non_production' + end + end + + private + + def fnok_action?(action) + [ + ArchiveConfig.ACTION_ADD_FNOK, + ArchiveConfig.ACTION_REMOVE_FNOK, + ArchiveConfig.ACTION_ADDED_AS_FNOK, + ArchiveConfig.ACTION_REMOVED_AS_FNOK + ].include?(action) + end + + def fnok_action_name(item) + action_leaf = + case item.action + when ArchiveConfig.ACTION_ADD_FNOK + "has_added" + when ArchiveConfig.ACTION_REMOVE_FNOK + "has_removed" + when ArchiveConfig.ACTION_ADDED_AS_FNOK + "was_added" + when ArchiveConfig.ACTION_REMOVED_AS_FNOK + "was_removed" + end + + t( + "users_helper.log.fnok.#{action_leaf}", + user_id: item.fnok_user_id + ) + end +end diff --git a/app/helpers/validation_helper.rb b/app/helpers/validation_helper.rb new file mode 100755 index 0000000..7e7e72f --- /dev/null +++ b/app/helpers/validation_helper.rb @@ -0,0 +1,181 @@ +require 'json' + +module ValidationHelper + + # VALIDATION_NAME_MAPPING[options_key], where `options_key` is a valid key for + # the `options` Hash passed to `validation_for_field`, returns the corresponding + # key for the validation_for_X.add(Validate[key], ...) JavaScript function call. + VALIDATION_NAME_MAPPING = { + presence: "Presence", + maximum_length: "Length", + minimum_length: "Length", + numericality: "Numericality", + exclusion: "Exclusion", + } + + # Set a custom error-message handler that puts the errors on + # their respective fields instead of on the top of the page + ActionView::Base.field_error_proc = Proc.new {|html_tag, instance| + %(#{html_tag}).html_safe + # # don't put errors on the labels, duh + # if !html_tag.match(/label/) + # %(#{html_tag}).html_safe + # elsif instance.error_message.kind_of?(Array) + # %(#{html_tag}
    • #{instance.error_message.join('
    • ')}
    ).html_safe + # else + # %(#{html_tag} #{instance.error_message}).html_safe + # end + } + + # much simplified and html-safed version of error_messages_for + # error messages containing a "^" will have everything before the "^" wiped out + def error_messages_for(object) + if object.is_a? Symbol + object = instance_variable_get("@#{object}") + end + + if object && object.errors.any? + errors = object.errors.full_messages + intro = content_tag(:h4, h(ts("Sorry! We couldn't save this %{objectname} because:", objectname: object.class.model_name.human.to_s.downcase.gsub(/_/, ' ')))) + error_messages_formatted(errors, intro) + end + end + + def error_messages_formatted(errors, intro = "") + return unless errors.present? + + error_messages = errors.map { |msg| content_tag(:li, msg.gsub(/^(.*?)\^/, "").html_safe) } + .join("\n").html_safe + content_tag(:div, intro.html_safe + content_tag(:ul, error_messages), id: "error", class: "error") + end + + # use to make sure we have consistent name throughout + def live_validation_varname(id) + "validation_for_#{id}" + end + + # puts the standard wrapper around the code and declares the LiveValidation object + def live_validation_wrapper(id, validation_code) + valid = "var #{live_validation_varname(id)} = new LiveValidation('#{id}', { wait: 500, onlyOnBlur: false });\n".html_safe + valid += validation_code + return javascript_tag valid + end + + # Generate javascript call for live validation. All the messages have default translated values. + # Options: + # presence: true/false -- ensure the field is not blank. (default TRUE) + # failureMessage: msg -- shown if field is blank (default "Must be present.") + # validMessage: msg -- shown when field is ok (default has been set to empty in the actual livevalidation.js file) + # maximum_length: [max value] -- field must be no more than this many characters long + # tooLongMessage: msg -- shown if too long + # minimum_length: [min value] -- field must be at least this many characters long + # tooShortMessage: msg -- shown if too short + # + # Most basic usage: + # + # <%= live_validation_for_field("field_to_validate") %> + # This will make sure this field is present and use translated error messages. + # + # More custom usage (from work form): + # <%= c.text_area :content, class: "mce-editor", id: "content" %> + # <%= live_validation_for_field('content', + # maximum_length: ArchiveConfig.CONTENT_MAX, minimum_length: ArchiveConfig.CONTENT_MIN, + # tooLongMessage: 'We salute your ambition! But sadly the content must be less than %d letters long. (Maybe you want to create a multi-chaptered work?)'/ArchiveConfig.CONTENT_MAX, + # tooShortMessage: 'Brevity is the soul of wit, but your content does have to be at least %d letters long.'/ArchiveConfig.CONTENT_MIN, + # failureMessage: 'You did want to post a story here, right?') + # %> + # + # Add more default values here! There are many more live validation options, see the code in + # the javascripts folder for details. + def live_validation_for_field(id, options = {}) + defaults = {presence: true, + failureMessage: 'Must be present.', + validMessage: ''} + if options[:maximum_length] + defaults.merge!(tooLongMessage: 'Must be less than ' + options[:maximum_length].to_s + ' letters long.') #/ + end + if options[:minimum_length] + defaults.merge!(tooShortMessage: 'Must be at least ' + options[:minimum_length].to_s + ' letters long.') #/ + end + if options[:notANumberMessage] + defaults.merge!(notANumberMessage: 'Please enter a number') #/ + end + + options = defaults.merge(options) + + # Remove things where the value is a falsey, e.g.: + # live_validation_for_field(id, {presence: false}) + options.reject!{|k, v| !v} + + # Generates a Hash mapping option[] keys to Hashes, each Hash being a + # representation of the arguments passed to validation_for_X.add() in + # JavaScript. + validation_hashes = {} + options.each do |key, _| + validation_hashes[key] = + case key + when :presence + { + "failureMessage" => options[:failureMessage].to_s, + "validMessage" => options[:validMessage].to_s, + } + when :maximum_length + { + "maximum" => options[:maximum_length].to_s, + "tooLongMessage" => options[:tooLongMessage].to_s, + } + when :minimum_length + { + "minimum" => options[:minimum_length].to_s, + "tooShortMessage" => options[:tooShortMessage].to_s, + } + when :numericality + { + "notANumberMessage" => options[:notANumberMessage].to_s, + "validMessage" => options[:validMessage].to_s + } + when :exclusion + { + "within" => options[:exclusion], + "failureMessage" => options[:failureMessage], + "validMessage" => options[:validMessage], + } + end + end + + # Build the validation code from the hashes created above. + validation_code = validation_code_builder(id, validation_hashes) + + return live_validation_wrapper(id, validation_code.html_safe) + end + + private + + # Builds validation_for_X.add(...) JavaScript calls. + # + # Implementation note: JSON is a subset of JavaScript, so `object.to_json` + # works *brilliantly* for this. + def validation_json(id, validate_key, object) + validation_code = live_validation_varname(id) + validation_code += ".add(Validate.#{validate_key}, %s);" % object.to_json + + validation_code + end + + # Builds a sequence of validation_for_X.add(...) JavaScript calls. + # + # Takes `id` and a hash mapping `options` keys to a Hash that, when converted + # converted to JSON, is the second argument for validation_for_X.add(). + # + # For each key specified both in the hash and in `options`, it adds the + # corresponding validation_for_X.add(...) call. + def validation_code_builder(id, validation_hashes) + validation_hashes.reject! {|k, v| v.nil?} + + validation_hashes.map do |option_key, object| + validate_key = VALIDATION_NAME_MAPPING[option_key] + validation_json(id, validate_key, object) + end.join("\n") + end + +end diff --git a/app/helpers/works_helper.rb b/app/helpers/works_helper.rb new file mode 100755 index 0000000..02b60bc --- /dev/null +++ b/app/helpers/works_helper.rb @@ -0,0 +1,232 @@ +module WorksHelper + + # List of date, chapter and length info for the work show page + def work_meta_list(work, chapter = nil) + # if we're previewing, grab the unsaved date, else take the saved first chapter date + published_date = (chapter && work.preview_mode) ? chapter.published_at : work.first_chapter.published_at + list = [[ts("Published:"), "published", localize(published_date)], + [ts("Words:"), "words", number_with_delimiter(work.word_count)], + [ts("Chapters:"), "chapters", chapter_total_display(work)]] + + if (comment_count = work.count_visible_comments) > 0 + list.concat([[ts("Comments:"), "comments", number_with_delimiter(work.count_visible_comments)]]) + end + + if work.all_kudos_count > 0 + list.concat([[ts("Kudos:"), "kudos", number_with_delimiter(work.all_kudos_count)]]) + end + + if (bookmark_count = work.public_bookmarks_count) > 0 + list.concat([[ts("Bookmarks:"), "bookmarks", link_to(number_with_delimiter(bookmark_count), work_bookmarks_path(work))]]) + end + list.concat([[ts("Hits:"), "hits", number_with_delimiter(work.hits)]]) + + if work.chaptered? && work.revised_at + prefix = work.is_wip ? ts('Updated:') : ts('Completed:') + latest_date = (work.preview_mode && work.backdate) ? published_date : date_in_user_time_zone(work.revised_at).to_date + list.insert(1, [prefix, 'status', localize(latest_date)]) + end + list = list.map { |list_item| content_tag(:dt, list_item.first, class: list_item.second) + content_tag(:dd, list_item.last.to_s, class: list_item.second) }.join.html_safe + content_tag(:dl, list.to_s, class: 'stats').html_safe + end + + def recipients_link(work) + # join doesn't maintain html_safe, so mark the join safe + work.gifts.not_rejected.includes(:pseud).map { |gift| link_to(h(gift.recipient), gift.pseud ? user_gifts_path(gift.pseud.user) : gifts_path(recipient: gift.recipient_name)) }.join(", ").html_safe + end + + # select default rating if this is a new work + def rating_selected(work) + work.nil? || work.rating_string.empty? ? ArchiveConfig.RATING_DEFAULT_TAG_NAME : work.rating_string + end + + # Determines whether or not to expand the related work association fields when the work form loads + def check_parent_box(work) + work.parents_after_saving.present? + end + + # Determines whether or not "manage series" dropdown should appear + def check_series_box(work) + work.series.present? || work_series_value(:id).present? || work_series_value(:title).present? + end + + # Passes value of fields for work series back to form when an error occurs on posting + def work_series_value(field) + params.dig :work, :series_attributes, field + end + + def language_link(work) + if work.respond_to?(:language) && work.language + link_to work.language.name, work.language, lang: work.language.short + else + "N/A" + end + end + + # Check whether this non-admin user has permission to view the unrevealed work + def can_access_unrevealed_work(work, user) + # Creators and invited can see their works + return true if work.user_is_owner_or_invited?(user) + + # Moderators can see unrevealed works: + work.collections.each do |collection| + return true if collection.user_is_maintainer?(user) + end + + false + end + + def marked_for_later?(work) + return unless current_user + reading = Reading.find_by(work_id: work.id, user_id: current_user.id) + reading && reading.toread? + end + + def mark_as_read_button(work) + button_to t("works_helper.mark_as_read_button"), mark_as_read_work_path(work), method: :patch + end + + def mark_for_later_button(work) + button_to t("works_helper.mark_for_later_button"), mark_for_later_work_path(work), method: :patch + end + + def get_endnotes_link(work) + return "#work_endnotes" unless current_page?({ controller: "chapters", action: "show" }) + + if work.posted? && work.last_posted_chapter + chapter_path(work.last_posted_chapter.id, anchor: "work_endnotes") + else + chapter_path(work.last_chapter.id, anchor: "work_endnotes") + end + end + + def get_related_works_url + current_page?({ controller: "chapters", action: "show" }) ? + chapter_path(@work.last_posted_chapter.id, anchor: 'children') : + "#children" + end + + def get_inspired_by(work) + work.approved_related_works.where(translation: false) + end + + def related_work_note(related_work, relation, download: false) + work_link = link_to related_work.title, polymorphic_url(related_work) + language = tag.span(related_work.language.name, lang: related_work.language.short) if related_work.language + default_locale = download ? :en : nil + + creator_link = if download + byline(related_work, visibility: "public", only_path: false) + else + byline(related_work) + end + + if related_work.respond_to?(:unrevealed?) && related_work.unrevealed? + if relation == "translated_to" + t(".#{relation}.unrevealed_html", + language: language) + else + t(".#{relation}.unrevealed", + locale: default_locale) + end + elsif related_work.restricted? && (download || !logged_in?) + t(".#{relation}.restricted_html", + language: language, + locale: default_locale, + creator_link: creator_link) + else + t(".#{relation}.revealed_html", + language: language, + locale: default_locale, + work_link: work_link, + creator_link: creator_link) + end + end + + # Can the work be downloaded, i.e. is it posted and visible to all registered + # users. + def downloadable? + @work.posted? && !@work.hidden_by_admin && !@work.in_unrevealed_collection? + end + + def download_url_for_work(work, format) + path = Download.new(work, format: format).public_path + url_for("#{path}?updated_at=#{work.updated_at.to_i}").gsub(' ', '%20') + end + + # Generates a list of a work's tags and details for use in feeds + def feed_summary(work) + tags = work.tags.group_by(&:type) + text = "

    by #{byline(work, { visibility: 'public', full_path: true })}

    " + text << work.summary if work.summary + text << "

    Words: #{work.word_count}, Chapters: #{chapter_total_display(work)}, Language: #{work.language ? work.language.name : 'English'}

    " + unless work.series.count == 0 + text << "

    Series: #{series_list_for_feeds(work)}

    " + end + # Create list of tags + text << "
      " + %w(Fandom Rating ArchiveWarning Category Character Relationship Freeform).each do |type| + if tags[type] + text << "
    • #{type.constantize.label_name}: #{tags[type].map { |t| link_to_tag_works(t, full_path: true) }.join(', ')}
    • " + end + end + text << "
    " + text + end + + # Returns true or false to determine whether the work notes module should display + def show_work_notes?(work) + work.notes.present? || + work.endnotes.present? || + work.gifts.not_rejected.present? || + work.challenge_claims.present? || + work.parents_after_saving.present? || + work.approved_related_works.present? + end + + # Returns true or false to determine whether the work associations should be included + def show_associations?(work) + work.gifts.not_rejected.present? || + work.approved_related_works.where(translation: true).exists? || + work.parents_after_saving.present? || + work.challenge_claims.present? + end + + def all_coauthor_skins + users = @work.users.to_a + users << User.current_user if User.current_user.is_a?(User) + WorkSkin.approved_or_owned_by_any(users).order(:title) + end + + def sorted_languages + Language.default_order + end + + # 1/1, 2/3, 5/?, etc. + def chapter_total_display(work) + current = work.posted? ? work.number_of_posted_chapters : 1 + number_with_delimiter(current) + "/" + number_with_delimiter(work.wip_length) + end + + # For works that are more than 1 chapter, returns "current #/expected #" of chapters + # (e.g. 3/5, 2/?), with the current # linked to that chapter. If the work is 1 chapter, + # returns the un-linked version. + def chapter_total_display_with_link(work) + total_posted_chapters = work.number_of_posted_chapters + if total_posted_chapters > 1 + link_to(number_with_delimiter(total_posted_chapters), + work_chapter_path(work, work.last_posted_chapter.id)) + + "/" + + number_with_delimiter(work.wip_length) + else + chapter_total_display(work) + end + end + + def get_open_assignments(user) + offer_signups = user.offer_assignments.undefaulted.unstarted.sent + pinch_hits = user.pinch_hit_assignments.undefaulted.unstarted.sent + + (offer_signups + pinch_hits) + end +end diff --git a/app/helpers/wrangling_helper.rb b/app/helpers/wrangling_helper.rb new file mode 100755 index 0000000..6b69f6b --- /dev/null +++ b/app/helpers/wrangling_helper.rb @@ -0,0 +1,14 @@ +module WranglingHelper + def tag_counts_per_category + counts = {} + [Fandom, Character, Relationship, Freeform].each do |klass| + counts[klass.to_s.downcase.pluralize.to_sym] = Rails.cache.fetch("/wrangler/counts/sidebar/#{klass}", race_condition_ttl: 10, expires_in: 1.hour) do + TagQuery.new(type: klass.to_s, in_use: true, unwrangleable: false, unwrangled: true, has_posted_works: true).count + end + end + counts[:UnsortedTag] = Rails.cache.fetch("/wrangler/counts/sidebar/UnsortedTag", race_condition_ttl: 10, expires_in: 1.hour) do + UnsortedTag.count + end + counts + end +end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100755 index 0000000..2cbf4e3 --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,14 @@ +class ApplicationJob < ActiveJob::Base + include AfterCommitEverywhere + extend AfterCommitEverywhere + + queue_as :utilities + + def self.perform_after_commit(*args, **kwargs) + after_commit { perform_later(*args, **kwargs) } + end + + def enqueue_after_commit + after_commit { enqueue } + end +end diff --git a/app/jobs/application_mailer_job.rb b/app/jobs/application_mailer_job.rb new file mode 100755 index 0000000..3e76819 --- /dev/null +++ b/app/jobs/application_mailer_job.rb @@ -0,0 +1,34 @@ +class ApplicationMailerJob < ActionMailer::MailDeliveryJob + # TODO: We have a mix of mailers that take ActiveRecords as arguments, and + # mailers that take IDs as arguments. If an item is unavailable when the + # notification is sent, it'll produce an ActiveJob::DeserializationError in + # the former case, and an ActiveRecord::RecordNotFound error in the latter. + # + # Ideally, we don't want to catch RecordNotFound errors, because they might + # be a sign of a different problem. But until we move all of the mailers over + # to taking ActiveRecords as arguments, we need to catch both errors. + + retry_on ActiveJob::DeserializationError, + attempts: 3, + wait: 1.minute do + # silently discard job after 3 failures + end + + retry_on ActiveRecord::RecordNotFound, + attempts: 3, + wait: 1.minute do + # silently discard job after 3 failures + end + + # Retry three times when calling a method on a nil association, and then fall + # back on the Resque failure queue if the error persists (so that we have a + # record of it). This should address the issues that arise when we + # successfully load an object, but can't load its associations because the + # original object has been deleted in the meantime. + # + # (Most errors for calling a method on a nil object will be NoMethodErrors, + # but any that occur within the template itself will be converted to + # ActionView::Template:Errors. So we handle both.) + retry_on NoMethodError, attempts: 3, wait: 1.minute + retry_on ActionView::Template::Error, attempts: 3, wait: 1.minute +end diff --git a/app/jobs/async_indexer_job.rb b/app/jobs/async_indexer_job.rb new file mode 100755 index 0000000..99fd04a --- /dev/null +++ b/app/jobs/async_indexer_job.rb @@ -0,0 +1,15 @@ +# A job to index the record IDs queued up by AsyncIndexer. +class AsyncIndexerJob < ApplicationJob + REDIS = AsyncIndexer::REDIS + + def perform(name) + indexer = name.split(":").first.constantize + ids = REDIS.smembers(name) + + return if ids.empty? + + batch = indexer.new(ids).index_documents + IndexSweeper.new(batch, indexer).process_batch + REDIS.del(name) + end +end diff --git a/app/jobs/hit_count_update_job.rb b/app/jobs/hit_count_update_job.rb new file mode 100755 index 0000000..9a473a2 --- /dev/null +++ b/app/jobs/hit_count_update_job.rb @@ -0,0 +1,44 @@ +# A job for transferring the hit counts collected by the RedisHitCounter from +# Redis to the database. +class HitCountUpdateJob < RedisHashJob + queue_as :hits + + def self.redis + RedisHitCounter.redis + end + + def self.job_size + ArchiveConfig.HIT_COUNT_JOB_SIZE + end + + def self.batch_size + ArchiveConfig.HIT_COUNT_BATCH_SIZE + end + + def self.base_key + :recent_counts + end + + # In a single transaction, loop through the works in the batch and update + # their hit counts: + def perform_on_batch(batch) + StatCounter.transaction do + batch.sort.each do |work_id, value| + work = Work.find_by(id: work_id) + stat_counter = StatCounter.lock.find_by(work_id: work_id) + + next if prevent_hits?(work) || stat_counter.nil? + + stat_counter.update(hit_count: stat_counter.hit_count + value.to_i) + end + end + end + + # Check whether the work should allow hits at the moment: + def prevent_hits?(work) + work.nil? || + work.in_unrevealed_collection || + work.hidden_by_admin || + !work.posted + end +end diff --git a/app/jobs/instance_method_job.rb b/app/jobs/instance_method_job.rb new file mode 100755 index 0000000..176d92b --- /dev/null +++ b/app/jobs/instance_method_job.rb @@ -0,0 +1,10 @@ +# Job for calling an instance method on an object. +class InstanceMethodJob < ApplicationJob + def perform(object, *args, **kwargs) + object.send(*args, **kwargs) + end + + retry_on ActiveJob::DeserializationError, attempts: 3, wait: 5.minutes do + # silently discard job after 3 failures + end +end diff --git a/app/jobs/invite_from_queue_job.rb b/app/jobs/invite_from_queue_job.rb new file mode 100755 index 0000000..ded0e0f --- /dev/null +++ b/app/jobs/invite_from_queue_job.rb @@ -0,0 +1,13 @@ +class InviteFromQueueJob < ApplicationJob + if defined?(Sentry::Cron::MonitorCheckIns) + include Sentry::Cron::MonitorCheckIns + + sentry_monitor_check_ins + end + + def perform(count:, creator: nil) + InviteRequest.order(:id).limit(count).each do |request| + request.invite_and_remove(creator) + end + end +end diff --git a/app/jobs/readings_job.rb b/app/jobs/readings_job.rb new file mode 100755 index 0000000..457c90d --- /dev/null +++ b/app/jobs/readings_job.rb @@ -0,0 +1,37 @@ +class ReadingsJob < RedisSetJob + queue_as :readings + + def self.base_key + "Reading:new" + end + + def self.job_size + ArchiveConfig.READING_JOB_SIZE + end + + def self.batch_size + ArchiveConfig.READING_BATCH_SIZE + end + + def perform_on_batch(batch) + # Each item in the batch is an array of arguments encoded as a JSON: + parsed_batch = batch.map do |json| + ActiveSupport::JSON.decode(json) + end + + # Sort to try to reduce deadlocks. + # + # The first argument is user_id, the third argument is work_id: + sorted_batch = parsed_batch.sort_by do |args| + [args.first.to_i, args.third.to_i] + end + + # Finally, start a transaction and call Reading.reading_object to write the + # information to the database: + Reading.transaction do + sorted_batch.each do |args| + Reading.reading_object(*args) + end + end + end +end diff --git a/app/jobs/redis_hash_job.rb b/app/jobs/redis_hash_job.rb new file mode 100755 index 0000000..04ff8ea --- /dev/null +++ b/app/jobs/redis_hash_job.rb @@ -0,0 +1,16 @@ +# An abstract subclass of the RedisSetJob class that adapts the class to handle +# hashes instead of sets. +class RedisHashJob < RedisSetJob + # Add items to be processed when this job runs: + def add_to_job(batch) + redis.mapped_hmset(key, batch) + end + + # Use hscan to iterate through the hash, and hdel to remove: + def self.scan_and_remove(redis, key, batch_size:) + scan_hash_in_batches(redis, key, batch_size: batch_size) do |batch| + yield batch + redis.hdel(key, batch.keys) + end + end +end diff --git a/app/jobs/redis_job_spawner.rb b/app/jobs/redis_job_spawner.rb new file mode 100755 index 0000000..d8f3e87 --- /dev/null +++ b/app/jobs/redis_job_spawner.rb @@ -0,0 +1,25 @@ +# An ActiveJob designed to spawn a bunch of subclasses of RedisSetJob or +# RedisHashJob. Renames the desired redis key to avoid conflicts with other +# code that might be modifying the same set/hash, then calls spawn_jobs on the +# desired job class. +class RedisJobSpawner < ApplicationJob + def perform(job_name, *args, key: nil, redis: nil, **kwargs) + job_class = job_name.constantize + + # Read settings from the job class: + redis ||= job_class.redis + key ||= job_class.base_key + + # Bail out early if there's nothing to process: + return unless redis.exists(key) + + # Rename the job to a unique name to avoid conflicts when this is called + # multiple times in a short period: + spawn_id = redis.incr("job:#{job_name.underscore}:spawn:id") + spawn_key = "job:#{job_name.underscore}:spawn:#{spawn_id}" + redis.rename(key, spawn_key) + + # Tell the job class to handle the spawning. + job_class.spawn_jobs(*args, redis: redis, key: spawn_key, **kwargs) + end +end diff --git a/app/jobs/redis_set_job.rb b/app/jobs/redis_set_job.rb new file mode 100755 index 0000000..1d2206b --- /dev/null +++ b/app/jobs/redis_set_job.rb @@ -0,0 +1,76 @@ +# An abstract class designed to make it easier to queue up jobs with a Redis +# set, then split those jobs into chunks to process them. +class RedisSetJob < ApplicationJob + extend RedisScanning + + # For any subclasses of this job, we want to try to recover from deadlocks + # and lock wait timeouts. The 5 minute delay should hopefully be long enough + # that whatever transaction caused the deadlock will be over with by the time + # we retry. + retry_on ActiveRecord::Deadlocked, attempts: 10, wait: 5.minutes + retry_on ActiveRecord::LockWaitTimeout, attempts: 10, wait: 5.minutes + + # The redis server used for this job. + def self.redis + REDIS_GENERAL + end + + # The default key for the Redis set that we want to process. Used by the + # RedisJobSpawner. + def self.base_key + raise "Must be implemented in subclass!" + end + + # The number of items we'd like to have in a single job. + def self.job_size + 1000 + end + + # The number of items to process in a single call to perform_on_batch. This + # should be smaller than job_size, otherwise it'll just use job_size for the + # batch size. + def self.batch_size + 100 + end + + def perform(*args, **kwargs) + scan_and_remove(redis, key, batch_size: batch_size) do |batch| + perform_on_batch(batch, *args, **kwargs) + end + end + + # This is where the real work happens: + def perform_on_batch(*) + raise "Must be implemented in subclass!" + end + + # The Redis key used to store the objects that this job needs to process: + def key + @key ||= "job:#{self.class.name.underscore}:batch:#{job_id}" + end + + # Add items to be processed when this job runs: + def add_to_job(batch) + redis.sadd(key, batch) + end + + # Use sscan to iterate through the set, and srem to remove: + def self.scan_and_remove(redis, key, batch_size:) + scan_set_in_batches(redis, key, batch_size: batch_size) do |batch| + yield batch + redis.srem(key, batch) + end + end + + # Use scan_and_remove to divide the queue into batches, and create a job for + # each batch: + def self.spawn_jobs(*args, redis: self.redis, key: self.base_key, **kwargs) + scan_and_remove(redis, key, batch_size: job_size) do |batch| + job = new(*args, **kwargs) + job.add_to_job(batch) + job.enqueue + end + end + + delegate :redis, :job_size, :batch_size, :scan_and_remove, to: :class +end diff --git a/app/jobs/report_attachment_job.rb b/app/jobs/report_attachment_job.rb new file mode 100755 index 0000000..2e3fbad --- /dev/null +++ b/app/jobs/report_attachment_job.rb @@ -0,0 +1,7 @@ +class ReportAttachmentJob < ApplicationJob + def perform(ticket_id, work) + download = Download.new(work, mime_type: "text/html") + html = DownloadWriter.new(download).generate_html + FeedbackReporter.new.send_attachment!(ticket_id, "#{download.file_name}.html", html) + end +end diff --git a/app/jobs/resanitize_batch_job.rb b/app/jobs/resanitize_batch_job.rb new file mode 100755 index 0000000..8c8e6a4 --- /dev/null +++ b/app/jobs/resanitize_batch_job.rb @@ -0,0 +1,44 @@ +# A job for resanitizing all fields for a class, and saving the results to the +# database. Takes the name of a class and an array of IDs. +class ResanitizeBatchJob < ApplicationJob + include HtmlCleaner + + retry_on StandardError, attempts: 5, wait: 10.minutes + + queue_as :resanitize + + def perform(klass_name, ids) + klass = klass_name.constantize + + # Go through all of the fields allowing HTML and look for ones that this + # klass has, then calculate a list of pairs like: + # [["summary", "summary_sanitizer_version"], + # ["notes", "notes_sanitizer_version"]] + fields_to_sanitize = [] + + ArchiveConfig.FIELDS_ALLOWING_HTML.each do |field| + next unless klass.has_attribute?(field) && + klass.has_attribute?("#{field}_sanitizer_version") + + fields_to_sanitize << [field, "#{field}_sanitizer_version"] + end + + # Go through each record in the batch, and check the sanitizer version of + # all the fields that need processing. If any field has a sanitizer version + # less than the archive's SANITIZER_VERSION, run the sanitizer on the field + # and re-save it to the database. + klass.where(id: ids).each do |record| + record.with_lock do + fields_to_sanitize.each do |field, sanitizer_version| + next if record[sanitizer_version] && + record[sanitizer_version] >= ArchiveConfig.SANITIZER_VERSION + + record[field] = sanitize_value(field, record[field]) + record[sanitizer_version] = ArchiveConfig.SANITIZER_VERSION + end + + record.save(validate: false) + end + end + end +end diff --git a/app/jobs/stat_counter_job.rb b/app/jobs/stat_counter_job.rb new file mode 100755 index 0000000..7e0af2a --- /dev/null +++ b/app/jobs/stat_counter_job.rb @@ -0,0 +1,19 @@ +class StatCounterJob < RedisSetJob + queue_as :stats + + def self.base_key + "works_to_update_stats" + end + + def self.job_size + ArchiveConfig.STAT_COUNTER_JOB_SIZE + end + + def self.batch_size + ArchiveConfig.STAT_COUNTER_BATCH_SIZE + end + + def perform_on_batch(work_ids) + Work.where(id: work_ids).find_each(&:update_stat_counter) + end +end diff --git a/app/jobs/tag_count_update_job.rb b/app/jobs/tag_count_update_job.rb new file mode 100755 index 0000000..15007d2 --- /dev/null +++ b/app/jobs/tag_count_update_job.rb @@ -0,0 +1,24 @@ +class TagCountUpdateJob < RedisSetJob + queue_as :tag_counts + + def self.base_key + "tag_update" + end + + def self.job_size + ArchiveConfig.TAG_UPDATE_JOB_SIZE + end + + def self.batch_size + ArchiveConfig.TAG_UPDATE_BATCH_SIZE + end + + def perform_on_batch(tag_ids) + Tag.transaction do + tag_ids.each do |id| + value = REDIS_GENERAL.get("tag_update_#{id}_value") + Tag.where(id: id).update(taggings_count_cache: value) if value.present? + end + end + end +end diff --git a/app/jobs/tag_method_job.rb b/app/jobs/tag_method_job.rb new file mode 100755 index 0000000..36ca255 --- /dev/null +++ b/app/jobs/tag_method_job.rb @@ -0,0 +1,15 @@ +# Subclass of InstanceMethodJob with a custom retry setting that is useful for +# wrangling-related jobs. +class TagMethodJob < InstanceMethodJob + # Retry if we insert a non-unique record. + # + # The jobs for this class mostly already check for uniqueness in validations, + # so the only way this can be raised is if there are multiple transactions + # trying to insert the same record at roughly the same time. + retry_on ActiveRecord::RecordNotUnique, + attempts: 3, wait: 5.minutes + + # Try to prevent deadlocks and lock wait timeouts: + retry_on ActiveRecord::Deadlocked, attempts: 10, wait: 5.minutes + retry_on ActiveRecord::LockWaitTimeout, attempts: 10, wait: 5.minutes +end diff --git a/app/mailers/README.md b/app/mailers/README.md new file mode 100755 index 0000000..e97259a --- /dev/null +++ b/app/mailers/README.md @@ -0,0 +1,3 @@ +If `deliver_later` is called within a transaction, the job is added to the Resque queue immediately, but the data written in the transaction is only available once the transaction is complete. This can cause `RecordNotFound` errors when sending emails about brand new objects, as well as other issues with emails containing old data. + +To help avoid these transaction issues, use the `deliver_after_commit` method introduced by [this monkeypatch](../../config/initializers/monkeypatches/deliver_after_commit.rb), which uses the `after_commit_everywhere` gem to ensure that the job is only added to the queue after the transaction has finished. diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb new file mode 100755 index 0000000..5b16703 --- /dev/null +++ b/app/mailers/admin_mailer.rb @@ -0,0 +1,35 @@ +class AdminMailer < ApplicationMailer + # Sends a spam report + def send_spam_alert(spam) + # Make sure that the keys of the spam array are integers, so that we can do + # an easy look-up with user IDs. We call stringify_keys first because + # the currently installed version of Resque::Mailer does odd things when + # you pass a hash as an argument, and we want to know what we're dealing with. + @spam = spam.stringify_keys.transform_keys(&:to_i) + + @users = User.where(id: @spam.keys).to_a + return if @users.empty? + + # The users might have been retrieved from the database out of order, so + # re-sort them by their score. + @users.sort_by! { |user| @spam[user.id]["score"] }.reverse! + + mail( + to: ArchiveConfig.SPAM_ALERT_ADDRESS, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}] Potential spam alert" + ) + end + + # Emails newly created admin, giving them info about their account and a link + # to set their password. Expects the raw password reset token (not the + # encrypted one in the database); it is used to create the reset link. + def set_password_notification(admin, token) + @admin = admin + @token = token + + mail( + to: @admin.email, + subject: t(".subject", app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100755 index 0000000..b3d5f94 --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,7 @@ +class ApplicationMailer < ActionMailer::Base + self.delivery_job = ApplicationMailerJob + + layout "mailer" + helper :mailer + default from: "Sunset Archive" + "<#{ArchiveConfig.RETURN_ADDRESS}>" +end diff --git a/app/mailers/archive_devise_mailer.rb b/app/mailers/archive_devise_mailer.rb new file mode 100755 index 0000000..f19e2c8 --- /dev/null +++ b/app/mailers/archive_devise_mailer.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +# Class for customizing the reset_password_instructions email. +class ArchiveDeviseMailer < Devise::Mailer + layout "mailer" + helper :mailer + helper :application + + default from: "Sunset Archive <#{ArchiveConfig.RETURN_ADDRESS}>" + + def reset_password_instructions(record, token, options = {}) + @user = record + @token = token + subject = if @user.is_a?(Admin) + t("admin.mailer.reset_password_instructions.subject", + app_name: ArchiveConfig.APP_SHORT_NAME) + else + t("users.mailer.reset_password_instructions.subject", + app_name: ArchiveConfig.APP_SHORT_NAME) + end + devise_mail(record, :reset_password_instructions, + options.merge(subject: subject)) + end + + def confirmation_instructions(record, token, opts = {}) + @token = token + subject = t("users.mailer.confirmation_instructions.subject", app_name: ArchiveConfig.APP_SHORT_NAME) + devise_mail(record, :confirmation_instructions, opts.merge(subject: subject)) + end + + def password_change(record, opts = {}) + @pac_footer = true + subject = if record.is_a?(Admin) + t("admin.mailer.password_change.subject", + app_name: ArchiveConfig.APP_SHORT_NAME) + else + t("users.mailer.password_change.subject", + app_name: ArchiveConfig.APP_SHORT_NAME) + end + devise_mail(record, :password_change, opts.merge(subject: subject)) + end +end diff --git a/app/mailers/collection_mailer.rb b/app/mailers/collection_mailer.rb new file mode 100755 index 0000000..cadf1b6 --- /dev/null +++ b/app/mailers/collection_mailer.rb @@ -0,0 +1,16 @@ +class CollectionMailer < ApplicationMailer + helper :application + helper :tags + helper :works + helper :series + + def item_added_notification(creation_id, collection_id, item_type) + @item_type = item_type + @item_type == "Work" ? @creation = Work.find(creation_id) : @creation = Bookmark.find(creation_id) + @collection = Collection.find(collection_id) + mail( + to: @collection.email, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}] #{@item_type.capitalize} added to " + @collection.title.gsub(">", ">").gsub("<", "<") + ) + end +end diff --git a/app/mailers/comment_mailer.rb b/app/mailers/comment_mailer.rb new file mode 100755 index 0000000..bff84fd --- /dev/null +++ b/app/mailers/comment_mailer.rb @@ -0,0 +1,112 @@ +class CommentMailer < ApplicationMailer + # Sends email to an owner of the top-level commentable when a new comment is created + # This may be an admin, in which case we use the admin address instead + def comment_notification(user, comment) + @comment = comment + @owner = true + email = user.is_a?(Admin) ? ArchiveConfig.ADMIN_ADDRESS : user.email + locale = user.try(:preference).try(:locale_for_mails) || I18n.default_locale.to_s + I18n.with_locale(locale) do + mail( + to: email, + # i18n-tasks-use t("comment_mailer.comment_notification.subject.chapter") + # i18n-tasks-use t("comment_mailer.comment_notification.subject.other") + # i18n-tasks-use t("comment_mailer.comment_notification.subject.tag") + subject: subject_for_commentable(@comment) + ) + end + end + + # Sends email to an owner of the top-level commentable when a comment is edited + # This may be an admin, in which case we use the admin address instead + def edited_comment_notification(user, comment) + @comment = comment + @owner = true + email = user.is_a?(Admin) ? ArchiveConfig.ADMIN_ADDRESS : user.email + locale = user.try(:preference).try(:locale_for_mails) || I18n.default_locale.to_s + I18n.with_locale(locale) do + mail( + to: email, + # i18n-tasks-use t("comment_mailer.edited_comment_notification.subject.chapter") + # i18n-tasks-use t("comment_mailer.edited_comment_notification.subject.other") + # i18n-tasks-use t("comment_mailer.edited_comment_notification.subject.tag") + subject: subject_for_commentable(@comment) + ) + end + end + + # Sends email to commenter when a reply is posted to their comment + # This may be a non-user of the archive + def comment_reply_notification(your_comment, comment) + return if your_comment.comment_owner_email.blank? + return if your_comment.pseud_id.nil? && AdminBlacklistedEmail.is_blacklisted?(your_comment.comment_owner_email) + + @your_comment = your_comment + @comment = comment + mail( + to: @your_comment.comment_owner_email, + # i18n-tasks-use t("comment_mailer.comment_reply_notification.subject.chapter") + # i18n-tasks-use t("comment_mailer.comment_reply_notification.subject.other") + # i18n-tasks-use t("comment_mailer.comment_reply_notification.subject.tag") + subject: subject_for_commentable(@comment) + ) + end + + # Sends email to commenter when a reply to their comment is edited + # This may be a non-user of the archive + def edited_comment_reply_notification(your_comment, edited_comment) + return if your_comment.comment_owner_email.blank? + return if your_comment.pseud_id.nil? && AdminBlacklistedEmail.is_blacklisted?(your_comment.comment_owner_email) + return if your_comment.is_deleted? + + @your_comment = your_comment + @comment = edited_comment + mail( + to: @your_comment.comment_owner_email, + # i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.subject.chapter") + # i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.subject.other") + # i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.subject.tag") + subject: subject_for_commentable(@comment) + ) + end + + # Sends email to the poster of a top-level comment + def comment_sent_notification(comment) + @comment = comment + @noreply = true # don't give reply link to your own comment + mail( + to: @comment.comment_owner_email, + # i18n-tasks-use t("comment_mailer.comment_sent_notification.subject.chapter") + # i18n-tasks-use t("comment_mailer.comment_sent_notification.subject.other") + # i18n-tasks-use t("comment_mailer.comment_sent_notification.subject.tag") + subject: subject_for_commentable(@comment) + ) + end + + # Sends email to the poster of a reply to a comment + def comment_reply_sent_notification(comment) + @comment = comment + @parent_comment = comment.commentable + @noreply = true + mail( + to: @comment.comment_owner_email, + # i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.subject.chapter") + # i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.subject.other") + # i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.subject.tag") + subject: subject_for_commentable(@comment) + ) + end + + private + + def subject_for_commentable(comment) + name = comment.ultimate_parent.commentable_name.gsub(">", ">").gsub("<", "<").html_safe + if comment.ultimate_parent.is_a?(Tag) + t(".subject.tag", app_name: ArchiveConfig.APP_SHORT_NAME, name: name) + elsif comment.parent.is_a?(Chapter) && comment.parent.work.chaptered? + t(".subject.chapter", app_name: ArchiveConfig.APP_SHORT_NAME, position: comment.parent.position, title: name) + else + t(".subject.other", app_name: ArchiveConfig.APP_SHORT_NAME, title: name) + end + end +end diff --git a/app/mailers/kudo_mailer.rb b/app/mailers/kudo_mailer.rb new file mode 100755 index 0000000..6c210c3 --- /dev/null +++ b/app/mailers/kudo_mailer.rb @@ -0,0 +1,27 @@ +class KudoMailer < ApplicationMailer + # send a batched-up notification + # user_kudos is a hash of arrays converted to JSON string format + # [commentable_type]_[commentable_id] => + # names: [array of users who left kudos with the last entry being "# guests" if any] + # guest_count: number of guest kudos + def batch_kudo_notification(user_id, user_kudos) + @commentables = [] + @user_kudos = JSON.parse(user_kudos) + user = User.find(user_id) + kudos_hash = JSON.parse(user_kudos) + + kudos_hash.each_pair do |commentable_info, _kudo_givers_hash| + # Parse the key to extract the type and id of the commentable so we can + # weed out any commentables that no longer exist. + commentable_type, commentable_id = commentable_info.split("_") + commentable = commentable_type.constantize.find_by(id: commentable_id) + next unless commentable + + @commentables << commentable + end + mail( + to: user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end +end diff --git a/app/mailers/tag_wrangling_supervisor_mailer.rb b/app/mailers/tag_wrangling_supervisor_mailer.rb new file mode 100755 index 0000000..a9c287c --- /dev/null +++ b/app/mailers/tag_wrangling_supervisor_mailer.rb @@ -0,0 +1,12 @@ +class TagWranglingSupervisorMailer < ApplicationMailer + default to: ArchiveConfig.TAG_WRANGLER_SUPERVISORS_ADDRESS + + # Send an email to tag wrangling supervisors when a tag wrangler changes their username + def wrangler_username_change_notification(old_name, new_name) + @old_username = old_name + @new_username = new_name + mail( + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end +end diff --git a/app/mailers/tos_update_mailer.rb b/app/mailers/tos_update_mailer.rb new file mode 100755 index 0000000..2c694c9 --- /dev/null +++ b/app/mailers/tos_update_mailer.rb @@ -0,0 +1,11 @@ +class TosUpdateMailer < ApplicationMailer + # Sent by notifications:send_tos_update + def tos_update_notification(user, admin_post_id) + @username = user.login + @admin_post = admin_post_id + mail( + to: user.email, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}] Updates to #{ArchiveConfig.APP_SHORT_NAME}'s Terms of Service" + ) + end +end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100755 index 0000000..11542c4 --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,417 @@ +class UserMailer < ApplicationMailer + helper_method :current_user + helper_method :current_admin + helper_method :logged_in? + helper_method :logged_in_as_admin? + + helper :application + helper :tags + helper :works + helper :users + helper :date + helper :series + include HtmlCleaner + + # Send an email letting a creator know that their work has been added to a collection by an archivist + def archivist_added_to_collection_notification(user_id, work_id, collection_id) + @user = User.find(user_id) + @work = Work.find(work_id) + @collection = Collection.find(collection_id) + mail( + to: @user.email, + subject: t(".subject", app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title) + ) + end + + # Send a request to a work owner asking that they approve the inclusion + # of their work in a collection + def invited_to_collection_notification(user_id, work_id, collection_id) + @user = User.find(user_id) + @work = Work.find(work_id) + @collection = Collection.find(collection_id) + mail( + to: @user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title) + ) + end + + # We use an options hash here, instead of keyword arguments, to avoid + # compatibility issues with resque/resque_mailer. + def anonymous_or_unrevealed_notification(user_id, work_id, collection_id, options = {}) + options = options.with_indifferent_access + + @becoming_anonymous = options.fetch(:anonymous, false) + @becoming_unrevealed = options.fetch(:unrevealed, false) + + return unless @becoming_anonymous || @becoming_unrevealed + + @user = User.find(user_id) + @work = Work.find(work_id) + @collection = Collection.find(collection_id) + + # Symbol used to pick the appropriate translation string: + @status = if @becoming_anonymous && @becoming_unrevealed + :anonymous_unrevealed + elsif @becoming_anonymous + :anonymous + else + :unrevealed + end + mail( + to: @user.email, + subject: t(".subject.#{@status}", app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Sends an invitation to join the archive + # Must be sent synchronously as it is rescued + # TODO refactor to make it asynchronous + def invitation(invitation_id) + @invitation = Invitation.find(invitation_id) + @user_name = (@invitation.creator.is_a?(User) ? @invitation.creator.login : "") + mail( + to: @invitation.invitee_email, + subject: t("user_mailer.invitation.subject", app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Sends an invitation to join the archive and claim stories that have been imported as part of a bulk import + def invitation_to_claim(invitation_id, archivist_login) + @invitation = Invitation.find(invitation_id) + @external_author = @invitation.external_author + @archivist = archivist_login || "An archivist" + @token = @invitation.token + mail( + to: @invitation.invitee_email, + subject: t("user_mailer.invitation_to_claim.subject", app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Notifies a writer that their imported works have been claimed + def claim_notification(creator_id, claimed_work_ids) + creator = User.find(creator_id) + @external_email = creator.email + @claimed_works = Work.where(id: claimed_work_ids) + mail( + to: creator.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Sends a batched subscription notification + def batch_subscription_notification(subscription_id, entries) + # Here we use find_by_id so that if the subscription is not found + # then the resque job does not error and we just silently fail. + @subscription = Subscription.find_by(id: subscription_id) + return if @subscription.nil? + + creation_entries = JSON.parse(entries) + @creations = [] + # look up all the creations that have generated updates for this subscription + creation_entries.each do |creation_info| + creation_type, creation_id = creation_info.split("_") + creation = creation_type.constantize.where(id: creation_id).first + next unless creation && creation.try(:posted) + next if creation.is_a?(Chapter) && !creation.work.try(:posted) + next if creation.try(:hidden_by_admin) || (creation.is_a?(Chapter) && creation.work.try(:hidden_by_admin)) + next if creation.pseuds.any? { |p| p.user == User.orphan_account } # no notifications for orphan works + + # TODO: allow subscriptions to orphan_account to receive notifications + + # If the subscription notification is for a user subscription, we don't + # want to send updates about works that have recently become anonymous. + if @subscription.subscribable_type == "User" + next if Subscription.anonymous_creation?(creation) + end + + @creations << creation + end + + return if @creations.empty? + + # make sure we only notify once per creation + @creations.uniq! + + subject = @subscription.subject_text(@creations.first) + subject += " and #{@creations.count - 1} more" if @creations.count > 1 + I18n.with_locale(@subscription.user.preference.locale_for_mails) do + mail( + to: @subscription.user.email, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}] #{subject}" + ) + end + end + + # Emails a user to say they have been given more invitations for their friends + def invite_increase_notification(user_id, total) + @user = User.find(user_id) + @total = total + mail( + to: @user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Emails a user to say that their request for invitation codes has been declined + def invite_request_declined(user_id, total, reason) + @user = User.find(user_id) + @total = total + @reason = reason + mail( + to: @user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + def collection_notification(collection_id, subject, message, email) + @message = message + @collection = Collection.find(collection_id) + mail( + to: email, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}][#{@collection.title}] #{subject}" + ) + end + + def invalid_signup_notification(collection_id, invalid_signup_ids, email) + @collection = Collection.find(collection_id) + @invalid_signups = invalid_signup_ids + @is_collection_email = (email == @collection.collection_email) + mail( + to: email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title) + ) + end + + # This is sent at the end of matching, i.e., after assignments are generated. + # It is also sent when assignments are regenerated. + def potential_match_generation_notification(collection_id, email) + @collection = Collection.find(collection_id) + @is_collection_email = (email == @collection.collection_email) + mail( + to: email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title) + ) + end + + def challenge_assignment_notification(collection_id, assigned_user_id, assignment_id) + @collection = Collection.find(collection_id) + @assigned_user = User.find(assigned_user_id) + @assignment = ChallengeAssignment.find(assignment_id) + @request = @assignment.request_signup + mail( + to: @assigned_user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, collection_title: @collection.title) + ) + end + + # Asks a user to validate and activate their new account + def signup_notification(user_id) + @user = User.find(user_id) + I18n.with_locale(@user.preference.locale_for_mails) do + mail( + to: @user.email, + subject: t("user_mailer.signup_notification.subject", app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + end + + # Confirms to a user that their email was changed + def change_email(user_id, old_email, new_email) + @user = User.find(user_id) + @old_email = old_email + @new_email = new_email + @pac_footer = true + mail( + to: @old_email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + def change_username(user, old_username) + @user = user + @old_username = old_username + @new_username = user.login + @next_change_time = user.renamed_at + ArchiveConfig.USER_RENAME_LIMIT_DAYS.days + mail( + to: @user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + ### WORKS NOTIFICATIONS ### + + # Sends email when an archivist adds someone as a co-creator. + def creatorship_notification_archivist(creatorship_id, archivist_id) + @creatorship = Creatorship.find(creatorship_id) + @archivist = User.find(archivist_id) + @user = @creatorship.pseud.user + @creation = @creatorship.creation + mail( + to: @user.email, + subject: t("user_mailer.creatorship_notification_archivist.subject", + app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Sends email when a user is added as a co-creator + def creatorship_notification(creatorship_id, adding_user_id) + @creatorship = Creatorship.find(creatorship_id) + @adding_user = User.find(adding_user_id) + @user = @creatorship.pseud.user + @creation = @creatorship.creation + mail( + to: @user.email, + subject: t("user_mailer.creatorship_notification.subject", + app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Sends email when a user is added as an unapproved/pending co-creator + def creatorship_request(creatorship_id, inviting_user_id) + @creatorship = Creatorship.find(creatorship_id) + @inviting_user = User.find(inviting_user_id) + @user = @creatorship.pseud.user + @creation = @creatorship.creation + mail( + to: @user.email, + subject: t("user_mailer.creatorship_request.subject", + app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Sends emails to creators whose stories were listed as the inspiration of another work + def related_work_notification(user_id, related_work_id) + @user = User.find(user_id) + @related_work = RelatedWork.find(related_work_id) + @related_parent_link = url_for(controller: :works, action: :show, id: @related_work.parent) + @related_child_link = url_for(controller: :works, action: :show, id: @related_work.work) + mail( + to: @user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Emails a recipient to say that a gift has been posted for them + def recipient_notification(user_id, work_id, collection_id = nil) + @user = User.find(user_id) + @work = Work.find(work_id) + @collection = Collection.find(collection_id) if collection_id + subject = if @collection + t("user_mailer.recipient_notification.subject.collection", + app_name: ArchiveConfig.APP_SHORT_NAME, + collection_title: @collection.title) + else + t("user_mailer.recipient_notification.subject.no_collection", + app_name: ArchiveConfig.APP_SHORT_NAME) + end + mail( + to: @user.email, + subject: subject + ) + end + + # Emails a prompter to say that a response has been posted to their prompt + def prompter_notification(work_id, collection_id = nil) + @work = Work.find(work_id) + @collection = Collection.find(collection_id) if collection_id + @work.challenge_claims.each do |claim| + user = User.find(claim.request_signup.pseud.user.id) + I18n.with_locale(user.preference.locale_for_mails) do + mail( + to: user.email, + subject: "[#{ArchiveConfig.APP_SHORT_NAME}] A response to your prompt" + ) + end + end + end + + # Sends email to creators when a creation is deleted + # NOTE: this must be sent synchronously! otherwise the work will no longer be there to send + # TODO refactor to make it asynchronous by passing the content in the method + def delete_work_notification(user, work, deleter) + @user = user + @work = work + @deleter = deleter + download = Download.new(@work, mime_type: "text/html", include_draft_chapters: true) + html = DownloadWriter.new(download).generate_html + html = ::Mail::Encodings::Base64.encode(html) + attachments["#{download.file_name}.html"] = { content: html, encoding: "base64" } + attachments["#{download.file_name}.txt"] = { content: html, encoding: "base64" } + + mail( + to: user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Sends email to creators when a creation is deleted by an admin + # NOTE: this must be sent synchronously! otherwise the work will no longer be there to send + # TODO refactor to make it asynchronous by passing the content in the method + def admin_deleted_work_notification(user, work) + @user = user + @work = work + download = Download.new(@work, mime_type: "text/html", include_draft_chapters: true) + html = DownloadWriter.new(download).generate_html + html = ::Mail::Encodings::Base64.encode(html) + attachments["#{download.file_name}.html"] = { content: html, encoding: "base64" } + attachments["#{download.file_name}.txt"] = { content: html, encoding: "base64" } + + mail( + to: user.email, + subject: t("user_mailer.admin_deleted_work_notification.subject", app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + # Sends email to creators when a creation is hidden by an admin + def admin_hidden_work_notification(creation_ids, user_id) + @pac_footer = true + @user = User.find_by(id: user_id) + @works = Work.where(id: creation_ids) + return if @works.empty? + + mail( + to: @user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, count: @works.size) + ) + end + + def admin_spam_work_notification(creation_id, user_id) + @user = User.find_by(id: user_id) + @work = Work.find_by(id: creation_id) + + mail( + to: @user.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME) + ) + end + + ### OTHER NOTIFICATIONS ### + + # archive feedback + def feedback(feedback_id) + feedback = Feedback.find(feedback_id) + return unless feedback.email + + @summary = feedback.summary + @comment = feedback.comment + @username = feedback.username if feedback.username.present? + @language = feedback.language + mail( + to: feedback.email, + subject: default_i18n_subject(app_name: ArchiveConfig.APP_SHORT_NAME, summary: strip_html_breaks_simple(feedback.summary)) + ) + end + + def abuse_report(abuse_report_id) + abuse_report = AbuseReport.find(abuse_report_id) + @username = abuse_report.username + @email = abuse_report.email + @url = abuse_report.url + @summary = abuse_report.summary + @comment = abuse_report.comment + mail( + to: abuse_report.email, + subject: t("user_mailer.abuse_report.subject", app_name: ArchiveConfig.APP_SHORT_NAME, summary: strip_html_breaks_simple(@summary)) + ) + end +end diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb new file mode 100755 index 0000000..0ea537c --- /dev/null +++ b/app/models/abuse_report.rb @@ -0,0 +1,214 @@ +class AbuseReport < ApplicationRecord + validates :email, email_format: { allow_blank: false } + validates_presence_of :language + validates_presence_of :summary + validates_presence_of :comment + validates :url, presence: true, length: { maximum: 2080 } + validate :url_is_not_over_reported + validate :email_is_not_over_reporting + validates_length_of :summary, maximum: ArchiveConfig.FEEDBACK_SUMMARY_MAX, + too_long: ts('must be less than %{max} + characters long.', + max: ArchiveConfig.FEEDBACK_SUMMARY_MAX_DISPLAYED) + + before_validation :truncate_url, if: :will_save_change_to_url? + + # It doesn't have the type set properly in the database, so override it here: + attribute :summary_sanitizer_version, :integer, default: 0 + + # Truncates the user-provided URL to the maximum we can store in the database. We don't want to reject reports with very long URLs, but we need to do + # something to avoid a 500 error for long URLs. + def truncate_url + self.url = url[0..2079] + end + + validate :check_for_spam + def check_for_spam + approved = logged_in_with_matching_email? || !Akismetor.spam?(akismet_attributes) + errors.add(:base, ts("This report looks like spam to our system!")) unless approved + end + + def logged_in_with_matching_email? + User.current_user.present? && User.current_user.email.downcase == email.downcase + end + + def akismet_attributes + name = username ? username : "" + # If the user is logged in and we're sending info to Akismet, we can assume + # the email does not match. + role = User.current_user.present? ? "user-with-nonmatching-email" : "guest" + { + comment_type: "contact-form", + key: ArchiveConfig.AKISMET_KEY, + blog: ArchiveConfig.AKISMET_NAME, + user_ip: ip_address, + user_role: role, + comment_author: name, + comment_author_email: email, + comment_content: comment + } + end + + scope :by_date, -> { order('created_at DESC') } + + # Standardize the format of work, chapter, and profile URLs to get it ready + # for the url_is_not_over_reported validation. + # Work URLs: "works/123" + # Chapter URLs: "chapters/123" + # Profile URLs: "users/username" + before_validation :standardize_url, on: :create + def standardize_url + return unless url =~ %r{((chapters|works)/\d+)} || url =~ %r{(users\/\w+)} + + self.url = add_scheme_to_url(url) + self.url = clean_url(url) + self.url = add_work_id_to_url(self.url) + end + + def add_scheme_to_url(url) + uri = Addressable::URI.parse(url) + return url unless uri.scheme.nil? + + "https://#{uri}" + end + + # Clean work or profile URLs so we can prevent the same URLs from getting + # reported too many times. + # If the URL ends without a / at the end, add it: url_is_not_over_reported + # uses the / so "/works/1234" isn't a match for "/works/123" + def clean_url(url) + uri = Addressable::URI.parse(url) + + uri.query = nil + uri.fragment = nil + uri.path += "/" unless uri.path.end_with? "/" + + uri.to_s + end + + # Get the chapter id from the URL and try to get the work id + # If successful, add the work id to the URL in front of "/chapters" + def add_work_id_to_url(url) + return url unless url =~ %r{(chapters/\d+)} && url !~ %r{(works/\d+)} + + chapter_regex = %r{(chapters/)(\d+)} + regex_groups = chapter_regex.match url + chapter_id = regex_groups[2] + work_id = Chapter.find_by(id: chapter_id).try(:work_id) + + return url if work_id.nil? + + uri = Addressable::URI.parse(url) + uri.path = "/works/#{work_id}" + uri.path + + uri.to_s + end + + validate :url_on_archive, if: :will_save_change_to_url? + def url_on_archive + parsed_url = Addressable::URI.heuristic_parse(url) + errors.add(:url, :not_on_archive) unless ArchiveConfig.PERMITTED_HOSTS.include?(parsed_url.host) + rescue Addressable::URI::InvalidURIError + errors.add(:url, :not_on_archive) + end + + def email_and_send + UserMailer.abuse_report(id).deliver_later + send_report + end + + def send_report + return unless zoho_enabled? + + reporter = AbuseReporter.new( + title: summary, + description: comment, + language: language, + email: email, + username: username, + ip_address: ip_address, + url: url, + creator_ids: creator_ids + ) + response = reporter.send_report! + ticket_id = response["id"] + return if ticket_id.blank? + + attach_work_download(ticket_id) + end + + def creator_ids + work_id = reported_work_id + return unless work_id + + work = Work.find_by(id: work_id) + return "deletedwork" unless work + + ids = work.pseuds.pluck(:user_id).push(*work.original_creators.pluck(:user_id)).uniq.sort + ids.prepend("orphanedwork") if ids.delete(User.orphan_account.id) + ids.join(", ") + end + + # ID of the reported work, unless the report is about comment(s) on the work + def reported_work_id + comments = url[%r{/comments/}, 0] + url[%r{/works/(\d+)}, 1] if comments.nil? + end + + def attach_work_download(ticket_id) + work_id = reported_work_id + return unless work_id + + work = Work.find_by(id: work_id) + ReportAttachmentJob.perform_later(ticket_id, work) if work + end + + # if the URL clearly belongs to a work (i.e. contains "/works/123") + # or a user profile (i.e. contains "/users/username") + # make sure it isn't reported more than ABUSE_REPORTS_PER_WORK_MAX + # or ABUSE_REPORTS_PER_USER_MAX times per month + def url_is_not_over_reported + message = ts('This page has already been reported. Our volunteers only + need one report in order to investigate and resolve an issue, + so please be patient and do not submit another report.') + if url =~ /\/works\/\d+/ + # use "/works/123/" to avoid matching chapter or external work ids + work_params_only = url.match(/\/works\/\d+\//).to_s + existing_reports_total = AbuseReport.where('created_at > ? AND + url LIKE ?', + 1.month.ago, + "%#{work_params_only}%").count + if existing_reports_total >= ArchiveConfig.ABUSE_REPORTS_PER_WORK_MAX + errors.add(:base, message) + end + elsif url =~ /\/users\/\w+/ + user_params_only = url.match(/\/users\/\w+\//).to_s + existing_reports_total = AbuseReport.where('created_at > ? AND + url LIKE ?', + 1.month.ago, + "%#{user_params_only}%").count + if existing_reports_total >= ArchiveConfig.ABUSE_REPORTS_PER_USER_MAX + errors.add(:base, message) + end + end + end + + def email_is_not_over_reporting + existing_reports_total = AbuseReport.where("created_at > ? AND + email LIKE ?", + 1.day.ago, + email).count + return if existing_reports_total < ArchiveConfig.ABUSE_REPORTS_PER_EMAIL_MAX + + errors.add(:base, ts("You have reached our daily reporting limit. To keep our + volunteers from being overwhelmed, please do not seek + out violations to report, but only report violations you + encounter during your normal browsing.")) + end + + private + + def zoho_enabled? + %w[staging production].include?(Rails.env) + end +end diff --git a/app/models/admin.rb b/app/models/admin.rb new file mode 100755 index 0000000..c8573d6 --- /dev/null +++ b/app/models/admin.rb @@ -0,0 +1,43 @@ +class Admin < ApplicationRecord + VALID_ROLES = %w[superadmin board board_assistants_team communications development_and_membership docs elections legal translation tag_wrangling support policy_and_abuse open_doors].freeze + + serialize :roles, type: Array, coder: YAML, yaml: { permitted_classes: [String] } + + devise :database_authenticatable, + :lockable, + :recoverable, + :validatable, + password_length: ArchiveConfig.ADMIN_PASSWORD_LENGTH_MIN..ArchiveConfig.ADMIN_PASSWORD_LENGTH_MAX, + reset_password_within: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES.days, + lock_strategy: :none, + unlock_strategy: :none + devise :pwned_password unless Rails.env.test? + + include BackwardsCompatiblePasswordDecryptor + + has_many :log_items + has_many :invitations, as: :creator + has_many :wrangled_tags, class_name: 'Tag', as: :last_wrangler + + validates :login, + presence: true, + uniqueness: true, + length: { in: ArchiveConfig.LOGIN_LENGTH_MIN..ArchiveConfig.LOGIN_LENGTH_MAX } + validates_presence_of :password_confirmation, if: :new_record? + validates_confirmation_of :password, if: :new_record? + + validate :allowed_roles + def allowed_roles + return unless roles && (roles - VALID_ROLES).present? + + errors.add(:roles, :invalid) + end + + # For requesting admins set a new password before their first login. Uses same + # mechanism as password reset requests, but different email notification. + after_create :send_set_password_notification + def send_set_password_notification + token = set_reset_password_token + AdminMailer.set_password_notification(self, token).deliver + end +end diff --git a/app/models/admin_activity.rb b/app/models/admin_activity.rb new file mode 100755 index 0000000..1cc3aca --- /dev/null +++ b/app/models/admin_activity.rb @@ -0,0 +1,25 @@ +class AdminActivity < ApplicationRecord + belongs_to :admin + belongs_to :target, polymorphic: true + + validates_presence_of :admin_id + + delegate :login, to: :admin, prefix: true + + def self.log_action(admin, target, options={}) + self.create do |activity| + activity.admin = admin + activity.target = target + activity.action = options[:action] + activity.summary = options[:summary] + end + end + + def target_name + if target.is_a?(Pseud) + "Pseud #{target.name} (#{target&.user&.login})" + else + "#{target_type} #{target_id}" + end + end +end diff --git a/app/models/admin_banner.rb b/app/models/admin_banner.rb new file mode 100755 index 0000000..321f497 --- /dev/null +++ b/app/models/admin_banner.rb @@ -0,0 +1,28 @@ +class AdminBanner < ApplicationRecord + validates_presence_of :content + + after_save :expire_cached_admin_banner, if: :should_expire_cache? + after_destroy :expire_cached_admin_banner, if: :active? + + # update admin banner setting for all users when banner notice is changed + def self.banner_on + Preference.update_all("banner_seen = false") + end + + def self.active? + self.active? + end + + # we should expire the cache when an active banner is changed or when a banner starts or stops being active + def should_expire_cache? + self.saved_change_to_active? || self.active? + end + + private + + def expire_cached_admin_banner + unless Rails.env.development? + Rails.cache.delete("admin_banner") + end + end +end diff --git a/app/models/admin_blacklisted_email.rb b/app/models/admin_blacklisted_email.rb new file mode 100755 index 0000000..f69a304 --- /dev/null +++ b/app/models/admin_blacklisted_email.rb @@ -0,0 +1,38 @@ +class AdminBlacklistedEmail < ApplicationRecord + before_validation :canonicalize_email + after_create :remove_invite_requests + + validates :email, presence: true, uniqueness: { case_sensitive: false }, email_format: true + + def canonicalize_email + self.email = AdminBlacklistedEmail.canonical_email(self.email) if self.email + end + + def remove_invite_requests + InviteRequest.where(simplified_email: self.email).destroy_all + end + + # Produces a canonical version of a given email reduced to its simplest form + # This is what we store in the db, so that if we subsequently check a submitted email, + # we only need to clean the submitted email the same way and look for it. + def self.canonical_email(email_to_clean) + canonical_email = email_to_clean.downcase + canonical_email.strip! + canonical_email.sub!('@googlemail.com','@gmail.com') + + # strip periods from gmail addresses + if (matchdata = canonical_email.match(/(.+)\@gmail\.com/)) + canonical_email = matchdata[1].gsub('.', '') + "@gmail.com" + end + + # strip out anything after a + + canonical_email.sub!(/(\+.*)(@.*$)/, '\2') + + return canonical_email + end + + # Check if an email is + def self.is_blacklisted?(email_to_check) + AdminBlacklistedEmail.exists?(email: AdminBlacklistedEmail.canonical_email(email_to_check)) + end +end diff --git a/app/models/admin_post.rb b/app/models/admin_post.rb new file mode 100755 index 0000000..d1a873a --- /dev/null +++ b/app/models/admin_post.rb @@ -0,0 +1,140 @@ +class AdminPost < ApplicationRecord + self.per_page = 8 # option for WillPaginate + + acts_as_commentable + enum :comment_permissions, { + enable_all: 0, + disable_anon: 1, + disable_all: 2 + }, default: :disable_anon, suffix: :comments + + belongs_to :language + belongs_to :translated_post, class_name: "AdminPost" + has_many :translations, class_name: "AdminPost", foreign_key: "translated_post_id", dependent: :destroy + has_many :admin_post_taggings + has_many :tags, through: :admin_post_taggings, source: :admin_post_tag + + validates_presence_of :title + validates_length_of :title, + minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) + + validates_length_of :title, + maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) + + validates_presence_of :content + validates_length_of :content, minimum: ArchiveConfig.CONTENT_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.CONTENT_MIN) + + validates_length_of :content, maximum: ArchiveConfig.CONTENT_MAX, + too_long: ts("cannot be more than %{max} characters long.", max: ArchiveConfig.CONTENT_MAX) + + validate :translated_post_must_exist + + validate :translated_post_language_must_differ + + scope :non_translated, -> { where("translated_post_id IS NULL") } + + scope :for_homepage, -> { order("created_at DESC").limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) } + + before_save :inherit_translated_post_comment_permissions, :inherit_translated_post_tags + after_save :expire_cached_home_admin_posts, :update_translation_comment_permissions, :update_translation_tags + after_destroy :expire_cached_home_admin_posts + + # Return the name to link comments to for this object + def commentable_name + self.title + end + def commentable_owners + begin + [Admin.find(self.admin_id)] + rescue + [] + end + end + + def tag_list + tags.map{ |t| t.name }.join(", ") + end + + def tag_list=(list) + return if translated_post_id.present? + + self.tags = list.split(",").uniq.collect { |t| + AdminPostTag.fetch(name: t.strip, language_id: self.language_id, post: self) + }.compact + end + + def translated_post_must_exist + if translated_post_id.present? && AdminPost.find_by(id: translated_post_id).nil? + errors.add(:translated_post_id, "does not exist") + end + end + + def translated_post_language_must_differ + return if translated_post.blank? + return unless translated_post.language == language + + errors.add(:translated_post_id, "cannot be same language as original post") + end + + #################### + # DELAYED JOBS + #################### + + include AsyncWithResque + @queue = :utilities + + # Turns off comments for all posts that are older than the configured time period. + # If the configured period is nil or less than 1 day, no action is taken. + def self.disable_old_post_comments + return unless ArchiveConfig.ADMIN_POST_COMMENTING_EXPIRATION_DAYS&.positive? + + where.not(comment_permissions: :disable_all) + .where(created_at: ..ArchiveConfig.ADMIN_POST_COMMENTING_EXPIRATION_DAYS.days.ago) + .update_all(comment_permissions: :disable_all) + end + + private + + def expire_cached_home_admin_posts + unless Rails.env.development? + Rails.cache.delete("home/index/home_admin_posts") + end + end + + def inherit_translated_post_comment_permissions + return if translated_post.blank? + + self.comment_permissions = translated_post.comment_permissions + end + + def inherit_translated_post_tags + return if translated_post.blank? + + self.tags = translated_post.tags + end + + def update_translation_comment_permissions + return if translations.blank? + + transaction do + translations.find_each do |post| + post.comment_permissions = self.comment_permissions + post.save + end + end + end + + def update_translation_tags + return if translations.blank? + + transaction do + translations.find_each do |post| + post.tags = self.tags + post.save + end + end + end +end diff --git a/app/models/admin_post_tag.rb b/app/models/admin_post_tag.rb new file mode 100755 index 0000000..93c46db --- /dev/null +++ b/app/models/admin_post_tag.rb @@ -0,0 +1,21 @@ +class AdminPostTag < ApplicationRecord + belongs_to :language + has_many :admin_post_taggings + has_many :admin_posts, through: :admin_post_taggings + + validates_presence_of :name + validates :name, uniqueness: true + validates_format_of :name, with: /[a-zA-Z0-9-]+$/, multiline: true + + # Find or create by name, and set the language if it's a new record + def self.fetch(options) + unless options[:name].blank? + tag = self.find_by_name(options[:name]) + return tag unless tag.nil? + tag = AdminPostTag.new(name: options[:name], + language_id: options[:language]) + tag.save ? tag : nil + end + end + +end diff --git a/app/models/admin_post_tagging.rb b/app/models/admin_post_tagging.rb new file mode 100755 index 0000000..894ec7f --- /dev/null +++ b/app/models/admin_post_tagging.rb @@ -0,0 +1,4 @@ +class AdminPostTagging < ApplicationRecord + belongs_to :admin_post + belongs_to :admin_post_tag +end diff --git a/app/models/admin_setting.rb b/app/models/admin_setting.rb new file mode 100755 index 0000000..3b40e7f --- /dev/null +++ b/app/models/admin_setting.rb @@ -0,0 +1,102 @@ +class AdminSetting < ApplicationRecord + include AfterCommitEverywhere + + belongs_to :last_updated, class_name: 'Admin', foreign_key: :last_updated_by + validates_presence_of :last_updated_by + validates :invite_from_queue_number, numericality: { greater_than_or_equal_to: 1, + allow_nil: false, message: "must be greater than 0. To disable invites, uncheck the appropriate setting." } + + before_save :update_invite_date + before_update :check_filter_status + + belongs_to :default_skin, class_name: 'Skin' + + DEFAULT_SETTINGS = { + invite_from_queue_enabled?: ArchiveConfig.INVITE_FROM_QUEUE_ENABLED, + request_invite_enabled?: false, + invite_from_queue_at: nil, + invite_from_queue_number: ArchiveConfig.INVITE_FROM_QUEUE_NUMBER, + invite_from_queue_frequency: ArchiveConfig.INVITE_FROM_QUEUE_FREQUENCY, + account_creation_enabled?: ArchiveConfig.ACCOUNT_CREATION_ENABLED, + days_to_purge_unactivated: 2, + suspend_filter_counts?: false, + enable_test_caching?: false, + cache_expiration: 10, + tag_wrangling_off?: false, + downloads_enabled?: true, + disable_support_form?: false, + default_skin_id: nil + }.freeze + + # Create AdminSetting.first on a blank database. We call this only in an initializer + # or a testing setup, not as part of any heavily used methods (e.g. AdminSetting.current). + def self.default + return AdminSetting.first if AdminSetting.first + + settings = AdminSetting.new( + invite_from_queue_enabled: ArchiveConfig.INVITE_FROM_QUEUE_ENABLED, + invite_from_queue_number: ArchiveConfig.INVITE_FROM_QUEUE_NUMBER, + invite_from_queue_frequency: ArchiveConfig.INVITE_FROM_QUEUE_FREQUENCY, + account_creation_enabled: ArchiveConfig.ACCOUNT_CREATION_ENABLED, + days_to_purge_unactivated: 2 + ) + settings.save(validate: false) + settings + end + + def self.current + Rails.cache.fetch("admin_settings-v2", race_condition_ttl: 10.seconds) { AdminSetting.first } || OpenStruct.new(DEFAULT_SETTINGS) + end + + class << self + delegate *DEFAULT_SETTINGS.keys, :to => :current + delegate :default_skin, to: :current + end + + # run hourly with the resque scheduler + def self.check_queue + return unless self.invite_from_queue_enabled? && InviteRequest.any? && Time.current >= self.invite_from_queue_at + + new_time = Time.current + self.invite_from_queue_frequency.hours + current_setting = self.first + current_setting.invite_from_queue_at = new_time + current_setting.save(validate: false, touch: false) + InviteFromQueueJob.perform_now(count: invite_from_queue_number) + end + + @queue = :admin + # This will be called by a worker when a job needs to be processed + def self.perform(method, *args) + self.send(method, *args) + end + + after_save :recache_settings + def recache_settings + # If the default skin has just been created and set, it will have a closed + # file handle from attaching a preview image, and cannot be serialized for + # caching. To avoid that, we need to reload a fresh copy of the record, + # within the current transaction to guarantee up-to-date data. + self.reload + + # However, we only cache it if the transaction is successful. + after_commit { Rails.cache.write("admin_settings-v2", self) } + end + + private + + def check_filter_status + if self.suspend_filter_counts_changed? + if self.suspend_filter_counts? + self.suspend_filter_counts_at = Time.now + else + #FilterTagging.update_filter_counts_since(self.suspend_filter_counts_at) + end + end + end + + def update_invite_date + if self.invite_from_queue_frequency_changed? + self.invite_from_queue_at = Time.current + self.invite_from_queue_frequency.hours + end + end +end diff --git a/app/models/api_key.rb b/app/models/api_key.rb new file mode 100755 index 0000000..484ff42 --- /dev/null +++ b/app/models/api_key.rb @@ -0,0 +1,8 @@ +class ApiKey < ApplicationRecord + validates :name, presence: true, uniqueness: true + validates :access_token, presence: true, uniqueness: true + + before_validation(on: :create) do + self.access_token = SecureRandom.hex + end +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100755 index 0000000..b050454 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,18 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true + self.per_page = ArchiveConfig.ITEMS_PER_PAGE + + before_save :update_sanitizer_version + + def update_sanitizer_version + ArchiveConfig.FIELDS_ALLOWING_HTML.each do |field| + if self.will_save_change_to_attribute?(field) + self.send("#{field}_sanitizer_version=", ArchiveConfig.SANITIZER_VERSION) + end + end + end + + def self.random_order + order(Arel.sql("RAND()")) + end +end diff --git a/app/models/archive_faq.rb b/app/models/archive_faq.rb new file mode 100755 index 0000000..8160272 --- /dev/null +++ b/app/models/archive_faq.rb @@ -0,0 +1,32 @@ +class ArchiveFaq < ApplicationRecord + acts_as_list + translates :title + translation_class.include(Globalized) + + has_many :questions, -> { order(:position) }, dependent: :destroy + accepts_nested_attributes_for :questions, allow_destroy: true + + validates :slug, presence: true, uniqueness: true + + belongs_to :language + + before_validation :set_slug + def set_slug + if I18n.locale == :en + self.slug = self.title.parameterize + end + end + + # Change the positions of the questions in the archive_faq + def reorder_list(positions) + SortableList.new(self.questions.in_order).reorder_list(positions) + end + + def to_param + slug_was + end + + def self.reorder_list(positions) + SortableList.new(self.order('position ASC')).reorder_list(positions) + end +end diff --git a/app/models/archive_warning.rb b/app/models/archive_warning.rb new file mode 100755 index 0000000..5fed25e --- /dev/null +++ b/app/models/archive_warning.rb @@ -0,0 +1,31 @@ +class ArchiveWarning < Tag + validates :canonical, presence: { message: "^Only canonical warning tags are allowed." } + + NAME = ArchiveConfig.WARNING_CATEGORY_NAME + + DISPLAY_NAME_MAPPING = { + ArchiveConfig.WARNING_DEFAULT_TAG_NAME => ArchiveConfig.WARNING_DEFAULT_TAG_DISPLAY_NAME, + ArchiveConfig.WARNING_NONE_TAG_NAME => ArchiveConfig.WARNING_NONE_TAG_DISPLAY_NAME + }.freeze + + def self.warning_tags + Set[ArchiveConfig.WARNING_DEFAULT_TAG_NAME, + ArchiveConfig.WARNING_NONE_TAG_NAME, + ArchiveConfig.WARNING_VIOLENCE_TAG_NAME, + ArchiveConfig.WARNING_DEATH_TAG_NAME, + ArchiveConfig.WARNING_NONCON_TAG_NAME, + ArchiveConfig.WARNING_CHAN_TAG_NAME] + end + + def self.warning?(warning) + warning_tags.include? warning + end + + def self.label_name + "Warnings" + end + + def display_name + DISPLAY_NAME_MAPPING[name] || name + end +end diff --git a/app/models/banned.rb b/app/models/banned.rb new file mode 100755 index 0000000..431f94c --- /dev/null +++ b/app/models/banned.rb @@ -0,0 +1,5 @@ +class Banned < Tag + + NAME = ArchiveConfig.BANNED_CATEGORY_NAME + +end diff --git a/app/models/block.rb b/app/models/block.rb new file mode 100755 index 0000000..f7937ee --- /dev/null +++ b/app/models/block.rb @@ -0,0 +1,27 @@ +class Block < ApplicationRecord + belongs_to :blocker, class_name: "User" + belongs_to :blocked, class_name: "User" + + validates :blocker, :blocked, presence: true + validates :blocked_id, uniqueness: { scope: :blocker_id } + + validate :check_self + def check_self + errors.add(:blocked, :self) if blocked == blocker + end + + validate :check_official, if: :blocked + def check_official + errors.add(:blocked, :official) if blocked.official + end + + validate :check_block_limit + def check_block_limit + errors.add(:blocked, :limit) if blocker.blocked_users.count >= ArchiveConfig.MAX_BLOCKED_USERS + end + + def blocked_byline=(byline) + pseud = Pseud.parse_byline(byline) + self.blocked = pseud.user unless pseud.nil? + end +end diff --git a/app/models/bookmark.rb b/app/models/bookmark.rb new file mode 100755 index 0000000..e2d97f8 --- /dev/null +++ b/app/models/bookmark.rb @@ -0,0 +1,216 @@ +class Bookmark < ApplicationRecord + include Collectible + include Searchable + include Responder + include Taggable + + belongs_to :bookmarkable, polymorphic: true, inverse_of: :bookmarks + belongs_to :pseud, optional: false + + validates_length_of :bookmarker_notes, + maximum: ArchiveConfig.NOTES_MAX, too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.NOTES_MAX) + + validate :not_already_bookmarked_by_user, on: :create + def not_already_bookmarked_by_user + return unless self.pseud && self.bookmarkable + + return if self.pseud.user.bookmarks.where(bookmarkable: self.bookmarkable).empty? + + errors.add(:base, ts("You have already bookmarked that.")) + end + + validate :check_new_external_work + def check_new_external_work + return unless bookmarkable.is_a?(ExternalWork) && bookmarkable.new_record? + + errors.add(:base, "Fandom tag is required") if bookmarkable.fandom_string.blank? + + return if bookmarkable.valid? + + bookmarkable.errors.full_messages.each do |message| + errors.add(:base, message) + end + end + + # renaming scope :public -> :is_public because otherwise it overlaps with the "public" keyword + scope :is_public, -> { where(private: false, hidden_by_admin: false) } + scope :not_public, -> { where(private: true) } + scope :not_private, -> { where(private: false) } + scope :since, lambda { |*args| where("bookmarks.created_at > ?", (args.first || 1.week.ago)) } + scope :recs, -> { where(rec: true) } + scope :order_by_created_at, -> { order("created_at DESC") } + + scope :join_work, -> { + joins("LEFT JOIN works ON (bookmarks.bookmarkable_id = works.id AND bookmarks.bookmarkable_type = 'Work')"). + merge(Work.visible_to_all) + } + + scope :join_series, -> { + joins("LEFT JOIN series ON (bookmarks.bookmarkable_id = series.id AND bookmarks.bookmarkable_type = 'Series')"). + merge(Series.visible_to_all) + } + + scope :join_external_works, -> { + joins("LEFT JOIN external_works ON (bookmarks.bookmarkable_id = external_works.id AND bookmarks.bookmarkable_type = 'ExternalWork')"). + merge(ExternalWork.visible_to_all) + } + + scope :join_bookmarkable, -> { + joins("LEFT JOIN works ON (bookmarks.bookmarkable_id = works.id AND bookmarks.bookmarkable_type = 'Work') + LEFT JOIN series ON (bookmarks.bookmarkable_id = series.id AND bookmarks.bookmarkable_type = 'Series') + LEFT JOIN external_works ON (bookmarks.bookmarkable_id = external_works.id AND bookmarks.bookmarkable_type = 'ExternalWork')") + } + + scope :visible_to_all, -> { + is_public.with_bookmarkable_visible_to_all + } + + scope :visible_to_registered_user, -> { + is_public.with_bookmarkable_visible_to_registered_user + } + + # Scope for retrieving bookmarks with a bookmarkable visible to registered + # users (regardless of the bookmark's hidden_by_admin/private status). + scope :with_bookmarkable_visible_to_registered_user, -> { + join_bookmarkable.where( + "(works.posted = 1 AND works.hidden_by_admin = 0) OR + (series.hidden_by_admin = 0) OR + (external_works.hidden_by_admin = 0)" + ) + } + + # Scope for retrieving bookmarks with a bookmarkable visible to logged-out + # users (regardless of the bookmark's hidden_by_admin/private status). + scope :with_bookmarkable_visible_to_all, -> { + join_bookmarkable.where( + "(works.posted = 1 AND works.restricted = 0 AND works.hidden_by_admin = 0) OR + (series.restricted = 0 AND series.hidden_by_admin = 0) OR + (external_works.hidden_by_admin = 0)" + ) + } + + # Scope for retrieving bookmarks with a missing bookmarkable (regardless of + # the bookmark's hidden_by_admin/private status). + scope :with_missing_bookmarkable, -> { + join_bookmarkable.where( + "works.id IS NULL AND series.id IS NULL AND external_works.id IS NULL" + ) + } + + scope :visible_to_admin, -> { not_private } + + scope :latest, -> { is_public.order_by_created_at.limit(ArchiveConfig.ITEMS_PER_PAGE).join_work } + + scope :for_blurb, -> { includes(:bookmarkable, :tags, :collections, pseud: [:user]) } + + # a complicated dynamic scope here: + # if the user is an Admin, we use the "visible_to_admin" scope + # if the user is not a logged-in User, we use the "visible_to_all" scope + # otherwise, we use a join to get userids and then get all posted works that are either unhidden OR belong to this user. + # Note: in that last case we have to use select("DISTINCT works.") because of cases where the same user appears twice + # on a work. + scope :visible_to_user, lambda {|user| + if user.is_a?(Admin) + visible_to_admin + elsif !user.is_a?(User) + visible_to_all + else + select("DISTINCT bookmarks.*"). + visible_to_registered_user. + joins("JOIN pseuds as p1 ON p1.id = bookmarks.pseud_id JOIN users ON users.id = p1.user_id"). + where("bookmarks.hidden_by_admin = 0 OR users.id = ?", user.id) + end + } + + # Use the current user to determine what works are visible + scope :visible, -> { visible_to_user(User.current_user) } + + before_destroy :invalidate_bookmark_count + after_save :invalidate_bookmark_count, :update_pseud_index + + after_create :update_work_stats + after_destroy :update_work_stats, :update_pseud_index + + def invalidate_bookmark_count + work = Work.where(id: self.bookmarkable_id) + if work.present? && self.bookmarkable_type == 'Work' + work.first.invalidate_public_bookmarks_count + end + end + + # We index the bookmark count, so if it should change, update the pseud + def update_pseud_index + return unless destroyed? || saved_change_to_id? || saved_change_to_private? || saved_change_to_hidden_by_admin? + IndexQueue.enqueue_id(Pseud, pseud_id, :background) + end + + def visible?(current_user=User.current_user) + return true if current_user == self.pseud.user + unless current_user == :false || !current_user + # Admins should not see private bookmarks + return true if current_user.is_a?(Admin) && self.private == false + end + if !(self.private? || self.hidden_by_admin?) + if self.bookmarkable.nil? + # only show bookmarks for deleted works to the user who + # created the bookmark + return true if pseud.user == current_user + else + if self.bookmarkable_type == 'Work' || self.bookmarkable_type == 'Series' || self.bookmarkable_type == 'ExternalWork' + return true if self.bookmarkable.visible?(current_user) + else + return true + end + end + end + return false + end + + # Returns the number of bookmarks on an item visible to the current user + def self.count_visible_bookmarks(bookmarkable, current_user=:false) + bookmarkable.bookmarks.visible.size + end + + # TODO: Is this necessary anymore? + before_destroy :save_parent_info + + # Because of the way the elasticsearch parent/child index is set up, we need + # to know what the bookmarkable type and id was in order to delete the + # bookmark from the index after it's been deleted from the database + def save_parent_info + expire_time = (Time.now + 2.weeks).to_i + REDIS_GENERAL.setex( + "deleted_bookmark_parent_#{self.id}", + expire_time, + "#{bookmarkable_id}-#{bookmarkable_type.underscore}" + ) + end + + ################################# + ## SEARCH ####################### + ################################# + + def document_json + BookmarkIndexer.new({}).document(self) + end + + def bookmarker + pseud.try(:byline) + end + + def with_notes + bookmarker_notes.present? + end + + def collection_ids + approved_collections.pluck(:id, :parent_id).flatten.uniq.compact + end + + def bookmarkable_date + if bookmarkable.respond_to?(:revised_at) + bookmarkable.revised_at + elsif bookmarkable.respond_to?(:updated_at) + bookmarkable.updated_at + end + end +end diff --git a/app/models/category.rb b/app/models/category.rb new file mode 100755 index 0000000..b011110 --- /dev/null +++ b/app/models/category.rb @@ -0,0 +1,7 @@ +class Category < Tag + validates :canonical, presence: { message: "^Only canonical category tags are allowed." } + + NAME = ArchiveConfig.CATEGORY_CATEGORY_NAME + +end + diff --git a/app/models/challenge_assignment.rb b/app/models/challenge_assignment.rb new file mode 100755 index 0000000..e5cf994 --- /dev/null +++ b/app/models/challenge_assignment.rb @@ -0,0 +1,498 @@ +class ChallengeAssignment < ApplicationRecord + # We use "-1" to represent all the requested items matching + ALL = -1 + + belongs_to :collection + belongs_to :offer_signup, class_name: "ChallengeSignup" + belongs_to :request_signup, class_name: "ChallengeSignup" + belongs_to :pinch_hitter, class_name: "Pseud" + belongs_to :pinch_request_signup, class_name: "ChallengeSignup" # TODO: AO3-6851 Remove pinch_request_signup association from the challenge_assignments table + belongs_to :creation, polymorphic: true + + # Make sure that the signups are an actual match if we're in the process of assigning + # (post-sending, all potential matches have been deleted!) + validate :signups_match, on: :update + def signups_match + if self.sent_at.nil? && + self.request_signup.present? && + self.offer_signup.present? && + !self.request_signup.request_potential_matches.pluck(:offer_signup_id).include?(self.offer_signup_id) + errors.add(:base, ts("does not match. Did you mean to write-in a giver?")) + end + end + + scope :for_request_signup, ->(signup) { where("request_signup_id = ?", signup.id) } + + scope :for_offer_signup, ->(signup) { where("offer_signup_id = ?", signup.id) } + + scope :in_collection, ->(collection) { where("challenge_assignments.collection_id = ?", collection.id) } + + scope :defaulted, -> { where.not(defaulted_at: nil) } + scope :undefaulted, -> { where("defaulted_at IS NULL") } + scope :uncovered, -> { where("covered_at IS NULL") } + scope :covered, -> { where.not(covered_at: nil) } + scope :sent, -> { where.not(sent_at: nil) } + + scope :with_pinch_hitter, -> { where.not(pinch_hitter_id: nil) } + + scope :with_offer, -> { where("offer_signup_id IS NOT NULL OR pinch_hitter_id IS NOT NULL") } + scope :with_request, -> { where.not(request_signup_id: nil) } + scope :with_no_request, -> { where("request_signup_id IS NULL") } + scope :with_no_offer, -> { where("offer_signup_id IS NULL AND pinch_hitter_id IS NULL") } + + # sorting by request/offer + + REQUESTING_PSEUD_JOIN = "INNER JOIN challenge_signups ON challenge_assignments.request_signup_id = challenge_signups.id + INNER JOIN pseuds ON challenge_signups.pseud_id = pseuds.id".freeze + + OFFERING_PSEUD_JOIN = "LEFT JOIN challenge_signups ON challenge_assignments.offer_signup_id = challenge_signups.id + INNER JOIN pseuds ON (challenge_assignments.pinch_hitter_id = pseuds.id OR challenge_signups.pseud_id = pseuds.id)".freeze + + scope :order_by_requesting_pseud, -> { joins(REQUESTING_PSEUD_JOIN).order("pseuds.name") } + + scope :order_by_offering_pseud, -> { joins(OFFERING_PSEUD_JOIN).order("pseuds.name") } + + # Get all of a user's assignments + scope :by_offering_user, lambda { |user| + select("DISTINCT challenge_assignments.*") + .joins(OFFERING_PSEUD_JOIN) + .joins("INNER JOIN users ON pseuds.user_id = users.id") + .where("users.id = ?", user.id) + } + + # sorting by fulfilled/posted status + COLLECTION_ITEMS_JOIN = "INNER JOIN collection_items ON (collection_items.collection_id = challenge_assignments.collection_id AND + collection_items.item_id = challenge_assignments.creation_id AND + collection_items.item_type = challenge_assignments.creation_type)" + + COLLECTION_ITEMS_LEFT_JOIN = "LEFT JOIN collection_items ON (collection_items.collection_id = challenge_assignments.collection_id AND + collection_items.item_id = challenge_assignments.creation_id AND + collection_items.item_type = challenge_assignments.creation_type)" + + WORKS_JOIN = "INNER JOIN works ON works.id = challenge_assignments.creation_id AND challenge_assignments.creation_type = 'Work'" + WORKS_LEFT_JOIN = "LEFT JOIN works ON works.id = challenge_assignments.creation_id AND challenge_assignments.creation_type = 'Work'" + + scope :fulfilled, lambda { + joins(COLLECTION_ITEMS_JOIN).joins(WORKS_JOIN) + .where("challenge_assignments.creation_id IS NOT NULL AND collection_items.user_approval_status = ? AND collection_items.collection_approval_status = ? AND works.posted = 1", + CollectionItem.user_approval_statuses[:approved], CollectionItem.collection_approval_statuses[:approved]) + } + + scope :posted, -> { joins(WORKS_JOIN).where("challenge_assignments.creation_id IS NOT NULL AND works.posted = 1") } + + # should be faster than unfulfilled scope because no giant left joins + def self.unfulfilled_in_collection(collection) + fulfilled_ids = ChallengeAssignment.in_collection(collection).fulfilled.pluck(:id) + fulfilled_ids.empty? ? in_collection(collection) : in_collection(collection).where.not(challenge_assignments: { id: fulfilled_ids }) + end + + # faster than unposted scope because no left join! + def self.unposted_in_collection(collection) + posted_ids = ChallengeAssignment.in_collection(collection).posted.pluck(:id) + posted_ids.empty? ? in_collection(collection) : in_collection(collection).where("'challenge_assignments.creation_id IS NULL OR challenge_assignments.id NOT IN (?)", posted_ids) + end + + def self.duplicate_givers(collection) + ids = in_collection(collection).group("challenge_assignments.offer_signup_id HAVING count(DISTINCT id) > 1").pluck(:offer_signup_id).compact + ChallengeAssignment.where(offer_signup_id: ids) + end + + def self.duplicate_recipients(collection) + ids = in_collection(collection).group("challenge_assignments.request_signup_id HAVING count(DISTINCT id) > 1").pluck(:request_signup_id).compact + ChallengeAssignment.where(request_signup_id: ids) + end + + # has to be a left join to get assignments that don't have a collection item + scope :unfulfilled, lambda { + joins(COLLECTION_ITEMS_LEFT_JOIN).joins(WORKS_LEFT_JOIN) + .where("challenge_assignments.creation_id IS NULL OR collection_items.user_approval_status != ? OR collection_items.collection_approval_status != ? OR works.posted = 0", + CollectionItem.user_approval_statuses[:approved], CollectionItem.collection_approval_statuses[:approved]) + } + + # ditto + scope :unposted, -> { joins(WORKS_LEFT_JOIN).where("challenge_assignments.creation_id IS NULL OR works.posted = 0") } + + scope :unstarted, -> { where("challenge_assignments.creation_id IS NULL") } + + before_destroy :clear_assignment + def clear_assignment + if offer_signup + offer_signup.assigned_as_offer = false + offer_signup.save! + end + + if request_signup + request_signup.assigned_as_request = false + request_signup.save! + end + end + + def get_collection_item + return nil unless self.creation + + CollectionItem.where("collection_id = ? AND item_id = ? AND item_type = ?", self.collection_id, self.creation_id, self.creation_type).first + end + + def started? + !self.creation.nil? + end + + def fulfilled? + self.posted? && (item = get_collection_item) && item.approved? + end + + def posted? + self.creation && (creation.respond_to?(:posted?) ? creation.posted? : true) + end + + def defaulted=(value) + self.defaulted_at = (Time.now if value == "1") + end + + def defaulted + !self.defaulted_at.nil? + end + alias defaulted? defaulted + + def offer_signup_pseud=(pseud_byline) + if pseud_byline.blank? + self.offer_signup = nil + else + signup = signup_for_byline(pseud_byline) + self.offer_signup = signup if signup + end + end + + def offer_signup_pseud + self.offer_signup.try(:pseud).try(:byline) || "" + end + + def request_signup_pseud=(pseud_byline) + if pseud_byline.blank? + self.request_signup = nil + else + signup = signup_for_byline(pseud_byline) + self.request_signup = signup if signup + end + end + + def request_signup_pseud + self.request_signup.try(:pseud).try(:byline) || "" + end + + def signup_for_byline(byline) + pseud = Pseud.parse_byline(byline) + collection.signups.find_by(pseud: pseud) + end + + def title + "#{self.collection.title} (#{self.request_byline})" + end + + def offering_user + offering_pseud ? offering_pseud.user : nil + end + + def offering_pseud + offer_signup ? offer_signup.pseud : pinch_hitter + end + + def requesting_pseud + request_signup&.pseud + end + + def offer_byline + if offer_signup && offer_signup.pseud + offer_signup.pseud.byline + else + (pinch_hitter ? I18n.t("challenge_assignment.offer_byline.pinch_hitter", pinch_hitter_byline: pinch_hitter.byline) : I18n.t("challenge_assignment.offer_byline.none")) + end + end + + def request_byline + requesting_pseud&.byline || I18n.t("challenge_assignment.request_byline.none") + end + + def pinch_hitter_byline + pinch_hitter ? pinch_hitter.byline : "" + end + + def pinch_hitter_byline=(byline) + self.pinch_hitter = Pseud.parse_byline(byline) + end + + def default + self.defaulted_at = Time.now + save + end + + def cover(pseud) + new_assignment = self.covered_at ? request_signup.request_assignments.last : ChallengeAssignment.new + new_assignment.collection = self.collection + new_assignment.request_signup_id = request_signup_id + new_assignment.pinch_hitter = pseud + new_assignment.sent_at = nil + new_assignment.save! + new_assignment.send_out + self.covered_at = Time.now + new_assignment.save && save + end + + def send_out + # don't resend! + unless self.sent_at + self.sent_at = Time.now + save + assigned_to = if self.offer_signup + self.offer_signup.pseud.user + else + (self.pinch_hitter ? self.pinch_hitter.user : nil) + end + if assigned_to && self.request_signup + I18n.with_locale(assigned_to.preference.locale_for_mails) do + UserMailer.challenge_assignment_notification(collection.id, assigned_to.id, self.id).deliver_later + end + end + end + end + + @queue = :collection + # This will be called by a worker when a job needs to be processed + def self.perform(method, *args) + self.send(method, *args) + end + + # send assignments out to all participants + def self.send_out(collection) + Resque.enqueue(ChallengeAssignment, :delayed_send_out, collection.id) + end + + def self.delayed_send_out(collection_id) + collection = Collection.find(collection_id) + + # update the collection challenge with the time the assignments are sent + challenge = collection.challenge + challenge.assignments_sent_at = Time.now + challenge.save + + # send out each assignment + collection.assignments.each do |assignment| + assignment.send_out + end + collection.notify_maintainers_assignments_sent + + # purge the potential matches! we don't want bazillions of them in our db + PotentialMatch.clear!(collection) + end + + # generate automatic match for a collection + # this requires potential matches to already be generated + def self.generate(collection) + REDIS_GENERAL.set(progress_key(collection), 1) + Resque.enqueue(ChallengeAssignment, :delayed_generate, collection.id) + end + + def self.progress_key(collection) + "challenge_assignment_in_progress_for_#{collection.id}" + end + + def self.in_progress?(collection) + REDIS_GENERAL.get(progress_key(collection)) ? true : false + end + + def self.delayed_generate(collection_id) + collection = Collection.find(collection_id) + + if collection.challenge.assignments_sent_at.present? + # If assignments have been sent, we don't want to delete everything and + # regenerate. (If the challenge moderator wants to regenerate assignments + # after sending assignments, they can use the Purge Assignments button.) + return + end + + settings = collection.challenge.potential_match_settings + + REDIS_GENERAL.set(progress_key(collection), 1) + ChallengeAssignment.clear!(collection) + + # we sort signups into buckets based on how many potential matches they have + @request_match_buckets = {} + @offer_match_buckets = {} + @max_match_count = 0 + if settings.nil? || settings.no_match_required? + # stuff everyone into the same bucket + @max_match_count = 1 + @request_match_buckets[1] = collection.signups + @offer_match_buckets[1] = collection.signups + else + collection.signups.find_each do |signup| + next if signup.nil? + + request_match_count = signup.request_potential_matches.count + @request_match_buckets[request_match_count] ||= [] + @request_match_buckets[request_match_count] << signup + @max_match_count = (request_match_count > @max_match_count ? request_match_count : @max_match_count) + + offer_match_count = signup.offer_potential_matches.count + @offer_match_buckets[offer_match_count] ||= [] + @offer_match_buckets[offer_match_count] << signup + @max_match_count = (offer_match_count > @max_match_count ? offer_match_count : @max_match_count) + end + end + + # now that we have the buckets, we go through assigning people in order + # of people with the fewest options first. + # (if someone has no potential matches they get a placeholder assignment with no + # matches.) + 0.upto(@max_match_count) do |count| + if @request_match_buckets[count] + @request_match_buckets[count].sort_by { rand } + .each do |request_signup| + # go through the potential matches in order from best to worst and try and assign + request_signup.reload + next if request_signup.assigned_as_request + + ChallengeAssignment.assign_request!(collection, request_signup) + end + end + + next unless @offer_match_buckets[count] + + @offer_match_buckets[count].sort_by { rand } + .each do |offer_signup| + offer_signup.reload + next if offer_signup.assigned_as_offer + + ChallengeAssignment.assign_offer!(collection, offer_signup) + end + end + REDIS_GENERAL.del(progress_key(collection)) + + if collection.collection_email.present? + UserMailer.potential_match_generation_notification(collection.id, collection.collection_email).deliver_later + else + collection.maintainers_list.each do |user| + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.potential_match_generation_notification(collection.id, user.email).deliver_later + end + end + end + end + + # go through the request's potential matches in order from best to worst and try and assign + def self.assign_request!(collection, request_signup) + assignment = ChallengeAssignment.new(collection: collection, request_signup: request_signup) + last_choice = nil + assigned = false + request_signup.request_potential_matches.sort.reverse.each do |potential_match| + # skip if this signup has already been assigned as an offer + next if potential_match.offer_signup.assigned_as_offer + + # if there's a circular match let's save it as our last choice + if potential_match.offer_signup.assigned_as_request && !last_choice && + collection.assignments.for_request_signup(potential_match.offer_signup).first.offer_signup == request_signup + last_choice = potential_match + next + end + + # otherwise let's use it + assigned = ChallengeAssignment.do_assign_request!(assignment, potential_match) + break + end + + ChallengeAssignment.do_assign_request!(assignment, last_choice) if !assigned && last_choice + + request_signup.assigned_as_request = true + request_signup.save! + + assignment.save! + assignment + end + + # go through the offer's potential matches in order from best to worst and try and assign + def self.assign_offer!(collection, offer_signup) + assignment = ChallengeAssignment.new(collection: collection, offer_signup: offer_signup) + last_choice = nil + assigned = false + offer_signup.offer_potential_matches.sort.reverse.each do |potential_match| + # skip if already assigned as a request + next if potential_match.request_signup.assigned_as_request + + # if there's a circular match let's save it as our last choice + if potential_match.request_signup.assigned_as_offer && !last_choice && + collection.assignments.for_offer_signup(potential_match.request_signup).first.request_signup == offer_signup + last_choice = potential_match + next + end + + # otherwise let's use it + assigned = ChallengeAssignment.do_assign_offer!(assignment, potential_match) + break + end + + ChallengeAssignment.do_assign_offer!(assignment, last_choice) if !assigned && last_choice + + offer_signup.assigned_as_offer = true + offer_signup.save! + + assignment.save! + assignment + end + + def self.do_assign_request!(assignment, potential_match) + assignment.offer_signup = potential_match.offer_signup + potential_match.offer_signup.assigned_as_offer = true + potential_match.offer_signup.save! + end + + def self.do_assign_offer!(assignment, potential_match) + assignment.request_signup = potential_match.request_signup + potential_match.request_signup.assigned_as_request = true + potential_match.request_signup.save! + end + + # clear out all previous assignments. + # note: this does NOT invoke callbacks because ChallengeAssignments don't have any dependent=>destroy + # or associations + def self.clear!(collection) + ChallengeAssignment.where(collection_id: collection.id).delete_all + ChallengeSignup.where(collection_id: collection.id).update_all(assigned_as_offer: false, assigned_as_request: false) + end + + # create placeholders for any assignments left empty + # (this is for after manual updates have left some users without an + # assignment) + def self.update_placeholder_assignments!(collection) + # delete any assignments that have neither an offer nor a request associated + collection.assignments.each do |assignment| + assignment.destroy if assignment.offer_signup.blank? && assignment.request_signup.blank? + end + + collection.signups.each do |signup| + # if this signup has at least one giver now, get rid of any leftover placeholders + if signup.request_assignments.count > 1 + signup.request_assignments.each do |assignment| + assignment.destroy if assignment.offer_signup.blank? + end + end + # if this signup has at least one recipient now, get rid of any leftover placeholders + if signup.offer_assignments.count > 1 + signup.offer_assignments.each do |assignment| + assignment.destroy if assignment.request_signup.blank? + end + end + + # if this signup doesn't have any giver now, create a placeholder + if signup.request_assignments.empty? + assignment = ChallengeAssignment.new(collection: collection, request_signup: signup) + assignment.save + end + + # if this signup doesn't have any recipient now, create a placeholder + if signup.offer_assignments.empty? + assignment = ChallengeAssignment.new(collection: collection, offer_signup: signup) + assignment.save + end + end + end +end diff --git a/app/models/challenge_claim.rb b/app/models/challenge_claim.rb new file mode 100755 index 0000000..ea104c5 --- /dev/null +++ b/app/models/challenge_claim.rb @@ -0,0 +1,155 @@ +class ChallengeClaim < ApplicationRecord + belongs_to :claiming_user, class_name: "User", inverse_of: :request_claims + belongs_to :collection + belongs_to :request_signup, class_name: "ChallengeSignup" + belongs_to :request_prompt, class_name: "Prompt" + belongs_to :creation, polymorphic: true + + before_create :inherit_fields_from_request_prompt + def inherit_fields_from_request_prompt + return unless request_prompt + + self.collection = request_prompt.collection + self.request_signup = request_prompt.challenge_signup + end + + scope :for_request_signup, lambda {|signup| + where('request_signup_id = ?', signup.id) + } + + scope :by_claiming_user, lambda {|user| + select('DISTINCT challenge_claims.*') + .joins("INNER JOIN users ON challenge_claims.claiming_user_id = users.id") + .where('users.id = ?', user.id) + } + + scope :in_collection, lambda {|collection| + where('challenge_claims.collection_id = ?', collection.id) + } + + scope :with_request, -> { where('request_signup IS NOT NULL') } + scope :with_no_request, -> { where('request_signup_id IS NULL') } + + REQUESTING_PSEUD_JOIN = "INNER JOIN challenge_signups ON (challenge_claims.request_signup_id = challenge_signups.id) + INNER JOIN pseuds ON challenge_signups.pseud_id = pseuds.id" + + CLAIMING_PSEUD_JOIN = "INNER JOIN users ON challenge_claims.claiming_user_id = users.id" + + COLLECTION_ITEMS_JOIN = "INNER JOIN collection_items ON (collection_items.collection_id = challenge_claims.collection_id AND + collection_items.item_id = challenge_claims.creation_id AND + collection_items.item_type = challenge_claims.creation_type)" + + COLLECTION_ITEMS_LEFT_JOIN = "LEFT JOIN collection_items ON (collection_items.collection_id = challenge_claims.collection_id AND + collection_items.item_id = challenge_claims.creation_id AND + collection_items.item_type = challenge_claims.creation_type)" + + + scope :order_by_date, -> { order("created_at ASC") } + + def self.order_by_requesting_pseud(dir="ASC") + if dir.casecmp("ASC").zero? + joins(REQUESTING_PSEUD_JOIN).order("pseuds.name ASC") + else + joins(REQUESTING_PSEUD_JOIN).order("pseuds.name DESC") + end + end + + def self.order_by_offering_pseud(dir="ASC") + if dir.casecmp("ASC").zero? + joins(CLAIMING_PSEUD_JOIN).order("pseuds.name ASC") + else + joins(CLAIMING_PSEUD_JOIN).order("pseuds.name DESC") + end + end + + WORKS_JOIN = "INNER JOIN works ON works.id = challenge_claims.creation_id AND challenge_claims.creation_type = 'Work'" + WORKS_LEFT_JOIN = "LEFT JOIN works ON works.id = challenge_claims.creation_id AND challenge_claims.creation_type = 'Work'" + + scope :fulfilled, -> { + joins(COLLECTION_ITEMS_JOIN).joins(WORKS_JOIN) + .where("challenge_claims.creation_id IS NOT NULL AND collection_items.user_approval_status = ? AND collection_items.collection_approval_status = ? AND works.posted = 1", + CollectionItem.user_approval_statuses[:approved], CollectionItem.collection_approval_statuses[:approved]) + } + + + scope :posted, -> { joins(WORKS_JOIN).where("challenge_claims.creation_id IS NOT NULL AND works.posted = 1") } + + # should be faster than unfulfilled scope because no giant left joins + def self.unfulfilled_in_collection(collection) + fulfilled_ids = ChallengeClaim.in_collection(collection).fulfilled.pluck(:id) + fulfilled_ids.empty? ? in_collection(collection) : in_collection(collection).where("challenge_claims.id NOT IN (?)", fulfilled_ids) + end + + # faster than unposted scope because no left join! + def self.unposted_in_collection(collection) + posted_ids = ChallengeClaim.in_collection(collection).posted.pluck(:id) + posted_ids.empty? ? in_collection(collection) : in_collection(collection).where("challenge_claims.creation_id IS NULL OR challenge_claims.id NOT IN (?)", posted_ids) + end + + # has to be a left join to get works that don't have a collection item + scope :unfulfilled, -> { + joins(COLLECTION_ITEMS_LEFT_JOIN).joins(WORKS_LEFT_JOIN) + .where("challenge_claims.creation_id IS NULL OR collection_items.user_approval_status != ? OR collection_items.collection_approval_status != ? OR works.posted = 0", + CollectionItem.user_approval_statuses[:approved], CollectionItem.collection_approval_statuses[:approved]) + } + + # ditto + scope :unposted, -> { joins(WORKS_LEFT_JOIN).where("challenge_claims.creation_id IS NULL OR works.posted = 0") } + + scope :unstarted, -> { where("challenge_claims.creation_id IS NULL") } + + def self.unposted_for_user(user) + all_claims = ChallengeClaim.by_claiming_user(user) + posted_ids = all_claims.posted.pluck(:id) + all_claims.where("challenge_claims.id NOT IN (?)", posted_ids) + end + + + def get_collection_item + return nil unless self.creation + CollectionItem.where('collection_id = ? AND item_id = ? AND item_type = ?', self.collection_id, self.creation_id, self.creation_type).first + end + + def fulfilled? + self.creation && (item = get_collection_item) && item.approved? + end + + def title + if !self.request_prompt.title.blank? + title = request_prompt.title + else + title = ts("Untitled Prompt") + end + title += " " + ts("in") + " #{self.collection.title}" + if self.request_prompt.anonymous? + title += " " + ts("(Anonymous)") + else + title += " (#{self.request_byline})" + end + return title + end + + def claiming_pseud + claiming_user.try(:default_pseud) + end + + def requesting_pseud + request_signup ? request_signup.pseud : nil + end + + def claim_byline + claiming_pseud.try(:byline) || "deleted user" + end + + def request_byline + request_signup ? request_signup.pseud.byline : "- None -" + end + + def user_allowed_to_destroy?(current_user) + (self.claiming_user == current_user) || self.collection.user_is_maintainer?(current_user) + end + + def prompt_description + request_prompt&.description || "" + end +end diff --git a/app/models/challenge_models/gift_exchange.rb b/app/models/challenge_models/gift_exchange.rb new file mode 100755 index 0000000..06853e3 --- /dev/null +++ b/app/models/challenge_models/gift_exchange.rb @@ -0,0 +1,81 @@ +class GiftExchange < ApplicationRecord + PROMPT_TYPES = %w[requests offers].freeze + include ChallengeCore + + override_datetime_setters + + belongs_to :collection + has_one :collection, as: :challenge + + # limits the kind of prompts users can submit + belongs_to :request_restriction, class_name: "PromptRestriction", dependent: :destroy + accepts_nested_attributes_for :request_restriction + + belongs_to :offer_restriction, class_name: "PromptRestriction", dependent: :destroy + accepts_nested_attributes_for :offer_restriction + + belongs_to :potential_match_settings, dependent: :destroy + accepts_nested_attributes_for :potential_match_settings + + validates :signup_instructions_general, :signup_instructions_requests, :signup_instructions_offers, length: { + allow_blank: true, + maximum: ArchiveConfig.INFO_MAX, too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.INFO_MAX) + } + + PROMPT_TYPES.each do |type| + %w[required allowed].each do |setting| + prompt_limit_field = "#{type}_num_#{setting}" + validates prompt_limit_field, numericality: { + only_integer: true, + less_than_or_equal_to: ArchiveConfig.PROMPTS_MAX, + greater_than_or_equal_to: 1 + } + end + end + + before_validation :update_allowed_values + def update_allowed_values + %w[request offer].each do |prompt_type| + required = send("#{prompt_type}s_num_required") + allowed = send("#{prompt_type}s_num_allowed") + send("#{prompt_type}s_num_allowed=", required) if required > allowed + end + end + + # make sure that challenge sign-up / close / open dates aren't contradictory + validate :validate_signup_dates + + # When Challenges are deleted, there are two references left behind that need to be reset to nil + before_destroy :clear_challenge_references + + after_save :copy_tag_set_from_offer_to_request + def copy_tag_set_from_offer_to_request + return unless self.offer_restriction + + self.request_restriction.set_owned_tag_sets(self.offer_restriction.owned_tag_sets) + + # copy the tag-set-based restriction settings + self.request_restriction.character_restrict_to_fandom = self.offer_restriction.character_restrict_to_fandom + self.request_restriction.relationship_restrict_to_fandom = self.offer_restriction.relationship_restrict_to_fandom + self.request_restriction.character_restrict_to_tag_set = self.offer_restriction.character_restrict_to_tag_set + self.request_restriction.relationship_restrict_to_tag_set = self.offer_restriction.relationship_restrict_to_tag_set + self.request_restriction.save + end + + # override core + def allow_name_change? + false + end + + def topmost_tag_type + self.request_restriction.topmost_tag_type + end + + def user_allowed_to_see_requests_summary?(user) + self.collection.user_is_maintainer?(user) || self.requests_summary_visible? + end + + def user_allowed_to_see_prompt?(user, prompt) + self.collection.user_is_maintainer?(user) || prompt.pseud.user == user + end +end diff --git a/app/models/challenge_models/prompt_meme.rb b/app/models/challenge_models/prompt_meme.rb new file mode 100755 index 0000000..b398ebf --- /dev/null +++ b/app/models/challenge_models/prompt_meme.rb @@ -0,0 +1,49 @@ +class PromptMeme < ApplicationRecord + PROMPT_TYPES = %w(requests) + include ChallengeCore + + override_datetime_setters + + belongs_to :collection + has_one :collection, as: :challenge + + # limits the kind of prompts users can submit + belongs_to :request_restriction, class_name: "PromptRestriction", dependent: :destroy + accepts_nested_attributes_for :request_restriction + + validates_length_of :signup_instructions_general, :signup_instructions_requests, { + allow_blank: true, + maximum: ArchiveConfig.INFO_MAX, too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.INFO_MAX) + } + + PROMPT_TYPES.each do |type| + %w(required allowed).each do |setting| + prompt_limit_field = "#{type}_num_#{setting}" + validates_numericality_of prompt_limit_field, only_integer: true, less_than_or_equal_to: ArchiveConfig.PROMPT_MEME_PROMPTS_MAX, greater_than_or_equal_to: 1 + end + end + + before_validation :update_allowed_values, :update_allowed_prompts + + # make sure that challenge sign-up / close / open dates aren't contradictory + validate :validate_signup_dates + + def update_allowed_prompts + required = self.requests_num_required + allowed = self.requests_num_allowed + if required > allowed + self.requests_num_allowed = required + end + end + + # When Challenges are deleted, there are two references left behind that need to be reset to nil + before_destroy :clear_challenge_references + + def user_allowed_to_see_signups?(user) + true + end + + def user_allowed_to_see_claims?(user) + user_allowed_to_see_assignments?(user) + end +end diff --git a/app/models/challenge_signup.rb b/app/models/challenge_signup.rb new file mode 100755 index 0000000..5d393f6 --- /dev/null +++ b/app/models/challenge_signup.rb @@ -0,0 +1,202 @@ +class ChallengeSignup < ApplicationRecord + include TagTypeHelper + + # -1 represents all matching + ALL = -1 + + belongs_to :pseud + belongs_to :collection + + has_many :prompts, dependent: :destroy, inverse_of: :challenge_signup + has_many :requests, dependent: :destroy, inverse_of: :challenge_signup + has_many :offers, dependent: :destroy, inverse_of: :challenge_signup + + has_many :offer_potential_matches, class_name: "PotentialMatch", foreign_key: 'offer_signup_id', dependent: :destroy + has_many :request_potential_matches, class_name: "PotentialMatch", foreign_key: 'request_signup_id', dependent: :destroy + + has_many :offer_assignments, class_name: "ChallengeAssignment", foreign_key: 'offer_signup_id' + has_many :request_assignments, class_name: "ChallengeAssignment", foreign_key: 'request_signup_id' + + has_many :request_claims, class_name: "ChallengeClaim", foreign_key: 'request_signup_id' + + before_destroy :clear_assignments_and_claims + def clear_assignments_and_claims + # remove this signup reference from any existing assignments + offer_assignments.each {|assignment| assignment.offer_signup = nil; assignment.save} + request_assignments.each {|assignment| assignment.request_signup = nil; assignment.save} + request_claims.each {|claim| claim.destroy} + end + + # we reject prompts if they are empty except for associated references + accepts_nested_attributes_for :offers, :prompts, :requests, {allow_destroy: true, + reject_if: proc { |attrs| + attrs[:url].blank? && attrs[:description].blank? && + (attrs[:tag_set_attributes].nil? || attrs[:tag_set_attributes].all? {|k,v| v.blank?}) && + (attrs[:optional_tag_set_attributes].nil? || attrs[:optional_tag_set_attributes].all? {|k,v| v.blank?}) + } + } + + scope :by_user, lambda {|user| + select("DISTINCT challenge_signups.*"). + joins(pseud: :user). + where('users.id = ?', user.id) + } + + scope :by_pseud, lambda {|pseud| where('pseud_id = ?', pseud.id) } + + scope :pseud_only, -> { select(:pseud_id) } + + scope :order_by_pseud, -> { joins(:pseud).order("pseuds.name") } + + scope :order_by_date, -> { order("updated_at DESC") } + + scope :in_collection, lambda {|collection| where('challenge_signups.collection_id = ?', collection.id)} + + scope :no_potential_offers, -> { where("id NOT IN (SELECT offer_signup_id FROM potential_matches)") } + scope :no_potential_requests, -> { where("id NOT IN (select request_signup_id FROM potential_matches)") } + + # Scopes used to include extra data when loading. + scope :with_request_tags, -> { includes( + requests: [tag_set: :tags, optional_tag_set: :tags] + ) } + scope :with_offer_tags, -> { includes( + offers: [tag_set: :tags, optional_tag_set: :tags] + ) } + + ### VALIDATION + + validates_presence_of :pseud, :collection + + # only one signup per challenge! + validates_uniqueness_of :pseud_id, scope: [:collection_id], message: ts("^You seem to already have signed up for this challenge.") + + # we validate number of prompts/requests/offers at the challenge + validate :number_of_prompts + def number_of_prompts + if (challenge = collection.challenge) + errors_to_add = [] + %w(offers requests).each do |prompt_type| + allowed = self.send("#{prompt_type}_num_allowed") + required = self.send("#{prompt_type}_num_required") + count = eval("@#{prompt_type}") ? eval("@#{prompt_type}.size") : eval("#{prompt_type}.size") + unless count.between?(required, allowed) + if allowed == 0 + errors_to_add << ts("You cannot submit any #{prompt_type.pluralize} for this challenge.") + elsif required == allowed + errors_to_add << ts("You must submit exactly %{required} #{required > 1 ? prompt_type.pluralize : prompt_type} for this challenge. You currently have %{count}.", + required: required, count: count) + else + errors_to_add << ts("You must submit between %{required} and %{allowed} #{prompt_type.pluralize} to sign up for this challenge. You currently have %{count}.", + required: required, allowed: allowed, count: count) + end + end + end + unless errors_to_add.empty? + # yuuuuuck :( but so much less ugly than define-method'ing these all + self.errors.add(:base, errors_to_add.join("
  • ").html_safe) + end + end + end + + # make sure that tags are unique across each group of prompts + validate :unique_tags + def unique_tags + return unless (challenge = collection.challenge) + + challenge.class::PROMPT_TYPES.each do |prompt_type| + # requests => request_restriction, offers => offer_restriction + restriction = challenge.send("#{prompt_type.singularize}_restriction") + + next unless restriction + + prompts = send(prompt_type) + + TagSet::TAG_TYPES.each do |tag_type| + next unless restriction.require_unique?(tag_type) + + all_tags_used = prompts.flat_map do |prompt| + prompt.tag_set.send("#{tag_type}_taglist") + end + + unless all_tags_used.size == all_tags_used.uniq.size + errors.add(:base, ts("You have submitted more than one %{prompt_type} with the same %{tag_type} tags. This challenge requires them all to be unique.", + prompt_type: prompt_type.singularize, tag_type: tag_type_label_name(tag_type).downcase)) + end + end + end + end + + # define "offers_num_allowed" etc here + %w(offers requests).each do |prompt_type| + %w(required allowed).each do |permission| + define_method("#{prompt_type}_num_#{permission}") do + collection.challenge.respond_to?("#{prompt_type}_num_#{permission}") ? collection.challenge.send("#{prompt_type}_num_#{permission}") : 0 + end + end + end + + def can_delete?(prompt) + prompt_type = prompt.class.to_s.downcase.pluralize + current_num_prompts = self.send(prompt_type).count + required_num_prompts = self.send("#{prompt_type}_num_required") + if current_num_prompts > required_num_prompts + true + else + false + end + end + + # sort alphabetically + include Comparable + def <=>(other) + self.pseud.name.downcase <=> other.pseud.name.downcase + end + + def user + self.pseud.user + end + + def user_allowed_to_destroy?(current_user) + (self.pseud.user == current_user) || self.collection.user_is_maintainer?(current_user) + end + + def user_allowed_to_see?(current_user) + (self.pseud.user == current_user) || user_allowed_to_see_signups?(current_user) + end + + def user_allowed_to_see_signups?(user) + self.collection.user_is_maintainer?(user) || + self.collection.challenge_type == "PromptMeme" || + (self.challenge.respond_to?("user_allowed_to_see_signups?") && self.challenge.user_allowed_to_see_signups?(user)) + end + + def byline + pseud.byline + end + + # Returns nil if not a match otherwise returns PotentialMatch object + # self is the request, other is the offer + def match(other, settings = nil) + if settings.nil? || settings.no_match_required? + # No match is required, so everything matches everything, and the best + # match is perfect. + return PotentialMatch.new( + offer_signup: other, + request_signup: self, + collection_id: collection_id, + num_prompts_matched: ALL, + max_tags_matched: ALL + ) + end + + builder = PotentialMatchBuilder.new(self, other, settings) + + requests.each do |request| + other.offers.each do |offer| + builder.try_prompt_match(request, offer) + end + end + + builder.build_potential_match + end +end diff --git a/app/models/challenge_signup_summary.rb b/app/models/challenge_signup_summary.rb new file mode 100755 index 0000000..305f713 --- /dev/null +++ b/app/models/challenge_signup_summary.rb @@ -0,0 +1,151 @@ +class ChallengeSignupSummary + + attr_reader :collection, :challenge + + def initialize(collection) + @collection = collection + @challenge = collection.challenge + end + + ###################################################################### + # CALCULATING INFO FOR THE SUMMARY + ###################################################################### + + # The type of tags to be summarized. + # + # For a multi-fandom challenge, this is probably fandom, but for a + # single-fandom challenge, it will probably be character or relationship (or + # one of the other tag types, if the challenge doesn't include either). + # + # Note that this returns the lowercase tag type. + def tag_type + @tag_type = collection.challenge.topmost_tag_type + end + + # Returns an array of tag listings that includes the number of requests and + # offers each tag has in this challenge, sorted by least-offered and most-requested + def summary + @summary ||= tags.map { |tag| tag_summary(tag) }.compact.sort + end + + private + + # The class of tags to be summarized. Calls tag_type to retrieve the type. + def tag_class + raise "Redshirt: Attempted to constantize invalid class initialize tag_class #{tag_type.classify}" unless Tag::TYPES.include?(tag_type.classify) + tag_type.classify.constantize + end + + # All of the tags of the desired type that have been + # used in requests or offers for this challenge + def tags + @tags ||= tag_class.in_challenge(collection) + end + + def tag_summary(tag) + request_count = Request.in_collection(collection).with_tag(tag).count + offer_count = Offer.in_collection(collection).with_tag(tag).count + + if request_count > 0 + ChallengeSignupTagSummary.new(tag.id, tag.name, request_count, offer_count) + end + end + + public + + ###################################################################### + # GENERATING THE SUMMARY IN RESQUE + ###################################################################### + + @queue = :collection + + # The action to be performed when this class is enqueued using Resque. + def self.perform(collection_id) + collection = Collection.find(collection_id) + summary = ChallengeSignupSummary.new(collection) + summary.generate_in_background + end + + # Asynchronously generate the cached version. + def enqueue_for_generation + Resque.enqueue(ChallengeSignupSummary, collection.id) + end + + # Write the summary to Memcached, so that it can be retrieved and displayed. + def generate_in_background + locals = { + challenge_collection: collection, + tag_type: self.tag_type, + summary_tags: self.summary, + generated_live: false + } + + partial = "challenge/#{self.challenge.class.name.demodulize.tableize.singularize}/challenge_signups_summary" + + self.cached_contents = ChallengeSignupsController.render(partial: partial, + locals: locals) + end + + ###################################################################### + # CACHING THE SUMMARY + ###################################################################### + + # Retrieve the value of the cache for this signup summary. + def cached_contents + cached_info[:contents] + end + + # Retrieve the time that the cache was last updated. + def cached_time + cached_info[:time] + end + + # The equivalent of touching a file in the file system. Update the + # modification time. + def touch_cache + data = cached_info.dup + data[:time] = Time.now + Rails.cache.write(cache_key, data) + end + + private + + # Set the value of the cache for this signup summary. + def cached_contents=(value) + data = { + contents: value, + time: Time.now + } + + Rails.cache.write(cache_key, data) + end + + # Retrieve the hash containing cached info: the value being cached (if it + # exists), and the time that it was updated. + def cached_info + Rails.cache.read(cache_key) || {} + end + + # The key used to store info about the signup summary in memcached. + def cache_key + "/v1/challenge_signup_summaries/#{collection.id}" + end +end + +class ChallengeSignupTagSummary < Struct.new(:id, :name, :requests, :offers) + + # Prioritize tags with the fewest offers and most requests + # If they have the same number of offers and requests, sort by name + def <=>(other) + if self.offers == other.offers + if self.requests == other.requests + self.name <=> other.name + else + other.requests <=> self.requests + end + else + self.offers <=> other.offers + end + end + +end diff --git a/app/models/chapter.rb b/app/models/chapter.rb new file mode 100755 index 0000000..40545b1 --- /dev/null +++ b/app/models/chapter.rb @@ -0,0 +1,209 @@ +# encoding=utf-8 + +class Chapter < ApplicationRecord + include HtmlCleaner + include WorkChapterCountCaching + include CreationNotifier + include Creatable + + belongs_to :work, inverse_of: :chapters + # acts_as_list scope: 'work_id = #{work_id}' + + acts_as_commentable + + validates_length_of :title, allow_blank: true, maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) + + validates_length_of :summary, allow_blank: true, maximum: ArchiveConfig.SUMMARY_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.SUMMARY_MAX) + validates_length_of :notes, allow_blank: true, maximum: ArchiveConfig.NOTES_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.NOTES_MAX) + validates_length_of :endnotes, allow_blank: true, maximum: ArchiveConfig.NOTES_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.NOTES_MAX) + + + validates_presence_of :content + validates_length_of :content, minimum: ArchiveConfig.CONTENT_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.CONTENT_MIN) + + validates_length_of :content, maximum: ArchiveConfig.CONTENT_MAX, + too_long: ts("cannot be more than %{max} characters long.", max: ArchiveConfig.CONTENT_MAX) + + attr_accessor :wip_length_placeholder + + before_validation :inherit_creatorships + def inherit_creatorships + if work && creatorships.empty? && current_user_pseuds.blank? + work.pseuds_after_saving.each do |pseud| + creatorships.build(pseud: pseud) + end + end + end + + before_save :strip_title + before_save :set_word_count + before_save :validate_published_at + + after_create :notify_after_creation + after_update :notify_after_update + + scope :in_order, -> { order(:position) } + scope :posted, -> { where(posted: true) } + + after_save :fix_positions + def fix_positions + if work&.persisted? + positions_changed = false + self.position ||= 1 + chapters = work.chapters.order(:position) + if chapters && chapters.length > 1 + chapters = chapters - [self] + chapters.insert(self.position-1, self) + chapters.compact.each_with_index do |chapter, i| + if chapter.position != i+1 + Chapter.where(["id = ?", chapter.id]).update_all(["position = ?", i + 1]) + positions_changed = true + end + end + end + # We're caching the chapter positions in the comment blurbs and the last + # chapter link in the work blurbs so we need to expire the blurbs and the + # work indexes. + if positions_changed + work.comments.each{ |c| c.touch } + work.expire_caches + end + end + end + + after_save :invalidate_chapter_count, + if: Proc.new { |chapter| chapter.saved_change_to_posted? } + + before_destroy :fix_positions_before_destroy, :invalidate_chapter_count + def fix_positions_before_destroy + if work&.persisted? && position + chapters = work.chapters.where(["position > ?", position]) + chapters.each { |c| c.update_attribute(:position, c.position - 1) } + end + end + + after_commit :update_series_index + def update_series_index + return unless work&.series.present? && should_reindex_series? + work.serial_works.each(&:update_series_index) + end + + def should_reindex_series? + pertinent_attributes = %w[id posted] + destroyed? || (saved_changes.keys & pertinent_attributes).present? + end + + def invalidate_chapter_count + if work + invalidate_work_chapter_count(work) + end + end + + def moderated_commenting_enabled? + work && work.moderated_commenting_enabled? + end + + # strip leading spaces from title + def strip_title + unless self.title.blank? + self.title = self.title.gsub(/^\s*/, '') + end + end + + def chapter_header + "#{ts("Chapter")} #{position}" + end + + def chapter_title + self.title.blank? ? self.chapter_header : self.title + end + + # Header plus title, used in subscriptions + def full_chapter_title + str = chapter_header + if title.present? + str += ": #{title}" + end + str + end + + def display_title + self.position.to_s + '. ' + self.chapter_title + end + + def abbreviated_display_title + self.display_title.length > 50 ? (self.display_title[0..50] + "...") : self.display_title + end + + # make em-dashes into html code +# def clean_emdashes +# self.content.gsub!(/\xE2\x80\"/, '—') +# end + # check if this chapter is the only chapter of its work + def is_only_chapter? + self.work.chapters.count == 1 + end + + def only_non_draft_chapter? + self.posted? && self.work.chapters.posted.count == 1 + end + + # Virtual attribute for work wip_length + # Chapter needed its own version for sense-checking purposes + def wip_length + if self.new_record? && self.work.expected_number_of_chapters == self.work.number_of_chapters + self.work.expected_number_of_chapters += 1 + elsif self.work.expected_number_of_chapters && self.work.expected_number_of_chapters < self.work.number_of_chapters + "?" + else + self.work.wip_length + end + end + + # Can't directly access work from a chapter virtual attribute + # Using a placeholder variable for edits, where the value isn't saved immediately + def wip_length=(number) + self.wip_length_placeholder = number + end + + # Checks the chapter published_at date isn't in the future + def validate_published_at + if !self.published_at + self.published_at = Date.current + elsif self.published_at > Date.current + errors.add(:base, ts("Publication date can't be in the future.")) + throw :abort + end + end + + # Set the value of word_count to reflect the length of the text in the chapter content + def set_word_count + if self.new_record? || self.content_changed? || self.word_count.nil? + counter = WordCounter.new(self.content) + self.word_count = counter.count + else + self.word_count + end + end + + # Return the name to link comments to for this object + def commentable_name + self.work.title + end + + def expire_comments_count + super + work&.expire_comments_count + end + + def expire_byline_cache + [true, false].each do |only_path| + Rails.cache.delete("#{cache_key}/byline-nonanon/#{only_path}") + end + end +end diff --git a/app/models/character.rb b/app/models/character.rb new file mode 100755 index 0000000..63f1a2c --- /dev/null +++ b/app/models/character.rb @@ -0,0 +1,32 @@ +class Character < Tag + + NAME = ArchiveConfig.CHARACTER_CATEGORY_NAME + + # Types of tags to which a character tag can belong via common taggings or meta taggings + def parent_types + ['Fandom', 'MetaTag'] + end + def child_types + ['Relationship', 'SubTag', 'Merger'] + end + + def characters + (children + parents).select {|t| t.is_a? Character}.sort + end + + def relationships + children.by_type('Relationship').by_name + end + + def freeforms + children.by_type('Freeform').by_name + end + + def fandoms + parents.by_type('Fandom').by_name + end + + def medias + parents.by_type('Media').by_name + end +end diff --git a/app/models/collection.rb b/app/models/collection.rb new file mode 100755 index 0000000..ad21b7a --- /dev/null +++ b/app/models/collection.rb @@ -0,0 +1,464 @@ +class Collection < ApplicationRecord + include Filterable + include WorksOwner + + has_one_attached :icon do |attachable| + attachable.variant(:standard, resize_to_limit: [100, 100], loader: { n: -1 }) + end + + # i18n-tasks-use t("errors.attributes.icon.invalid_format") + # i18n-tasks-use t("errors.attributes.icon.too_large") + validates :icon, attachment: { + allowed_formats: %r{image/\S+}, + maximum_size: ArchiveConfig.ICON_SIZE_KB_MAX.kilobytes + } + + belongs_to :parent, class_name: "Collection", inverse_of: :children + has_many :children, class_name: "Collection", foreign_key: "parent_id", inverse_of: :parent + + has_one :collection_profile, dependent: :destroy + accepts_nested_attributes_for :collection_profile + + has_one :collection_preference, dependent: :destroy + accepts_nested_attributes_for :collection_preference + + before_validation :clear_icon + before_validation :cleanup_url + before_create :ensure_associated + def ensure_associated + self.collection_preference = CollectionPreference.new unless self.collection_preference + self.collection_profile = CollectionProfile.new unless self.collection_profile + end + + belongs_to :challenge, dependent: :destroy, polymorphic: true + has_many :prompts, dependent: :destroy + + has_many :signups, class_name: "ChallengeSignup", dependent: :destroy + has_many :potential_matches, dependent: :destroy + has_many :assignments, class_name: "ChallengeAssignment", dependent: :destroy + has_many :claims, class_name: "ChallengeClaim", dependent: :destroy + + # We need to get rid of all of these if the challenge is destroyed + after_save :clean_up_challenge + def clean_up_challenge + return if self.challenge_id + + assignments.each(&:destroy) + potential_matches.each(&:destroy) + signups.each(&:destroy) + prompts.each(&:destroy) + end + + has_many :collection_items, dependent: :destroy + accepts_nested_attributes_for :collection_items, allow_destroy: true + has_many :approved_collection_items, -> { approved_by_both }, class_name: "CollectionItem" + + has_many :works, through: :collection_items, source: :item, source_type: "Work" + has_many :approved_works, -> { posted }, through: :approved_collection_items, source: :item, source_type: "Work" + + has_many :bookmarks, through: :collection_items, source: :item, source_type: "Bookmark" + has_many :approved_bookmarks, through: :approved_collection_items, source: :item, source_type: "Bookmark" + + has_many :collection_participants, dependent: :destroy + accepts_nested_attributes_for :collection_participants, allow_destroy: true + + has_many :participants, through: :collection_participants, source: :pseud + has_many :users, through: :participants, source: :user + has_many :invited, -> { where(collection_participants: { participant_role: CollectionParticipant::INVITED }) }, through: :collection_participants, source: :pseud + has_many :owners, -> { where(collection_participants: { participant_role: CollectionParticipant::OWNER }) }, through: :collection_participants, source: :pseud + has_many :moderators, -> { where(collection_participants: { participant_role: CollectionParticipant::MODERATOR }) }, through: :collection_participants, source: :pseud + has_many :members, -> { where(collection_participants: { participant_role: CollectionParticipant::MEMBER }) }, through: :collection_participants, source: :pseud + has_many :posting_participants, -> { where(collection_participants: { participant_role: [CollectionParticipant::MEMBER, CollectionParticipant::MODERATOR, CollectionParticipant::OWNER] }) }, through: :collection_participants, source: :pseud + + CHALLENGE_TYPE_OPTIONS = [ + ["", ""], + [ts("Gift Exchange"), "GiftExchange"], + [ts("Prompt Meme"), "PromptMeme"] + ].freeze + + validate :must_have_owners + def must_have_owners + # we have to use collection participants because the association may not exist until after + # the collection is saved + errors.add(:base, ts("Collection has no valid owners.")) if (self.collection_participants + (self.parent ? self.parent.collection_participants : [])).select(&:is_owner?) + .empty? + end + + validate :collection_depth + def collection_depth + errors.add(:base, ts("Sorry, but %{name} is a subcollection, so it can't also be a parent collection.", name: parent.name)) if self.parent&.parent || (self.parent && !self.children.empty?) || (!self.children.empty? && !self.children.collect(&:children).flatten.empty?) + end + + validate :parent_exists + def parent_exists + errors.add(:base, ts("We couldn't find a collection with name %{name}.", name: parent_name)) unless parent_name.blank? || Collection.find_by(name: parent_name) + end + + validate :parent_is_allowed + def parent_is_allowed + if parent + if parent == self + errors.add(:base, ts("You can't make a collection its own parent.")) + elsif parent_id_changed? && !parent.user_is_maintainer?(User.current_user) + errors.add(:base, ts("You have to be a maintainer of %{name} to make a subcollection.", name: parent.name)) + end + end + end + + validates :name, presence: { message: ts("Please enter a name for your collection.") } + validates :name, uniqueness: { message: ts("Sorry, that name is already taken. Try again, please!") } + validates :name, + length: { minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) } + validates :name, + length: { maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) } + validates :name, + format: { message: ts("must begin and end with a letter or number; it may also contain underscores. It may not contain any other characters, including spaces."), + with: /\A[A-Za-z0-9]\w*[A-Za-z0-9]\Z/ } + validates :icon_alt_text, length: { allow_blank: true, maximum: ArchiveConfig.ICON_ALT_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_ALT_MAX) } + validates :icon_comment_text, length: { allow_blank: true, maximum: ArchiveConfig.ICON_COMMENT_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_COMMENT_MAX) } + + validates :email, email_format: { allow_blank: true } + + validates :title, presence: { message: ts("Please enter a title to be displayed for your collection.") } + validates :title, + length: { minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) } + validates :title, + length: { maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) } + validate :no_reserved_strings + def no_reserved_strings + errors.add(:title, ts("^Sorry, the ',' character cannot be in a collection Display Title.")) if + title.match(/,/) + end + + # return title.html_safe to overcome escaping done by sanitiser + def title + self[:title].try(:html_safe) + end + + validates :description, + length: { allow_blank: true, + maximum: ArchiveConfig.SUMMARY_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.SUMMARY_MAX) } + + validates :header_image_url, format: { allow_blank: true, with: URI::DEFAULT_PARSER.make_regexp(%w[http https]), message: ts("is not a valid URL.") } + validates :header_image_url, format: { allow_blank: true, with: /\A\S+\.(png|gif|jpg)\z/, message: ts("can only point to a gif, jpg, or png file.") } + + validates :tags_after_saving, + length: { maximum: ArchiveConfig.COLLECTION_TAGS_MAX, + message: "^Sorry, a collection can only have %{count} tags." } + + scope :top_level, -> { where(parent_id: nil) } + scope :closed, -> { joins(:collection_preference).where(collection_preferences: { closed: true }) } + scope :not_closed, -> { joins(:collection_preference).where(collection_preferences: { closed: false }) } + scope :moderated, -> { joins(:collection_preference).where(collection_preferences: { moderated: true }) } + scope :unmoderated, -> { joins(:collection_preference).where(collection_preferences: { moderated: false }) } + scope :unrevealed, -> { joins(:collection_preference).where(collection_preferences: { unrevealed: true }) } + scope :anonymous, -> { joins(:collection_preference).where(collection_preferences: { anonymous: true }) } + scope :no_challenge, -> { where(challenge_type: nil) } + scope :gift_exchange, -> { where(challenge_type: "GiftExchange") } + scope :prompt_meme, -> { where(challenge_type: "PromptMeme") } + scope :name_only, -> { select("collections.name") } + scope :by_title, -> { order(:title) } + scope :for_blurb, -> { includes(:parent, :moderators, :children, :collection_preference, owners: [:user]).with_attached_icon } + + def cleanup_url + self.header_image_url = Addressable::URI.heuristic_parse(self.header_image_url) if self.header_image_url + end + + # Get only collections with running challenges + def self.signup_open(challenge_type) + case challenge_type + when "PromptMeme" + not_closed.where(challenge_type: challenge_type) + .joins("INNER JOIN prompt_memes on prompt_memes.id = challenge_id").where("prompt_memes.signup_open = 1") + .where("prompt_memes.signups_close_at > ?", Time.zone.now).order("prompt_memes.signups_close_at DESC") + when "GiftExchange" + not_closed.where(challenge_type: challenge_type) + .joins("INNER JOIN gift_exchanges on gift_exchanges.id = challenge_id").where("gift_exchanges.signup_open = 1") + .where("gift_exchanges.signups_close_at > ?", Time.zone.now).order("gift_exchanges.signups_close_at DESC") + end + end + + scope :with_name_like, lambda { |name| + where("collections.name LIKE ?", "%#{name}%") + .limit(10) + } + + scope :with_title_like, lambda { |title| + where("collections.title LIKE ?", "%#{title}%") + } + + scope :with_item_count, lambda { + select("collections.*, count(distinct collection_items.id) as item_count") + .joins("left join collections child_collections on child_collections.parent_id = collections.id + left join collection_items on ( (collection_items.collection_id = child_collections.id OR collection_items.collection_id = collections.id) + AND collection_items.user_approval_status = 1 + AND collection_items.collection_approval_status = 1)") + .group("collections.id") + } + + def to_param + name_was + end + + # Change membership of collection(s) from a particular pseud to the orphan account + def self.orphan(pseuds, collections, default: true) + pseuds.each do |pseud| + collections.each do |collection| + if pseud && collection && collection.owners.include?(pseud) + orphan_pseud = default ? User.orphan_account.default_pseud : User.orphan_account.pseuds.find_or_create_by(name: pseud.name) + pseud.change_membership(collection, orphan_pseud) + end + end + end + end + + ## AUTOCOMPLETE + # set up autocomplete and override some methods + include AutocompleteSource + + def autocomplete_search_string + "#{name} #{title}" + end + + def autocomplete_search_string_before_last_save + "#{name_before_last_save} #{title_before_last_save}" + end + + def autocomplete_prefixes + ["autocomplete_collection_all", + "autocomplete_collection_#{closed? ? 'closed' : 'open'}"] + end + + def autocomplete_score + all_items.approved_by_collection.approved_by_user.count + end + ## END AUTOCOMPLETE + + def parent_name=(name) + @parent_name = name + self.parent = Collection.find_by(name: name) + end + + def parent_name + @parent_name || (self.parent ? self.parent.name : "") + end + + def all_owners + (self.owners + (self.parent ? self.parent.owners : [])).uniq + end + + def all_moderators + (self.moderators + (self.parent ? self.parent.moderators : [])).uniq + end + + def all_members + (self.members + (self.parent ? self.parent.members : [])).uniq + end + + def all_posting_participants + (self.posting_participants + (self.parent ? self.parent.posting_participants : [])).uniq + end + + def all_participants + (self.participants + (self.parent ? self.parent.participants : [])).uniq + end + + def all_items + CollectionItem.where(collection_id: ([self.id] + self.children.pluck(:id))) + end + + def maintainers + self.all_owners + self.all_moderators + end + + def user_is_owner?(user) + user && user != false && !(user.pseuds & self.all_owners).empty? + end + + def user_is_moderator?(user) + user && user != false && !(user.pseuds & self.all_moderators).empty? + end + + def user_is_maintainer?(user) + user && user != false && !(user.pseuds & (self.all_moderators + self.all_owners)).empty? + end + + def user_is_participant?(user) + user && user != false && !get_participating_pseuds_for_user(user).empty? + end + + def user_is_posting_participant?(user) + user && user != false && !(user.pseuds & self.all_posting_participants).empty? + end + + def get_participating_pseuds_for_user(user) + (user && user != false) ? user.pseuds & self.all_participants : [] + end + + def get_participants_for_user(user) + return [] unless user + + CollectionParticipant.in_collection(self).for_user(user) + end + + def assignment_notification + self.collection_profile.assignment_notification || (parent ? parent.collection_profile.assignment_notification : "") + end + + def gift_notification + self.collection_profile.gift_notification || (parent ? parent.collection_profile.gift_notification : "") + end + + def moderated?() = self.collection_preference.moderated + + def closed?() = self.collection_preference.closed + + def unrevealed?() = self.collection_preference.unrevealed + + def anonymous?() = self.collection_preference.anonymous + + def challenge?() = !self.challenge.nil? + + def gift_exchange? + self.challenge_type == "GiftExchange" + end + + def prompt_meme? + self.challenge_type == "PromptMeme" + end + + def maintainers_list + self.maintainers.collect(&:user).flatten.uniq + end + + def collection_email + return self.email if self.email.present? + return parent.email if parent && parent.email.present? + end + + def notify_maintainers_assignments_sent + subject = I18n.t("user_mailer.collection_notification.assignments_sent.subject") + message = I18n.t("user_mailer.collection_notification.assignments_sent.complete") + if self.collection_email.present? + UserMailer.collection_notification(self.id, subject, message, self.collection_email).deliver_later + else + # if collection email is not set and collection parent email is not set, loop through maintainers and send each a notice via email + self.maintainers_list.each do |user| + I18n.with_locale(user.preference.locale_for_mails) do + translated_subject = I18n.t("user_mailer.collection_notification.assignments_sent.subject") + translated_message = I18n.t("user_mailer.collection_notification.assignments_sent.complete") + UserMailer.collection_notification(self.id, translated_subject, translated_message, user.email).deliver_later + end + end + end + end + + def notify_maintainers_challenge_default(challenge_assignment, assignments_page_url) + if self.collection_email.present? + subject = I18n.t("user_mailer.collection_notification.challenge_default.subject", offer_byline: challenge_assignment.offer_byline) + message = I18n.t("user_mailer.collection_notification.challenge_default.complete", offer_byline: challenge_assignment.offer_byline, request_byline: challenge_assignment.request_byline, assignments_page_url: assignments_page_url) + UserMailer.collection_notification(self.id, subject, message, self.collection_email).deliver_later + else + # if collection email is not set and collection parent email is not set, loop through maintainers and send each a notice via email + self.maintainers_list.each do |user| + I18n.with_locale(user.preference.locale_for_mails) do + translated_subject = I18n.t("user_mailer.collection_notification.challenge_default.subject", offer_byline: challenge_assignment.offer_byline) + translated_message = I18n.t("user_mailer.collection_notification.challenge_default.complete", offer_byline: challenge_assignment.offer_byline, request_byline: challenge_assignment.request_byline, assignments_page_url: assignments_page_url) + UserMailer.collection_notification(self.id, translated_subject, translated_message, user.email).deliver_later + end + end + end + end + + include AsyncWithResque + @queue = :collection + + def reveal! + async(:reveal_collection_items) + end + + def reveal_authors! + async(:reveal_collection_item_authors) + end + + def reveal_collection_items + approved_collection_items.each { |collection_item| collection_item.update_attribute(:unrevealed, false) } + send_reveal_notifications + end + + def reveal_collection_item_authors + approved_collection_items.each { |collection_item| collection_item.update_attribute(:anonymous, false) } + end + + def send_reveal_notifications + approved_collection_items.each(&:notify_of_reveal) + end + + def self.sorted_and_filtered(sort, filters, page) + pagination_args = { page: page } + + # build up the query with scopes based on the options the user specifies + query = Collection.top_level + + if filters[:title].present? + # we get the matching collections out of autocomplete and use their ids + ids = Collection.autocomplete_lookup(search_param: filters[:title], + autocomplete_prefix: (if filters[:closed].blank? + "autocomplete_collection_all" + else + (filters[:closed] ? "autocomplete_collection_closed" : "autocomplete_collection_open") + end)).map { |result| Collection.id_from_autocomplete(result) } + query = query.where(collections: { id: ids }) + elsif filters[:closed].present? + query = (filters[:closed] == "true" ? query.closed : query.not_closed) + end + query = (filters[:moderated] == "true" ? query.moderated : query.unmoderated) if filters[:moderated].present? + if filters[:challenge_type].present? + case filters[:challenge_type] + when "gift_exchange" + query = query.gift_exchange + when "prompt_meme" + query = query.prompt_meme + when "no_challenge" + query = query.no_challenge + end + end + query = query.order(sort).for_blurb + + if filters[:fandom].blank? + query.paginate(pagination_args) + else + fandom = Fandom.find_by_name(filters[:fandom]) + if fandom + (fandom.approved_collections & query).paginate(pagination_args) + else + [] + end + end + end + + # Delete current icon (thus reverting to archive default icon) + def delete_icon=(value) + @delete_icon = !value.to_i.zero? + end + + def delete_icon + !!@delete_icon + end + alias delete_icon? delete_icon + + def clear_icon + return unless delete_icon? + + self.icon.purge + self.icon_alt_text = nil + self.icon_comment_text = nil + end +end diff --git a/app/models/collection_item.rb b/app/models/collection_item.rb new file mode 100755 index 0000000..b542d5f --- /dev/null +++ b/app/models/collection_item.rb @@ -0,0 +1,275 @@ +class CollectionItem < ApplicationRecord + APPROVAL_OPTIONS = [ + ["", :unreviewed], + [ts("Approved"), :approved], + [ts("Rejected"), :rejected] + ] + + belongs_to :collection, inverse_of: :collection_items + belongs_to :item, polymorphic: :true, inverse_of: :collection_items, touch: true + belongs_to :work, class_name: "Work", foreign_key: "item_id", inverse_of: :collection_items + belongs_to :bookmark, class_name: "Bookmark", foreign_key: "item_id" + + validates_uniqueness_of :collection_id, scope: [:item_id, :item_type], + message: ts("already contains this item.") + + enum :user_approval_status, { + rejected: -1, + unreviewed: 0, + approved: 1 + }, suffix: :by_user + + enum :collection_approval_status, { + rejected: -1, + unreviewed: 0, + approved: 1 + }, suffix: :by_collection + + validate :collection_is_open, on: :create + def collection_is_open + if self.new_record? && self.collection && self.collection.closed? && !self.collection.user_is_maintainer?(User.current_user) + errors.add(:base, ts("The collection %{title} is not currently open.", title: self.collection.title)) + end + end + + scope :include_for_works, -> { includes(item: :pseuds) } + scope :unrevealed, -> { where(unrevealed: true) } + scope :anonymous, -> { where(anonymous: true) } + + def self.for_user(user=User.current_user) + # get ids of user's bookmarks and works + bookmark_ids = Bookmark.joins(:pseud).where("pseuds.user_id = ?", user.id).pluck(:id) + work_ids = Work.joins(:pseuds).where("pseuds.user_id = ?", user.id).pluck(:id) + # now return the relation + where("(item_id IN (?) AND item_type = 'Work') OR (item_id IN (?) AND item_type = 'Bookmark')", work_ids, bookmark_ids) + end + + scope :invited_by_collection, -> { approved_by_collection.unreviewed_by_user } + scope :approved_by_both, -> { approved_by_collection.approved_by_user } + + before_save :set_anonymous_and_unrevealed + def set_anonymous_and_unrevealed + if self.new_record? && collection + self.unrevealed = true if collection.reload.unrevealed? + self.anonymous = true if collection.reload.anonymous? + end + end + + after_save :update_work + after_destroy :update_work + + # Set associated works to anonymous or unrevealed as appropriate. + # + # Inverses are set up properly on self.item, so we use that field to check + # whether we're currently in the process of saving a brand new work, or + # whether the work is in the process of being destroyed. (In which case we + # rely on the Work's callbacks to set anon/unrevealed status properly.) But + # because we want to discard changes made in preview mode, we perform the + # actual anon/unrevealed updates on self.work, which doesn't have proper + # inverses and therefore is freshly loaded from the database. + def update_work + return unless item.is_a?(Work) && item.persisted? && !item.saved_change_to_id? + + if work.present? + work.update_anon_unrevealed + + # For a more helpful error message, raise an error saying that the work + # is invalid if we fail to save it. + raise ActiveRecord::RecordInvalid, work unless work.save(validate: false) + end + end + + # Poke the item if it's just been approved or unapproved so it gets picked up by the search index + after_update :update_item_for_status_change + def update_item_for_status_change + if saved_change_to_user_approval_status? || saved_change_to_collection_approval_status? + item.save!(validate: false) + end + end + + after_create_commit :notify_of_association + def notify_of_association + email_notify = self.collection.collection_preference && + self.collection.collection_preference.email_notify + + if email_notify && !self.collection.email.blank? + CollectionMailer.item_added_notification(item_id, collection_id, item_type).deliver_later + end + end + + after_create_commit :notify_archivist_added + # Sends emails to item creator(s) in the case that an archivist + # has added them to the collection. + def notify_archivist_added + return unless item.is_a?(Work) && User.current_user&.archivist && collection.user_is_maintainer?(User.current_user) + + item.users.each do |email_recipient| + next if email_recipient.preference.collection_emails_off + + I18n.with_locale(email_recipient.preference.locale_for_mails) do + UserMailer.archivist_added_to_collection_notification( + email_recipient.id, + item.id, + collection.id + ).deliver_later + end + end + end + + before_save :approve_automatically + def approve_automatically + return unless self.new_record? + + # approve with the current user, who is the person who has just + # added this item -- might be either moderator or owner + # rubocop:disable Lint/BooleanSymbol + approve(User.current_user == :false ? nil : User.current_user) + # rubocop:enable Lint/BooleanSymbol + + # if the collection is open or the user who owns this work is a member, go ahead and approve + # for the collection + return unless !approved_by_collection? && collection + + approve_by_collection if !collection.moderated? || collection.user_is_maintainer?(User.current_user) || collection.user_is_posting_participant?(User.current_user) + end + + before_save :send_work_invitation + def send_work_invitation + return if approved_by_user? || !approved_by_collection? || !self.new_record? || User.current_user.is_author_of?(item) + + # a maintainer is attempting to add this work to their collection + # so we send an email to all the works owners + item.users.each do |email_author| + next if email_author.preference.collection_emails_off + + I18n.with_locale(email_author.preference.locale_for_mails) do + UserMailer.invited_to_collection_notification(email_author.id, item.id, collection.id).deliver_now + end + end + end + + after_destroy :expire_caches + def expire_caches + if self.item.respond_to?(:expire_caches) + self.item.expire_caches + CacheMaster.record(item_id, 'collection', collection_id) + end + end + + attr_writer :remove + def remove + @remove || "" + end + + def recipients + item.respond_to?(:recipients) ? item.recipients : "" + end + + def item_creator_pseuds + if self.item + if self.item.respond_to?(:pseuds) + self.item.pseuds + elsif self.item.respond_to?(:pseud) + [self.item.pseud] + else + [] + end + else + [] + end + end + + def item_date + item.respond_to?(:revised_at) ? item.revised_at : item.updated_at + end + + def user_allowed_to_destroy?(user) + user.is_author_of?(self.item) || + (self.collection.user_is_maintainer?(user) && !self.rejected_by_user?) + end + + def approve_by_user + self.user_approval_status = :approved + end + + def approve_by_collection + self.collection_approval_status = :approved + end + + def approved? + approved_by_user? && approved_by_collection? + end + + def approve(user) + if user.nil? + # this is being run via rake task eg for importing collections + approve_by_user + approve_by_collection + else + author_of_item = user.is_author_of?(item) || + (user == User.current_user && item.respond_to?(:pseuds) ? item.pseuds.empty? : item.pseud.nil?) + archivist_maintainer = user.archivist && self.collection.user_is_maintainer?(user) + approve_by_user if author_of_item || archivist_maintainer + approve_by_collection if self.collection.user_is_maintainer?(user) + end + end + + def posted? + self.item.respond_to?(:posted?) ? self.item.posted? : true + end + + def notify_of_reveal + unless self.unrevealed? || !self.posted? + recipient_pseuds = Pseud.parse_bylines(self.recipients)[:pseuds] + recipient_pseuds.each do |pseud| + user_preference = pseud.user.preference + next if user_preference.recipient_emails_off + + I18n.with_locale(user_preference.locale_for_mails) do + UserMailer.recipient_notification(pseud.user.id, self.item.id, self.collection.id).deliver_after_commit + end + end + + # also notify prompters of responses to their prompt + if item_type == "Work" && !item.challenge_claims.blank? + UserMailer.prompter_notification(self.item.id, self.collection.id).deliver_after_commit + end + + # also notify the owners of any parent/inspired-by works + if item_type == "Work" && !item.parent_work_relationships.empty? + item.parent_work_relationships.each do |relationship| + relationship.notify_parent_owners + end + end + end + end + + after_update :notify_of_unrevealed_or_anonymous + def notify_of_unrevealed_or_anonymous + # This CollectionItem's anonymous/unrevealed status can only affect the + # item's status if (a) the CollectionItem is approved by the user and (b) + # the item is a work. (Bookmarks can't be anonymous/unrevealed at the + # moment.) + return unless approved_by_user? && item.is_a?(Work) + + # Check whether anonymous/unrevealed is becoming true, when the work + # currently has it set to false: + newly_anonymous = (saved_change_to_anonymous?(to: true) && !item.anonymous?) + newly_unrevealed = (saved_change_to_unrevealed?(to: true) && !item.unrevealed?) + + return unless newly_unrevealed || newly_anonymous + + # Don't notify if it's one of the work creators who is changing the work's + # status. + return if item.users.include?(User.current_user) + + item.users.each do |user| + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.anonymous_or_unrevealed_notification( + user.id, item.id, collection.id, + anonymous: newly_anonymous, unrevealed: newly_unrevealed + ).deliver_after_commit + end + end + end +end diff --git a/app/models/collection_participant.rb b/app/models/collection_participant.rb new file mode 100755 index 0000000..308980b --- /dev/null +++ b/app/models/collection_participant.rb @@ -0,0 +1,57 @@ +class CollectionParticipant < ApplicationRecord + belongs_to :pseud + has_one :user, through: :pseud + belongs_to :collection + + PARTICIPANT_ROLES = ["None", "Owner", "Moderator", "Member", "Invited"] + NONE = PARTICIPANT_ROLES[0] + OWNER = PARTICIPANT_ROLES[1] + MODERATOR = PARTICIPANT_ROLES[2] + MEMBER = PARTICIPANT_ROLES[3] + INVITED = PARTICIPANT_ROLES[4] + MAINTAINER_ROLES = [PARTICIPANT_ROLES[1], PARTICIPANT_ROLES[2]] + PARTICIPANT_ROLE_OPTIONS = [ [ts("None"), NONE], + [ts("Invited"), INVITED], + [ts("Member"), MEMBER], + [ts("Moderator"), MODERATOR], + [ts("Owner"), OWNER] ] + + validates_uniqueness_of :pseud_id, scope: [:collection_id], + message: ts("That person appears to already be a participant in that collection.") + + validates_presence_of :participant_role + validates_inclusion_of :participant_role, in: PARTICIPANT_ROLES, + message: ts("That is not a valid participant role.") + + scope :for_user, lambda {|user| + select("DISTINCT collection_participants.*"). + joins(pseud: :user). + where('users.id = ?', user.id) + } + + scope :in_collection, lambda {|collection| + select("DISTINCT collection_participants.*"). + joins(:collection). + where('collections.id = ?', collection.id) + } + + def is_owner? ; self.participant_role == OWNER ; end + def is_moderator? ; self.participant_role == MODERATOR ; end + def is_maintainer? ; is_owner? || is_moderator? ; end + def is_member? ; self.participant_role == MEMBER ; end + def is_invited? ; self.participant_role == INVITED ; end + def is_none? ; self.participant_role == NONE ; end + + def approve_membership! + self.participant_role = MEMBER + save + end + + def user_allowed_to_destroy?(user) + self.collection.user_is_maintainer?(user) || self.pseud.user == user + end + + def user_allowed_to_promote?(user, role) + (role == MEMBER || role == NONE) ? self.collection.user_is_maintainer?(user) : self.collection.user_is_owner?(user) + end +end diff --git a/app/models/collection_preference.rb b/app/models/collection_preference.rb new file mode 100755 index 0000000..54b56b3 --- /dev/null +++ b/app/models/collection_preference.rb @@ -0,0 +1,15 @@ +class CollectionPreference < ApplicationRecord + belongs_to :collection + after_update :after_update + + def after_update + if self.collection.valid? && self.valid? + if self.saved_change_to_unrevealed? && !self.unrevealed? + self.collection.reveal! + end + if self.saved_change_to_anonymous? && !self.anonymous? + collection.reveal_authors! + end + end + end +end diff --git a/app/models/collection_profile.rb b/app/models/collection_profile.rb new file mode 100755 index 0000000..7b6443d --- /dev/null +++ b/app/models/collection_profile.rb @@ -0,0 +1,24 @@ +class CollectionProfile < ApplicationRecord + belongs_to :collection + + validates_length_of :intro, + allow_blank: true, + maximum: ArchiveConfig.INFO_MAX, too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.INFO_MAX) + + validates_length_of :faq, + allow_blank: true, + maximum: ArchiveConfig.INFO_MAX, too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.INFO_MAX) + + validates_length_of :rules, + allow_blank: true, + maximum: ArchiveConfig.INFO_MAX, too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.INFO_MAX) + + validates_length_of :assignment_notification, + allow_blank: true, + maximum: ArchiveConfig.SUMMARY_MAX, too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.SUMMARY_MAX) + + validates_length_of :gift_notification, + allow_blank: true, + maximum: ArchiveConfig.SUMMARY_MAX, too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.SUMMARY_MAX) + +end diff --git a/app/models/comment.rb b/app/models/comment.rb new file mode 100755 index 0000000..ad6ff4c --- /dev/null +++ b/app/models/comment.rb @@ -0,0 +1,555 @@ +class Comment < ApplicationRecord + include HtmlCleaner + include AfterCommitEverywhere + + belongs_to :pseud + belongs_to :commentable, polymorphic: true + belongs_to :parent, polymorphic: true + + has_many :inbox_comments, foreign_key: 'feedback_comment_id', dependent: :destroy + has_many :users, through: :inbox_comments + + has_many :reviewed_replies, -> { reviewed }, + class_name: "Comment", as: :commentable, inverse_of: :commentable + + has_many :thread_comments, class_name: 'Comment', foreign_key: :thread + + validates :name, presence: { unless: :pseud_id }, not_forbidden_name: { if: :will_save_change_to_name? } + validates :email, email_format: { on: :create, unless: :pseud_id }, email_blacklist: { on: :create, unless: :pseud_id } + + validates_presence_of :comment_content + validates_length_of :comment_content, + maximum: ArchiveConfig.COMMENT_MAX, + too_long: ts("must be less than %{count} characters long.", count: ArchiveConfig.COMMENT_MAX) + + delegate :user, to: :pseud, allow_nil: true + + # Whether the writer of the comment this is replying to allows guest replies + validate :guest_can_reply, if: :reply_comment?, unless: :pseud_id, on: :create + def guest_can_reply + errors.add(:commentable, :guest_replies_off) if commentable.guest_replies_disallowed? + end + + # Whether the writer of this comment disallows guest replies + def guest_replies_disallowed? + return false unless user + + user.preference.guest_replies_off && !user.is_author_of?(ultimate_parent) + end + + # Check if the writer of this comment is blocked by the writer of the comment + # they're replying to: + validates :user, not_blocked: { + by: :commentable, + if: :reply_comment?, + unless: :on_tag?, + message: :blocked_reply + } + + # Check if the writer of this comment is blocked by one of the creators of + # the work they're replying to: + validates :user, not_blocked: { + by: :ultimate_parent, + unless: :on_tag?, + message: :blocked_comment + } + + def on_tag? + parent_type == "Tag" + end + + def by_anonymous_creator? + ultimate_parent.try(:anonymous?) && user&.is_author_of?(ultimate_parent) + end + + validate :check_for_spam, on: :create + + def check_for_spam + self.approved = skip_spamcheck? || !spam? + + errors.add(:base, :spam) unless approved + end + + validate :edited_spam, on: :update, if: [:will_save_change_to_edited_at?, :will_save_change_to_comment_content?] + + def edited_spam + return if skip_spamcheck? || !content_too_different?(comment_content, comment_content_in_database, ArchiveConfig.EDITED_COMMENT_SPAM_CHECK_THRESHOLD) + + errors.add(:base, :spam) if spam? + end + + validates :comment_content, uniqueness: { + scope: [:commentable_id, :commentable_type, :name, :email, :pseud_id], + unless: :is_deleted?, + message: :duplicate_comment + } + + scope :ordered_by_date, -> { order('created_at DESC') } + scope :top_level, -> { where.not(commentable_type: "Comment") } + scope :include_pseud, -> { includes(:pseud) } + scope :not_deleted, -> { where(is_deleted: false) } + scope :reviewed, -> { where(unreviewed: false) } + scope :unreviewed_only, -> { where(unreviewed: true) } + + scope :for_display, lambda { + includes( + pseud: { user: [:roles, :block_of_current_user, :block_by_current_user, :preference] }, + parent: { work: [:pseuds, :users] } + ).merge(Pseud.with_attached_icon) + } + + # Gets methods and associations from acts_as_commentable plugin + acts_as_commentable + has_comment_methods + + def akismet_attributes + # While we do have tag comments, those are from logged-in users with special + # access granted by admins, so we never spam check them, unlike comments on + # works or admin posts. + comment_type = ultimate_parent.is_a?(Work) ? "fanwork-comment" : "comment" + + if pseud_id.nil? + user_role = "guest" + comment_author = name + else + user_role = "user" + comment_author = user.login + end + + attributes = { + comment_type: comment_type, + key: ArchiveConfig.AKISMET_KEY, + blog: ArchiveConfig.AKISMET_NAME, + user_ip: ip_address, + user_agent: user_agent, + user_role: user_role, + comment_author: comment_author, + comment_author_email: comment_owner_email, + comment_content: comment_content + } + + attributes[:recheck_reason] = "edit" if will_save_change_to_edited_at? && will_save_change_to_comment_content? + + attributes + end + + after_create :expire_parent_comments_count + after_update :expire_parent_comments_count, if: :saved_change_to_visibility? + after_destroy :expire_parent_comments_count + def expire_parent_comments_count + after_commit { parent&.expire_comments_count } + end + + def saved_change_to_visibility? + pertinent_attributes = %w[is_deleted hidden_by_admin unreviewed approved] + (saved_changes.keys & pertinent_attributes).present? + end + + before_validation :set_parent_and_unreviewed, on: :create + + before_create :set_depth + before_create :set_thread_for_replies + before_create :set_parent_and_unreviewed + after_create :update_thread + before_create :adjust_threading, if: :reply_comment? + + after_create :update_work_stats + after_destroy :update_work_stats + + # If a comment has changed too much, we might need to put it back in moderation: + before_update :recheck_unreviewed + def recheck_unreviewed + return unless edited_at_changed? && + comment_content_changed? && + moderated_commenting_enabled? && + !is_creator_comment? && + content_too_different?(comment_content, comment_content_was, ArchiveConfig.COMMENT_MODERATION_THRESHOLD) + + self.unreviewed = true + end + + after_update :after_update + def after_update + users = [] + + if self.saved_change_to_edited_at? || (self.saved_change_to_unreviewed? && !self.unreviewed?) + # Reply to owner of parent comment if this is a reply comment + # Potentially we are notifying the original commenter of a newly-approved reply to their comment + if (parent_comment_owner = notify_parent_comment_owner) + users << parent_comment_owner + end + end + + if self.saved_change_to_edited_at? + # notify the commenter + if self.comment_owner && notify_user_of_own_comments?(self.comment_owner) + users << self.comment_owner + end + if notify_user_by_email?(self.comment_owner) && notify_user_of_own_comments?(self.comment_owner) + if self.reply_comment? + CommentMailer.comment_reply_sent_notification(self).deliver_after_commit + else + CommentMailer.comment_sent_notification(self).deliver_after_commit + end + end + + # send notification to the owner(s) of the ultimate parent, who can be users or admins + # at this point, users contains those who've already been notified + if users.empty? + users = self.ultimate_parent.commentable_owners + else + # replace with the owners of the commentable who haven't already been notified + users = self.ultimate_parent.commentable_owners - users + end + users.each do |user| + unless user == self.comment_owner && !notify_user_of_own_comments?(user) + if notify_user_by_email?(user) || self.ultimate_parent.is_a?(Tag) + CommentMailer.edited_comment_notification(user, self).deliver_after_commit + end + if user.is_a?(User) && notify_user_by_inbox?(user) + update_feedback_in_inbox(user) + end + end + end + end + end + + after_create :after_create + def after_create + self.reload + # eventually we will set the locale to the user's stored language of choice + #Locale.set ArchiveConfig.SUPPORTED_LOCALES[ArchiveConfig.DEFAULT_LOCALE] + users = [] + + # notify the commenter + if self.comment_owner && notify_user_of_own_comments?(self.comment_owner) + users << self.comment_owner + end + if notify_user_by_email?(self.comment_owner) && notify_user_of_own_comments?(self.comment_owner) + if self.reply_comment? + CommentMailer.comment_reply_sent_notification(self).deliver_after_commit + else + CommentMailer.comment_sent_notification(self).deliver_after_commit + end + end + + # Reply to owner of parent comment if this is a reply comment + if (parent_comment_owner = notify_parent_comment_owner) + users << parent_comment_owner + end + + # send notification to the owner(s) of the ultimate parent, who can be users or admins + # at this point, users contains those who've already been notified + if users.empty? + users = self.ultimate_parent.commentable_owners + else + # replace with the owners of the commentable who haven't already been notified + users = self.ultimate_parent.commentable_owners - users + end + users.each do |user| + unless user == self.comment_owner && !notify_user_of_own_comments?(user) + if notify_user_by_email?(user) || self.ultimate_parent.is_a?(Tag) + CommentMailer.comment_notification(user, self).deliver_after_commit + end + if user.is_a?(User) && notify_user_by_inbox?(user) + add_feedback_to_inbox(user) + end + end + end + end + + after_create :record_wrangling_activity, if: :on_tag? + def record_wrangling_activity + self.comment_owner&.update_last_wrangling_activity + end + + protected + + def notify_user_of_own_comments?(user) + if user.nil? || user == User.orphan_account + false + elsif user.is_a?(Admin) + true + else + !user.preference.comment_copy_to_self_off? + end + end + + def notify_user_by_inbox?(user) + if user.nil? || user == User.orphan_account + false + elsif user.is_a?(Admin) + true + else + !user.preference.comment_inbox_off? + end + end + + def notify_user_by_email?(user) + if user.nil? || user == User.orphan_account + false + elsif user.is_a?(Admin) + true + else + !user.preference.comment_emails_off? + end + end + + def update_feedback_in_inbox(user) + if (edited_feedback = user.inbox_comments.find_by(feedback_comment_id: self.id)) + edited_feedback.update_attribute(:read, false) + else # original inbox comment was deleted + add_feedback_to_inbox(user) + end + end + + def add_feedback_to_inbox(user) + new_feedback = user.inbox_comments.build + new_feedback.feedback_comment_id = self.id + new_feedback.save + end + + def content_too_different?(new_content, old_content, threshold) + # we added more than the threshold # of chars, just return + return true if new_content.length > (old_content.length + threshold) + + # quick and dirty iteration to compare the two strings + cost = 0 + new_i = 0 + old_i = 0 + while new_i < new_content.length && old_i < old_content.length + if new_content[new_i] == old_content[old_i] + new_i += 1 + old_i += 1 + next + end + + cost += 1 + # interrupt as soon as we have changed > threshold chars + return true if cost > threshold + + # peek ahead to see if we can catch up on either side eg if a letter has been inserted/deleted + if new_content[new_i + 1] == old_content[old_i] + new_i += 1 + elsif new_content[new_i] == old_content[old_i + 1] + old_i += 1 + else + # just keep going + new_i += 1 + old_i += 1 + end + end + + cost > threshold + end + + def not_user_commenter?(parent_comment) + (!parent_comment.comment_owner && parent_comment.comment_owner_email && parent_comment.comment_owner_name) + end + + def different_owner?(parent_comment) + not_user_commenter?(parent_comment) || (parent_comment.comment_owner != self.comment_owner) + end + + def notify_parent_comment_owner + return unless self.reply_comment? && !self.unreviewed? + + parent_comment = self.commentable + parent_comment_owner = parent_comment.comment_owner # will be nil if not a user, including if an admin + + # if I'm replying to a comment you left for me, mark your comment as replied to in my inbox + if self.comment_owner && (inbox_comment = self.comment_owner.inbox_comments.find_by(feedback_comment_id: parent_comment.id)) + inbox_comment.update(replied_to: true, read: true) + end + + return unless different_owner?(parent_comment) + + # Never notify people who are not tag wranglers (any more) about comments on tags + return if self.ultimate_parent.is_a?(Tag) && !parent_comment_owner&.is_tag_wrangler? + + # send notification to the owner of the original comment if they're not the same as the commenter + if !parent_comment_owner || notify_user_by_email?(parent_comment_owner) || self.ultimate_parent.is_a?(Tag) + if self.saved_change_to_edited_at? + CommentMailer.edited_comment_reply_notification(parent_comment, self).deliver_after_commit + else + CommentMailer.comment_reply_notification(parent_comment, self).deliver_after_commit + end + end + + if parent_comment_owner && notify_user_by_inbox?(parent_comment_owner) + if self.saved_change_to_edited_at? + update_feedback_in_inbox(parent_comment_owner) + else + add_feedback_to_inbox(parent_comment_owner) + end + end + + parent_comment_owner + end + + public + + # Set the depth of the comment: 0 for a first-class comment, increasing with each level of nesting + def set_depth + self.depth = self.reply_comment? ? self.commentable.depth + 1 : 0 + end + + # The thread value for a reply comment should be the same as its parent comment + def set_thread_for_replies + self.thread = self.commentable.thread if self.reply_comment? + end + + # Save the ultimate parent and reviewed status + def set_parent_and_unreviewed + self.parent = self.reply_comment? ? self.commentable.parent : self.commentable + # we only mark comments as unreviewed if moderated commenting is enabled on their parent + self.unreviewed = self.parent.respond_to?(:moderated_commenting_enabled?) && + self.parent.moderated_commenting_enabled? && + !User.current_user.try(:is_author_of?, self.ultimate_parent) + true + end + + # is this a comment by the creator of the ultimate parent + def is_creator_comment? + pseud && pseud.user && pseud.user.try(:is_author_of?, ultimate_parent) + end + + def moderated_commenting_enabled? + parent.respond_to?(:moderated_commenting_enabled?) && parent.moderated_commenting_enabled? + end + + # We need a unique thread id for replies, so we'll make use of the fact + # that ids are unique + def update_thread + self.update_attribute(:thread, self.id) unless self.thread + end + + def adjust_threading + self.commentable.add_child(self) + end + + # Is this a first-class comment? + def top_level? + !self.reply_comment? + end + + def comment_owner + self.pseud.try(:user) + end + + def comment_owner_name + self.pseud.try(:name) || self.name + end + + def comment_owner_email + comment_owner.try(:email) || self.email + end + + # override this method from commentable_entity.rb + # to return the name of the ultimate parent this is on + # we have to do this somewhat roundabout because until the comment is + # set and saved, the ultimate_parent method will not work (the thread is not set) + # and this is being called from before then. + def commentable_name + self.reply_comment? ? self.commentable.ultimate_parent.commentable_name : self.commentable.commentable_name + end + + # override this method from comment_methods.rb to return ultimate + alias :original_ultimate_parent :ultimate_parent + def ultimate_parent + myparent = self.original_ultimate_parent + myparent.kind_of?(Chapter) ? myparent.work : myparent + end + + def self.commentable_object(commentable) + commentable.kind_of?(Work) ? commentable.last_posted_chapter : commentable + end + + def find_all_comments + self.all_children + end + + def count_all_comments + self.children_count + end + + def count_visible_comments + self.children_count #FIXME + end + + def skip_spamcheck? + return false unless pseud_id + + on_tag? || !user.should_spam_check_comments? || is_creator_comment? + end + + def spam? + return false unless %w[staging production].include?(Rails.env) + + Akismetor.spam?(akismet_attributes) + end + + def submit_spam + Rails.env.production? && Akismetor.submit_spam(akismet_attributes) + end + + def submit_ham + Rails.env.production? && Akismetor.submit_ham(akismet_attributes) + end + + def mark_as_spam! + update_attribute(:approved, false) + submit_spam + end + + def mark_as_ham! + update_attribute(:approved, true) + submit_ham + end + + # Freeze single comment. + def mark_frozen! + update_attribute(:iced, true) + end + + # Freeze all comments. + def self.mark_all_frozen!(comments) + transaction do + comments.each(&:mark_frozen!) + end + end + + # Unfreeze single comment. + def mark_unfrozen! + update_attribute(:iced, false) + end + + # Unfreeze all comments. + def self.mark_all_unfrozen!(comments) + transaction do + comments.each(&:mark_unfrozen!) + end + end + + def mark_hidden! + update_attribute(:hidden_by_admin, true) + end + + def mark_unhidden! + update_attribute(:hidden_by_admin, false) + end + + def sanitized_content + sanitize_field(self, :comment_content, image_safety_mode: use_image_safety_mode?) + end + + def sanitized_mailer_content + sanitize_field(self, :comment_content, image_safety_mode: true) + end + + def use_image_safety_mode? + pseud_id.nil? || hidden_by_admin || parent_type.in?(ArchiveConfig.PARENTS_WITH_IMAGE_SAFETY_MODE) + end + + include Responder +end diff --git a/app/models/common_tagging.rb b/app/models/common_tagging.rb new file mode 100755 index 0000000..0a88f04 --- /dev/null +++ b/app/models/common_tagging.rb @@ -0,0 +1,96 @@ +# This class represents parent-child relationships between tags +# It should probably be renamed "ChildTagging" and have the flip tagging called "ParentTagging"? +# Also it doesn't need to be polymorphic -- in practice, all the types are Tag +# -- NN 11/2012 +# Because I never understand without looking at one in the database: common_tag +# is the child tag and filterable is the parent tag. +# -- Sarken 01/2019 +class CommonTagging < ApplicationRecord + include Wrangleable + + # we need "touch" here so that when a common tagging changes, the tag(s) themselves are updated and + # they get noticed by the tag sweeper (which then updates their autocomplete data) + belongs_to :common_tag, class_name: 'Tag', touch: true + belongs_to :filterable, polymorphic: true, touch: true + + validates_presence_of :common_tag, :filterable, message: "does not exist." + validates_uniqueness_of :common_tag_id, scope: :filterable_id + + after_create :update_wrangler + after_create :inherit_parents + after_create :remove_uncategorized_media + after_create :add_to_autocomplete + + before_destroy :remove_from_autocomplete + + after_commit :update_search + + def update_wrangler + unless User.current_user.nil? + common_tag.update!(last_wrangler: User.current_user) + end + end + + def add_to_autocomplete + return unless filterable.is_a?(Fandom) && common_tag.eligible_for_fandom_autocomplete? + + common_tag.add_to_fandom_autocomplete(filterable) + end + + def remove_from_autocomplete + return unless filterable.is_a?(Fandom) && common_tag&.was_eligible_for_fandom_autocomplete? + + common_tag.remove_from_fandom_autocomplete(filterable) + end + + # A relationship should inherit its characters' fandoms + def inherit_parents + if common_tag.is_a?(Relationship) && filterable.is_a?(Character) + filterable.fandoms.each do |fandom| + common_tag.add_association(fandom) + end + end + end + + validate :check_canonical_filterable, :check_compatible_types + + # The parent tag must always be canonical. + def check_canonical_filterable + return if filterable.nil? || filterable.canonical + errors.add(:base, "Parent tag is not canonical.") + end + + # The child tag must have a type compatible with the parent tag. + def check_compatible_types + return if filterable.nil? || common_tag.nil? + return if filterable.child_types.include?(common_tag.type) + + errors.add(:base, "A tag of type #{filterable.type} cannot have a child " \ + "of type #{common_tag.type}.") + end + + # Make sure that our fandoms lose the Uncategorized media as soon as they're + # assigned to a particular medium. + def remove_uncategorized_media + return unless common_tag.is_a?(Fandom) && filterable.is_a?(Media) + return if common_tag.medias.count < 2 + common_tag.common_taggings.where(filterable: Media.uncategorized).destroy_all + end + + # If a tag's parent changes, reindex immediately to update unwrangled bins. + def update_search + common_tag&.reindex_document + end + + # Go through all CommonTaggings and destroy the invalid ones. + def self.destroy_invalid + includes(:common_tag, :filterable).find_each do |ct| + valid = ct.valid? + + # Let callers do something on each iteration. + yield ct, valid if block_given? + + ct.destroy unless valid + end + end +end diff --git a/app/models/concerns/async_with_active_job.rb b/app/models/concerns/async_with_active_job.rb new file mode 100755 index 0000000..f470343 --- /dev/null +++ b/app/models/concerns/async_with_active_job.rb @@ -0,0 +1,17 @@ +# A concern defining the async/async_after_commit functions, which allow +# instance methods on an object to be used as ActiveJobs. +module AsyncWithActiveJob + extend ActiveSupport::Concern + + included do + class_attribute :async_job_class, default: InstanceMethodJob + end + + def async(*args, job_class: async_job_class, **kwargs) + job_class.perform_later(self, *args, **kwargs) + end + + def async_after_commit(*args, job_class: async_job_class, **kwargs) + job_class.perform_after_commit(self, *args, **kwargs) + end +end diff --git a/app/models/concerns/async_with_resque.rb b/app/models/concerns/async_with_resque.rb new file mode 100755 index 0000000..8549bcd --- /dev/null +++ b/app/models/concerns/async_with_resque.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# A module used to make it easy to call asynchronous methods on ActiveRecord +# objects (both on the class and on the instance). +module AsyncWithResque + extend ActiveSupport::Concern + include AfterCommitEverywhere + + # The instance version of the async function. Uses perform_on_instance so + # that we can use the same perform() function for instance methods and class + # methods. + def async(method, *args) + self.class.async(:perform_on_instance, id, method, *args) + end + + class_methods do + # The class version of the async function. Uses base_class so that we + # handle subclasses properly. + def async(method, *args) + Resque.enqueue(base_class, method, *args) + end + + # Actually perform the delayed action. + def perform(method, *args) + if method.is_a?(Integer) + # TODO: For backwards compatibility, if the "method" is an integer, we + # treat it like an ID and use perform_on_instance instead. But once all + # of the jobs in the queue have been processed (or deleted), we should + # be able to remove this check. + perform_on_instance(method, *args) + else + send(method, *args) + end + end + + # Find the instance with the given ID, and call the method on it instead. + # This function allows us to use the same perform() function for both class + # functions and instance functions. + def perform_on_instance(id, method, *args) + find(id).send(method, *args) + end + end + + # A function that can be used to help with stale data issues. Instead of + # immediately adding the desired action to the Resque queue the way that + # async() does, it uses AfterCommitEverywhere to call async() after the + # commit has gone through. + def async_after_commit(*args) + after_commit do + async(*args) + end + end +end diff --git a/app/models/concerns/creatable.rb b/app/models/concerns/creatable.rb new file mode 100755 index 0000000..dab9dbb --- /dev/null +++ b/app/models/concerns/creatable.rb @@ -0,0 +1,228 @@ +# frozen_string_literal: true + +# A module used for classes that can appear as the "creation" in a Creatorship +# (i.e. Work, Series, and Chapter). +module Creatable + extend ActiveSupport::Concern + + included do + has_many :creatorships, + autosave: true, + as: :creation, + inverse_of: :creation + + has_many :approved_creatorships, + -> { Creatorship.approved }, + class_name: "Creatorship", + as: :creation, + inverse_of: :creation + + has_many :pseuds, + through: :approved_creatorships, + before_add: :disallow_pseud_changes, + before_remove: :disallow_pseud_changes + + has_many :users, + -> { distinct }, + through: :pseuds + + attr_reader :current_user_pseuds + + validate :check_no_creators + validate :check_current_user_pseuds + after_save :update_current_user_pseuds + after_destroy :destroy_creatorships + end + + ######################################## + # CALLBACKS & VALIDATIONS + ######################################## + + # Updating pseuds directly goes through the approved_creatorships relation, + # so it will automatically approve any pseuds added in this way. So we want + # to make sure that this is a read-only relation. + def disallow_pseud_changes(*) + raise "Cannot add or remove pseuds through the pseuds association!" + end + + # Make sure that there will be at least one approved creator after saving: + def check_no_creators + return if @current_user_pseuds.present? || pseuds_after_saving.any? + + errors.add(:base, ts("%{type} must have at least one creator.", + type: model_name.human)) + end + + # Make sure that if @current_user_pseuds is not nil, then the user has + # selected at least one pseud, and that all of the pseuds they've selected + # are their own. + def check_current_user_pseuds + return unless @current_user_pseuds && User.current_user.is_a?(User) + + if @current_user_pseuds.empty? + errors.add(:base, ts("You haven't selected any pseuds for this %{type}.", + type: model_name.human.downcase)) + end + + if @current_user_pseuds.any? { |p| p.user_id != User.current_user.id } + errors.add(:base, ts("You're not allowed to use that pseud.")) + end + end + + # The variable @current_user_pseuds stores which pseuds the current editor + # wants to use on this work. The pseuds should contain only pseuds owned by + # User.current_user. + def update_current_user_pseuds + return unless @current_user_pseuds + + set_current_user_pseuds(@current_user_pseuds) + @current_user_pseuds = nil + end + + # Clean up all creatorships associated with this item. + def destroy_creatorships + creatorships.destroy_all + end + + ######################################## + # VIRTUAL ATTRIBUTES + ######################################## + + # Update all creator-related attributes. + def author_attributes=(attributes) + self.new_bylines = attributes[:byline] if attributes[:byline].present? + self.new_co_creator_ids = attributes[:coauthors] if attributes[:coauthors].present? + self.current_user_pseud_ids = attributes[:ids] if attributes[:ids].present? + end + + # Invite new co-creators by passing in their byline. + def new_bylines=(bylines) + bylines.split(",").reject(&:blank?).map(&:strip).each do |byline| + self.creatorships.build(byline: byline, enable_notifications: true) + end + end + + # Invite new co-creators by ID. + def new_co_creator_ids=(ids) + new_pseuds = Pseud.where(id: ids).to_a + + creatorships.each do |creatorship| + if new_pseuds.include?(creatorship.pseud) + new_pseuds.delete(creatorship.pseud) + end + end + + new_pseuds.each do |pseud| + self.creatorships.build(pseud: pseud, enable_notifications: true) + end + end + + # Update which of User.current_user's pseuds should be listed on the byline + # after saving. + def current_user_pseud_ids=(ids) + return unless User.current_user.is_a?(User) + + @current_user_pseuds = Pseud.where(id: ids).to_a + end + + # This behaves very similarly to new_bylines=, but because it's designed to + # be used for bulk editing works, it doesn't handle ambiguous pseuds well. So + # we need to manually refine our guess as much as possible. + def pseuds_to_add=(pseud_names) + names = pseud_names.split(",").reject(&:blank?).map(&:strip) + + names.each do |name| + possible_pseuds = Pseud.parse_byline_ambiguous(name) + + pseud = if possible_pseuds.size > 1 + Pseud.parse_byline(name) + else + possible_pseuds.first + end + + if pseud + creatorship = creatorships.find_or_initialize_by(pseud: pseud) + creatorship.enable_notifications = true + end + end + end + + ######################################## + # USEFUL FUNCTIONS + ######################################## + + # Update the pseuds on this item so that User.current_user's pseuds are + # replaced by the passed-in array of pseuds new_pseuds. If it's a Series, we + # also update the user's byline on any owned works in the series. If it's a + # Work, we also update the user's byline on any owned chapters in the series. + def set_current_user_pseuds(new_pseuds) + return unless User.current_user.is_a?(User) + + user_id = User.current_user.id + + children = if is_a?(Work) + chapters.to_a + elsif is_a?(Series) + works.to_a + else + [] + end + + transaction do + children.each do |child| + next unless child.users.include?(User.current_user) + child.set_current_user_pseuds(new_pseuds) + end + + # Create before destroying, so that we don't run into issues with + # deleting the very last creator. + new_pseuds.each do |pseud| + creatorships.approve_or_create_by(pseud: pseud) + end + + creatorships.each do |creatorship| + creatorship.destroy unless new_pseuds.include?(creatorship.pseud) || + creatorship.pseud&.user_id != user_id + end + end + end + + # Figure out which creatorships will exist after saving. + # + # Excludes creatorships with a missing pseud, because those orphaned + # creatorships can break various bits of code if they're considered valid. + def creatorships_after_saving + creatorships.select(&:valid?).reject(&:marked_for_destruction?). + reject { |creatorship| creatorship.pseud.nil? } + end + + # Calculate what the pseuds on this work will be after saving, taking into + # account validity, approval, and @current_user_pseuds. + def pseuds_after_saving + pseuds = creatorships_after_saving.select(&:approved?).map(&:pseud) + + if @current_user_pseuds + pseuds = (pseuds - User.current_user.pseuds) + @current_user_pseuds + end + + pseuds.uniq + end + + # Check whether the passed-in user has been invited to become a creator. + def user_has_creator_invite?(user) + return false unless user.is_a?(User) + creatorships.unapproved.for_user(user).exists? + end + + # Check whether the given user has some kind of creatorship (approved or + # unapproved) associated with this item. + def user_is_owner_or_invited?(user) + return false unless user.is_a?(User) + creatorships.for_user(user).exists? + end + + # Get all orphan_account pseuds that (co-)created this creatable, excluding the orphan_account's default_pseud + def orphan_pseuds + self.pseuds.where(user_id: User.orphan_account.id, is_default: false) + end +end diff --git a/app/models/concerns/filterable.rb b/app/models/concerns/filterable.rb new file mode 100755 index 0000000..bf7f061 --- /dev/null +++ b/app/models/concerns/filterable.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +# A module for types that are supposed to have FilterTaggings, calculated based +# on their tags. Includes Taggable. +module Filterable + extend ActiveSupport::Concern + include Taggable + + included do + has_many :filter_taggings, as: :filterable, inverse_of: :filterable + has_many :filters, through: :filter_taggings + + has_many :direct_filter_taggings, + -> { where(inherited: false) }, + class_name: "FilterTagging", + as: :filterable + has_many :direct_filters, + source: :filter, + through: :direct_filter_taggings + end + + # Update filters for this particular filterable. + def update_filters + FilterUpdater.new(self.class.base_class, [id], :main).update + end + + class_methods do + # Update the filters for all filterables in this relation. + def update_filters(async_update: false, + reindex_queue: :background, + job_queue: :utilities) + batch_size = ArchiveConfig.FILTER_UPDATE_BATCH_SIZE + + select(:id).find_in_batches(batch_size: batch_size) do |batch| + updater = FilterUpdater.new(base_class, batch.map(&:id), reindex_queue) + + if async_update + updater.async_update(job_queue: job_queue) + else + updater.update + end + + # Allow for progress messages in long-running updates. + yield if block_given? + end + end + + # This is the callback that gets called when FilterUpdater is done with a + # single batch of Filterables of this type. Designed to reindex all of the + # Filterables whose filters changed. It's called in after_commit, to + # minimize issues with stale data. + # + # The _ids argument isn't used here, but is used in some of the subclasses. + def reindex_for_filter_changes(_ids, filter_taggings, queue) + changed_ids = filter_taggings.map(&:filterable_id) + IndexQueue.enqueue_ids(base_class, changed_ids, queue) + end + end + + ################ + # SEARCH + ################ + + # Simple name to make it easier for people to use in full-text search + def tag + (tags.pluck(:name) + filters.pluck(:name)).uniq + end + + # Index all the filters for pulling works + def filter_ids + (tags.pluck(:id) + filters.pluck(:id)).uniq + end + + # Index only direct filters (non meta-tags) for facets + def filters_for_facets + @filters_for_facets ||= direct_filters.to_a + end + + def rating_ids + filters_for_facets.select { |t| t.type == "Rating" }.map(&:id) + end + + def archive_warning_ids + filters_for_facets.select { |t| t.type == "ArchiveWarning" }.map(&:id) + end + + def category_ids + filters_for_facets.select { |t| t.type == "Category" }.map(&:id) + end + + def fandom_ids + filters_for_facets.select { |t| t.type == "Fandom" }.map(&:id) + end + + def character_ids + filters_for_facets.select { |t| t.type == "Character" }.map(&:id) + end + + def relationship_ids + filters_for_facets.select { |t| t.type == "Relationship" }.map(&:id) + end + + def freeform_ids + filters_for_facets.select { |t| t.type == "Freeform" }.map(&:id) + end +end diff --git a/app/models/concerns/globalized.rb b/app/models/concerns/globalized.rb new file mode 100755 index 0000000..7c41ff1 --- /dev/null +++ b/app/models/concerns/globalized.rb @@ -0,0 +1,13 @@ +module Globalized + extend ActiveSupport::Concern + + included do + validate :check_locale + end + + def check_locale + return if Locale.exists?(iso: locale) + + globalized_model.errors.add(:base, ts("The locale %{name} does not exist.", name: locale)) + end +end diff --git a/app/models/concerns/justifiable.rb b/app/models/concerns/justifiable.rb new file mode 100755 index 0000000..bf4a0b3 --- /dev/null +++ b/app/models/concerns/justifiable.rb @@ -0,0 +1,70 @@ +module Justifiable + extend ActiveSupport::Concern + + included do + attr_accessor :ticket_number + attr_reader :ticket_url + + before_validation :strip_octothorpe + validates :ticket_number, + presence: true, + # i18n-tasks-use t("activerecord.errors.messages.numeric_with_optional_hash") + numericality: { only_integer: true, + message: :numeric_with_optional_hash }, + if: :justification_enabled? + + validate :ticket_number_exists_in_tracker, if: :justification_enabled? + end + + private + + def strip_octothorpe + return if ticket_number.is_a?(Integer) + + self.ticket_number = self.ticket_number.delete_prefix("#") unless self.ticket_number.nil? + end + + def justification_enabled? + # Only require a ticket if the record has been changed by an admin. + User.current_user.is_a?(Admin) && changed? + end + + def ticket_number_exists_in_tracker + # Skip ticket lookup if the previous validations fail. + return if errors.present? + + if ticket.blank? + errors.add(:ticket_number, :required) + return + end + + # The ticket must not be closed. + if ticket["status"].blank? || ticket["status"] == "Closed" + errors.add(:ticket_number, :closed_ticket) + return + end + + # The admin must have the role matching the ticket's department. + if admin_can_use_abuse_ticket? || admin_can_use_support_ticket? + @ticket_url = ticket["webUrl"] + else + errors.add(:ticket_number, :invalid_department) + end + end + + def admin_can_use_abuse_ticket? + (User.current_user.roles & %w[policy_and_abuse superadmin]).present? && ticket["departmentId"] == ArchiveConfig.ABUSE_ZOHO_DEPARTMENT_ID + end + + def admin_can_use_support_ticket? + (User.current_user.roles & %w[superadmin support]).present? && ticket["departmentId"] == ArchiveConfig.SUPPORT_ZOHO_DEPARTMENT_ID + end + + def ticket + @ticket ||= zoho_resource_client.find_ticket(ticket_number) + end + + def zoho_resource_client + @zoho_resource_client ||= ZohoResourceClient.new(access_token: ZohoAuthClient.new.access_token) + end +end diff --git a/app/models/concerns/password_resets_limitable.rb b/app/models/concerns/password_resets_limitable.rb new file mode 100755 index 0000000..350c753 --- /dev/null +++ b/app/models/concerns/password_resets_limitable.rb @@ -0,0 +1,46 @@ +module PasswordResetsLimitable + extend ActiveSupport::Concern + + included do + def password_resets_remaining + return ArchiveConfig.PASSWORD_RESET_LIMIT unless self.last_reset_within_cooldown? + + limit_delta = ArchiveConfig.PASSWORD_RESET_LIMIT - self.resets_requested + limit_delta.positive? ? limit_delta : 0 + end + + def password_resets_limit_reached? + password_resets_remaining.zero? + end + + def password_resets_available_time + self.reset_password_sent_at + ArchiveConfig.PASSWORD_RESET_COOLDOWN_HOURS.hours + end + + def update_password_resets_requested + if self.resets_requested.positive? && !self.last_reset_within_cooldown? + self.resets_requested = 1 + else + self.resets_requested += 1 + end + end + + protected + + # Resets the resets_requested count to the default value -- zero -- when a user successfully _completes_ + # the reset process. This extends the existing Devise method, which sets `reset_password_sent_at` to `nil`. + # If we don't also reset `resets_requested`, we will not know whether the number of resets means further + # reset requests should be limited or not. + def clear_reset_password_token + super + self.resets_requested = 0 + end + end + + private + + def last_reset_within_cooldown? + self.reset_password_sent_at.present? && + self.reset_password_sent_at > ArchiveConfig.PASSWORD_RESET_COOLDOWN_HOURS.hours.ago + end +end diff --git a/app/models/concerns/taggable.rb b/app/models/concerns/taggable.rb new file mode 100755 index 0000000..1538646 --- /dev/null +++ b/app/models/concerns/taggable.rb @@ -0,0 +1,163 @@ +module Taggable + extend ActiveSupport::Concern + + included do + has_many :taggings, as: :taggable, inverse_of: :taggable, dependent: :destroy, autosave: true + has_many :tags, through: :taggings, source: :tagger, source_type: "Tag" + + Tag::VISIBLE.each do |type| + has_many type.underscore.pluralize.to_sym, + -> { where(tags: { type: type }) }, + through: :taggings, + source: :tagger, + source_type: "Tag", + before_remove: :destroy_tagging + end + end + + # Used in works and external works: + Tag::VISIBLE.each do |type| + klass = type.constantize + underscore = type.underscore + + define_method("#{underscore}_strings") do + tags_after_saving_of_type(klass).map(&:name) + end + + define_method("#{underscore}_string") do + tags_after_saving_of_type(klass).map(&:name).join(ArchiveConfig.DELIMITER_FOR_OUTPUT) + end + + define_method("#{underscore}_string=") do |tag_string| + tags = parse_tags_of_type(tag_string, klass) + assign_tags_of_type(tags, klass) + end + + alias_method "#{underscore}_strings=", "#{underscore}_string=" + end + + # Used in bookmarks and collections: + def tag_strings + tags_after_saving.map(&:name) + end + + def tag_string + tags_after_saving.map(&:name).join(ArchiveConfig.DELIMITER_FOR_OUTPUT) + end + + def tag_string=(tag_string) + tags = parse_tags(tag_string) + assign_tags_of_type(tags, Tag) + end + + alias tag_strings= tag_string= + + def tag_groups + result = tags_after_saving.group_by(&:type) + + result["Fandom"] ||= [] + result["Rating"] ||= [] + result["ArchiveWarning"] ||= [] + result["Relationship"] ||= [] + result["Character"] ||= [] + result["Freeform"] ||= [] + + result + end + + # a work can only have one rating, so using first will work + # should always have a rating, if it doesn't err conservatively + def adult? + self.ratings.blank? || self.ratings.first.adult? + end + + # Returns the list of tags that this object will have after it's saved. This + # takes into account taggings that are built (but not saved), and taggings + # that have been marked for destruction. + def tags_after_saving + if taggings.target.empty? + # The taggings aren't loaded, and no new taggings have been created, so + # we can just resort to the base tags list for efficiency: + tags.to_a + else + taggings.reject(&:marked_for_destruction?).map(&:tagger).compact + end + end + + # Returns the number of tags of type Fandom, Character, Relationship, or + # Freeform. + def user_defined_tags_count + tags_after_saving.count do |tag| + Tag::USER_DEFINED.include?(tag.type) + end + end + + private + + # Take the list of tags after saving, and filter by type: + def tags_after_saving_of_type(klass) + tags_after_saving.select { |tag| tag.is_a?(klass) } + end + + # Split the tag string at each comma, and remove excess whitespace: + def split_tag_string(tag_string) + tag_array = if tag_string.is_a?(Array) + tag_string + else + tag_string.gsub(/\uff0c|\u3001/, ",").split(",") + end + + tag_array.map(&:squish).reject(&:blank?) + end + + # Split the tag_string, and find/create an array of tags of the given type. + def parse_tags_of_type(tag_string, klass) + tag_names = split_tag_string(tag_string) + + tag_names.map do |tag_name| + klass.find_or_create_by_name(tag_name) + end.uniq + end + + # Split the tag_string, and look up the tags for each of those tag names. We + # ignore tag type for this one, and create UnsortedTags for any tag names + # that we can't find. + # + # Used in bookmarks and collections. + def parse_tags(tag_string) + tag_names = split_tag_string(tag_string) + + tag_names.map do |tag_name| + Tag.find_by_name(tag_name) || UnsortedTag.create(name: tag_name) + end.uniq + end + + # Mark taggings for destruction, and create new taggings, so that we will end + # up with the specified set of tags after saving. + # + # Only deletes/checks tags of the given class. + def assign_tags_of_type(tags, klass) + missing = Set.new(tags) + + taggings.each do |tagging| + tag = tagging.tagger + + next unless tag.is_a?(klass) + + if missing.include?(tag) + missing.delete(tag) + tagging.reload if tagging.marked_for_destruction? + else + tagging.mark_for_destruction + end + end + + missing.each do |tag| + taggings.build(tagger: tag) + end + end + + def destroy_tagging(tag) + taggings.find_by(tagger: tag)&.destroy + end +end diff --git a/app/models/concerns/user_loggable.rb b/app/models/concerns/user_loggable.rb new file mode 100755 index 0000000..6cc6042 --- /dev/null +++ b/app/models/concerns/user_loggable.rb @@ -0,0 +1,61 @@ +module UserLoggable + extend ActiveSupport::Concern + + included do + before_destroy :log_removal_of_self_from_fnok_relationships + end + + def log_removal_of_self_from_fnok_relationships + fannish_next_of_kins.each do |fnok| + fnok.user.log_removal_of_next_of_kin(self) + end + + successor = fannish_next_of_kin&.kin + log_removal_of_next_of_kin(successor) + end + + def log_assignment_of_next_of_kin(kin, admin:) + log_user_history( + ArchiveConfig.ACTION_ADD_FNOK, + options: { fnok_user_id: kin.id }, + admin: admin + ) + + kin.log_user_history( + ArchiveConfig.ACTION_ADDED_AS_FNOK, + options: { fnok_user_id: self.id }, + admin: admin + ) + end + + def log_removal_of_next_of_kin(kin, admin: nil) + return if kin.blank? + + log_user_history( + ArchiveConfig.ACTION_REMOVE_FNOK, + options: { fnok_user_id: kin.id }, + admin: admin + ) + + kin.log_user_history( + ArchiveConfig.ACTION_REMOVED_AS_FNOK, + options: { fnok_user_id: self.id }, + admin: admin + ) + end + + def log_user_history(action, options: {}, admin: nil) + if admin.present? + options = { + admin_id: admin.id, + note: "Change made by #{admin.login}", + **options + } + end + + create_log_item({ + action: action, + **options + }) + end +end diff --git a/app/models/concerns/wrangleable.rb b/app/models/concerns/wrangleable.rb new file mode 100755 index 0000000..15ea409 --- /dev/null +++ b/app/models/concerns/wrangleable.rb @@ -0,0 +1,19 @@ +module Wrangleable + extend ActiveSupport::Concern + + included do + after_save :update_last_wrangling_activity, if: :update_wrangling_activity? + after_destroy :update_last_wrangling_activity, if: :update_wrangling_activity? + end + + private + + def update_last_wrangling_activity + current_user = User.current_user + current_user.update_last_wrangling_activity if current_user.respond_to?(:update_last_wrangling_activity) + end + + def update_wrangling_activity? + User.should_update_wrangling_activity + end +end diff --git a/app/models/creatorship.rb b/app/models/creatorship.rb new file mode 100755 index 0000000..4870a4d --- /dev/null +++ b/app/models/creatorship.rb @@ -0,0 +1,292 @@ +class Creatorship < ApplicationRecord + belongs_to :pseud + belongs_to :creation, polymorphic: true, touch: true + + scope :approved, -> { where(approved: true) } + scope :unapproved, -> { where(approved: false) } + + scope :for_user, ->(user) { joins(:pseud).merge(user.pseuds) } + + ######################################## + # VALIDATIONS + ######################################## + + before_validation :update_approved, on: :create + + validates_presence_of :creation + validates_uniqueness_of :pseud, scope: [:creation_type, :creation_id], on: :create + + validate :check_invalid, on: :create + validate :check_banned, on: :create + validate :check_disallowed, on: :create + validate :check_approved_becoming_false, on: :update + + # Update approval status if this creatorship should be automatically approved. + def update_approved + if !approved? && should_automatically_approve? + self.approved = true + end + end + + # Make sure that the pseud exists, and isn't ambiguous. + # + # Note that thanks to the definitions of missing? and ambiguous?, this is + # equivalent to having a validates_presence_of :pseud check, just with + # different error messages. + def check_invalid + if missing? + errors.add(:base, ts("Could not find a pseud %{name}.", name: byline)) + elsif ambiguous? + errors.add(:base, ts("The pseud %{name} is ambiguous.", name: byline)) + end + end + + # Make sure that the user isn't banned or suspended. + def check_banned + return unless pseud&.user&.banned || pseud&.user&.suspended + + errors.add(:base, ts("%{name} cannot be listed as a co-creator.", + name: pseud.byline)) + throw :abort + end + + # Make sure that if this is an invitation, we're not inviting someone who has + # disabled invitations. + def check_disallowed + return if approved? || pseud.nil? + return if pseud&.user&.preference&.allow_cocreator + errors.add(:base, ts("%{name} does not allow others to invite them to be a co-creator.", + name: pseud.byline)) + end + + # Make sure that we're not trying to set approved to false, since that could + # potentially violate some rules about co-creators. (e.g. Having a user + # listed as a chapter co-creator, but not a work co-creator.) + def check_approved_becoming_false + if !approved? && approved_changed? + errors.add(:base, "Once approved, a creatorship cannot become unapproved.") + end + end + + ######################################## + # CALLBACKS + ######################################## + + after_create :add_to_parents + after_update :add_to_parents, if: :saved_change_to_approved? + + before_destroy :expire_caches + before_destroy :check_not_last + before_destroy :save_original_creator + after_destroy :remove_from_children + + after_commit :update_indices + + after_create_commit :notify_creator, if: :enable_notifications + + # If a pseud is listed as a work co-creator (not invited, actually listed), + # they should also be listed on all of the work's series. Similarly, if a + # pseud is listed as a chapter co-creator, they should also be listed on the + # work. + def add_to_parents + return unless approved? + + parents = if creation.is_a?(Work) + creation.series.to_a + elsif creation.is_a?(Chapter) + [creation.work] + else + [] + end + + parents.each do |parent| + parent.creatorships.approve_or_create_by(pseud: pseud) + end + end + + # In order to make sure that all chapter co-creators are listed on the work, + # and all work co-creators are listed on the work's series, we need to make + # sure that when a creatorship is deleted, the deletion cascades downwards. + def remove_from_children + # If the creation is being deleted and it's a work, then its chapters are + # also going to be deleted (which will cause their creatorships to be + # deleted as well). If the creation is being deleted and it's a series, + # then we shouldn't delete the work creatorships. So if the creation is + # being deleted, we don't want to cascade the deletion downwards. + return if creation.nil? || creation.destroyed? + + children = if creation.is_a?(Work) + creation.chapters.to_a + elsif creation.is_a?(Series) + creation.works.to_a + else + [] + end + + children.each do |child| + child.creatorships.where(pseud: pseud).destroy_all + end + end + + # Make sure that both the creation and the pseud are enqueued to be + # reindexed. + def update_indices + if creation.is_a?(Searchable) + creation.enqueue_to_index + end + + if pseud && creation.is_a?(Work) + IndexQueue.enqueue(pseud, :background) + end + end + + # Only enable notifications for new creatorships when explicitly enabled. + attr_accessor :enable_notifications + + # Notify the pseud of their new creatorship. + def notify_creator + return unless User.current_user.is_a?(User) && + pseud.user != User.current_user && + pseud.user != User.orphan_account + + I18n.with_locale(pseud.user.preference.locale_for_mails) do + if approved? + if User.current_user.try(:is_archivist?) + UserMailer.creatorship_notification_archivist(id, User.current_user.id).deliver_later + else + UserMailer.creatorship_notification(id, User.current_user.id).deliver_later + end + else + UserMailer.creatorship_request(id, User.current_user.id).deliver_later + end + end + end + + # When deleting a creatorship, we want to make sure we're not deleting the + # very last creatorship for that item. + def check_not_last + # We can always delete unapproved creatorships: + return unless approved? + + # Check that the creation hasn't been deleted, and still has creatorships + # left: + return if creation.nil? || creation.destroyed? || + creation.creatorships.approved.count > 1 + + errors.add(:base, ts("Sorry, we can't remove all creators of a %{type}.", + type: creation.model_name.human.downcase)) + raise ActiveRecord::RecordInvalid, self + end + + # Record the original creator if the creation is a work. + # This information is stored temporarily to make it available for + # Policy and Abuse on orphaned works. + def save_original_creator + return unless approved? + return unless creation.is_a?(Work) + return if creation.destroyed? + + creation.original_creators.create_or_find_by(user: pseud.user).touch + end + + def expire_caches + if creation_type == "Work" && self.pseud.present? + CacheMaster.record(creation_id, "pseud", self.pseud_id) + CacheMaster.record(creation_id, "user", self.pseud.user_id) + end + end + + ######################################## + # OTHER METHODS + ######################################## + + attr_reader :ambiguous_pseuds + + # We define a virtual "byline" attribute to make it easier to handle + # ambiguous/missing pseuds. By storing the desired name in the @byline + # variable, we can generate nicely formatted messages. + def byline=(byline) + pseuds = Pseud.parse_byline_ambiguous(byline).to_a + + if pseuds.size == 1 + self.pseud = pseuds.first + @byline = nil + @ambiguous_pseuds = nil + else + self.pseud = nil + @byline = byline + @ambiguous_pseuds = pseuds + end + end + + # Retrieve the @byline variable, or, failing that, the pseud's byline. + def byline + @byline || pseud&.byline + end + + # A creatorship counts as "missing" if we couldn't find any pseuds matching + # the passed-in byline. + def missing? + pseud.nil? && @ambiguous_pseuds.blank? + end + + # A creatorship counts as "ambiguous" if there was more than one pseud + # matching the passed-in byline. + def ambiguous? + pseud.nil? && @ambiguous_pseuds.present? + end + + # Find or initialize a creatorship matching the options, and then set + # approved to true and save the results. This is a way of adding a new + # approved creatorship without potentially running into issues with a + # pre-existing unapproved creatorship. + def self.approve_or_create_by(options) + creatorship = find_or_initialize_by(options) + creatorship.approved = true + creatorship.save if creatorship.changed? + end + + # Change authorship of works or series from a particular pseud to the orphan account + def self.orphan(pseuds, orphans, default=true) + for pseud in pseuds + for new_orphan in orphans + unless pseud.blank? || new_orphan.blank? || !new_orphan.pseuds.include?(pseud) + orphan_pseud = default ? User.orphan_account.default_pseud : User.orphan_account.pseuds.find_or_create_by(name: pseud.name) + pseud.change_ownership(new_orphan, orphan_pseud) + end + end + end + end + + # Calculate whether this creatorship should count as approved, or whether + # it's just a creatorship invitation. + def should_automatically_approve? + # Approve if we're using an API key, or if the current user has special + # permissions: + return true if User.current_user.nil? || + pseud&.user == User.current_user || + pseud&.user == User.orphan_account || + User.current_user.try(:is_archivist?) + + # Approve if the creation is a chapter and the pseud is already listed on + # the work, or if the creation is a series and the pseud is already listed + # on one of the works: + (creation.is_a?(Chapter) && creation.work.pseuds.include?(pseud)) || + (creation.is_a?(Series) && creation.work_pseuds.include?(pseud)) + end + + # Accept the creatorship invitation. This consists of setting approved to + # true, and, if the creation is a work, adding the pseud to all of its + # chapters as well. + def accept! + transaction do + update(approved: true) + + if creation.is_a?(Work) + creation.chapters.each do |chapter| + chapter.creatorships.approve_or_create_by(pseud: pseud) + end + end + end + end +end diff --git a/app/models/download.rb b/app/models/download.rb new file mode 100755 index 0000000..e05af50 --- /dev/null +++ b/app/models/download.rb @@ -0,0 +1,140 @@ +class Download + attr_reader :work, :file_type, :mime_type + + def initialize(work, options = {}) + @work = work + @file_type = set_file_type(options.slice(:mime_type, :format)) + @mime_type = Marcel::MimeType.for(extension: @file_type).to_s + @include_draft_chapters = options[:include_draft_chapters] + end + + def generate + DownloadWriter.new(self).write + self + end + + def exists? + File.exist?(file_path) + end + + # Removes not just the file but the whole directory + # Should change if our approach to downloads ever changes + def remove + FileUtils.rm_rf(dir) + end + + # Given either a file extension or a mime type, figure out + # what format we're generating + # Defaults to html + def set_file_type(options) + if options[:mime_type] + file_type_from_mime(options[:mime_type]) + elsif ArchiveConfig.DOWNLOAD_FORMATS.include?(options[:format].to_s) + options[:format].to_s + else + "html" + end + end + + # Given a mime type, return a file extension + def file_type_from_mime(mime) + subtype = Marcel::Magic.new(mime.to_s).subtype + case subtype + when "x-mobipocket-ebook" + "mobi" + when "x-mobi8-ebook" + "azw3" + else + subtype + end + end + + + # The base name of the file (e.g., "War_and_Peace") + def file_name + name = clean(work.title) + # If the file name is 1-2 characters, append "_Work_#{work.id}". + # If the file name is blank, name the file "Work_#{work.id}". + name = [name, "Work_#{work.id}"].compact_blank.join("_") if name.length < 3 + name.strip + end + + # The public route to this download + def public_path + "/downloads/#{work.id}/#{file_name}.#{file_type}" + end + + # The path to the zip file (eg, "/tmp/42_epub_20190301-24600-17164a8/42.zip") + def zip_path + "#{dir}/#{work.id}.zip" + end + + # The path to the folder where web2disk downloads the xhtml and images + def assets_path + "#{dir}/assets" + end + + # The full path to the HTML file (eg, "/tmp/42_epub_20190301-24600-17164a8/The Hobbit.html") + def html_file_path + "#{dir}/#{file_name}.html" + end + + # The full path to the file (eg, "/tmp/42_epub_20190301-24600-17164a8/The Hobbit.epub") + def file_path + "#{dir}/#{file_name}.#{file_type}" + end + + # Get the temporary directory where downloads will be generated, + # creating the directory if it doesn't exist. + def dir + return @tmpdir if @tmpdir + @tmpdir = Dir.mktmpdir("#{work.id}_#{file_type}_") + @tmpdir + end + + def page_title + fandom = if work.fandoms.size > 3 + "Multifandom" + elsif work.fandoms.empty? + "No fandom specified" + else + work.fandom_string + end + [work.title, authors, fandom].join(" - ") + end + + def authors + author_names.join(", ") + end + + def author_names + work.anonymous? ? ["Anonymous"] : work.pseuds.sort.map(&:byline) + end + + def chapters + if @include_draft_chapters + work.chapters.order("position ASC") + else + work.chapters.order("position ASC").where(posted: true) + end + end + + private + + # make filesystem-safe + # ascii encoding + # squash spaces + # strip all non-alphanumeric + # truncate to 24 chars at a word boundary + # replace whitespace with underscore for bug with epub table of contents on Kindle (AO3-6625) + def clean(string) + # get rid of any HTML entities to avoid things like "amp" showing up in titles + string = string.gsub(/\&(\w+)\;/, '') + string = string.to_ascii + string = string.gsub(/[^[\w _-]]+/, '') + string = string.gsub(/ +/, " ") + string = string.strip + string = string.truncate(24, separator: ' ', omission: '') + string.gsub(/\s/, "_") + end +end diff --git a/app/models/download_writer.rb b/app/models/download_writer.rb new file mode 100755 index 0000000..7dffe7c --- /dev/null +++ b/app/models/download_writer.rb @@ -0,0 +1,176 @@ +require "open3" + +class DownloadWriter + attr_reader :download, :work + + def initialize(download) + @download = download + @work = download.work + end + + def write + generate_html_download + generate_ebook_download unless download.file_type == "html" + download + end + + def generate_html + renderer = ApplicationController.renderer.new( + http_host: ArchiveConfig.APP_HOST + ) + renderer.render( + template: "downloads/show", + layout: "barebones", + assigns: { + work: work, + page_title: download.page_title, + chapters: download.chapters + } + ) + end + + private + + # Write the HTML version to file + def generate_html_download + return if download.exists? + + File.open(download.html_file_path, "w:UTF-8") { |f| f.write(generate_html) } + end + + # transform HTML version into ebook version + def generate_ebook_download + return unless %w[azw3 epub mobi pdf].include?(download.file_type) + return if download.exists? + + cmds = get_commands + + # Make sure the command is sanitary, and use popen3 in order to + # capture and discard the stdin/out info + # See http://stackoverflow.com/a/5970819/469544 for details + cmds.each do |cmd| + exit_status = nil + Open3.popen3(*cmd) { |_stdin, _stdout, _stderr, wait_thread| exit_status = wait_thread.value } + unless exit_status + Rails.logger.warn "Download generation failed: " + cmd.to_s + end + end + end + + # Get the version of the command we need to execute + def get_commands + [get_web2disk_command, get_zip_command, get_calibre_command] + end + + # Create the format-specific command-line call to calibre/ebook-convert + def get_calibre_command + # Add info about first series if any + series = [] + if meta[:series_title].present? + series = ["--series", meta[:series_title], + "--series-index", meta[:series_position]] + end + + ### Format-specific options + # epub: don't generate a cover image + epub = download.file_type == "epub" ? ["--no-default-epub-cover"] : [] + + pdf = [] + if download.file_type == "pdf" + pdf = [ + # pdf: decrease margins from 72pt default + "--pdf-page-margin-top", "36", + "--pdf-page-margin-right", "36", + "--pdf-page-margin-bottom", "36", + "--pdf-page-margin-left", "36", + "--pdf-default-font-size", "17", + # pdf: only include necessary characters when embedding fonts + "--subset-embedded-fonts" + ] + end + + ### CSS options + # azw3, epub, and mobi get a special stylesheet + css = [] + if %w[azw3 epub mobi].include?(download.file_type) + css = ["--extra-css", + Rails.public_path.join("stylesheets/ebooks.css").to_s] + end + + [ + "ebook-convert", + download.zip_path, + download.file_path, + "--input-encoding", "utf-8", + # Prevent it from turning links to endnotes into entries for the table of + # contents on works with fewer than the specified number of chapters. + "--toc-threshold", "0", + "--use-auto-toc", + "--title", meta[:title], + "--title-sort", meta[:sortable_title], + "--authors", meta[:authors], + "--author-sort", meta[:sortable_authors], + "--comments", meta[:summary], + "--tags", meta[:tags], + "--pubdate", meta[:pubdate], + "--publisher", ArchiveConfig.APP_NAME, + "--language", meta[:language], + # XPaths for detecting chapters are overly specific to make sure we don't grab + # anything inputted by the user. First path is for single-chapter works, + # second for multi-chapter, and third for the preface and afterword + "--chapter", "//h:body/h:div[@id='chapters']/h:h2[@class='toc-heading'] | //h:body/h:div[@id='chapters']/h:div[@class='meta group']/h:h2[@class='heading'] | //h:body/h:div[@id='preface' or @id='afterword']/h:h2[@class='toc-heading']" + ] + series + css + epub + pdf + end + + # Grab the HTML file and any images and put them in --base-dir. + # --max-recursions 0 prevents it from grabbing all the linked pages. + # --dont-download-stylesheets isn't strictly necessary for us but avoids + # creating an empty stylesheets directory. + def get_web2disk_command + [ + "web2disk", + "--base-dir", download.assets_path, + "--max-recursions", "0", + "--dont-download-stylesheets", + "file://#{download.html_file_path}" + ] + end + + # Zip the directory containing the HTML file and images. + def get_zip_command + [ + "zip", + "-r", + download.zip_path, + download.assets_path + ] + end + + # A hash of the work data calibre needs + def meta + return @metadata if @metadata + @metadata = { + title: work.title, + sortable_title: work.sorted_title, + # Using ampersands as instructed by Calibre's ebook-convert documentation + # hides all but the first author name in Books (formerly iBooks). The + # other authors cannot be used for searching or sorting. Using commas + # just means Calibre's GUI treats it as one name, e.g. "testy, testy2" is + # like "Fangirl, Suzy Q", for searching and sorting. + authors: download.authors, + sortable_authors: work.authors_to_sort_on, + # We add "Fanworks" because Books uses the first tag as the category and + # it would otherwise be the work's rating, which is weird. + tags: "Fanworks, " + work.tags.pluck(:name).join(", "), + pubdate: work.revised_at.to_date.to_s, + summary: work.summary.to_s, + language: work.language.short + } + if work.series.exists? + series = work.series.first + @metadata[:series_title] = series.title + @metadata[:series_position] = series.position_of(work).to_s + end + @metadata + end +end diff --git a/app/models/external_author.rb b/app/models/external_author.rb new file mode 100755 index 0000000..ce9d524 --- /dev/null +++ b/app/models/external_author.rb @@ -0,0 +1,178 @@ +class ExternalAuthor < ApplicationRecord + # send :include, Activation # eventually we will let users create new identities + + EMAIL_LENGTH_MIN = 3 + EMAIL_LENGTH_MAX = 300 + + belongs_to :user + + has_many :external_author_names, dependent: :destroy + accepts_nested_attributes_for :external_author_names, allow_destroy: true + validates_associated :external_author_names + + has_many :external_creatorships, through: :external_author_names + has_many :works, -> { distinct }, through: :external_creatorships, source: :creation, source_type: 'Work' + + has_one :invitation + + validates :email, uniqueness: { + allow_blank: true, + message: ts('There is already an external author with that email.') + } + + validates :email, email_format: true + + def self.claimed + where(is_claimed: true) + end + + def self.unclaimed + where(is_claimed: false) + end + + after_create :create_default_name + + def external_work_creatorships + external_creatorships.where("external_creatorships.creation_type = 'Work'") + end + + def create_default_name + @default_name = self.external_author_names.build + @default_name.name = self.email.to_s + self.save + end + + def default_name + self.external_author_names.select {|external_name| external_name.name == self.email.to_s }.first + end + + def names + self.external_author_names + end + + def claimed? + is_claimed + end + + def claim!(claiming_user) + raise "There is no user claiming this external author." unless claiming_user + raise "This external author is already claimed by another user" if claimed? && self.user != claiming_user + + claimed_works = [] + external_author_names.each do |external_author_name| + external_author_name.external_work_creatorships.each do |external_creatorship| + work = external_creatorship.creation + other_external_creators = work.external_creatorships - [external_creatorship] + other_unclaimed_creators = other_external_creators.reject(&:claimed?) + + # if previously claimed by this user, don't do it again + unless work.users.include?(claiming_user) + # Get the pseud to associate with the work + pseud_to_add = claiming_user.pseuds.select {|pseud| pseud.name == external_author_name.name}.first || claiming_user.default_pseud + + # If there are no other unclaimed authors, or if none of the other unclaimed authors have the same archivist, + # remove this user's archivist from the work creators, else just add the claiming user + claiming_user_archivist = external_creatorship.archivist + if other_unclaimed_creators.map(&:archivist).exclude?(claiming_user_archivist) + change_ownership(work, claiming_user_archivist, claiming_user, pseud_to_add) + else + add_creator(work, claiming_user, pseud_to_add) + end + claimed_works << work.id + end + end + end + + self.user = claiming_user + self.is_claimed = true + save + notify_user_of_claim(claimed_works) + end + + def unclaim! + return false unless self.is_claimed + + self.external_work_creatorships.each do |external_creatorship| + # remove user, add archivist back + archivist = external_creatorship.archivist + work = external_creatorship.creation + change_ownership(work, user, archivist) + end + + self.user = nil + self.is_claimed = false + save + end + + def orphan(remove_pseud) + external_author_names.each do |external_author_name| + external_author_name.external_work_creatorships.each do |external_creatorship| + # remove archivist as owner, convert to the pseud + archivist = external_creatorship.archivist + work = external_creatorship.creation + archivist_pseud = work.pseuds.select {|pseud| archivist.pseuds.include?(pseud)}.first + orphan_pseud = remove_pseud ? User.orphan_account.default_pseud : User.orphan_account.pseuds.find_or_create_by(name: external_author_name.name) + change_ownership(work, archivist, User.orphan_account, orphan_pseud) + end + end + end + + def delete_works + self.external_work_creatorships.each do |external_creatorship| + work = external_creatorship.creation + work.destroy + end + end + + def block_import + self.do_not_import = true + save + end + + def notify_user_of_claim(claimed_work_ids) + # send announcement to user of the stories they have been given + I18n.with_locale(self.user.preference.locale_for_mails) do + UserMailer.claim_notification(self.user_id, claimed_work_ids).deliver_later + end + end + + def find_or_invite(archivist = nil) + if self.email + matching_user = User.find_by(email: self.email) || User.find_by_id(self.user_id) + if matching_user + self.claim!(matching_user) + else + # invite person at the email address unless they don't want invites + unless self.do_not_email + @invitation = Invitation.new(invitee_email: self.email, external_author: self, creator: User.current_user) + @invitation.save + end + end + end + end + + private + + # Add a new creator to the work: + def add_creator(work, creator_to_add, new_pseud = nil) + new_pseud = creator_to_add.default_pseud if new_pseud.nil? + + work.transaction do + work.creatorships.find_or_create_by(pseud: new_pseud) + + work.chapters.each do |chapter| + chapter.creatorships.find_or_create_by(pseud: new_pseud) + end + end + end + + # Transfer ownership of the work from one user to another + def change_ownership(work, old_user, new_user, new_pseud = nil) + raise "No new user provided, cannot change ownership" unless new_user + + work.transaction do + add_creator(work, new_user, new_pseud) + work.remove_author(old_user) + end + end +end diff --git a/app/models/external_author_name.rb b/app/models/external_author_name.rb new file mode 100755 index 0000000..b4b4b6b --- /dev/null +++ b/app/models/external_author_name.rb @@ -0,0 +1,34 @@ +class ExternalAuthorName < ApplicationRecord + NAME_LENGTH_MIN = 1 + NAME_LENGTH_MAX = 100 + + belongs_to :external_author, inverse_of: :external_author_names + has_many :external_creatorships, inverse_of: :external_author_name + has_many :works, -> { uniq }, through: :external_creatorships, source: :creation, source_type: 'Work' + + validates_presence_of :name + + validates_length_of :name, + within: NAME_LENGTH_MIN..NAME_LENGTH_MAX, + too_short: ts("is too short (minimum is %{min} characters)", min: NAME_LENGTH_MIN), + too_long: ts("is too long (maximum is %{max} characters)", max: NAME_LENGTH_MAX) + + validates :name, uniqueness: { scope: :external_author_id } + + validates_format_of :name, + message: ts('can contain letters, numbers, spaces, underscores, @-signs, dots, and dashes.'), + with: /\A\w[ \w\-\@\.]*\Z/ + + validates_format_of :name, + message: ts('must contain at least one letter or number.'), + with: /[a-zA-Z0-9]/ + + def to_s + self.name + ' <' + self.external_author.email + '>' + end + + def external_work_creatorships + external_creatorships.where("external_creatorships.creation_type = 'Work'") + end + +end diff --git a/app/models/external_creatorship.rb b/app/models/external_creatorship.rb new file mode 100755 index 0000000..81fa402 --- /dev/null +++ b/app/models/external_creatorship.rb @@ -0,0 +1,26 @@ +class ExternalCreatorship < ApplicationRecord + belongs_to :external_author_name, inverse_of: :external_creatorships + belongs_to :archivist, class_name: 'User', foreign_key: 'archivist_id' + belongs_to :creation, polymorphic: true , inverse_of: :external_creatorships + + def external_author=(external_author) + self.external_author_name = external_author.try(:default_name) + end + + def external_author + self.external_author_name.try(:external_author) + end + + def claimed? + self.external_author_name.try(:external_author).try(:claimed?) + end + + def to_s + ts("%{title} by %{name}", title: self.creation.title, name: self.external_author_name) + end + + def author_name + self.external_author_name.try(:name) || "" + end + +end diff --git a/app/models/external_work.rb b/app/models/external_work.rb new file mode 100755 index 0000000..9d7a915 --- /dev/null +++ b/app/models/external_work.rb @@ -0,0 +1,126 @@ +class ExternalWork < ApplicationRecord + include Bookmarkable + include Filterable + include Searchable + + has_many :related_works, as: :parent + + belongs_to :language + + # .duplicate.count.size returns the number of URLs with multiple external works + scope :duplicate, -> { group(:url).having("count(DISTINCT id) > 1") } + + scope :for_blurb, -> { includes(:language, :tags) } + + AUTHOR_LENGTH_MAX = 500 + + validates_presence_of :title + validates_length_of :title, minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} characters long.", + min: ArchiveConfig.TITLE_MIN) + validates_length_of :title, maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", + max: ArchiveConfig.TITLE_MAX) + + validates_length_of :summary, allow_blank: true, maximum: ArchiveConfig.SUMMARY_MAX, + too_long: ts("must be less than %{max} characters long.", + max: ArchiveConfig.SUMMARY_MAX) + + validates :author, presence: { message: ts("can't be blank") } + validates_length_of :author, maximum: AUTHOR_LENGTH_MAX, + too_long: ts("must be less than %{max} characters long.", + max: AUTHOR_LENGTH_MAX) + + validates :user_defined_tags_count, + at_most: { maximum: proc { ArchiveConfig.USER_DEFINED_TAGS_MAX } } + + # TODO: External works should have fandoms, but they currently don't get added through the + # post new work form so we can't validate them + #validates_presence_of :fandoms + + before_validation :cleanup_url + # i18n-tasks-use t("errors.attributes.url.invalid") + validates :url, presence: true, url_format: true, url_active: true + def cleanup_url + self.url = Addressable::URI.heuristic_parse(self.url) if self.url + rescue Addressable::URI::InvalidURIError + # url_format validation creates the error message + end + + # Allow encoded characters to display correctly in titles + def title + read_attribute(:title).try(:html_safe) + end + + ######################################################################## + # VISIBILITY + ######################################################################## + # Adapted from work.rb + + scope :visible_to_all, -> { where(hidden_by_admin: false) } + scope :visible_to_registered_user, -> { where(hidden_by_admin: false) } + scope :visible_to_admin, -> { where("") } + + # a complicated dynamic scope here: + # if the user is an Admin, we use the "visible_to_admin" scope + # if the user is not a logged-in User, we use the "visible_to_all" scope + # otherwise, we use a join to get userids and then get all posted works that are either unhidden OR belong to this user. + # Note: in that last case we have to use select("DISTINCT works.") because of cases where the same user appears twice + # on a work. + scope :visible_to_user, lambda {|user| user.is_a?(Admin) ? visible_to_admin : visible_to_all} + + # Use the current user to determine what external works are visible + scope :visible, -> { visible_to_user(User.current_user) } + + # Visible unless we're hidden by admin, in which case only an Admin can see. + def visible?(user=User.current_user) + self.hidden_by_admin? ? user.kind_of?(Admin) : true + end + + # Visibility has changed, which means we need to reindex + # the external work's bookmarker pseuds, to update their bookmark counts. + def should_reindex_pseuds? + pertinent_attributes = %w[id hidden_by_admin] + destroyed? || (saved_changes.keys & pertinent_attributes).present? + end + + ###################### + # SEARCH + ###################### + + def bookmarkable_json + as_json( + root: false, + only: [ + :title, :summary, :hidden_by_admin, :created_at + ], + methods: [ + :posted, :restricted, :tag, :filter_ids, :rating_ids, + :archive_warning_ids, :category_ids, :fandom_ids, :character_ids, + :relationship_ids, :freeform_ids, :creators, :revised_at + ] + ).merge( + language_id: language&.short, + bookmarkable_type: "ExternalWork", + bookmarkable_join: { name: "bookmarkable" } + ) + end + + def posted + true + end + alias_method :posted?, :posted + + def restricted + false + end + alias_method :restricted?, :restricted + + def creators + [author] + end + + def revised_at + created_at + end +end diff --git a/app/models/fandom.rb b/app/models/fandom.rb new file mode 100755 index 0000000..d194fce --- /dev/null +++ b/app/models/fandom.rb @@ -0,0 +1,50 @@ +class Fandom < Tag + + NAME = ArchiveConfig.FANDOM_CATEGORY_NAME + + has_many :wrangling_assignments + has_many :wranglers, through: :wrangling_assignments, source: :user + + has_many :parents, through: :common_taggings, source: :filterable, source_type: 'Tag', after_remove: :check_media + has_many :medias, -> { where(type: 'Media') }, through: :common_taggings, source: :filterable, source_type: 'Tag' + has_many :characters, -> { where(type: 'Character') }, through: :child_taggings, source: :common_tag + has_many :relationships, -> { where(type: 'Relationship') }, through: :child_taggings, source: :common_tag + has_many :freeforms, -> { where(type: 'Freeform') }, through: :child_taggings, source: :common_tag + + + scope :by_media, lambda {|media| where(media_id: media.id)} + + def unwrangled? + Media.uncategorized.fandoms.include?(self) + end + + # An association callback to add the default media if all others have been removed + def check_media(media) + self.add_media_for_uncategorized + end + + after_save :add_media_for_uncategorized + def add_media_for_uncategorized + if self.medias.empty? && self.type == "Fandom" # type could be something else if the tag is in the process of being re-categorised (re-sorted) + self.parents << Media.uncategorized + end + end + + before_update :check_wrangling_status + def check_wrangling_status + if self.canonical_changed? && !self.canonical? + if !self.canonical? && self.merger_id + self.merger.wranglers = (self.wranglers + self.merger.wranglers).uniq + end + self.wranglers = [] + end + end + + # Types of tags to which a fandom tag can belong via common taggings or meta taggings + def parent_types + ['Media', 'MetaTag'] + end + def child_types + ['Character', 'Relationship', 'Freeform', 'SubTag', 'Merger'] + end +end diff --git a/app/models/fannish_next_of_kin.rb b/app/models/fannish_next_of_kin.rb new file mode 100755 index 0000000..b30eaf8 --- /dev/null +++ b/app/models/fannish_next_of_kin.rb @@ -0,0 +1,10 @@ +class FannishNextOfKin < ApplicationRecord + belongs_to :user + belongs_to :kin, class_name: "User" + + validates :user, :kin, :kin_email, presence: true + + def kin_name + kin.try(:login) + end +end diff --git a/app/models/favorite_tag.rb b/app/models/favorite_tag.rb new file mode 100755 index 0000000..7d30fb9 --- /dev/null +++ b/app/models/favorite_tag.rb @@ -0,0 +1,46 @@ +class FavoriteTag < ApplicationRecord + belongs_to :user + belongs_to :tag + + validates :user_id, presence: true + validates :tag_id, presence: true, + uniqueness: { scope: :user_id, + message: ts("is already in your favorite tags.") + } + + validate :within_limit, on: :create + def within_limit + if user && user.favorite_tags.reload.count >= ArchiveConfig.MAX_FAVORITE_TAGS + errors.add(:base, + ts("Sorry, you can only save %{maximum} favorite tags.", + maximum: ArchiveConfig.MAX_FAVORITE_TAGS)) + end + end + + validate :canonical, on: :create + def canonical + unless tag && tag.canonical? + errors.add(:base, "Sorry, you can only add canonical tags to your favorite tags.") + end + end + + after_save :expire_cached_home_favorite_tags + after_destroy :expire_cached_home_favorite_tags + + def tag + Tag.find_by(id: tag_id) + end + + def tag_name + tag = self.tag + tag.name + end + + private + + def expire_cached_home_favorite_tags + unless Rails.env.development? + Rails.cache.delete("home/index/#{user_id}/home_favorite_tags") + end + end +end diff --git a/app/models/feedback.rb b/app/models/feedback.rb new file mode 100755 index 0000000..68ea964 --- /dev/null +++ b/app/models/feedback.rb @@ -0,0 +1,91 @@ +# Class which holds feedback sent to the archive administrators about the archive as a whole +class Feedback < ApplicationRecord + attr_accessor :ip_address, :referer, :site_skin + + # NOTE: this has NOTHING to do with the Comment class! + # This is just the name of the text field in the Feedback + # class which holds the user's comments. + validates_presence_of :comment + validates_presence_of :summary + validates_presence_of :language + validates :email, email_format: { allow_blank: false } + validates_length_of :summary, maximum: ArchiveConfig.FEEDBACK_SUMMARY_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.FEEDBACK_SUMMARY_MAX_DISPLAYED) + + validate :check_for_spam + def check_for_spam + approved = logged_in_with_matching_email? || !Akismetor.spam?(akismet_attributes) + errors.add(:base, ts("This report looks like spam to our system!")) unless approved + end + + def logged_in_with_matching_email? + User.current_user.present? && User.current_user.email == email + end + + def akismet_attributes + # If the user is logged in and we're sending info to Akismet, we can assume + # the email does not match. + role = User.current_user.present? ? "user-with-nonmatching-email" : "guest" + { + comment_type: "contact-form", + key: ArchiveConfig.AKISMET_KEY, + blog: ArchiveConfig.AKISMET_NAME, + user_ip: ip_address, + user_agent: user_agent, + user_role: role, + comment_author_email: email, + comment_content: comment + } + end + + def mark_as_spam! + # don't submit spam reports unless in production mode + Rails.env.production? && Akismetor.submit_spam(akismet_attributes) + end + + def mark_as_ham! + # don't submit ham reports unless in production mode + Rails.env.production? && Akismetor.submit_ham(akismet_attributes) + end + + def email_and_send + UserMailer.feedback(id).deliver_later + send_report + end + + def rollout_string + string = "" + # ES UPGRADE TRANSITION # + # Remove ES version logic, but leave this method for future rollout use + # string << if Feedback.use_new_search? + # "ES 6.0" + # else + # "ES 0.90" + # end + end + + def send_report + return unless zoho_enabled? + + reporter = SupportReporter.new( + title: summary, + description: comment, + language: language, + email: email, + username: username, + user_agent: user_agent, + site_revision: ArchiveConfig.REVISION.to_s, + rollout: rollout, + ip_address: ip_address, + referer: referer, + site_skin: site_skin + ) + reporter.send_report! + end + + private + + def zoho_enabled? + %w[staging production].include?(Rails.env) + end +end diff --git a/app/models/feedback_reporters/abuse_reporter.rb b/app/models/feedback_reporters/abuse_reporter.rb new file mode 100755 index 0000000..f0d6d1a --- /dev/null +++ b/app/models/feedback_reporters/abuse_reporter.rb @@ -0,0 +1,42 @@ +class AbuseReporter < FeedbackReporter + attr_accessor :creator_ids + + def report_attributes + super.deep_merge( + "departmentId" => department_id, + "subject" => subject, + "description" => ticket_description, + "cf" => custom_zoho_fields + ) + end + + private + + def custom_zoho_fields + # To avoid issues where Zoho ticket creation silently fails, only grab the first + # 2080 characters of the referer URL. That may miss some complex search queries, + # but still keep enough to be useful most of the time. + truncated_referer = url.present? ? url[0..2079] : "" + { + "cf_ip" => ip_address.presence || "Unknown IP", + "cf_ticket_url" => truncated_referer, + "cf_user_id" => creator_ids.presence || "" + } + end + + def department_id + ArchiveConfig.ABUSE_ZOHO_DEPARTMENT_ID + end + + def subject + return "[#{ArchiveConfig.APP_SHORT_NAME}] Abuse - #{title.html_safe}" if title.present? + + "[#{ArchiveConfig.APP_SHORT_NAME}] Abuse - No Subject" + end + + def ticket_description + return "No comment submitted." if description.blank? + + strip_images(description.html_safe, keep_src: true) + end +end diff --git a/app/models/feedback_reporters/feedback_reporter.rb b/app/models/feedback_reporters/feedback_reporter.rb new file mode 100755 index 0000000..c0cce2e --- /dev/null +++ b/app/models/feedback_reporters/feedback_reporter.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +require "zoho_auth_client" +require "zoho_resource_client" + +class FeedbackReporter + include HtmlCleaner + require "url_formatter" + + attr_accessor :title, + :description, + :email, + :language, + :category, + :username, + :url, + :ip_address + + def initialize(attrs = {}) + attrs.each_pair do |key, val| + self.send("#{key}=", val) + end + end + + def title + strip_html_breaks_simple(@title) + end + + def description + add_break_between_paragraphs(@description) + end + + def send_report! + zoho_resource_client.create_ticket(ticket_attributes: report_attributes) + end + + def send_attachment!(id, filename, download) + zoho_resource_client.create_ticket_attachment( + ticket_id: id, + attachment_attributes: attachment_attributes(filename, download) + ) + end + + def report_attributes + { + "email" => email, + "contactId" => zoho_contact_id, + "cf" => { + "cf_language" => language.presence || Language.default.name, + "cf_name" => username.presence || "Anonymous user" + } + } + end + + def attachment_attributes(filename, download) + attachment = StringIO.new(download) + # Workaround for HTTParty not recognizing StringIO as a file-like object: + # https://github.com/jnunemaker/httparty/issues/675#issuecomment-590757288 + attachment.define_singleton_method(:path) { filename } + { file: attachment } + end + + private + + def zoho_contact_id + zoho_resource_client.retrieve_contact_id + end + + def access_token + @access_token ||= ZohoAuthClient.new.access_token + end + + def zoho_resource_client + @zoho_resource_client ||= ZohoResourceClient.new( + access_token: access_token, + email: email + ) + end +end diff --git a/app/models/feedback_reporters/support_reporter.rb b/app/models/feedback_reporters/support_reporter.rb new file mode 100755 index 0000000..920cfe3 --- /dev/null +++ b/app/models/feedback_reporters/support_reporter.rb @@ -0,0 +1,45 @@ +class SupportReporter < FeedbackReporter + attr_accessor :user_agent, :referer, :rollout, :site_revision, :site_skin + + def report_attributes + super.deep_merge( + "departmentId" => department_id, + "subject" => subject, + "description" => ticket_description, + "cf" => custom_zoho_fields + ) + end + + private + + def custom_zoho_fields + # To avoid issues where Zoho ticket creation silently fails, only grab the first + # 2080 characters of the referer URL. That may miss some complex search queries, + # but still keep enough to be useful most of the time. + truncated_referer = referer.present? ? referer[0..2079] : "" + { + "cf_archive_version" => site_revision.presence || "Unknown site revision", + "cf_rollout" => rollout.presence || "Unknown", + "cf_user_agent" => user_agent.presence || "Unknown user agent", + "cf_ip" => ip_address.presence || "Unknown IP", + "cf_ticket_url" => truncated_referer, + "cf_site_skin" => site_skin&.public ? site_skin.title : "Custom skin" + } + end + + def department_id + ArchiveConfig.SUPPORT_ZOHO_DEPARTMENT_ID + end + + def subject + return "[#{ArchiveConfig.APP_SHORT_NAME}] Support - #{title.html_safe}" if title.present? + + "[#{ArchiveConfig.APP_SHORT_NAME}] Support - No Title" + end + + def ticket_description + return "No description submitted." if description.blank? + + strip_images(description.html_safe, keep_src: true) + end +end diff --git a/app/models/filter_count.rb b/app/models/filter_count.rb new file mode 100755 index 0000000..7302592 --- /dev/null +++ b/app/models/filter_count.rb @@ -0,0 +1,141 @@ +class FilterCount < ApplicationRecord + belongs_to :filter, class_name: 'Tag', inverse_of: :filter_count + validates_presence_of :filter_id + validates_uniqueness_of :filter_id + + # "Large" filter counts should be updated less frequently, to reduce strain + # on the database. + def self.large + where("unhidden_works_count > ?", + ArchiveConfig.LARGE_FILTER_COUNT_THRESHOLD || 1000) + end + + # Return a relation containing all tags that need FilterCount objects. + # We only need to cache counts for canonical tags, because non-canonicals + # don't have associated filter-taggings. And we only need to cache counts for + # user-defined tags, because those are the only ones whose counts are used + # and/or displayed. + def self.filters_needing_counts + Tag.canonical.where(type: Tag::USER_DEFINED) + end + + # Set accurate filter counts for all canonical tags + def self.set_all + filters_needing_counts.select(:id).find_in_batches do |batch| + enqueue_filters(batch) + end + end + + def self.suspended? + admin_settings = AdminSetting.current + admin_settings.suspend_filter_counts? + end + + #################### + # DELAYED JOBS + #################### + + include AsyncWithResque + @queue = :utilities + + #################### + # QUEUE MANAGEMENT + #################### + + REDIS = REDIS_GENERAL + QUEUE_KEY_SMALL = "filter_count:queue_small".freeze + QUEUE_KEY_LARGE = "filter_count:queue_large".freeze + BATCH_SIZE = 1000 + + # Queue up a single filter (or filter ID) to have its counts recalculated. + def self.enqueue_filter(filter) + enqueue_filters([filter]) + end + + # Queue up a list of filters (or filter IDs) to have their filter counts + # recalculated in the next periodic task. + def self.enqueue_filters(filters) + return if suspended? || filters.blank? + + ids = filters.map do |filter| + filter.respond_to?(:id) ? filter.id : filter + end.uniq + + # Separate the large filters from the small filters, so that they can be + # processed at different intervals. + large_ids = FilterCount.large.where(filter_id: ids).pluck(:filter_id) + small_ids = ids - large_ids + + # Add all filters to the appropriate queues. + REDIS.sadd(QUEUE_KEY_LARGE, large_ids) if large_ids.present? + REDIS.sadd(QUEUE_KEY_SMALL, small_ids) if small_ids.present? + end + + # Update counts for small filters. + def self.update_counts_for_small_queue + update_counts_for_queue(QUEUE_KEY_SMALL) + end + + # Update counts for large filters. + def self.update_counts_for_large_queue + update_counts_for_queue(QUEUE_KEY_LARGE) + end + + # Divide the queue up into batches of size BATCH_SIZE, and asynchronously + # process each batch. + def self.update_counts_for_queue(queue_key) + return if suspended? || REDIS.scard(queue_key).zero? + + # Rename to a temporary key to make sure that we don't run into concurrency + # issues. + temp_key = "#{queue_key}:#{Time.now.to_i}" + return unless REDIS.renamenx(queue_key, temp_key) + + while REDIS.scard(temp_key).positive? + batch = REDIS.spop(temp_key, BATCH_SIZE) + + # Build a separate REDIS set for the next batch to process. + batch_key = "#{temp_key}:#{batch.first}" + REDIS.sadd(batch_key, batch) + async(:update_counts_for_batch, batch_key) + end + + REDIS.del(temp_key) + end + + # Given the key for a batch of filter IDs, either update or create the + # FilterCount objects for those filters. + def self.update_counts_for_batch(key) + batch_ids = REDIS.smembers(key).map(&:to_i) + + filters_needing_counts.where(id: batch_ids).each do |filter| + if filter.filter_count.nil? + filter.build_filter_count.update_counts + else + filter.filter_count.update_counts + end + end + + REDIS.del(key) + end + + #################### + # COUNT CALCULATION + #################### + + # Calculate the two counts for this object, and save the results. + def update_counts + # Perform a single SQL query to get the counts of restricted and + # unrestricted works with the desired filter. + counts = filter.filtered_works.posted.unhidden.group(:restricted).count + + # Retrieve the total number of works with restricted set to false. + self.public_works_count = counts[false].to_i + + # Combine the restricted/unrestricted totals to get the number visible to + # logged-in users. + self.unhidden_works_count = counts.values.sum + + save if changed? + end +end diff --git a/app/models/filter_tagging.rb b/app/models/filter_tagging.rb new file mode 100755 index 0000000..2f451b4 --- /dev/null +++ b/app/models/filter_tagging.rb @@ -0,0 +1,30 @@ +# This is essentially a mirror of the taggings table as applied to works (right now) +# except with all works connected to canonical tags instead of their synonyms for +# browsing and filtering purposes. Filter = tag, filterable = thing that's been tagged. +# +# Note that this doesn't have very many validations or callbacks -- this is +# because the ONLY class that should be adding/updating FilterTaggings is the +# FilterUpdater, which handles those itself. +class FilterTagging < ApplicationRecord + belongs_to :filter, class_name: "Tag", inverse_of: :filter_taggings + belongs_to :filterable, polymorphic: true, inverse_of: :filter_taggings + + validates_uniqueness_of :filter_id, scope: [:filterable_type, :filterable_id] + + after_destroy_commit :expire_caches + def expire_caches + return unless filterable_type == "Work" + + CacheMaster.record(filterable_id, "tag", filter_id) + end + + def self.update_filter_counts_since(date) + if date + FilterCount.enqueue_filters( + FilterTagging.where("created_at > ?", date).distinct.pluck(:filter_id) + ) + else + raise "date not set for filter count suspension! very bad!" + end + end +end diff --git a/app/models/filter_updater.rb b/app/models/filter_updater.rb new file mode 100755 index 0000000..5b044ff --- /dev/null +++ b/app/models/filter_updater.rb @@ -0,0 +1,212 @@ +# frozen_string_literal: true + +# A class for calculating the filters that should be on a particular +# filterable, and updating the FilterTaggings to match. +# +# Operates in bulk to try to work faster. +class FilterUpdater + include AfterCommitEverywhere + + attr_reader :klass, :type, :ids, :reindex_queue + + # Takes as argument the type of filterable that we're modifying, the list of + # IDs of filterables that we're modifying, and the priority of the current + # change. (The priority, reindex_queue, is not used in this class. It's just + # passed along to the filterable class through reindex_for_filter_changes.) + def initialize(type, ids, reindex_queue) + @type = type.to_s + @ids = ids.to_a + @reindex_queue = reindex_queue + + @klass = [Work, ExternalWork, Collection].find { |klass| klass.to_s == @type } + + raise "FilterUpdater type '#{type}' not allowed." unless @klass + + # A list for storing all of the FilterTaggings that we end up creating, + # modifying, or deleting. That way, we have a better idea of what we need + # to reindex. + @modified = [] + end + + ######################################## + # DELAY CALCULATIONS WITH RESQUE + ######################################## + + # Put this object on the Resque queue so that update will be called later. + def async_update(job_queue: :utilities) + Resque.enqueue_to(job_queue, self.class, type, ids, reindex_queue) + end + + # Perform for Resque. + def self.perform(type, ids, reindex_queue) + FilterUpdater.new(type, ids, reindex_queue).update + end + + ######################################## + # COMPUTE INFO + ######################################## + + # Calculate what the filters should be for every valid item in the batch, and + # updates the existing FilterTaggings to match. + def update + FilterTagging.transaction do + load_info + + filter_taggings_by_id = FilterTagging.where( + filterable_type: type, filterable_id: @valid_item_ids + ).group_by(&:filterable_id) + + @valid_item_ids.each do |id| + update_filters_for_item(id, filter_taggings_by_id[id] || []) + end + end + + # Even if we're inside a nested transaction, the asynchronous steps + # required by reindexing should always take place outside of the + # transaction. + after_commit { reindex_changed } + end + + private + + # Calculate what the filters should be for a particular item, and perform the + # updates needed to ensure that those are the current filter taggings. Takes + # as argument the ID of the item to update, and the list of filter_taggings + # for that item. + def update_filters_for_item(item_id, filter_taggings) + missing_direct = Set.new(@direct_filters[item_id]) + missing_inherited = Set.new(@inherited_filters[item_id]) + + filter_taggings.each do |ft| + if missing_direct.delete?(ft.filter_id) + update_inherited(ft, false) + elsif missing_inherited.delete?(ft.filter_id) + update_inherited(ft, true) + else + destroy(ft) + end + end + + create_multiple(item_id, missing_direct, false) + create_multiple(item_id, missing_inherited, true) + end + + # Notify the filterable class about the changes that we made, so that it can + # perform the appropriate steps to reindex everything. + def reindex_changed + klass.reindex_for_filter_changes(@valid_item_ids, @modified, reindex_queue) + end + + ######################################## + # RETRIEVE INFO FROM DATABASE + ######################################## + + # Calculates @direct_filters, @meta_tags, and @inherited_filters for this + # batch of items. + def load_info + load_valid_item_ids + load_direct_filters + load_meta_tags + load_inherited_filters + end + + # Calculate which items exist in the database, so that we don't try to create + # FilterTaggings for items that have been deleted. + def load_valid_item_ids + @valid_item_ids = klass.unscoped.where(id: ids).distinct.pluck(:id) + end + + # Calculates what the direct filters should be for this batch of items. + # + # Sets @direct_filters equal to a hash mapping from item IDs to a list of + # direct filter IDs (that is, filters that the item is either directly tagged + # with, or tagged with one of its synonyms). The default value for the + # hash is an empty list. + def load_direct_filters + taggings = Tagging.where(taggable_type: type, taggable_id: @valid_item_ids) + + filter_relations = [ + Tag.canonical.joins(:taggings), + Tag.canonical.joins(mergers: :taggings) + ] + + pairs = filter_relations.flat_map do |filters| + filters.merge(taggings).pluck("taggings.taggable_id", "tags.id") + end + + @direct_filters = hash_from_pairs(pairs) + end + + # Reads MetaTagging info from the database for all tags included in this + # batch. + # + # Sets @meta_tags equal to a hash mapping from tag IDs to the tag's metatag + # IDs. The default value for the hash is an empty list. + def load_meta_tags + all_filters = @direct_filters.values.flatten.uniq + + pairs = Tag.canonical.joins(:sub_taggings).where( + meta_taggings: { sub_tag_id: all_filters } + ).pluck(:sub_tag_id, :meta_tag_id) + + @meta_tags = hash_from_pairs(pairs) + end + + # Uses @direct_filters and @meta_tags to calculate what the inherited filters + # should be for each of the items in this batch. Creates a hash + # @inherited_filters mapping from item IDs to the inherited tag IDs. + def load_inherited_filters + @inherited_filters = Hash.new([].freeze) + + @direct_filters.each_pair do |item_id, filter_ids| + inherited = filter_ids.flat_map { |filter_id| @meta_tags[filter_id] } + @inherited_filters[item_id] = (inherited - filter_ids).uniq + end + end + + # Given a list of pairs of IDs, treat each pair as a (key, value) pair, and + # return a hash that associates each key with a list of values. Sets the + # default value of the hash to an empty frozen list, and freezes all of the + # lists in the hash at the end. + def hash_from_pairs(pairs) + hash = Hash.new([].freeze) + + pairs.uniq.each do |key, value| + hash[key] = [] unless hash.key?(key) + hash[key] << value + end + + hash.transform_values!(&:freeze) + end + + ######################################## + # CHANGE FILTERS AND RECORD + ######################################## + + # Create multiple FilterTaggings for the same item, with the given + # filter_ids. Records the new item in the list @modified. + def create_multiple(item_id, filter_ids, inherited) + filter_ids.each do |filter_id| + @modified << FilterTagging.create(filter_id: filter_id, + filterable_type: type, + filterable_id: item_id, + inherited: inherited) + end + end + + # Modify an existing filter tagging, and record the modified item in the list + # @modified. + def update_inherited(filter_tagging, inherited) + return if filter_tagging.inherited == inherited + + filter_tagging.update(inherited: inherited) + @modified << filter_tagging + end + + # Destroy an existing filter tagging, and record the modified item in + # the list @modified. + def destroy(filter_tagging) + filter_tagging.destroy + @modified << filter_tagging + end +end diff --git a/app/models/freeform.rb b/app/models/freeform.rb new file mode 100755 index 0000000..784cd0e --- /dev/null +++ b/app/models/freeform.rb @@ -0,0 +1,37 @@ +class Freeform < Tag + + NAME = ArchiveConfig.FREEFORM_CATEGORY_NAME + + def self.label_name + "Additional Tags" + end + + # Types of tags to which a freeform tag can belong via common taggings or meta taggings + def parent_types + ['Fandom', 'MetaTag'] + end + def child_types + ['SubTag', 'Merger'] + end + + def characters + parents.select {|t| t.is_a? Character}.sort + end + + def relationships + parents.select {|t| t.is_a? Relationship}.sort + end + + def freeforms + (parents + children).select {|t| t.is_a? Freeform}.sort + end + + def fandoms + parents.select {|t| t.is_a? Fandom}.sort + end + + def medias + parents.select {|t| t.is_a? Media}.sort + end + +end diff --git a/app/models/gift.rb b/app/models/gift.rb new file mode 100755 index 0000000..3d06a31 --- /dev/null +++ b/app/models/gift.rb @@ -0,0 +1,75 @@ +class Gift < ApplicationRecord + NAME_LENGTH_MAX = 100 + + belongs_to :work, touch: true + belongs_to :pseud + has_one :user, through: :pseud + + validates_length_of :recipient_name, + maximum: NAME_LENGTH_MAX, + too_long: ts("must be less than %{max} characters long.", max: NAME_LENGTH_MAX), + allow_blank: true + + validates_format_of :recipient_name, + message: ts("must contain at least one letter or number."), + with: /[a-zA-Z0-9]/, + allow_blank: true + + validate :has_name_or_pseud + def has_name_or_pseud + unless self.pseud || !self.recipient_name.blank? + errors.add(:base, ts("A gift must have a recipient specified.")) + end + end + + validates_uniqueness_of :pseud_id, + scope: :work_id, + message: ts("You can't give a gift to the same person twice.") + + # Don't allow giving the same gift to the same user more than once + validate :has_not_given_to_user + def has_not_given_to_user + if self.pseud && self.work + other_pseuds = Gift.where(work_id: self.work_id).pluck(:pseud_id) - [self.pseud_id] + if Pseud.where(id: other_pseuds, user_id: self.pseud.user_id).exists? + errors.add(:base, ts("You seem to already have given this work to that user.")) + end + end + end + + scope :for_pseud, lambda {|pseud| where("pseud_id = ?", pseud.id)} + + scope :for_user, lambda {|user| where("pseud_id IN (?)", user.pseuds.collect(&:id).flatten)} + + scope :for_recipient_name, lambda {|name| where("recipient_name = ?", name)} + + scope :for_name_or_byline, lambda { |name| + where("recipient_name = ? OR pseud_id = ?", + name, + Pseud.parse_byline(name)) + } + + scope :in_collection, lambda {|collection| + select("DISTINCT gifts.*"). + joins({work: :collection_items}). + where("collection_items.collection_id = ?", collection.id) + } + + scope :name_only, -> { select(:recipient_name) } + + scope :include_pseuds, -> { includes(work: [:pseuds]) } + + scope :not_rejected, -> { where(rejected: false) } + + scope :are_rejected, -> { where(rejected: true) } + + def recipient=(new_recipient_name) + self.pseud = Pseud.parse_byline(new_recipient_name) + self.recipient_name = pseud ? nil : new_recipient_name + end + + def recipient + pseud ? pseud.byline : recipient_name + end + +end diff --git a/app/models/inbox_comment.rb b/app/models/inbox_comment.rb new file mode 100755 index 0000000..e766afb --- /dev/null +++ b/app/models/inbox_comment.rb @@ -0,0 +1,43 @@ +class InboxComment < ApplicationRecord + validates_presence_of :user_id + validates_presence_of :feedback_comment_id + + belongs_to :user + belongs_to :feedback_comment, class_name: 'Comment' + + # Filters inbox comments by read and/or replied to and sorts by date + scope :find_by_filters, lambda { |filters| + read = case filters[:read] + when 'true' then true + when 'false' then false + else [true, false] + end + replied_to = case filters[:replied_to] + when 'true' then true + when 'false' then false + else [true, false] + end + direction = (filters[:date]&.upcase == "ASC" ? "created_at ASC" : "created_at DESC") + + includes(feedback_comment: :pseud). + order(direction). + where(read: read, replied_to: replied_to) + } + + scope :for_homepage, -> { + where(read: false). + order(created_at: :desc). + limit(ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE) + } + + # Gets the number of unread comments + def self.count_unread + where(read: false).count + end + + # Remove comments that do not exist, were flagged as spam, or hidden by admin + def self.with_bad_comments_removed + joins("LEFT JOIN comments ON comments.id = inbox_comments.feedback_comment_id") + .where("comments.id IS NOT NULL AND comments.is_deleted = 0 AND comments.approved AND NOT comments.hidden_by_admin") + end +end diff --git a/app/models/indexing/cache_master.rb b/app/models/indexing/cache_master.rb new file mode 100755 index 0000000..4a0d5be --- /dev/null +++ b/app/models/indexing/cache_master.rb @@ -0,0 +1,63 @@ +class CacheMaster + + CACHED_CLASSES = %w(Work Tag User Pseud Collection) + + ################### + # CLASS METHODS + ################### + + def self.expire_caches(work_ids) + work_ids.each { |id| self.new(id).expire } + end + + def self.record(work_id, owner_type, owner_id) + self.new(work_id).record(owner_type, owner_id) + end + + ################### + # INSTANCE METHODS + ################### + + attr_reader :work_id + + def initialize(work_id) + @work_id = work_id + end + + def key + "works:#{work_id}:assocs" + end + + def get_hash + REDIS_GENERAL.hgetall(key) + end + + def get_value(owner_type) + REDIS_GENERAL.hget(key, owner_type) + end + + def set_value(owner_type, value) + REDIS_GENERAL.hset(key, owner_type, value) + end + + def reset! + REDIS_GENERAL.del(key) + end + + def record(owner_type, owner_id) + owner_type = owner_type.to_s + data = get_value(owner_type) + value = data.nil? ? owner_id.to_s : "#{data},#{owner_id}" + set_value(owner_type, value) + end + + def expire + get_hash.each_pair do |key, id_string| + raise "Redshirt: Attempted to constantize invalid class initialize expire #{key.classify}" unless CACHED_CLASSES.include?(key.classify) + klass = key.classify.constantize + klass.expire_ids(id_string.split(',')) + end + reset! + end + +end diff --git a/app/models/indexing/index_queue.rb b/app/models/indexing/index_queue.rb new file mode 100755 index 0000000..c1d61cb --- /dev/null +++ b/app/models/indexing/index_queue.rb @@ -0,0 +1,92 @@ +class IndexQueue + + BATCH_SIZE = 1000 + REDIS = REDIS_GENERAL + + ################## + # CLASS METHODS + ################## + + def self.all + REDIS.keys("index:*") + end + + def self.get_key(klass, label) + klass = klass.is_a?(Class) ? klass.base_class : klass + "index:#{klass.to_s.underscore}:#{label}" + end + + def self.enqueue(object, label) + klass = object.is_a?(Tag) ? 'Tag' : object.class.to_s + enqueue_id(klass, object.id, label) + end + + def self.enqueue_id(klass, id, label) + key = get_key(klass, label) + new(key).add_id(id) + end + + def self.enqueue_ids(klass, ids, label) + key = get_key(klass, label) + new(key).add_ids(ids) + end + + def self.from_class_and_label(klass, label) + new(get_key(klass, label)) + end + + #################### + # INSTANCE METHODS + #################### + + attr_reader :name + + def initialize(name) + @name = name + @old_name = name + end + + def add_id(id) + REDIS.sadd(name, id) + end + + def add_ids(ids) + REDIS.sadd(name, ids) unless ids.blank? + end + + def run + return unless exists? + rename + create_subqueues + delete + end + + def ids + @ids = REDIS.smembers(name) + end + + private + + def exists? + REDIS.exists(name) + end + + def rename + @name = "#{name}:#{Time.now.to_i}" + REDIS.rename(@old_name, @name) + end + + def create_subqueues + _, klass, label = name.split(":") + klass = klass.classify # convert to the uppercase version + + ids.in_groups_of(BATCH_SIZE, false).each_with_index do |id_batch, i| + AsyncIndexer.index(klass, id_batch, label) + end + end + + def delete + REDIS.del(name) + end + +end diff --git a/app/models/indexing/scheduled_reindex_job.rb b/app/models/indexing/scheduled_reindex_job.rb new file mode 100755 index 0000000..5d37481 --- /dev/null +++ b/app/models/indexing/scheduled_reindex_job.rb @@ -0,0 +1,18 @@ +class ScheduledReindexJob + MAIN_CLASSES = %w[Pseud Tag Work Bookmark Series ExternalWork User].freeze + + def self.perform(reindex_type) + classes = case reindex_type + when 'main', 'background' + MAIN_CLASSES + when 'stats' + %w(StatCounter) + end + classes.each{ |klass| run_queue(klass, reindex_type) } + end + + def self.run_queue(klass, reindex_type) + IndexQueue.from_class_and_label(klass, reindex_type).run + end + +end diff --git a/app/models/inherited_meta_tag_updater.rb b/app/models/inherited_meta_tag_updater.rb new file mode 100755 index 0000000..4af3d63 --- /dev/null +++ b/app/models/inherited_meta_tag_updater.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +# A helper class for calculating inherited meta taggings. +class InheritedMetaTagUpdater + attr_reader :base, :boundary, :all + + def initialize(base) + @base = base + @boundary = [base.id] + @all = [base.id] + end + + # Advance to the next depth of our breadth-first search. + def advance + return if done? + + @boundary = MetaTagging.where( + direct: true, + sub_tag_id: @boundary + ).pluck(:meta_tag_id) - @all + + @all += @boundary + end + + # Check whether we're done finding all of our inherited metatags. + def done? + @boundary.empty? + end + + # Go through the breadth-first search steps to figure out what this tag's + # inherited metatags should be. + def calculate + advance until done? + end + + # Generate the missing inherited meta taggings and delete the ones that are + # no longer needed. Returns true if any meta taggings were created/deleted, + # and false otherwise. + def update + calculate + + # Keep track of whether the meta taggings were modified: + modified = false + + missing = Set.new(all) + missing.delete(base.id) + + # Delete the unnecessary meta taggings. + base.meta_taggings.each do |mt| + # If the metatag ID is in the list of IDs we're looking for, we don't + # need to modify the meta tagging at all -- we just need to mark that + # we've seen it by removing it from the list of missing metatag IDs. + # + # We also shouldn't modify the meta tagging if it's direct. + next if missing.delete?(mt.meta_tag_id) || mt.direct + + # The inherited metatag isn't one of the ones we're expecting to see, + # which means that it shouldn't be here: + mt.destroy + modified = true + end + + # Build the missing meta taggings. + Tag.where(id: missing.to_a).each do |tag| + base.meta_taggings.create(direct: false, meta_tag: tag) + modified = true + end + + modified + end + + # Fixes inherited metatags for all tags with at least one meta tagging. + def self.update_all + Tag.joins(:meta_taggings).distinct.find_each do |tag| + new(tag).update + + # Yield each tag to allow for progress messages. + yield tag if block_given? + end + end +end diff --git a/app/models/invitation.rb b/app/models/invitation.rb new file mode 100755 index 0000000..7cea09d --- /dev/null +++ b/app/models/invitation.rb @@ -0,0 +1,106 @@ +# Beta invitations +# http://railscasts.com/episodes/124-beta-invitations +class Invitation < ApplicationRecord + belongs_to :creator, polymorphic: true + belongs_to :invitee, polymorphic: true + belongs_to :external_author + + validate :recipient_is_not_registered, on: :create + def recipient_is_not_registered + # we allow invitations to be sent to existing users if the purpose is to claim an external author + if self.invitee_email && User.find_by(email: self.invitee_email) && !self.external_author + errors.add :invitee_email, ts('is already being used by an account holder.') + end + end + + # ensure email is valid + validates :invitee_email, email_format: true, allow_blank: true + + scope :unsent, -> { where(invitee_email: nil, redeemed_at: nil) } + scope :unredeemed, -> { where('invitee_email IS NOT NULL and redeemed_at IS NULL') } + scope :redeemed, -> { where('redeemed_at IS NOT NULL') } + scope :from_queue, -> { where(external_author: nil).where(creator_type: [nil, "Admin"]) } + + before_validation :generate_token, on: :create + after_save :send_and_set_date, if: :saved_change_to_invitee_email? + after_save :adjust_user_invite_status + + #Create a certain number of invitations for all valid users + def self.grant_all(total) + raise unless total > 0 && total < 20 + User.valid.each do |user| + total.times do + user.invitations.create + end + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.invite_increase_notification(user.id, total).deliver_later + end + end + User.out_of_invites.update_all('out_of_invites = 0') + end + + #Create a certain number of invitations for all users who are out of them + def self.grant_empty(total) + raise unless total > 0 && total < 20 + User.valid.out_of_invites.each do |user| + total.times do + user.invitations.create + end + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.invite_increase_notification(user.id, total).deliver_later + end + end + User.out_of_invites.update_all('out_of_invites = 0') + end + + def mark_as_redeemed(user=nil) + self.invitee = user + self.redeemed_at = Time.now + save + end + + def send_and_set_date(resend: false) + return if invitee_email.blank? + + if self.external_author + archivist = self.external_author.external_creatorships.collect(&:archivist).collect(&:login).uniq.join(", ") + # send invite synchronously for now -- this should now work delayed but just to be safe + UserMailer.invitation_to_claim(self.id, archivist).deliver_now + else + # send invitations actively sent by a user synchronously to avoid delays + UserMailer.invitation(self.id).deliver_now + end + + # Skip callbacks within after_save by using update_column to avoid a callback loop + if resend + attrs = { resent_at: Time.current } + # This applies to old invites when AO3-6094 wasn't fixed. + attrs[:sent_at] = self.created_at if self.sent_at.nil? + self.update_columns(attrs) + else + self.update_column(:sent_at, Time.current) + end + rescue StandardError => e + errors.add(:base, :notification_could_not_be_sent, error: e.message) + end + + def can_resend? + # created_at fallback is a vestige of the already fixed AO3-6094. + checked_date = self.resent_at || self.sent_at || self.created_at + checked_date < ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION.hours.ago + end + + private + + def generate_token + self.token = Digest::SHA1.hexdigest([Time.current, rand].join) + end + + #Update the user's out_of_invites status + def adjust_user_invite_status + if self.creator.respond_to?(:out_of_invites) + self.creator.out_of_invites = (self.creator.invitations.unredeemed.count < 1) + self.creator.save!(validate: false) + end + end +end diff --git a/app/models/invite_request.rb b/app/models/invite_request.rb new file mode 100755 index 0000000..d17857c --- /dev/null +++ b/app/models/invite_request.rb @@ -0,0 +1,60 @@ +class InviteRequest < ApplicationRecord + validates :email, presence: true, email_format: true + validates :email, uniqueness: { message: "is already part of our queue." } + before_validation :set_simplified_email, on: :create + validate :check_admin_banned_list, on: :create + validate :compare_with_users, on: :create + validate :simplified_email_uniqueness, on: :create + + # Borrow the blacklist cleaner but just strip out all the periods for all domains + def set_simplified_email + return if email.blank? + + simplified = AdminBlacklistedEmail.canonical_email(email).split('@') + self.simplified_email = simplified.first.delete(".").gsub(/\+.+$/, "") + "@#{simplified.last}" + end + + # Doing this with a method so the error message makes more sense + def simplified_email_uniqueness + # Exit if raw email uniqueness error already exists + return if errors.of_kind?(:email, :taken) + + errors.add(:email, "is already part of our queue.") if InviteRequest.exists?(simplified_email: simplified_email) + end + + def proposed_fill_time + admin_settings = AdminSetting.current + number_of_rounds = (self.position.to_f/admin_settings.invite_from_queue_number.to_f).ceil - 1 + proposed_time = admin_settings.invite_from_queue_at + (admin_settings.invite_from_queue_frequency * number_of_rounds).hours + Time.current > proposed_time ? Time.current : proposed_time + end + + def position + InviteRequest.where("id <= ?", id).count + end + + # Ensure that email is not banned + def check_admin_banned_list + return unless email.present? && AdminBlacklistedEmail.is_blacklisted?(email) + + errors.add(:email, :blocked_email) + throw :abort + end + + # Ensure that invite request is for a new user + def compare_with_users + return unless User.exists?(email: self.email) + + errors.add(:email, :email_in_use) + throw :abort + end + + # Turn a request into an invite and then remove it from the queue + def invite_and_remove(creator=nil) + invitation = creator ? creator.invitations.build(invitee_email: self.email, from_queue: true) : + Invitation.new(invitee_email: self.email, from_queue: true) + if invitation.save + self.destroy + end + end +end diff --git a/app/models/known_issue.rb b/app/models/known_issue.rb new file mode 100755 index 0000000..d00c8b0 --- /dev/null +++ b/app/models/known_issue.rb @@ -0,0 +1,20 @@ +class KnownIssue < ApplicationRecord + # why is this included here? FIXME? + include HtmlCleaner + + validates_presence_of :title + validates_length_of :title, + minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} letters long.", min: ArchiveConfig.TITLE_MIN) + + validates_length_of :title, + maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.TITLE_MAX) + + validates_presence_of :content + validates_length_of :content, minimum: ArchiveConfig.CONTENT_MIN, + too_short: ts("must be at least %{min} letters long.", min: ArchiveConfig.CONTENT_MIN) + + validates_length_of :content, maximum: ArchiveConfig.CONTENT_MAX, + too_long: ts("cannot be more than %{max} characters long.", max: ArchiveConfig.CONTENT_MAX) +end diff --git a/app/models/kudo.rb b/app/models/kudo.rb new file mode 100755 index 0000000..f420453 --- /dev/null +++ b/app/models/kudo.rb @@ -0,0 +1,105 @@ +class Kudo < ApplicationRecord + include Responder + + VALID_COMMENTABLE_TYPES = %w[Work].freeze + + belongs_to :user + belongs_to :commentable, polymorphic: true + + validates :commentable_type, inclusion: { in: VALID_COMMENTABLE_TYPES } + validates :commentable, + presence: true, + if: proc { |c| VALID_COMMENTABLE_TYPES.include?(c.commentable_type) } + + validates :user, not_blocked: { by: :commentable, on: :create } + + validate :cannot_be_author, on: :create + def cannot_be_author + return unless user&.is_author_of?(commentable) + + errors.add(:commentable, :author_on_own_work) + end + + validate :guest_cannot_kudos_restricted_work, on: :create + def guest_cannot_kudos_restricted_work + return unless user.blank? && commentable.is_a?(Work) && commentable.restricted? + + errors.add(:commentable, :guest_on_restricted) + end + + validate :cannot_be_suspended, on: :create + def cannot_be_suspended + return unless user&.banned || user&.suspended + + if user.banned + errors.add(:commentable, :user_is_banned) + else + errors.add(:commentable, :user_is_suspended) + end + end + + validates :ip_address, + uniqueness: { scope: [:commentable_id, :commentable_type] }, + if: proc { |kudo| kudo.ip_address.present? } + + validates :user_id, + uniqueness: { scope: [:commentable_id, :commentable_type] }, + if: proc { |kudo| kudo.user.present? } + + validate :cannot_be_official_user, on: :create + def cannot_be_official_user + return unless user&.official + + errors.add(:user, :official) + end + + validate :cannot_be_archivist_account, on: :create + def cannot_be_archivist_account + return unless user&.archivist + + errors.add(:user, :archivist) + end + + scope :with_user, -> { where("user_id IS NOT NULL") } + scope :by_guest, -> { where("user_id IS NULL") } + + after_destroy :update_work_stats + after_create :after_create, :update_work_stats + def after_create + users = self.commentable.pseuds.map(&:user).uniq + + users.each do |user| + if notify_user_by_email?(user) + RedisMailQueue.queue_kudo(user, self) + end + end + end + + after_save :expire_caches + def expire_caches + if commentable_type == "Work" + # Expire the work's cached total kudos count. + Rails.cache.delete("works/#{commentable_id}/kudos_count-v2") + # If it's a guest kudo, also expire the work's cached guest kudos count. + Rails.cache.delete("works/#{commentable_id}/guest_kudos_count-v2") if user_id.nil? + end + + # Expire the cached kudos section under the work. + ActionController::Base.new.expire_fragment("#{commentable.cache_key}/kudos-v4") + end + + def notify_user_by_email?(user) + user.nil? ? false : ( user.is_a?(Admin) ? true : + !(user == User.orphan_account || user.preference.kudos_emails_off?) ) + end + + # Return either the name of the kudo-giver or "guest". + # Used in kudo notifications. + def name + if self.user + user.login + else + "guest" + end + end +end diff --git a/app/models/language.rb b/app/models/language.rb new file mode 100755 index 0000000..314d6e1 --- /dev/null +++ b/app/models/language.rb @@ -0,0 +1,28 @@ +class Language < ApplicationRecord + include WorksOwner + validates :short, presence: true, uniqueness: true, length: { maximum: 4 } + validates :name, presence: true, uniqueness: true + + has_many :works + has_many :locales + has_many :admin_posts + has_many :archive_faqs + + scope :default_order, -> { order(Arel.sql("COALESCE(NULLIF(sortable_name,''), short)")) } + + def to_param + short + end + + def self.default + self.find_or_create_by(short: ArchiveConfig.DEFAULT_LANGUAGE_SHORT, name: ArchiveConfig.DEFAULT_LANGUAGE_NAME) + end + + def work_count + self.works.where(posted: true).count + end + + def fandom_count + Fandom.joins(:works).where(works: { id: self.works.posted.collect(&:id) }).distinct.select("tags.id").count + end +end diff --git a/app/models/last_wrangling_activity.rb b/app/models/last_wrangling_activity.rb new file mode 100755 index 0000000..ab9577e --- /dev/null +++ b/app/models/last_wrangling_activity.rb @@ -0,0 +1,3 @@ +class LastWranglingActivity < ApplicationRecord + belongs_to :user +end diff --git a/app/models/locale.rb b/app/models/locale.rb new file mode 100755 index 0000000..253d97c --- /dev/null +++ b/app/models/locale.rb @@ -0,0 +1,28 @@ +class Locale < ApplicationRecord + belongs_to :language + validates_presence_of :iso + validates :iso, uniqueness: true + validates_presence_of :name + + scope :default_order, -> { order(:iso) } + + def to_param + iso + end + + def self.default + language = Language.default + Locale.set_base_locale(iso: ArchiveConfig.DEFAULT_LOCALE_ISO, name: ArchiveConfig.DEFAULT_LOCALE_NAME, language_id: language.id) + end + + def self.set_base_locale(locale={iso: "en", name: "English"}) + language = Language.find_by(short: ArchiveConfig.DEFAULT_LANGUAGE_SHORT) + Locale.find_by(iso: locale[:iso].to_s) || language.locales.create(iso: locale[:iso].to_s, name: locale[:name].to_s, main: 1) + end + + after_update :update_translations, if: :saved_change_to_iso? + def update_translations + ArchiveFaq::Translation.where(locale: iso_before_last_save).update_all(locale: iso) + Question::Translation.where(locale: iso_before_last_save).update_all(locale: iso) + end +end diff --git a/app/models/log_item.rb b/app/models/log_item.rb new file mode 100755 index 0000000..3c14592 --- /dev/null +++ b/app/models/log_item.rb @@ -0,0 +1,17 @@ +class LogItem < ApplicationRecord + # Ignore the note_sanitizer_version field until it can be deleted. + self.ignored_columns = [:note_sanitizer_version] + + belongs_to :user + belongs_to :admin + + belongs_to :role + + belongs_to :fnok_user, class_name: "User" + + validates_presence_of :note + validates_presence_of :action + + validates_length_of :note, maximum: ArchiveConfig.LOGNOTE_MAX + +end diff --git a/app/models/media.rb b/app/models/media.rb new file mode 100755 index 0000000..366f905 --- /dev/null +++ b/app/models/media.rb @@ -0,0 +1,36 @@ +class Media < Tag + NAME = ArchiveConfig.MEDIA_CATEGORY_NAME + + has_many :common_taggings, as: :filterable + has_many :fandoms, -> { where(type: 'Fandom') }, through: :common_taggings, source: :common_tag + + after_create :expire_caches + after_update :expire_caches, if: -> { saved_change_to_name? || saved_change_to_type? || saved_change_to_canonical? } + after_destroy :expire_caches + + def expire_caches + ActionController::Base.new.expire_fragment("menu-fandoms-version5") + ActionController::Base.new.expire_fragment("homepage-fandoms-version2") + end + + def child_types + ['Fandom'] + end + + # The media tag for unwrangled fandoms + def self.uncategorized + tag = self.find_or_create_by_name(ArchiveConfig.MEDIA_UNCATEGORIZED_NAME) + tag.update(canonical: true) unless tag.canonical + tag + end + + # The list of media used for the menu on every page. All media except "No + # Media" and "Uncategorized Fandoms" are listed in order, and then + # "Uncategorized Fandoms" is tacked onto the list at the end. + def self.for_menu + canonical.by_name.where.not( + name: [ArchiveConfig.MEDIA_UNCATEGORIZED_NAME, + ArchiveConfig.MEDIA_NO_TAG_NAME] + ).to_a + [uncategorized] + end +end diff --git a/app/models/meta_tagging.rb b/app/models/meta_tagging.rb new file mode 100755 index 0000000..6be7247 --- /dev/null +++ b/app/models/meta_tagging.rb @@ -0,0 +1,55 @@ +# Relationships between meta and sub tags +# Meta tags represent a superset of sub tags +class MetaTagging < ApplicationRecord + include Wrangleable + + belongs_to :meta_tag, class_name: 'Tag' + belongs_to :sub_tag, class_name: 'Tag' + + validates_presence_of :meta_tag, :sub_tag, message: "does not exist." + validates_uniqueness_of :meta_tag_id, + scope: :sub_tag_id, + message: "has already been added (possibly as an indirect metatag)." + + after_create :expire_caching + after_destroy :expire_caching + after_commit :update_inherited + + validate :meta_tag_validation + def meta_tag_validation + if self.meta_tag && self.sub_tag + unless self.meta_tag.class == self.sub_tag.class + self.errors.add(:base, "Meta taggings can only exist between two tags of the same type.") + end + unless self.meta_tag.canonical? && self.sub_tag.canonical + self.errors.add(:base, "Meta taggings can only exist between canonical tags.") + end + if self.meta_tag == self.sub_tag + self.errors.add(:base, "A tag can't be its own metatag.") + end + if self.meta_tag.meta_taggings.where(meta_tag: self.sub_tag).exists? + self.errors.add(:base, "A metatag can't be its own grandparent.") + end + end + end + + def update_inherited + sub_tag.async(:update_inherited_meta_tags) if direct && sub_tag + end + + def expire_caching + self.meta_tag&.update_works_index_timestamp! + end + + # Go through all MetaTaggings and destroy the invalid ones. + def self.destroy_invalid + includes(:sub_tag, meta_tag: :meta_tags).find_each do |mt| + valid = mt.valid? + + # Let callers do something on each iteration. + yield mt, valid if block_given? + + mt.destroy unless valid + end + end +end diff --git a/app/models/moderated_work.rb b/app/models/moderated_work.rb new file mode 100755 index 0000000..75760fd --- /dev/null +++ b/app/models/moderated_work.rb @@ -0,0 +1,71 @@ +class ModeratedWork < ApplicationRecord + belongs_to :work + validates :work_id, uniqueness: true + + delegate :title, :revised_at, to: :work + + def self.register(work) + find_or_create_by(work_id: work.id) + end + + def self.mark_reviewed(work) + register(work).mark_reviewed! + end + + def self.mark_approved(work) + register(work).mark_approved! + end + + def self.bulk_update(params = {}) + ids = processed_bulk_ids(params) + transaction do + bulk_review(ids[:spam]) + bulk_approve(ids[:ham]) + end + end + + def self.processed_bulk_ids(params = {}) + spam_ids = params[:spam] || [] + ham_ids = params[:ham] || [] + # Ensure no overlap + admin_confusion = spam_ids & ham_ids + if admin_confusion + spam_ids -= admin_confusion + ham_ids -= admin_confusion + end + { spam: spam_ids, ham: ham_ids } + end + + def self.bulk_review(ids) + return true unless ids.present? + where(id: ids).update_all(reviewed: true, approved: false) + # Ensure works are hidden and spam if they weren't already + Work.joins(:moderated_work).where("moderated_works.id IN (?)", ids).each do |work| + work.notify_of_hiding_for_spam unless work.hidden_by_admin? + work.update(hidden_by_admin: true, spam: true) + end + end + + def self.bulk_approve(ids) + return true unless ids.present? + where(id: ids).update_all("approved = 1") + Work.joins(:moderated_work).where("moderated_works.id IN (?)", ids).each do |work| + work.mark_as_ham! + end + end + + def mark_reviewed! + update_attribute(:reviewed, true) + end + + def mark_approved! + update_attribute(:approved, true) + end + + # Easy access to the creators of spam works + def admin_user_links + work.users.map do |u| + "#{u.login}" + end.join(", ").html_safe + end +end diff --git a/app/models/mute.rb b/app/models/mute.rb new file mode 100755 index 0000000..3bf8387 --- /dev/null +++ b/app/models/mute.rb @@ -0,0 +1,35 @@ +class Mute < ApplicationRecord + include MuteHelper + + belongs_to :muter, class_name: "User" + belongs_to :muted, class_name: "User" + + validates :muter, :muted, presence: true + validates :muted_id, uniqueness: { scope: :muter_id } + + validate :check_self + def check_self + errors.add(:muted, :self) if muted == muter + end + + validate :check_official, if: :muted + def check_official + errors.add(:muted, :official) if muted.official + end + + validate :check_mute_limit + def check_mute_limit + errors.add(:muted, :limit) if muter.muted_users.count >= ArchiveConfig.MAX_MUTED_USERS + end + + after_create :update_cache + after_destroy :update_cache + def update_cache + Rails.cache.write(mute_css_key(muter), mute_css_uncached(muter)) + end + + def muted_byline=(byline) + pseud = Pseud.parse_byline(byline) + self.muted = pseud.user unless pseud.nil? + end +end diff --git a/app/models/offer.rb b/app/models/offer.rb new file mode 100755 index 0000000..2156771 --- /dev/null +++ b/app/models/offer.rb @@ -0,0 +1,7 @@ +class Offer < Prompt + belongs_to :challenge_signup, touch: true, inverse_of: :offers + + def prompt_restriction + collection&.challenge&.offer_restriction + end +end diff --git a/app/models/opendoors.rb b/app/models/opendoors.rb new file mode 100755 index 0000000..5610ea1 --- /dev/null +++ b/app/models/opendoors.rb @@ -0,0 +1,5 @@ +module Opendoors + def self.table_name_prefix + 'opendoors_' + end +end diff --git a/app/models/potential_match.rb b/app/models/potential_match.rb new file mode 100755 index 0000000..4d735cc --- /dev/null +++ b/app/models/potential_match.rb @@ -0,0 +1,284 @@ +class PotentialMatch < ApplicationRecord + # We use "-1" to represent all the requested items matching + ALL = -1 + + CACHE_PROGRESS_KEY = "potential_match_status_for_".freeze + CACHE_SIGNUP_KEY = "potential_match_signups_for_".freeze + CACHE_INTERRUPT_KEY = "potential_match_interrupt_for_".freeze + CACHE_INVALID_SIGNUP_KEY = "potential_match_invalid_signup_for_".freeze + + belongs_to :collection + belongs_to :offer_signup, class_name: "ChallengeSignup" + belongs_to :request_signup, class_name: "ChallengeSignup" + + + def self.progress_key(collection) + CACHE_PROGRESS_KEY + collection.id.to_s + end + + def self.signup_key(collection) + CACHE_SIGNUP_KEY + collection.id.to_s + end + + def self.interrupt_key(collection) + CACHE_INTERRUPT_KEY + collection.id.to_s + end + + def self.invalid_signup_key(collection) + CACHE_INVALID_SIGNUP_KEY + collection.id.to_s + end + + def self.clear!(collection) + # rapidly delete all potential prompt matches and potential matches + # WITHOUT CALLBACKS + pmids = collection.potential_matches.pluck(:id) + PotentialMatch.where(id: pmids).delete_all + end + + def self.set_up_generating(collection) + REDIS_GENERAL.set progress_key(collection), "0.0" + end + + def self.cancel_generation(collection) + REDIS_GENERAL.set interrupt_key(collection), "1" + end + + def self.canceled?(collection) + REDIS_GENERAL.get(interrupt_key(collection)) == "1" + end + + @queue = :collection + + # This only works on class methods + def self.perform(method, *args) + self.send(method, *args) + end + + def self.generate(collection) + Resque.enqueue(self, :generate_in_background, collection.id) + end + + # Regenerate the potential matches for a given signup + def self.regenerate_for_signup(signup) + Resque.enqueue(self, :regenerate_for_signup_in_background, signup.id) + end + + def self.invalid_signups_for(collection) + REDIS_GENERAL.smembers(invalid_signup_key(collection)) + end + + def self.clear_invalid_signups(collection) + REDIS_GENERAL.del invalid_signup_key(collection) + end + + # The actual method that generates the potential matches for an entire collection + def self.generate_in_background(collection_id) + collection = Collection.find(collection_id) + + if collection.challenge.assignments_sent_at.present? + # If assignments have been sent, we don't want to delete everything and + # regenerate. (If the challenge moderator wants to recalculate potential + # matches after sending assignments, they can use the Purge Assignments + # button.) + return + end + + # check for invalid signups + PotentialMatch.clear_invalid_signups(collection) + invalid_signup_ids = collection.signups.reject(&:valid?) + .collect(&:id) + if invalid_signup_ids.present? + invalid_signup_ids.each { |sid| REDIS_GENERAL.sadd invalid_signup_key(collection), sid } + + if collection.collection_email.present? + UserMailer.invalid_signup_notification(collection.id, invalid_signup_ids, collection.collection_email).deliver_later + else + collection.maintainers_list.each do |user| + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.invalid_signup_notification(collection.id, invalid_signup_ids, user.email).deliver_later + end + end + end + PotentialMatch.cancel_generation(collection) + else + + PotentialMatch.clear!(collection) + settings = collection.challenge.potential_match_settings + + if settings.no_match_required? + matcher = PotentialMatcherUnconstrained.new(collection) + else + index_type = PromptTagTypeInfo.new(collection).good_index_types.first + matcher = PotentialMatcherConstrained.new(collection, index_type) + end + + matcher.generate + end + # TODO: for any signups with no potential matches try regenerating? + PotentialMatch.finish_generation(collection) + end + + # Generate potential matches for a single signup. + def self.generate_for_signup(collection, signup, settings, collection_tag_sets, required_types, prompt_type = "request") + # only check the signups that have any overlap + match_signup_ids = PotentialMatch.matching_signup_ids(collection, signup, collection_tag_sets, required_types, prompt_type) + + # We randomize the signup ids to make sure potential matches are distributed across all the participants + match_signup_ids.shuffle.each do |other_signup_id| + next if signup.id == other_signup_id + + # The "match" method of ChallengeSignup creates and returns a new + # (unsaved) potential match object. It assumes the signup that is calling + # is the requesting signup, so if this is meant to be an offering signup + # instead, we call it from the other signup. + if prompt_type == "request" + other_signup = ChallengeSignup.with_offer_tags.find(other_signup_id) + potential_match = signup.match(other_signup, settings) + else + other_signup = ChallengeSignup.with_request_tags.find(other_signup_id) + potential_match = other_signup.match(signup, settings) + end + + potential_match.save if potential_match&.valid? + end + end + + # Get the ids of all signups that have some overlap in the tag types required for matching + def self.matching_signup_ids(collection, signup, collection_tag_sets, required_types, prompt_type = "request") + matching_signup_ids = [] + + if required_types.empty? + # nothing is required, so any signup can match -- check all of them + return collection.signups.pluck(:id) + end + + # get the tagsets used in the signup we are trying to match + signup_tagsets = signup.send(prompt_type.pluralize).pluck(:tag_set_id, :optional_tag_set_id).flatten.compact + + # get the ids of all the tags of the required types in the signup's tagsets + signup_tags = SetTagging.where(tag_set_id: signup_tagsets).joins(:tag).where(tags: { type: required_types }).pluck(:tag_id) + + if signup_tags.empty? + # a match is required by the settings but the user hasn't put any of the required tags in, meaning they are open to anything + return collection.signups.pluck(:id) + else + # now find all the tagsets in the collection that share the original signup's tags + match_tagsets = SetTagging.where(tag_id: signup_tags, tag_set_id: collection_tag_sets).pluck(:tag_set_id).uniq + + # and now we look up any signups that have one of those tagsets in the opposite position -- ie, + # if this signup is a request, we are looking for offers with the same tag; if it's an offer, we're + # looking for requests with the same tag. + matching_signup_ids = (prompt_type == "request" ? Offer : Request) + .where("tag_set_id IN (?) OR optional_tag_set_id IN (?)", match_tagsets, match_tagsets) + .pluck(:challenge_signup_id).compact + + # now add on "any" matches for the required types + condition = case required_types.first.underscore + when "fandom" + "any_fandom = 1" + when "character" + "any_character = 1" + when "rating" + "any_rating = 1" + when "relationship" + "any_relationship = 1" + when "category" + "any_category = 1" + when "archive_warning" + "any_archive_warning = 1" + when "freeform" + "any_freeform = 1" + else + " 1 = 0" + end + matching_signup_ids += collection.prompts.where(condition).pluck(:challenge_signup_id) + end + + matching_signup_ids.uniq + end + + # Regenerate potential matches for a single signup within a challenge where (presumably) + # the other signups already have matches generated. + # To do this, we have to regenerate its potential matches both as a request and as an offer + # (instead of just generating them as a request as we do when generating ALL potential matches) + def self.regenerate_for_signup_in_background(signup_id) + # The signup will be acting as both offer and request, so we want to load + # both request tags and offer tags. + signup = ChallengeSignup.with_request_tags.with_offer_tags.find(signup_id) + collection = signup.collection + + # Get all the data + settings = collection.challenge.potential_match_settings + collection_tag_sets = Prompt.where(collection_id: collection.id).pluck(:tag_set_id, :optional_tag_set_id).flatten.compact + required_types = settings.required_types.map(&:classify) + + # clear the existing potential matches for this signup in each direction + signup.offer_potential_matches.destroy_all + signup.request_potential_matches.destroy_all + + # We check the signup in both directions -- as a request signup and as an offer signup + %w[request offer].each do |prompt_type| + PotentialMatch.generate_for_signup(collection, signup, settings, collection_tag_sets, required_types, prompt_type) + end + end + + # Finish off the potential match generation + def self.finish_generation(collection) + REDIS_GENERAL.del progress_key(collection) + REDIS_GENERAL.del signup_key(collection) + if PotentialMatch.canceled?(collection) + REDIS_GENERAL.del interrupt_key(collection) + # eventually we'll want to be able to pick up where we left off, + # but not there yet + PotentialMatch.clear!(collection) + else + ChallengeAssignment.delayed_generate(collection.id) + end + end + + def self.in_progress?(collection) + if REDIS_GENERAL.get(progress_key(collection)) + if PotentialMatch.canceled?(collection) + self.finish_generation(collection) + return false + end + return true + end + false + end + + # The PotentialMatcherProgress class calculates the percent, so we just need + # to retrieve it from redis. + def self.progress(collection) + REDIS_GENERAL.get(progress_key(collection)) + end + + # sorting routine -- this gets used to rank the relative goodness of potential matches + include Comparable + def <=>(other) + return 0 if self.id == other.id + + # start with seeing how many offers/requests match + cmp = compare_all(self.num_prompts_matched, other.num_prompts_matched) + return cmp unless cmp.zero? + + # compare the "quality" of the best prompt match + # (i.e. the number of matching tags between the most closely-matching + # request prompt/offer prompt pair) + cmp = compare_all(max_tags_matched, other.max_tags_matched) + return cmp unless cmp.zero? + + # if we're a match down to here just match on id + self.id <=> other.id + end + + protected + + def compare_all(self_value, other_value) + if self_value == ALL + other_value == ALL ? 0 : 1 + else + (other_value == ALL ? -1 : self_value <=> other_value) + end + end +end diff --git a/app/models/potential_match_builder.rb b/app/models/potential_match_builder.rb new file mode 100755 index 0000000..bc510e8 --- /dev/null +++ b/app/models/potential_match_builder.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +# A class for building PotentialMatch objects by trying to add pairs of +# matching prompts. +class PotentialMatchBuilder + attr_accessor :num_prompts_matched, :max_tags_matched + + ALL = -1 + + def initialize(request, offer, settings) + @request = request + @offer = offer + @settings = settings + + @num_prompts_matched = 0 + @max_tags_matched = 0 + end + + # Check whether the PotentialMatch we're building is valid -- that is, + # whether it has the required number of prompt matches. + def valid? + desired_matches = @settings.num_required_prompts + desired_matches = @request.requests.size if desired_matches == ALL + @num_prompts_matched >= desired_matches + end + + # Check whether the two prompts match, and if so, record information about + # the match. + def try_prompt_match(request_prompt, offer_prompt) + return unless request_prompt.matches?(offer_prompt, @settings) + add_prompt_match(request_prompt, offer_prompt) + end + + # Record the fact that the two passed-in prompts match. + def add_prompt_match(request_prompt, offer_prompt) + @num_prompts_matched += 1 + + # Compute the number of matching tags, and update max_tags_matched if + # necessary. + curr_tags_matched = request_prompt.count_tags_matched(offer_prompt) + @max_tags_matched = [@max_tags_matched, curr_tags_matched].max + end + + # If possible, create the potential match that we've been building. + def build_potential_match + return nil unless valid? + + PotentialMatch.new( + offer_signup: @offer, + request_signup: @request, + collection_id: @offer.collection_id, + num_prompts_matched: @num_prompts_matched, + max_tags_matched: @max_tags_matched + ) + end +end diff --git a/app/models/potential_match_settings.rb b/app/models/potential_match_settings.rb new file mode 100755 index 0000000..94868d3 --- /dev/null +++ b/app/models/potential_match_settings.rb @@ -0,0 +1,41 @@ +class PotentialMatchSettings < ApplicationRecord + ALL = -1 + REQUIRED_MATCH_OPTIONS = [ + [ts("All"), ALL], + ["0", 0], + ["1", 1], + ["2", 2], + ["3", 3], + ["4", 4], + ["5", 5] + ] + + # VALIDATION + REQUIRED_TAG_ATTRIBUTES = %w(num_required_fandoms num_required_characters num_required_relationships num_required_freeforms num_required_categories + num_required_ratings num_required_archive_warnings) + + REQUIRED_TAG_ATTRIBUTES.each do |tag_limit_field| + validates_inclusion_of tag_limit_field, in: REQUIRED_MATCH_OPTIONS.collect {|entry| entry[1]}, + message: "%{value} is not a valid match setting" + end + + # must have at least one matching request + validates_inclusion_of :num_required_prompts, in: REQUIRED_MATCH_OPTIONS.collect {|entry| entry[1]}.delete_if {|elem| elem == 0}, message: "%{value} is not a valid match setting" + + # are all settings 0 + def no_match_required? + REQUIRED_TAG_ATTRIBUTES.all? {|attrib| self.send("#{attrib}") == 0} + end + + def required_types + TagSet::TAG_TYPES.select {|type| self.send("num_required_#{type.tableize}") != 0} + end + + def topmost_required_type + required_types.first + end + + def include_optional?(type) + send("include_optional_#{type.tableize}") + end +end diff --git a/app/models/potential_matcher/potential_matcher_constrained.rb b/app/models/potential_matcher/potential_matcher_constrained.rb new file mode 100755 index 0000000..3901d1f --- /dev/null +++ b/app/models/potential_matcher/potential_matcher_constrained.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +# Generates potential matches when the matching settings restrict who can be +# matched with whom. Uses PromptBatches to speed up matching. Does not generate +# assignments. +# +# The runtime is asymptotically quadratic in the number of signups, but the +# batching keeps the constants relatively low. +class PotentialMatcherConstrained + attr_reader :collection, :settings, :batch_size + attr_reader :index_tag_type, :index_optional + + def initialize(collection, index_tag_type = nil, batch_size = 100) + @collection = collection + @settings = collection.challenge.potential_match_settings + @batch_size = batch_size + + @required_types = @settings.required_types + @index_tag_type = index_tag_type || @required_types.first + @index_optional = @settings.include_optional?(@index_tag_type) + + # Set up a new progress object for recording our progress. + @progress = PotentialMatcherProgress.new(collection) + + # Set up a structure for holding multiple PotentialMatchBuilders. + @builders = {} + end + + private + + # Makes a batch for the given set of signups. + # Passes @index_tag_type and @index_optional to the constructor, so that the + # prompt batch knows how to build its indices properly. + def make_batch(signups, prompt_type) + PromptBatch.new(signups, prompt_type, @index_tag_type, @index_optional) + end + + # Try matching the two prompts. + def try_match_prompts(request, offer) + return unless request.matches?(offer, @settings) + + request_signup = request.challenge_signup + offer_signup = offer.challenge_signup + pair_key = "#{request_signup.id}|#{offer_signup.id}" + + @builders[pair_key] ||= PotentialMatchBuilder.new( + request_signup, offer_signup, @settings + ) + + # We've already checked that the request matches the offer, so we can use + # add_prompt_match instead of try_prompt_match (to avoid duplicating work). + @builders[pair_key].add_prompt_match(request, offer) + end + + # Builds and saves all PotentialMatches using @builders, then clears out the + # @builders table for the next batch. + def save_potential_matches + return if @builders.empty? + + PotentialMatch.transaction do + @builders.each_value do |builder| + match = builder.build_potential_match + match.save unless match.nil? + end + end + + @builders.clear + end + + # Tries to calculate all pairs of matching prompts between the given + # challenge signup (to be used as a request), and the batch of offers. + def build_matches_for_request(request_signup, offer_batch) + request_signup.requests.each do |request| + offer_candidates = offer_batch.candidates_for_matching(request) + + offer_candidates.each do |offer| + try_match_prompts(request, offer) + end + end + end + + # Generates (and saves) all PotentialMatches for the given request batch and + # offer batch. + def make_batch_matches(request_batch, offer_batch) + @progress.start_subtask(request_batch.signups.size) + + request_batch.signups.each do |request_signup| + build_matches_for_request(request_signup, offer_batch) + save_potential_matches + @progress.increment + end + + @progress.end_subtask + end + + public + + # Generates all potential matches for the collection. + def generate + # These two lines won't trigger SQL queries (which is good, because that'd + # be an awful lot of data to load). They're just defining relations that we + # can call find_in_batches on. + offers = @collection.signups.with_offer_tags + requests = @collection.signups.with_request_tags + + # We process a quadratic number of batch pairs. + batch_count = 1 + (@collection.signups.count - 1) / @batch_size + @progress.start_subtask(batch_count * batch_count) + + offers.find_in_batches(batch_size: @batch_size) do |offer_signups| + break if PotentialMatch.canceled?(@collection) + + offer_batch = make_batch(offer_signups, :offers) + + requests.find_in_batches(batch_size: @batch_size) do |request_signups| + break if PotentialMatch.canceled?(@collection) + + request_batch = make_batch(request_signups, :requests) + make_batch_matches(request_batch, offer_batch) + + @progress.increment + end + end + + @progress.end_subtask + end +end diff --git a/app/models/potential_matcher/potential_matcher_progress.rb b/app/models/potential_matcher/potential_matcher_progress.rb new file mode 100755 index 0000000..713faa3 --- /dev/null +++ b/app/models/potential_matcher/potential_matcher_progress.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +# A class for recording the progress of potential match generation. +# +# Designed to make it easier to record progress on subtasks. It keeps two +# stacks: @progress, and @limit. When you call start_subtask, it pushes 0 onto +# the @progress stack, and the number of ticks in the subtask onto the @limit +# stack. When you call increment, it increases the value at the very end of the +# @progress stack (so that the percent completion for that subtask, computed +# with @progress.last / @limit.last, increases). When you call end_subtask, it +# pops the last value off of the @progress and @limit, so that you go back to +# recording progress for the previous subtask. +# +# The overall percent completion is computed by examining all subtasks on the +# stack. You start from the end of the stack (with the subtask that was added +# last), and divide the progress by the limit to get the fractional completion. +# Then you move back to the previous subtask, add that fractional completion to +# that subtask's progress, and divide by the limit. Repeat until you've reached +# the first subtask. +# +# For a concrete example: If your first subtask has a limit of 10 "ticks" of +# work, and you've called increment 3 times, the percent progress will be 30%. +# If you then create a subtask with a limit of 5 ticks, and you call increment +# once, then you're 1 / 5 = 0.2 = 20% of the way through the subtask, but your +# progress on the whole work is (3 + 0.2) / 10 = 32%. Another call to increment +# will bring you up to 34%, then 36%, 38%, and finally 40% when you finish all +# five ticks of work. Then you can call end_task and increment (which will keep +# you at 40%, but without the subtask), and continue with the work that will +# bring you from 40% to 50%. +class PotentialMatcherProgress + attr_reader :redis_progress_key + attr_reader :progress_enabled + + # Create a new progress object. + def initialize(collection, progress_enabled = true) + @progress = [] + @limit = [] + @percent = 0 + + @progress_enabled = progress_enabled + @redis_progress_key = PotentialMatch.progress_key(collection) + end + + # Signal that you're starting work on a subtask. The sole argument gives the + # number of "ticks" in the subtask that you're about to work on, so that it's + # possible to calculate the percent completion for the subtask. + def start_subtask(max) + @progress.push(0) + @limit.push(max) + end + + # Signal that you're finishing work on the current subtask. + # + # NOTE: Never call start_subtask immediately after end_subtask. You should + # always have a call to increment in between, otherwise it'll look like your + # progress is getting lower. (In fact, in order to keep the counter from + # going backwards, you should always call increment immediately after + # end_subtask.) + def end_subtask + @progress.pop + @limit.pop + end + + # Signal that you've just done a "tick" of work on the current subtask. + def increment + value = @progress.pop + @progress.push(value + 1) + update if @progress_enabled + end + + # Calculate the percent progress. + def percent + value = 0.0 + + (@progress.size - 1).downto 0 do |index| + value = (@progress[index] + value) / @limit[index] + end + + (value * 10_000).floor / 100.0 + end + + # Update the REDIS progress key with the current percent. + def update + return unless @progress_enabled + REDIS_GENERAL.set @redis_progress_key, percent.to_s + end +end diff --git a/app/models/potential_matcher/potential_matcher_unconstrained.rb b/app/models/potential_matcher/potential_matcher_unconstrained.rb new file mode 100755 index 0000000..0ff6ebc --- /dev/null +++ b/app/models/potential_matcher/potential_matcher_unconstrained.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +# A class used to generate PotentialMatch objects when the matching is +# unconstrained -- that is, anyone can be assigned to anyone else. +class PotentialMatcherUnconstrained + ALL = -1 + + def initialize(collection, batch_size = 100) + @collection = collection + @batch_size = batch_size + + # Set up a new progress object for recording our progress. + @progress = PotentialMatcherProgress.new(collection) + end + + # Generates potential match objects for all (valid) pairs of requests and + # offers from the passed-in lists of ids. Saves time by not loading the + # offers or requests, because unconstrained challenges always have ALL for + # num_prompts_matched and max_tags_matched. + def make_all_matches(request_ids, offer_ids) + PotentialMatch.transaction do + request_ids.each do |request_id| + offer_ids.each do |offer_id| + next if offer_id == request_id + + PotentialMatch.create(collection: @collection, + offer_signup_id: offer_id, + request_signup_id: request_id, + num_prompts_matched: ALL, + max_tags_matched: ALL) + end + end + end + end + + # Divides the given array into batches using @batch_size. + def divide_into_batches(array) + temp = array.dup + + batches = [] + batches << temp.shift(@batch_size) until temp.empty? + + batches + end + + # Generates all potential matches for the collection, under the assumption + # that matching isn't constrained (so that everyone can match with everyone + # else, and all matches are equally good). + def generate + all_ids = @collection.signups.pluck(:id) + batched_ids = divide_into_batches(all_ids) + + @progress.start_subtask(all_ids.size) + + all_ids.each do |request_id| + break if PotentialMatch.canceled?(@collection) + + batched_ids.each do |offer_ids| + make_all_matches([request_id], offer_ids) + end + + @progress.increment + end + + @progress.end_subtask + end +end diff --git a/app/models/potential_matcher/prompt_batch.rb b/app/models/potential_matcher/prompt_batch.rb new file mode 100755 index 0000000..b3fd52c --- /dev/null +++ b/app/models/potential_matcher/prompt_batch.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +# A datastructure representing a batch of prompts. Used in order to speed up +# matching. +class PromptBatch + ALL = -1 + + attr_reader :signups, :prompt_type + attr_reader :prompts + + def initialize(signups, prompt_type, index_tag_type, index_optional) + @signups = signups + @prompt_type = prompt_type + @index_tag_type = index_tag_type + @index_optional = index_optional + + @prompts = if @prompt_type == :requests + @signups.flat_map(&:requests) + else + @signups.flat_map(&:offers) + end + end + + private + + # For the given prompt, get the list of all tags of the indexed tag type. + def indexed_tags_for_prompt(prompt) + if @index_optional + prompt.full_tag_set.tag_ids_by_type[@index_tag_type] || [] + else + prompt.tag_set.tag_ids_by_type[@index_tag_type] || [] + end + end + + # Build a list of prompts that accept "any" for the indexed tag type. + def build_prompts_with_any + @prompts_with_any = @prompts.select do |prompt| + prompt.accepts_any?(@index_tag_type) + end + end + + # Build a mapping from tag IDs to lists of prompts that want that tag. + def build_prompts_with_tag + @prompts_with_tag = {} + + @prompts.each do |prompt| + indexed_tags_for_prompt(prompt).each do |tag| + @prompts_with_tag[tag] ||= [] + @prompts_with_tag[tag] << prompt + end + end + end + + # Returns a list of prompts that accept "any" for the indexed tag type. + # Calls build_prompts_with_any if the list doesn't already exist. + def prompts_with_any + build_prompts_with_any if @prompts_with_any.nil? + @prompts_with_any + end + + # Returns a list of prompts that have the given tag. + # Calls build_prompts_with_tag if the hash table doesn't already exist. + def prompts_with_tag(tag) + build_prompts_with_tag if @prompts_with_tag.nil? + @prompts_with_tag[tag] || [] + end + + public + + # Computes the prompts in this set that are "candidates" for matching the + # passed-in prompt -- that is, prompts that share a tag, or prompts with any. + # If the passed-in prompt has no tags of the indexed type, or accepts any for + # the indexed type, this returns all prompts. + def candidates_for_matching(prompt) + tags = indexed_tags_for_prompt(prompt) + + if tags.empty? || prompt.accepts_any?(@index_tag_type) + @prompts + else + candidates = tags.flat_map { |tag_id| prompts_with_tag(tag_id) } + candidates += prompts_with_any + candidates.uniq + end + end +end diff --git a/app/models/potential_matcher/prompt_tag_type_info.rb b/app/models/potential_matcher/prompt_tag_type_info.rb new file mode 100755 index 0000000..ce418dc --- /dev/null +++ b/app/models/potential_matcher/prompt_tag_type_info.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +# A class used for gathering information about the rough frequency of different +# required tag types in all of the prompts in a collection. Used to figure out +# what would be a good "index type" -- that is, a type that we can use to try +# to look up matches with. +class PromptTagTypeInfo + # We use a larger batch size here because prompts are smaller than signups + # (which can contain many prompts), so we can store more of them in memory at + # the same time. + def initialize(collection, batch_size = 300) + @collection = collection + @batch_size = batch_size + + load_collection_info + initialize_data_tables + end + + private + + # Load information about the passed-in collection. + def load_collection_info + @total_prompts = @collection.prompts.count + @total_signups = @collection.signups.count + @settings = @collection.challenge.potential_match_settings + @required_types = @settings.required_types + + # Control the number of tags of each type that we want to see, in order to + # consider the tag type "good." (This is a lower limit -- the more + # different tags we see, the easier it will be to match on that type.) + @limit_first_tags = [ + ArchiveConfig.PREPROCESS_COUNT_TAGS_MAX, + @total_signups / ArchiveConfig.PREPROCESS_COUNT_TAGS_DIVISOR + ].min + + # Control the number of prompts with any that we want to see for a given + # type, in order to consider the type "good." (This is an upper limit -- + # the more prompts we see with "any," the harder it will be to match on + # that type.) + @limit_prompts_with_any = [ + ArchiveConfig.PREPROCESS_COUNT_ANY_MIN, + @total_prompts / ArchiveConfig.PREPROCESS_COUNT_ANY_DIVISOR + ].max + end + + # Set up @count_prompts_with_any and @first_tags_of_type with the correct + # defaults. + def initialize_data_tables + @count_prompts_with_any = {} + @first_tags_of_type = {} + + @required_types.each do |type| + @count_prompts_with_any[type] = 0 + @first_tags_of_type[type] = [] + end + end + + # A good type to use for indexing has a fair number of tags of that type (so + # that we aren't, e.g. trying to match prompts on fandom in a single-fandom + # exchange), and doesn't have very many people requesting "any" (so that we + # have a lot of constraints on who can match with whom). + def calculate_good_index_types + @good_index_types = @required_types.select do |type| + (@first_tags_of_type[type].size >= @limit_first_tags) && + (@count_prompts_with_any[type] <= @limit_prompts_with_any) + end + end + + # Read in data from the passed-in prompt, and use it to update our data + # stored in @first_tags_of_type and @count_prompts_with_any. + def process_prompt(prompt) + @required_types.each do |type| + @count_prompts_with_any[type] += 1 if prompt.send("any_#{type}") + + next if @first_tags_of_type[type].size >= @limit_first_tags + + prompt_tags = prompt.full_tag_set.tag_ids_by_type[type] + next if prompt_tags.nil? + + @first_tags_of_type[type] += prompt_tags + @first_tags_of_type[type].uniq! + end + end + + # Iterate through all prompts in the collection, and process data from each. + def build_good_index_types + return if @required_types.nil? || @required_types.empty? + + prompts = @collection.prompts.includes( + tag_set: :tags, + optional_tag_set: :tags + ) + + prompts.find_each(batch_size: @batch_size) do |prompt| + process_prompt(prompt) + end + + calculate_good_index_types + end + + public + + # Builds the list of good index types if necessary; otherwise just returns + # the pre-calculated list. + def good_index_types + build_good_index_types if @good_index_types.nil? + @good_index_types + end +end diff --git a/app/models/preference.rb b/app/models/preference.rb new file mode 100755 index 0000000..62fa5e8 --- /dev/null +++ b/app/models/preference.rb @@ -0,0 +1,48 @@ +class Preference < ApplicationRecord + # Ignore the email_visible and date_of_birth_visible fields until they can be deleted: + self.ignored_columns = [:email_visible, :date_of_birth_visible] + + belongs_to :user + belongs_to :skin + belongs_to :locale, foreign_key: "preferred_locale" + + validates :work_title_format, + format: { + with: /\A[a-zA-Z0-9_\-,\. ]+\z/, + message: ts("can only contain letters, numbers, spaces, and some limited punctuation (comma, period, dash, underscore).") + } + + validate :can_use_skin, if: :skin_id_changed? + + before_create :set_default_skin + def set_default_skin + self.skin_id = AdminSetting.current.default_skin_id + end + + def self.disable_work_skin?(param) + return false if param == "creator" + return true if %w[light disable].include?(param) + return false unless User.current_user.is_a?(User) + + User.current_user.try(:preference).try(:disable_work_skins) + end + + def can_use_skin + return if skin_id == AdminSetting.default_skin_id || + (skin.is_a?(Skin) && skin.approved_or_owned_by?(user)) + + errors.add(:base, "You don't have permission to use that skin!") + end + + def locale + $rollout.active?(:set_locale_preference, user) ? super : Locale.default + end + + def locale_for_mails + # Use preferred_locale to bypass the second $rollout check + l = Locale.find(preferred_locale) + return I18n.default_locale.to_s unless $rollout.active?(:set_locale_preference, user) && l.email_enabled + + l.iso + end +end diff --git a/app/models/profile.rb b/app/models/profile.rb new file mode 100755 index 0000000..5585e8f --- /dev/null +++ b/app/models/profile.rb @@ -0,0 +1,16 @@ +class Profile < ApplicationRecord + include Justifiable + + PROFILE_TITLE_MAX = 255 + ABOUT_ME_MAX = 2000 + + # Ignore the location and date_of_birth fields until they can be deleted: + self.ignored_columns = [:location, :date_of_birth] + + belongs_to :user + + validates_length_of :title, allow_blank: true, maximum: PROFILE_TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: PROFILE_TITLE_MAX) + validates_length_of :about_me, allow_blank: true, maximum: ABOUT_ME_MAX, + too_long: ts("must be less than %{max} characters long.", max: ABOUT_ME_MAX) +end diff --git a/app/models/prompt.rb b/app/models/prompt.rb new file mode 100755 index 0000000..cdae4bb --- /dev/null +++ b/app/models/prompt.rb @@ -0,0 +1,297 @@ +class Prompt < ApplicationRecord + include TagTypeHelper + + # -1 represents all matching + ALL = -1 + + # ASSOCIATIONS + + belongs_to :collection + belongs_to :pseud + has_one :user, through: :pseud + + belongs_to :challenge_signup, touch: true, inverse_of: :prompts + + belongs_to :tag_set, dependent: :destroy + accepts_nested_attributes_for :tag_set + has_many :tags, through: :tag_set + + belongs_to :optional_tag_set, class_name: "TagSet", dependent: :destroy + accepts_nested_attributes_for :optional_tag_set + has_many :optional_tags, through: :optional_tag_set, source: :tag + + has_many :request_claims, class_name: "ChallengeClaim", foreign_key: "request_prompt_id", inverse_of: :request_prompt, dependent: :destroy + + # SCOPES + + scope :claimed, -> { joins("INNER JOIN challenge_claims on prompts.id = challenge_claims.request_prompt_id") } + + scope :in_collection, lambda {|collection| where(collection_id: collection.id) } + + scope :with_tag, lambda { |tag| + joins("JOIN set_taggings ON set_taggings.tag_set_id = prompts.tag_set_id"). + where("set_taggings.tag_id = ?", tag.id) + } + + # VALIDATIONS + + before_validation :inherit_from_signup, on: :create, if: :challenge_signup + def inherit_from_signup + self.pseud = challenge_signup.pseud + self.collection = challenge_signup.collection + end + + validates_presence_of :collection_id + + validates_presence_of :challenge_signup + + # based on the prompt restriction + validates_presence_of :url, if: :url_required? + validates_presence_of :description, if: :description_required? + validates_presence_of :title, if: :title_required? + + delegate :url_required?, :description_required?, :title_required?, + to: :prompt_restriction, allow_nil: true + + validates_length_of :description, + maximum: ArchiveConfig.NOTES_MAX, + too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.NOTES_MAX) + validates_length_of :title, + maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.TITLE_MAX) + + # i18n-tasks-use t("errors.attributes.url.invalid") + validates :url, url_format: {allow_blank: true} # we validate the presence above, conditionally + + before_validation :cleanup_url + def cleanup_url + self.url = Addressable::URI.heuristic_parse(self.url) if self.url + rescue Addressable::URI::InvalidURIError + # url_format validation creates the error message + end + + validate :correct_number_of_tags + def correct_number_of_tags + prompt_type = self.class.name + restriction = prompt_restriction + if restriction + # make sure tagset has no more/less than the required/allowed number of tags of each type + TagSet::TAG_TYPES.each do |tag_type| + # get the tags of this type the user has specified + taglist = tag_set ? eval("tag_set.#{tag_type}_taglist") : [] + tag_count = taglist.count + tag_label = tag_type_label_name(tag_type).downcase + + # check if user has chosen the "Any" option + if self.send("any_#{tag_type}") + if tag_count > 0 + errors.add(:base, ts("^You have specified tags for %{tag_label} in your %{prompt_type} but also chose 'Any,' which will override them! Please only choose one or the other.", + tag_label: tag_label, prompt_type: prompt_type)) + end + next + end + + # otherwise let's make sure they offered the right number of tags + required = eval("restriction.#{tag_type}_num_required") + allowed = eval("restriction.#{tag_type}_num_allowed") + unless tag_count.between?(required, allowed) + taglist_string = taglist.empty? ? + ts("none") : + "(#{tag_count}) -- " + taglist.collect(&:name).join(ArchiveConfig.DELIMITER_FOR_OUTPUT) + if allowed == 0 + errors.add(:base, ts("^#{prompt_type}: Your #{prompt_type} cannot include any #{tag_label} tags, but you have included %{taglist}.", + taglist: taglist_string)) + elsif required == allowed + errors.add(:base, ts("^#{prompt_type}: Your #{prompt_type} must include exactly %{required} #{tag_label} tags, but you have included #{tag_count} #{tag_label} tags in your current #{prompt_type}.", + required: required)) + else + errors.add(:base, ts("^#{prompt_type}: Your #{prompt_type} must include between %{required} and %{allowed} #{tag_label} tags, but you have included #{tag_count} #{tag_label} tags in your current #{prompt_type}.", + required: required, allowed: allowed)) + end + end + end + end + end + + # make sure that if there is a specified set of allowed tags, the user's choices + # are within that set, or otherwise canonical + validate :allowed_tags + def allowed_tags + restriction = prompt_restriction + + return unless restriction && tag_set + + TagSet::TAG_TYPES.each do |tag_type| + # if we have a specified set of tags of this type, make sure that all the + # tags in the prompt are in the set. + + # skip the check, these will be tested in restricted_tags below + next if TagSet::TAG_TYPES_RESTRICTED_TO_FANDOM.include?(tag_type) && restriction.send("#{tag_type}_restrict_to_fandom") + + taglist = tag_set.send("#{tag_type}_taglist") + next if taglist.empty? + + if restriction.has_tags?(tag_type) + disallowed_taglist = taglist - restriction.tags(tag_type) + unless disallowed_taglist.empty? + errors.add( + :base, + ts( + "^These %{tag_label} tags in your %{prompt_type} are not allowed in this challenge: %{taglist}", + tag_label: tag_type_label_name(tag_type).downcase, + prompt_type: self.class.name.downcase, + taglist: disallowed_taglist.collect(&:name).join(ArchiveConfig.DELIMITER_FOR_OUTPUT) + ) + ) + end + else + noncanonical_taglist = taglist.reject(&:canonical) + unless noncanonical_taglist.empty? + errors.add( + :base, + ts( + "^These %{tag_label} tags in your %{prompt_type} are not canonical and cannot be used in this challenge: %{taglist}. To fix this, please ask your challenge moderator to set up a tag set for the challenge. New tags can be added to the tag set manually by the moderator or through open nominations.", + tag_label: tag_type_label_name(tag_type).downcase, + prompt_type: self.class.name.downcase, + taglist: noncanonical_taglist.collect(&:name).join(ArchiveConfig.DELIMITER_FOR_OUTPUT) + ) + ) + end + end + end + end + + # make sure that if any tags are restricted to fandom, the user's choices are + # actually in the fandom they have chosen. + validate :restricted_tags + def restricted_tags + restriction = prompt_restriction + return unless restriction + + tag_set_associations = TagSetAssociation.where(owned_tag_set_id: restriction.owned_tag_sets.pluck(:id)) + + TagSet::TAG_TYPES_RESTRICTED_TO_FANDOM.each do |tag_type| + next unless restriction.send("#{tag_type}_restrict_to_fandom") + + # tag_type is one of a set set so we know it is safe for constantize + allowed_tags = tag_type.classify.constantize.with_parents(tag_set.fandom_taglist).canonical + disallowed_taglist = tag_set ? tag_set.send("#{tag_type}_taglist") - allowed_tags : [] + + # check for tag set associations + disallowed_taglist -= tag_set_associations + .where(tag: disallowed_taglist, parent_tag_id: tag_set.fandom_taglist) + .includes(:tag) + .map(&:tag) + next if disallowed_taglist.empty? + + errors.add(:base, :tags_not_in_fandom, + prompt_type: self.class.name.downcase, + tag_label: tag_type_label_name(tag_type).downcase, fandom: tag_set.fandom_taglist.pluck(:name).join(I18n.t("support.array.words_connector")), + taglist: disallowed_taglist.pluck(:name).join(I18n.t("support.array.words_connector"))) + end + end + + # INSTANCE METHODS + + def can_delete? + if challenge_signup && !challenge_signup.can_delete?(self) + false + else + true + end + end + + def unfulfilled_claims + self.request_claims.unfulfilled_in_collection(self.collection) + end + + def fulfilled_claims + self.request_claims.fulfilled + end + + # Computes the "full" tag set (tag_set + optional_tag_set), and stores the + # result as an instance variable for speed. This is used by the matching + # algorithm, which doesn't change any signup/prompt/tagset information, so + # it's okay to cache some information. (And if the info does change + # mid-matching process, it's okay that we're using the tag sets that were + # there when the moderator started the matching process.) + def full_tag_set + if @full_tag_set.nil? + @full_tag_set = optional_tag_set ? tag_set + optional_tag_set : tag_set + end + + @full_tag_set + end + + # Returns true if there's a match, false otherwise. + # self is the request, other is the offer + def matches?(other, settings = nil) + return nil if challenge_signup.id == other.challenge_signup.id + return nil if settings.nil? + + TagSet::TAG_TYPES.each do |type| + # We definitely match in this type if the request or the offer accepts + # "any" for it. No need to check any more info for this type. + next if send("any_#{type}") || other.send("any_#{type}") + + required_count = settings.send("num_required_#{type.pluralize}") + match_count = if settings.send("include_optional_#{type.pluralize}") + full_tag_set.match_rank(other.full_tag_set, type) + else + # we don't use optional tags to count towards required + tag_set.match_rank(other.tag_set, type) + end + + # if we have to match all and don't, not a match + return false if required_count == ALL && match_count != ALL + + # we are a match only if we either match all or at least as many as required + return false if match_count != ALL && match_count < required_count + end + + true + end + + # Count the number of overlapping tags of all types. Does not use ALL to + # indicate a 100% match, since the goal is to give a bonus to matches where + # both requester and offerer were specific about their desires, and had a lot + # of overlap. + def count_tags_matched(other) + self_tags = full_tag_set.tags.map(&:id) + other_tags = other.full_tag_set.tags.map(&:id) + (self_tags & other_tags).size + end + + def accepts_any?(type) + send("any_#{type.downcase}") + end + + def prompt_restriction + raise "Base-type Prompt objects cannot have prompt restrictions. Try creating a Request or an Offer." + end + + # tag groups + def tag_groups + self.tag_set ? self.tag_set.tags.group_by { |t| t.type.to_s } : {} + end + + def claim_by(user) + ChallengeClaim.where(request_prompt_id: self.id, claiming_user_id: user.id) + end + + # checks if a prompt has been filled in a prompt meme + def unfulfilled? + if self.request_claims.empty? || !self.request_claims.fulfilled.exists? + return true + end + end + + # currently only prompt meme prompts can be claimed, and by any number of people + def claimable? + if self.collection.challenge.is_a?(PromptMeme) + true + else + false + end + end +end diff --git a/app/models/prompt_restriction.rb b/app/models/prompt_restriction.rb new file mode 100755 index 0000000..ed47b02 --- /dev/null +++ b/app/models/prompt_restriction.rb @@ -0,0 +1,124 @@ +class PromptRestriction < ApplicationRecord + has_many :owned_set_taggings, as: :set_taggable, dependent: :destroy + has_many :owned_tag_sets, -> { select("DISTINCT owned_tag_sets.*") }, through: :owned_set_taggings + has_many :tag_sets, through: :owned_tag_sets + + # note: there is no has_one/has_many association here because this class may or may not + # be used by many different challenge classes. For convenience, if you use this class in + # a challenge class, add that challenge class to this list so other coders can see where + # it is used and how it behaves: + # + # challenge/gift_exchange + # + + # VALIDATION + %w(fandom_num_required category_num_required rating_num_required character_num_required + relationship_num_required freeform_num_required archive_warning_num_required + fandom_num_allowed category_num_allowed rating_num_allowed character_num_allowed + relationship_num_allowed freeform_num_allowed archive_warning_num_allowed).each do |tag_limit_field| + validates_numericality_of tag_limit_field, only_integer: true, less_than_or_equal_to: ArchiveConfig.PROMPT_TAGS_MAX, greater_than_or_equal_to: 0 + end + + before_validation :update_allowed_values + # if anything is required make sure it is also allowed + def update_allowed_values + self.url_allowed = true if url_required + self.description_allowed = true if description_required + self.title_allowed = true if title_required + + TagSet::TAG_TYPES.each do |tag_type| + required = eval("#{tag_type}_num_required") || eval("self.#{tag_type}_num_required") || 0 + allowed = eval("#{tag_type}_num_allowed") || eval("self.#{tag_type}_num_allowed") || 0 + if required > allowed + eval("self.#{tag_type}_num_allowed = required") + end + end + end + + def required(tag_type) + self.send("#{tag_type}_num_required") + end + + def allowed(tag_type) + self.send("#{tag_type}_num_allowed") + end + + def restricted?(tag_type, restriction) + self.send("#{tag_type}_restrict_to_#{restriction}") + end + + def allow_any?(tag_type) + self.send("allow_any_#{tag_type}") + end + + def require_unique?(tag_type) + self.send("require_unique_#{tag_type}") + end + + def topmost_tag_type + topmost_type = "" + TagSet::TAG_TYPES.each do |tag_type| + if self.allowed(tag_type) > 0 + topmost_type = tag_type + break + end + end + topmost_type + end + + def set_owned_tag_sets(sets) + self.owned_set_taggings.delete_all + current = self.owned_tag_sets + new_sets = sets - self.owned_tag_sets + remove_sets = self.owned_tag_sets - sets + self.owned_tag_sets += new_sets + self.owned_tag_sets -= remove_sets + end + + def tag_sets_to_add=(tag_set_titles) + tag_set_titles.split(',').reject {|title| title.blank?}.each do |title| + title.strip! + ots = OwnedTagSet.find_by(title: title) + errors.add(:base, ts("We couldn't find the tag set {{title}}.", title: title)) and return if ots.nil? + errors.add(:base, ts("The tag set {{title}} is not available for public use.", title: title)) and return if (!ots.usable && !ots.user_is_moderator?(User.current_user)) + unless self.owned_tag_sets.include?(ots) + self.owned_tag_sets << ots + end + end + end + + def tag_sets_to_remove=(tag_set_ids) + tag_set_ids.reject {|id| id.blank?}.each do |id| + id.strip! + ots = OwnedTagSet.find(id) || nil + if ots && self.owned_tag_sets.include?(ots) + self.owned_tag_sets -= [ots] + end + end + end + + def tag_sets_to_add; nil; end + def tag_sets_to_remove; nil; end + + # Efficiently get ids of all tagsets thanks to Valium + def owned_tag_set_ids + OwnedSetTagging.where(set_taggable_type: self.class.name, set_taggable_id: self.id).pluck(:owned_tag_set_id) + end + + def tag_set_ids + TagSet.joins("INNER JOIN owned_tag_sets ON owned_tag_sets.tag_set_id = tag_sets.id + INNER JOIN owned_set_taggings ON owned_set_taggings.owned_tag_set_id = owned_tag_sets.id"). + where("owned_set_taggings.set_taggable_id = ? AND owned_set_taggings.set_taggable_type = 'PromptRestriction'", self.id).pluck :id + end + + def has_tags?(type="tag") + tags(type).exists? + end + + def tags(type="tag") + type = type.gsub(/\s+/, "").classify + raise "Redshirt: Attempted to constantize invalid class initialize tags -#{type}-" unless Tag::TYPES.include?(type) + type.constantize.in_prompt_restriction(self) # Safe constantize checked above + end + +end diff --git a/app/models/pseud.rb b/app/models/pseud.rb new file mode 100755 index 0000000..f6877df --- /dev/null +++ b/app/models/pseud.rb @@ -0,0 +1,455 @@ +class Pseud < ApplicationRecord + include Searchable + include WorksOwner + include Justifiable + include AfterCommitEverywhere + + has_one_attached :icon do |attachable| + attachable.variant(:standard, resize_to_limit: [100, 100], loader: { n: -1 }) + end + + # i18n-tasks-use t("errors.attributes.icon.invalid_format") + # i18n-tasks-use t("errors.attributes.icon.too_large") + validates :icon, attachment: { + allowed_formats: %w[image/gif image/jpeg image/png], + maximum_size: ArchiveConfig.ICON_SIZE_KB_MAX.kilobytes + } + + NAME_LENGTH_MIN = 1 + NAME_LENGTH_MAX = 40 + DESCRIPTION_MAX = 500 + + belongs_to :user + + delegate :login, to: :user, prefix: true, allow_nil: true + alias user_name user_login + + has_many :bookmarks, dependent: :destroy + has_many :recs, -> { where(rec: true) }, class_name: 'Bookmark' + has_many :comments + + has_many :creatorships, dependent: :destroy + has_many :approved_creatorships, -> { Creatorship.approved }, class_name: "Creatorship" + + has_many :works, through: :approved_creatorships, source: :creation, source_type: "Work" + has_many :chapters, through: :approved_creatorships, source: :creation, source_type: "Chapter" + has_many :series, through: :approved_creatorships, source: :creation, source_type: "Series" + + has_many :tags, through: :works + has_many :filters, through: :works + has_many :direct_filters, through: :works + has_many :collection_participants, dependent: :destroy + has_many :collections, through: :collection_participants + has_many :tag_set_ownerships, dependent: :destroy + has_many :tag_sets, through: :tag_set_ownerships + has_many :challenge_signups, dependent: :destroy + has_many :gifts, -> { where(rejected: false) }, inverse_of: :pseud, dependent: :destroy + has_many :gift_works, through: :gifts, source: :work + has_many :rejected_gifts, -> { where(rejected: true) }, class_name: "Gift", inverse_of: :pseud, dependent: :destroy + has_many :rejected_gift_works, through: :rejected_gifts, source: :work + + has_many :offer_assignments, -> { where("challenge_assignments.sent_at IS NOT NULL") }, through: :challenge_signups + has_many :pinch_hit_assignments, -> { where("challenge_assignments.sent_at IS NOT NULL") }, class_name: "ChallengeAssignment", foreign_key: "pinch_hitter_id" + + has_many :prompts, dependent: :destroy + + before_validation :clear_icon + + validates_presence_of :name + validates_length_of :name, + within: NAME_LENGTH_MIN..NAME_LENGTH_MAX, + too_short: ts("is too short (minimum is %{min} characters)", min: NAME_LENGTH_MIN), + too_long: ts("is too long (maximum is %{max} characters)", max: NAME_LENGTH_MAX) + validates :name, uniqueness: { scope: :user_id } + validates_format_of :name, + message: ts('can contain letters, numbers, spaces, underscores, and dashes.'), + with: /\A[\p{Word} -]+\Z/u + validates_format_of :name, + message: ts('must contain at least one letter or number.'), + with: /\p{Alnum}/u + validates_length_of :description, allow_blank: true, maximum: DESCRIPTION_MAX, + too_long: ts("must be less than %{max} characters long.", max: DESCRIPTION_MAX) + validates_length_of :icon_alt_text, allow_blank: true, maximum: ArchiveConfig.ICON_ALT_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_ALT_MAX) + validates_length_of :icon_comment_text, allow_blank: true, maximum: ArchiveConfig.ICON_COMMENT_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_COMMENT_MAX) + + after_create :reindex_user + after_update :check_default_pseud + after_update :expire_caches + after_update :reindex_user, if: :name_changed? + after_destroy :reindex_user + after_commit :reindex_creations, :touch_comments + + scope :alphabetical, -> { order(:name) } + scope :default_alphabetical, -> { order(is_default: :desc).alphabetical } + scope :abbreviated_list, -> { default_alphabetical.limit(ArchiveConfig.ITEMS_PER_PAGE) } + scope :for_search, -> { includes(:user).with_attached_icon } + + def self.not_orphaned + where("user_id != ?", User.orphan_account) + end + + # Enigel Dec 12 08: added sort method + # sorting by pseud name or by login name in case of equality + def <=>(other) + (self.name.downcase <=> other.name.downcase) == 0 ? (self.user_name.downcase <=> other.user_name.downcase) : (self.name.downcase <=> other.name.downcase) + end + + def to_param + name + end + + scope :public_work_count_for, -> (pseud_ids) { + select('pseuds.id, count(pseuds.id) AS work_count') + .joins(:works) + .where( + pseuds: { id: pseud_ids }, works: { posted: true, hidden_by_admin: false, restricted: false } + ).group('pseuds.id') + } + + scope :posted_work_count_for, -> (pseud_ids) { + select('pseuds.id, count(pseuds.id) AS work_count') + .joins(:works) + .where( + pseuds: { id: pseud_ids }, works: { posted: true, hidden_by_admin: false } + ).group('pseuds.id') + } + + scope :public_rec_count_for, -> (pseud_ids) { + select('pseuds.id, count(pseuds.id) AS rec_count') + .joins(:bookmarks) + .where( + pseuds: { id: pseud_ids }, bookmarks: { private: false, hidden_by_admin: false, rec: true } + ) + .group('pseuds.id') + } + + def self.rec_counts_for_pseuds(pseuds) + if pseuds.blank? + {} + else + pseuds_with_counts = Pseud.public_rec_count_for(pseuds.collect(&:id)) + count_hash = {} + pseuds_with_counts.each {|p| count_hash[p.id] = p.rec_count.to_i} + count_hash + end + end + + def self.work_counts_for_pseuds(pseuds) + if pseuds.blank? + {} + else + if User.current_user.nil? + pseuds_with_counts = Pseud.public_work_count_for(pseuds.collect(&:id)) + else + pseuds_with_counts = Pseud.posted_work_count_for(pseuds.collect(&:id)) + end + + count_hash = {} + pseuds_with_counts.each {|p| count_hash[p.id] = p.work_count.to_i} + count_hash + end + end + + def unposted_works + @unposted_works = self.works.where(posted: false).order(created_at: :desc) + end + + # Produces a byline that indicates the user's name if pseud is not unique + def byline + (name != user_name) ? "#{name} (#{user_name})" : name + end + + # get the former byline + def byline_was + past_name = name_was.blank? ? name : name_was + # if we have a user and their login has changed get the old one + past_user_name = user.blank? ? "" : (user.login_was.blank? ? user.login : user.login_was) + (past_name != past_user_name) ? "#{past_name} (#{past_user_name})" : past_name + end + + # Parse a string of the "pseud.name (user.login)" format into an array + # [pseud.name, user.login]. If there is no parenthesized login after the + # pseud name, returns [pseud.name, nil]. + def self.split_byline(byline) + pseud_name, login = byline.split("(", 2) + [pseud_name&.strip, login&.strip&.delete_suffix(")")] + end + + # Parse a string of the "pseud.name (user.login)" format into a pseud. If the + # form is just "pseud.name" with no parenthesized login, assumes that + # pseud.name = user.login and goes from there. + def self.parse_byline(byline) + pseud_name, login = split_byline(byline) + login ||= pseud_name + + Pseud.joins(:user).find_by(pseuds: { name: pseud_name }, users: { login: login }) + end + + # Parse a string of the "pseud.name (user.login)" format into a list of + # pseuds. Usually this will be just one pseud, but if the byline is of the + # form "pseud.name" with no parenthesized username, it'll look for any pseud + # with that name. + def self.parse_byline_ambiguous(byline) + pseud_name, login = split_byline(byline) + + if login + Pseud.joins(:user).where(pseuds: { name: pseud_name }, users: { login: login }) + else + Pseud.where(name: pseud_name) + end + end + + # Takes a comma-separated list of bylines + # Returns a hash containing an array of pseuds and an array of bylines that couldn't be found + def self.parse_bylines(bylines) + valid_pseuds = [] + failures = [] + banned_pseuds = [] + + bylines.split(",").each do |byline| + pseud = parse_byline(byline) + if pseud.nil? + failures << byline.strip + elsif pseud.user.banned? || pseud.user.suspended? + banned_pseuds << pseud + else + valid_pseuds << pseud + end + end + + { + pseuds: valid_pseuds.flatten.uniq, + invalid_pseuds: failures, + banned_pseuds: banned_pseuds.flatten.uniq.map(&:byline) + } + end + + ## AUTOCOMPLETE + # set up autocomplete and override some methods + include AutocompleteSource + def autocomplete_prefixes + [ "autocomplete_pseud" ] + end + + def autocomplete_value + "#{id}#{AUTOCOMPLETE_DELIMITER}#{byline}" + end + + # This method is for use in before_* callbacks + def autocomplete_value_was + "#{id}#{AUTOCOMPLETE_DELIMITER}#{byline_was}" + end + + # See byline_before_last_save for the reasoning behind why both this and + # autocomplete_value_was exist in this model + # + # This method is for use in after_* callbacks + def autocomplete_value_before_last_save + "#{id}#{AUTOCOMPLETE_DELIMITER}#{byline_before_last_save}" + end + + def byline_before_last_save + past_name = name_before_last_save.blank? ? name : name_before_last_save + + # In this case, self belongs to a user that has already been saved + # during it's (self's) callback cycle, which means we need to + # look *back* at the user's [attributes]_before_last_save, since + # [attribute]_was for the pseud's user will behave as if this were an + # after_* callback on the user, instead of a before_* callback on self. + # + # see psued_sweeper.rb:13 for more context + # + past_user_name = user.blank? ? "" : (user.login_before_last_save.blank? ? user.login : user.login_before_last_save) + (past_name != past_user_name) ? "#{past_name} (#{past_user_name})" : past_name + end + + # This method is for removing stale autocomplete records in a before_* + # callback, such as the one used in PseudSweeper + # + # This is a particular case for the Pseud model + def remove_stale_from_autocomplete_before_save + self.class.remove_from_autocomplete(self.autocomplete_search_string_was, self.autocomplete_prefixes, self.autocomplete_value_was) + end + + + ## END AUTOCOMPLETE + + def replace_me_with_default + replacement = user.default_pseud + + # We don't use change_ownership here because we want to transfer both + # approved and unapproved creatorships. + self.creatorships.includes(:creation).each do |creatorship| + next if creatorship.creation.nil? + + existing = + replacement.creatorships.find_by(creation: creatorship.creation) + + if existing + existing.update(approved: existing.approved || creatorship.approved) + else + creatorship.update(pseud: replacement) + end + end + + # Update the pseud ID for all comments. Also updates the timestamp, so that + # the cache is invalidated and the pseud change will be visible. + Comment.where(pseud_id: self.id).update_all(pseud_id: replacement.id, + updated_at: Time.now) + change_collections_membership + change_gift_recipients + change_challenge_participation + self.destroy + end + + # Change the ownership of a creation from one pseud to another + def change_ownership(creation, pseud, options={}) + transaction do + # Update children before updating the creation itself, since deleting + # creatorships from the creation will also delete them from the creation's + # children. + unless options[:skip_children] + children = if creation.is_a?(Work) + creation.chapters + elsif creation.is_a?(Series) + creation.works + else + [] + end + + children.each do |child| + change_ownership(child, pseud, options) + end + end + + # Should only add new creatorships if we're an approved co-creator. + if creation.creatorships.approved.where(pseud: self).exists? + creation.creatorships.find_or_create_by(pseud: pseud) + end + + # But we should delete all creatorships, even invited ones: + creation.creatorships.where(pseud: self).destroy_all + + if creation.is_a?(Work) + creation.series.each do |series| + if series.work_pseuds.where(id: id).exists? + series.creatorships.find_or_create_by(pseud: pseud) + else + change_ownership(series, pseud, options.merge(skip_children: true)) + end + end + comments = creation.total_comments.where("comments.pseud_id = ?", self.id) + comments.each do |comment| + comment.update_attribute(:pseud_id, pseud.id) + end + end + + # make sure changes affect caching/search/author fields + creation.save + end + end + + def change_membership(collection, new_pseud) + self.collection_participants.in_collection(collection).each do |cparticipant| + cparticipant.pseud = new_pseud + cparticipant.save + end + end + + def change_challenge_participation + # We want to update all prompts associated with this pseud, but although + # each prompt contains a pseud_id column, they're not indexed on it. That + # means doing the search Prompt.where(pseud_id: self.id) would require + # searching all rows of the prompts table. So instead, we do a join on the + # challenge_signups table and look up prompts whose ChallengeSignup has the + # pseud_id that we want to change. + Prompt.joins(:challenge_signup). + where("challenge_signups.pseud_id = #{id}"). + update_all("prompts.pseud_id = #{user.default_pseud.id}") + + ChallengeSignup.where("pseud_id = #{self.id}").update_all("pseud_id = #{self.user.default_pseud.id}") + ChallengeAssignment.where("pinch_hitter_id = #{self.id}").update_all("pinch_hitter_id = #{self.user.default_pseud.id}") + return + end + + def change_gift_recipients + Gift.where("pseud_id = #{self.id}").update_all("pseud_id = #{self.user.default_pseud.id}") + end + + def change_bookmarks_ownership + Bookmark.where("pseud_id = #{self.id}").update_all("pseud_id = #{self.user.default_pseud.id}") + end + + def change_collections_membership + CollectionParticipant.where("pseud_id = #{self.id}").update_all("pseud_id = #{self.user.default_pseud.id}") + end + + def check_default_pseud + if !self.is_default? && self.user.pseuds.to_enum.find(&:is_default?) == nil + default_pseud = self.user.pseuds.select{|ps| ps.name.downcase == self.user_name.downcase}.first + default_pseud.update_attribute(:is_default, true) + end + end + + def expire_caches + if saved_change_to_name? + works.touch_all + series.each(&:expire_byline_cache) + chapters.each(&:expire_byline_cache) + end + end + + def touch_comments + comments.touch_all + end + + # Delete current icon (thus reverting to archive default icon) + def delete_icon=(value) + @delete_icon = !value.to_i.zero? + end + + def delete_icon + !!@delete_icon + end + alias_method :delete_icon?, :delete_icon + + def clear_icon + return unless delete_icon? + + self.icon.purge + self.icon_alt_text = nil + self.icon_comment_text = nil + end + + ################################# + ## SEARCH ####################### + ################################# + + def collection_ids + collections.pluck(:id) + end + + def document_json + PseudIndexer.new({}).document(self) + end + + def should_reindex_creations? + pertinent_attributes = %w[id name] + destroyed? || (saved_changes.keys & pertinent_attributes).present? + end + + # If the pseud gets renamed, anything indexed with the old name needs to be reindexed: + # works, series, bookmarks. + def reindex_creations + return unless should_reindex_creations? + IndexQueue.enqueue_ids(Work, works.pluck(:id), :main) + IndexQueue.enqueue_ids(Bookmark, bookmarks.pluck(:id), :main) + IndexQueue.enqueue_ids(Series, series.pluck(:id), :main) + end + + def reindex_user + after_commit { user.enqueue_to_index } + end +end diff --git a/app/models/question.rb b/app/models/question.rb new file mode 100755 index 0000000..46fcde3 --- /dev/null +++ b/app/models/question.rb @@ -0,0 +1,33 @@ +class Question < ApplicationRecord + acts_as_list + + # The attributes that should be delegated to the translated class: + translates :question, :content, :is_translated, :content_sanitizer_version + translation_class.include(Globalized) + + # Ignore the screencast_sanitizer_version field until it can be deleted: + translation_class.ignored_columns = [:screencast_sanitizer_version] + + belongs_to :archive_faq + + validates_presence_of :question, before: :create + validates_presence_of :anchor, before: :create + validates_presence_of :content, before: :create + + validates_length_of :content, minimum: ArchiveConfig.CONTENT_MIN, + too_short: ts('must be at least %{min} letters long.', + min: ArchiveConfig.CONTENT_MIN) + + validates_length_of :content, maximum: ArchiveConfig.CONTENT_MAX, + too_long: ts('cannot be more than %{max} characters + long.', + max: ArchiveConfig.CONTENT_MAX) + + scope :in_order, -> { order(:position) } + + # Change the positions of the questions in the + def self.reorder(positions) + SortableList.new(self.find(:all, order: 'position ASC')). + reorder_list(positions) + end +end diff --git a/app/models/rating.rb b/app/models/rating.rb new file mode 100755 index 0000000..e9fd6d8 --- /dev/null +++ b/app/models/rating.rb @@ -0,0 +1,24 @@ +class Rating < Tag + validates :canonical, presence: { message: "^Only canonical rating tags are allowed." } + + NAME = ArchiveConfig.RATING_CATEGORY_NAME + + def self.label_name + to_s + end + + # Gives us the default ratings as Not Rated + low to high + def self.defaults_by_severity + ratings = [ArchiveConfig.RATING_DEFAULT_TAG_NAME, + ArchiveConfig.RATING_GENERAL_TAG_NAME, + ArchiveConfig.RATING_TEEN_TAG_NAME, + ArchiveConfig.RATING_MATURE_TAG_NAME, + ArchiveConfig.RATING_EXPLICIT_TAG_NAME] + ratings_by_id = Rating.where(name: ratings).inject({}) do |result, rating| + result[rating.name] = rating + result + end + ratings.map { |id| ratings_by_id[id] } + end + +end diff --git a/app/models/reading.rb b/app/models/reading.rb new file mode 100755 index 0000000..08d1dca --- /dev/null +++ b/app/models/reading.rb @@ -0,0 +1,52 @@ +class Reading < ApplicationRecord + belongs_to :user + belongs_to :work + + after_save :expire_cached_home_marked_for_later, if: :saved_change_to_toread? + after_destroy :expire_cached_home_marked_for_later, if: :toread? + + scope :visible, -> { left_joins(:work).merge(Work.visible_to_registered_user.or(Work.where(id: nil))) } + + # called from show in work controller + def self.update_or_create(work, user) + if user && user.preference.try(:history_enabled) && !user.is_author_of?(work) + reading_json = [user.id, Time.now, work.id, work.major_version, work.minor_version, false].to_json + REDIS_GENERAL.sadd("Reading:new", reading_json) + end + end + + # called from reading controller + def self.mark_to_read_later(work, user, toread) + reading = Reading.find_or_initialize_by(work_id: work.id, user_id: user.id) + reading.major_version_read = work.major_version + reading.minor_version_read = work.minor_version + reading.last_viewed = Time.now + reading.toread = toread + reading.save + end + + # create a reading object, but only if the user has reading + # history enabled and is not the author of the work + def self.reading_object(user_id, time, work_id, major_version, minor_version, later) + reading = Reading.find_or_initialize_by(work_id: work_id, user_id: user_id) + + # Only update the view time/version number if it's newer: + if reading.last_viewed.nil? || reading.last_viewed < time + reading.last_viewed = time + reading.major_version_read = major_version + reading.minor_version_read = minor_version + end + + reading.view_count = reading.view_count + 1 unless later + reading.save + reading + end + + private + + def expire_cached_home_marked_for_later + unless Rails.env.development? + Rails.cache.delete("home/index/#{user_id}/home_marked_for_later") + end + end +end diff --git a/app/models/redis_hit_counter.rb b/app/models/redis_hit_counter.rb new file mode 100755 index 0000000..9fdb17a --- /dev/null +++ b/app/models/redis_hit_counter.rb @@ -0,0 +1,131 @@ +# A class for keeping track of hits/IP addresses in redis. Writes the values in +# redis to the database when the HitCountUpdateJobs run. +class RedisHitCounter + class << self + include RedisScanning + + # Records a hit for the given IP address on the given work ID. If the IP + # address hasn't visited the work within the current 24 hour block, we + # increment the work's hit count. Otherwise, we do nothing. + def add(work_id, ip_address) + key = "visits:#{current_timestamp}" + visit = "#{work_id}:#{ip_address}" + + # Add the (work ID, IP address) pair to the set for this date. + added_visit = redis.sadd(key, visit) + + # If trying to add the (work ID, IP address) pair resulted in sadd + # returning true, we know that the user hasn't visited this work + # recently. So we increment the count of recent hits. + redis.hincrby(:recent_counts, work_id, 1) if added_visit + end + + # Go through the list of all keys starting with "visits:", compute the + # timestamp from the key, and delete the sets associated with any + # timestamps from before today. + def remove_old_visits + # NOTE: It's perfectly safe to convert the timestamp to an integer to be + # able to compare with other timestamps, as we're doing here. However, + # the integers shouldn't be used in any other way (e.g. subtraction, + # addition, etc.) since they won't behave the way you'd expect dates to. + last_timestamp = current_timestamp.to_i + + redis.scan_each(match: "visits:*", count: batch_size) do |key| + _, timestamp = key.split(":") + + next unless timestamp.to_i < last_timestamp + + enqueue_remove_set(key) + end + end + + protected + + # Remove the set at the given key. + # + # Deletion technique adapted from: + # https://www.redisgreen.net/blog/deleting-large-sets/ + def enqueue_remove_set(key) + garbage_key = make_garbage_key + + # In order to make sure that we're not simultaneously adding to the set + # and deleting it, we rename it. + redis.rename(key, garbage_key) + + # We use async to perform the deletion because we don't want to lose + # track of our garbage. If the key we're removing is in Resque, and the + # job fails, it'll be retried until it succeeds. + async(:remove_set, garbage_key) + end + + # Scan through the given set and delete it batch-by-batch. + def remove_set(key) + scan_set_in_batches(redis, key, batch_size: batch_size) do |batch| + redis.srem(key, batch) + end + end + + # Constructs an all-new key to use for deleting sets: + def make_garbage_key + "garbage:#{redis.incr('garbage:index')}" + end + + public + + # The redis instance that we want to use for hit counts. We use a namespace + # so that we can use simpler key names throughout this class. + def redis + @redis ||= Redis::Namespace.new( + "hit_count", + redis: REDIS_HITS + ) + end + + # Take the current time (offset by the rollover hour) and convert it to a + # date. We use this date as part of the key for storing which IP addresses + # have viewed a work recently. + def current_timestamp + (Time.now.utc - rollover_hour.hours).to_date.strftime("%Y%m%d") + end + + # The hour (in UTC time) that we want the hit counts to rollover at. If + # someone views the work shortly before this hour and shortly after, it + # counts as two hits. + def rollover_hour + ArchiveConfig.HIT_COUNT_ROLLOVER_HOUR + end + + # The size of the batches to be retrieved from redis. + def batch_size + ArchiveConfig.HIT_COUNT_BATCH_SIZE + end + + # Check whether the work should allow hits at the moment: + def prevent_hits?(work) + work.nil? || + work.in_unrevealed_collection || + work.hidden_by_admin || + !work.posted + end + + #################### + # DELAYED JOBS + #################### + + # The default queue to use when enqueuing Resque jobs in this class: + def queue + :utilities + end + + # This will be called by a worker when it's trying to perform a delayed + # task. Calls the passed-in class method with the passed-in arguments. + def perform(method, *args) + send(method, *args) + end + + # Queue up a method to be called later. + def async(method, *args) + Resque.enqueue(self, method, *args) + end + end +end diff --git a/app/models/redis_mail_queue.rb b/app/models/redis_mail_queue.rb new file mode 100755 index 0000000..c40684d --- /dev/null +++ b/app/models/redis_mail_queue.rb @@ -0,0 +1,104 @@ +class RedisMailQueue + # queue a kudo notification in redis + # we create a separate list in redis for each author and work to be notified on + # and store the names of each kudo'er in that list ("guest" for guest kudos) + def self.queue_kudo(author, kudo) + key = "kudos_#{author.id}_#{kudo.commentable_type}_#{kudo.commentable_id}" + REDIS_KUDOS.rpush(key, kudo.name) + REDIS_KUDOS.sadd("kudos_#{author.id}", key) + REDIS_KUDOS.sadd("notification_kudos", author.id) + end + + # batch and deliver all the outstanding kudo notifications + # this should be called from schedule.rb at some regular interval + def self.deliver_kudos + author_list = to_notify("kudos") + + author_list.each do |author_id| + user_kudos = {} + keys, = REDIS_KUDOS.multi do |redis| + kudos_list = "kudos_#{author_id}" + redis.smembers(kudos_list) + redis.del(kudos_list) + end + keys.each do |key| + # atomically get the info and then delete the key + guest_count, names, = REDIS_KUDOS.multi do + REDIS_KUDOS.lrem(key, 0, "guest") + REDIS_KUDOS.lrange(key, 0, -1) + REDIS_KUDOS.del(key) + end + + # get the commentable + _prefix, _author, commentable_type, commentable_id = key.split("_") + + # batch it + user_kudos["#{commentable_type}_#{commentable_id}"] = { names: names, guest_count: guest_count } + end + + next if user_kudos.blank? + + # queue the notification for delivery + begin + # don't die if we hit one deleted user + I18n.with_locale(User.find(author_id).preference.locale_for_mails) do + KudoMailer.batch_kudo_notification(author_id, user_kudos.to_json).deliver_later + end + rescue StandardError + # TODO: this should be reported to monitoring software so it can be used in analysis and alerting. + # However, we likely want this moved to ApplicationJob from its current Rake home first. + end + end + end + + # queue a subscription notification in redis + # we create a separate list in redis for each subscriber and subscription to be notified on + # and store the creation type and id in that set + def self.queue_subscription(subscription, creation) + key = "subscription_#{subscription.id}" + entry = "#{creation.class.name}_#{creation.id}" + REDIS_GENERAL.rpush(key, entry) + REDIS_GENERAL.sadd("notification_subscription", subscription.id) + end + + # batch and deliver all the outstanding subscription notifications + # this should be called from schedule.rb at some regular interval + def self.deliver_subscriptions + subscription_list = to_notify("subscription") + subscription_list.each do |subscription_id| + key = "subscription_#{subscription_id}" + entries, = REDIS_GENERAL.multi do + REDIS_GENERAL.lrange(key, 0, -1) + REDIS_GENERAL.del(key) + end + begin + # don't die if we hit one deleted subscription + UserMailer.batch_subscription_notification(subscription_id, entries.to_json).deliver_later + rescue ActiveRecord::RecordNotFound + # never rescue all errors + end + end + end + + def self.clear_queue(notification_type) + redis = redis_for_type(notification_type) + keys = redis.keys("#{notification_type}_*") + redis.del(*keys) unless keys.empty? + redis.del("notification_#{notification_type}") + end + + # Return and empty the list of users to be notified for a given type of notification + def self.to_notify(notification_type) + redis = redis_for_type(notification_type) + # atomically get all the users to notify and then delete the list + list, = redis.multi do + redis.smembers("notification_#{notification_type}") + redis.del "notification_#{notification_type}" + end + list + end + + def self.redis_for_type(notification_type) + notification_type == "kudos" ? REDIS_KUDOS : REDIS_GENERAL + end +end diff --git a/app/models/related_work.rb b/app/models/related_work.rb new file mode 100755 index 0000000..97d7dc4 --- /dev/null +++ b/app/models/related_work.rb @@ -0,0 +1,61 @@ +class RelatedWork < ActiveRecord::Base + belongs_to :work + belongs_to :parent, polymorphic: true, autosave: true + + attribute :url, :string + attribute :title, :string + attribute :author, :string + attribute :language_id, :integer + + scope :posted, -> { + joins("INNER JOIN `works` `child_works` ON `child_works`.`id` = `related_works`.`work_id`"). + where("child_works.posted = 1") + } + + before_validation :set_parent, if: :new_record? + def set_parent + return if parent + + if url.include?(ArchiveConfig.APP_HOST) + if url.match(%r{/works/(\d+)}) + self.parent = Work.find_by(id: Regexp.last_match(1)) + else + errors.add(:parent, :not_work) + throw :abort # don't generate any further errors + end + else + self.parent = ExternalWork.find_or_initialize_by( + url: url, + title: title, + author: author, + language_id: language_id + ) + end + end + + validates :parent, presence: true, on: :create + + validate :check_parent_protected, on: :create + def check_parent_protected + return unless parent.respond_to?(:users) + return if parent.anonymous? || parent.unrevealed? + + parent.users.each do |user| + errors.add(:parent, :protected, login: user.login) if user.protected_user + end + end + + def notify_parent_owners + if parent.respond_to?(:pseuds) + users = parent.pseuds.collect(&:user).uniq + orphan_account = User.orphan_account + users.each do |user| + unless user == orphan_account + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.related_work_notification(user.id, self.id).deliver_after_commit + end + end + end + end + end +end diff --git a/app/models/relationship.rb b/app/models/relationship.rb new file mode 100755 index 0000000..9b0a17d --- /dev/null +++ b/app/models/relationship.rb @@ -0,0 +1,43 @@ +class Relationship < Tag + + NAME = ArchiveConfig.RELATIONSHIP_CATEGORY_NAME + + # Types of tags to which a relationship tag can belong via common taggings or meta taggings + def parent_types + ['Fandom', 'Character', 'MetaTag'] + end + def child_types + ['SubTag', 'Merger'] + end + + def characters + parents.by_type('Character').by_name + end + + def all_characters + all = self.characters + if self.merger + all << self.merger.characters + end + all_with_synonyms = all.flatten.uniq.compact + all_with_synonyms << all_with_synonyms.collect{|c| c.mergers} + all_with_synonyms.flatten.uniq.compact + end + + def relationships + (parents + children).select {|t| t.is_a? Relationship}.sort + end + + def freeforms + children.by_type('Freeform').by_name + end + + def fandoms + parents.by_type('Fandom').by_name + end + + def medias + parents.by_type('Media').by_name + end + +end diff --git a/app/models/request.rb b/app/models/request.rb new file mode 100755 index 0000000..5ec7013 --- /dev/null +++ b/app/models/request.rb @@ -0,0 +1,7 @@ +class Request < Prompt + belongs_to :challenge_signup, touch: true, inverse_of: :requests + + def prompt_restriction + collection&.challenge&.request_restriction + end +end diff --git a/app/models/role.rb b/app/models/role.rb new file mode 100755 index 0000000..137eeea --- /dev/null +++ b/app/models/role.rb @@ -0,0 +1,11 @@ +# Defines named roles for users that may be applied to +# objects in a polymorphic fashion. For example, you could create a role +# "moderator" for an instance of a model (i.e., an object), a model class, +# or without any specification at all. +class Role < ApplicationRecord + has_many :roles_users + has_many :users, through: :roles_users + belongs_to :authorizable, polymorphic: true + + scope :assignable, -> { where(authorizable_id: nil, authorizable_type: nil) } +end diff --git a/app/models/roles_user.rb b/app/models/roles_user.rb new file mode 100755 index 0000000..a49bfd3 --- /dev/null +++ b/app/models/roles_user.rb @@ -0,0 +1,38 @@ +class RolesUser < ApplicationRecord + belongs_to :user + belongs_to :role + + delegate :enqueue_to_index, to: :user + + after_create :log_role_addition + after_create :enqueue_to_index + after_destroy :log_role_removal + after_destroy :destroy_last_wrangling_activity + after_destroy :enqueue_to_index + + def log_role_addition + admin = User.current_user + note = "Change made by #{admin&.login}" + user.create_log_item({ admin_id: admin&.id, + action: ArchiveConfig.ACTION_ADD_ROLE, + note: note, + role_id: role_id }) + end + + def log_role_removal + admin = User.current_user + note = "Change made by #{admin&.login}" + user.create_log_item({ admin_id: admin&.id, + action: ArchiveConfig.ACTION_REMOVE_ROLE, + note: note, + role_id: role_id }) + end + + # After removing the tag_wrangler role, remove the + # user's last wrangling activity as well. + def destroy_last_wrangling_activity + return unless role.name == "tag_wrangler" + + user.last_wrangling_activity&.destroy + end +end diff --git a/app/models/scheduled_tag_job.rb b/app/models/scheduled_tag_job.rb new file mode 100755 index 0000000..80fb430 --- /dev/null +++ b/app/models/scheduled_tag_job.rb @@ -0,0 +1,10 @@ +class ScheduledTagJob + def self.perform(job_type) + case job_type + when 'add_counts_to_queue' + Tag.where("taggings_count_cache > ?", 40 * (ArchiveConfig.TAGGINGS_COUNT_CACHE_DIVISOR || 1500)).each do |tag| + tag.async(:update_counts_cache, tag.id) + end + end + end +end diff --git a/app/models/search/async_indexer.rb b/app/models/search/async_indexer.rb new file mode 100755 index 0000000..f96e2f1 --- /dev/null +++ b/app/models/search/async_indexer.rb @@ -0,0 +1,68 @@ +class AsyncIndexer + REDIS = REDIS_GENERAL + + #################### + # CLASS METHODS + #################### + + def self.perform(name) + # TODO: Keep the method so we can still run queued jobs from previous + # versions. However, tests should no longer depend on it. + # + # Remove in a future version, once all old jobs have been retried or + # cleared. + raise "Avoid using AsyncIndexer.perform in tests" if Rails.env.test? + + indexer = name.split(":").first.constantize + ids = REDIS.smembers(name) + + return if ids.empty? + + batch = indexer.new(ids).index_documents + IndexSweeper.new(batch, indexer).process_batch + REDIS.del(name) + end + + # Get the appropriate indexers for the class and pass the ids off to them + # This method is only called internally and klass is not a user-supplied value + def self.index(klass, ids, priority) + if klass.to_s =~ /Indexer/ + indexers = [klass] + else + klass = klass.constantize if klass.respond_to?(:constantize) + indexers = klass.new.indexers + end + indexers.each do |indexer| + self.new(indexer, priority).enqueue_ids(ids) + end + end + + #################### + # INSTANCE METHODS + #################### + + attr_reader :indexer, :priority + + # Just standardizing priority/queue names + def initialize(indexer, priority) + @indexer = indexer + @priority = case priority.to_s + when "main" + "high" + when "background" + "low" + else + priority + end + end + + def enqueue_ids(ids) + name = "#{indexer}:#{ids.first}:#{Time.now.to_i}" + REDIS.sadd(name, ids) + AsyncIndexerJob.set(queue: queue).perform_later(name) + end + + def queue + "reindex_#{priority}" + end +end diff --git a/app/models/search/bookmark_indexer.rb b/app/models/search/bookmark_indexer.rb new file mode 100755 index 0000000..7cd3682 --- /dev/null +++ b/app/models/search/bookmark_indexer.rb @@ -0,0 +1,113 @@ +class BookmarkIndexer < Indexer + + def self.klass + "Bookmark" + end + + # Create the bookmarkable index/mapping first + # Skip delete on the subclasses so it doesn't delete the ones we've just + # reindexed + def self.index_all(options = {}) + unless options[:skip_delete] + options[:skip_delete] = true + BookmarkableIndexer.delete_index + BookmarkableIndexer.create_index(shards: ArchiveConfig.BOOKMARKABLE_SHARDS) + create_mapping + end + BookmarkedExternalWorkIndexer.index_all(skip_delete: true) + BookmarkedSeriesIndexer.index_all(skip_delete: true) + BookmarkedWorkIndexer.index_all(skip_delete: true) + super + end + + def self.mapping + { + properties: { + bookmarkable_join: { + type: "join", + relations: { + bookmarkable: "bookmark" + } + }, + title: { + type: "text", + analyzer: "simple" + }, + creators: { + type: "text", + analyzer: "standard" + }, + work_types: { + type: "keyword" + }, + bookmarkable_type: { + type: "keyword" + }, + bookmarker: { + type: "text", + analyzer: "standard" + }, + tag: { + type: "text", + analyzer: "simple" + }, + sort_id: { + type: "keyword" + } + } + } + end + + #################### + # INSTANCE METHODS + #################### + + def routing_info(id) + object = objects[id.to_i] + { + "_index" => index_name, + "_id" => id, + "routing" => parent_id(id, object) + } + end + + def parent_id(id, object) + if object.nil? + deleted_bookmark_info(id) + else + "#{object.bookmarkable_id}-#{object.bookmarkable_type.underscore}" + end + end + + def document(object) + tags = object.tags + json_object = object.as_json( + root: false, + only: [ + :id, :created_at, :bookmarkable_type, :bookmarkable_id, + :private, :updated_at, :hidden_by_admin, :pseud_id, :rec + ], + methods: [:bookmarker, :collection_ids, :with_notes, :bookmarkable_date] + ).merge( + user_id: object.pseud&.user_id, + tag: tags.map(&:name), + tag_ids: tags.map(&:id), + notes: object.bookmarker_notes + ) + + unless parent_id(object.id, object).match("deleted") + json_object.merge!( + bookmarkable_join: { + name: "bookmark", + parent: parent_id(object.id, object) + } + ) + end + + json_object + end + + def deleted_bookmark_info(id) + REDIS_GENERAL.get("deleted_bookmark_parent_#{id}") + end +end diff --git a/app/models/search/bookmark_query.rb b/app/models/search/bookmark_query.rb new file mode 100755 index 0000000..0ef43e3 --- /dev/null +++ b/app/models/search/bookmark_query.rb @@ -0,0 +1,364 @@ +class BookmarkQuery < Query + attr_accessor :bookmarkable_query + + def klass + 'Bookmark' + end + + def index_name + BookmarkIndexer.index_name + end + + def document_type + BookmarkIndexer.document_type + end + + # Load the options and create the linked BookmarkableQuery class (which is + # used to generate all of our parent filters). + def initialize(options = {}) + @options = HashWithIndifferentAccess.new(options) + add_owner + self.bookmarkable_query = BookmarkableQuery.new(self) + end + + # Combine the filters and queries for both the bookmark and the bookmarkable. + def filtered_query + make_bool( + # Score is based on our query + the bookmarkable query: + must: make_list(queries, bookmarkable_queries_and_filters), + filter: filters, + must_not: make_list(exclusion_filters, bookmarkable_exclusion_filters) + ) + end + + # Queries that apply only to the bookmark. Bookmarkable queries are handled + # in filtered_query, and should not be included here. + def queries + @queries ||= make_list( + general_query + ) + end + + # Filters that apply only to the bookmark. Bookmarkable filters are handled + # in filtered_query, and should not be included here. + def filters + @filters ||= make_list( + privacy_filter, + hidden_filter, + bookmarks_only_filter, + pseud_filter, + user_filter, + rec_filter, + notes_filter, + tags_filter, + named_tag_inclusion_filter, + collections_filter, + type_filter, + date_filter + ) + end + + # Exclusion filters that apply only to the bookmark. Exclusion filters for + # the bookmarkable are handled in filtered_query, and should not be included + # here. + def exclusion_filters + @exclusion_filters ||= make_list( + tag_exclusion_filter, + named_tag_exclusion_filter + ) + end + + def add_owner + owner = options[:parent] + field = case owner + when Tag + # Note that in a bookmark search for a Tag owner, we want to return + # the bookmarkables, not bookmarks, with that tag. + # This field will be handled in the linked BookmarkableQuery. + :filter_ids + when Pseud + :pseud_ids + when User + :user_ids + when Collection + :collection_ids + end + return unless field.present? + options[field] ||= [] + options[field] << owner.id + end + + #################### + # QUERIES + #################### + + def general_query + return nil if bookmark_query_text.blank? + + { query_string: { query: bookmark_query_text, default_operator: "AND" } } + end + + def bookmark_query_text + query_text = (options[:bookmark_query] || "").dup + query_text << split_query_text_words(:bookmarker, options[:bookmarker]) + query_text << split_query_text_words(:notes, options[:notes]) + escape_slashes(query_text.strip) + end + + #################### + # SORTING AND AGGREGATIONS + #################### + + def sort_column + @sort_column ||= + options[:sort_column].present? ? options[:sort_column] : default_sort + end + + def sort_direction + @sort_direction ||= + options[:sort_direction].present? ? options[:sort_direction] : "desc" + end + + def default_sort + facet_tags? ? 'created_at' : '_score' + end + + def sort + sort_hash = { sort_column => { order: sort_direction } } + + if %w(created_at bookmarkable_date).include?(sort_column) + sort_hash[sort_column][:unmapped_type] = 'date' + end + + [sort_hash, { id: { order: sort_direction } }] + end + + # The aggregations for just the bookmarks: + def bookmark_aggregations + aggs = {} + + if facet_collections? + aggs[:collections] = { terms: { field: 'collection_ids' } } + end + + if facet_tags? + aggs[:tag] = { terms: { field: "tag_ids" } } + end + + aggs + end + + # Combine the bookmark aggregations with the bookmarkable aggregations from + # the bookmarkable query. + def aggregations + aggs = bookmark_aggregations + + bookmarkable_aggregations = bookmarkable_query.bookmarkable_aggregations + if bookmarkable_aggregations.present? + aggs[:bookmarkable] = { + parent: { type: "bookmark" }, + aggs: bookmarkable_aggregations + } + end + + { aggs: aggs } if aggs.present? + end + + #################### + # BOOKMARKABLE + #################### + + # Wrap both the queries and the filters from the bookmarkable query into a + # single has_parent query. (The fewer has_parent queries we have, the faster + # the query will be.) + def bookmarkable_queries_and_filters + bool = make_bool( + must: bookmarkable_query.queries, + filter: bookmarkable_query.filters + ) + + return if bool.nil? + + { + has_parent: { + parent_type: "bookmarkable", + score: true, # include the score from the bookmarkable + query: bool + } + } + end + + # Wrap all of the must_not/not filters on the bookmarkable into a single + # has_parent query. Note that we wrap them in a should/or query because if + # any of the parent queries return true, we want to return false. (De + # Morgan's Law.) + def bookmarkable_exclusion_filters + return if bookmarkable_query.exclusion_filters.blank? + + { + has_parent: { + parent_type: "bookmarkable", + query: make_bool( + should: bookmarkable_query.exclusion_filters + ) + } + } + end + + #################### + # FILTERS + #################### + + def privacy_filter + term_filter(:private, 'false') unless include_private? + end + + def hidden_filter + term_filter(:hidden_by_admin, 'false') + end + + def rec_filter + term_filter(:rec, 'true') if %w(1 true).include?(options[:rec].to_s) + end + + def notes_filter + term_filter(:with_notes, 'true') if %w(1 true).include?(options[:with_notes].to_s) + end + + def type_filter + term_filter(:bookmarkable_type, options[:bookmarkable_type].gsub(" ", "")) if options[:bookmarkable_type].present? + end + + # The date filter on the bookmark (i.e. when the bookmark was created). + def date_filter + if options[:date].present? + { range: { created_at: SearchRange.parsed(options[:date]) } } + end + end + + def pseud_filter + if options[:pseud_ids].present? + terms_filter(:pseud_id, options[:pseud_ids].flatten.uniq) + end + end + + def user_filter + return unless options[:user_ids].present? + options[:user_ids].flatten.uniq.map { |user_id| term_filter(:user_id, user_id) } + end + + def tags_filter + if included_bookmark_tag_ids.present? + included_bookmark_tag_ids.map { |tag_id| term_filter(:tag_ids, tag_id) } + end + end + + def collections_filter + terms_filter(:collection_ids, options[:collection_ids]) if options[:collection_ids].present? + end + + def tag_exclusion_filter + terms_filter(:tag_ids, excluded_bookmark_tag_ids) if excluded_bookmark_tag_ids.present? + end + + # We don't want to accidentally return Bookmarkable documents when we're + # doing a search for Bookmarks. So we should only include documents that are + # marked as "bookmark" in their bookmarkable_join field. + def bookmarks_only_filter + term_filter(:bookmarkable_join, "bookmark") + end + + # This filter is used to restrict our results to only include bookmarks whose + # "tag" text matches all of the tag names in included_bookmark_tag_names. + # This is useful when the user enters a non-existent tag, which would be + # discarded by the included_bookmark_tag_ids function. + def named_tag_inclusion_filter + return if included_bookmark_tag_names.blank? + match_filter(:tag, included_bookmark_tag_names.join(" ")) + end + + # This set of filters is used to prevent us from matching any bookmarks + # whose "tag" text matches one of the passed-in tag names. This is useful + # when the user enters a non-existent tag, which would be discarded by the + # excluded_bookmark_tag_ids function. + # + # Unlike the inclusion filter, we separate the queries to make sure that with + # tags "A B" and "C D", we're searching for "not(A and B) and not(C and D)", + # instead of "not(A and B and C and D)" or "not(A or B or C or D)". + def named_tag_exclusion_filter + excluded_bookmark_tag_names.map do |tag_name| + match_filter(:tag, tag_name) + end + end + + #################### + # HELPERS + #################### + + def facet_tags? + options[:faceted] + end + + def facet_collections? + false + end + + def include_private? + # Use fetch instead of || here to make sure that we don't accidentally + # override a deliberate choice not to show private bookmarks. + options.fetch(:show_private, + User.current_user.is_a?(User) && + user_ids.include?(User.current_user.id)) + end + + def user_ids + user_ids = [] + if options[:user_ids].present? + user_ids += options[:user_ids].map(&:to_i) + end + if options[:pseud_ids].present? + user_ids += Pseud.where(id: options[:pseud_ids]).pluck(:user_id) + end + user_ids + end + + # The list of all tag IDs that should be required for our bookmarks. + def included_bookmark_tag_ids + @included_bookmark_tag_ids ||= [ + options[:tag_ids], + parsed_included_tags[:ids] + ].flatten.compact.uniq + end + + # The list of all tag IDs that should be prohibited for our bookmarks. + def excluded_bookmark_tag_ids + @excluded_bookmark_tag_ids ||= [ + options[:excluded_bookmark_tag_ids], + parsed_excluded_tags[:ids] + ].flatten.compact.uniq + end + + # The list of included tag names that weren't found in the database (and thus + # have to be used as text-matching constraints on the tag field). + def included_bookmark_tag_names + parsed_included_tags[:missing] + end + + # The list of excluded tag names that weren't found in the database (and thus + # have to be used as text-matching constraints on the tag field). + def excluded_bookmark_tag_names + parsed_excluded_tags[:missing] + end + + # Parse the tag names that should be included in our results. + def parsed_included_tags + @parsed_included_tags ||= + bookmarkable_query.parse_named_tags(%i[other_bookmark_tag_names]) + end + + # Parse the tag names that should be excluded from our results. + def parsed_excluded_tags + @parsed_excluded_tags ||= + bookmarkable_query.parse_named_tags(%i[excluded_bookmark_tag_names]) + end +end diff --git a/app/models/search/bookmark_search_form.rb b/app/models/search/bookmark_search_form.rb new file mode 100755 index 0000000..3e4c69b --- /dev/null +++ b/app/models/search/bookmark_search_form.rb @@ -0,0 +1,200 @@ +class BookmarkSearchForm + + extend ActiveModel::Naming + include ActiveModel::Conversion + include ActiveModel::Validations + + ATTRIBUTES = [ + :bookmark_query, + :bookmarkable_query, + :rec, + :bookmark_notes, + :with_notes, + :date, + :show_private, + :pseud_ids, + :user_ids, + :bookmarker, + :bookmarkable_pseud_names, + :bookmarkable_pseud_ids, + :bookmarkable_type, + :language_id, + :excluded_tag_names, + :excluded_bookmark_tag_names, + :excluded_tag_ids, + :excluded_bookmark_tag_ids, + :other_tag_names, + :other_bookmark_tag_names, + :tag_ids, + :filter_ids, + :filter_names, + :fandom_ids, + :character_ids, + :relationship_ids, + :freeform_ids, + :rating_ids, + :archive_warning_ids, + :category_ids, + :bookmarkable_title, + :bookmarkable_date, + :bookmarkable_complete, + :collection_ids, + :bookmarkable_collection_ids, + :sort_column, + :show_restricted, + :page, + :faceted + ] + + attr_accessor :options + + ATTRIBUTES.each do |filterable| + define_method(filterable) { options[filterable] } + end + + def initialize(options = {}) + @options = processed_options(options) + @searcher = BookmarkQuery.new(@options) + end + + def persisted? + false + end + + # This is used by SearchHelper.search_header. + def query + queries = [] + %w[bookmarkable_query bookmark_query].each do |key| + queries << options[key] if options[key].present? + end + queries.join(', ') + end + + def summary + summary = [] + %w[bookmarkable_query bookmark_query].each do |key| + if options[key].present? + summary << options[key] + end + end + if options[:bookmarker].present? + summary << "Bookmarker: #{options[:bookmarker]}" + end + if options[:notes].present? + summary << "Notes: #{options[:notes]}" + end + tags = [] + %w[other_tag_names other_bookmark_tag_names].each do |key| + if options[key].present? + tags << options[key] + end + end + all_tag_ids = [] + [:filter_ids, :fandom_ids, :rating_ids, :category_ids, :archive_warning_ids, :character_ids, :relationship_ids, :freeform_ids].each do |tag_ids| + if options[tag_ids].present? + all_tag_ids += options[tag_ids] + end + end + unless all_tag_ids.empty? + tags << Tag.where(id: all_tag_ids).pluck(:name).join(", ") + end + unless tags.empty? + summary << "Tags: #{tags.uniq.join(", ")}" + end + if self.bookmarkable_type.present? + summary << "Type: #{self.bookmarkable_type}" + end + if self.language_id.present? + language = Language.find_by(short: self.language_id) + if language.present? + summary << "Work language: #{language.name}" + end + end + if %w(1 true).include?(self.rec.to_s) + summary << "Rec" + end + if %w(1 true).include?(self.with_notes.to_s) + summary << "With Notes" + end + [:date, :bookmarkable_date].each do |countable| + if options[countable].present? + desc = (countable == :date) ? "Date bookmarked" : "Date updated" + summary << "#{desc}: #{options[countable]}" + end + end + summary.join(", ") + end + + def search_results + @searcher.search_results + end + + # Special function for returning the BookmarkableQuery results (instead of + # the BookmarkQuery results). + def bookmarkable_search_results + @searcher.bookmarkable_query.search_results + end + + ############### + # SORTING + ############### + + def sort_options + [ + ['Date Bookmarked', 'created_at'], + ['Date Updated', 'bookmarkable_date'], + ] + end + + def sort_values + sort_options.map{ |option| option.last } + end + + def sort_direction(sort_column) + 'desc' + end + + private + + def processed_options(opts = {}) + [:date, :bookmarkable_date].each do |countable| + if opts[countable].present? + opts[countable] = opts[countable].gsub(">", ">"). + gsub("<", "<") + end + end + + # If we call the form field 'notes', the parser adds html to it + opts[:notes] = opts[:bookmark_notes] + + opts = standardize_language_ids(opts) + + # Support legacy warning searches + if opts[:warning_ids].present? + opts[:archive_warning_ids] = opts.delete(:warning_ids) + end + + # We need to respect some options that are deliberately set to false, and + # false.blank? is true, so we check for nil? and not blank? here. + opts.delete_if { |_, v| v.nil? } + end + + # Maintain backward compatibility for old bookmark searches/filters: + def standardize_language_ids(opts) + # - Using language IDs in the "Work language" dropdown + if opts[:language_id].present? && opts[:language_id].to_i != 0 + language = Language.find_by(id: opts[:language_id]) + opts[:language_id] = language.short if language.present? + end + + # - Using language IDs in "Any field on work" (search) or "Search within results" (filters) + if opts[:bookmarkable_query].present? + opts[:bookmarkable_query] = opts[:bookmarkable_query].gsub(/\blanguage_id\s*:\s*(\d+)/) do + lang = Language.find_by(id: Regexp.last_match[1]) + lang = Language.default if lang.blank? + "language_id: " + lang.short + end + end + opts + end +end diff --git a/app/models/search/bookmarkable_indexer.rb b/app/models/search/bookmarkable_indexer.rb new file mode 100755 index 0000000..e6734fc --- /dev/null +++ b/app/models/search/bookmarkable_indexer.rb @@ -0,0 +1,37 @@ +class BookmarkableIndexer < Indexer + + def self.index_name + "#{ArchiveConfig.ELASTICSEARCH_PREFIX}_#{Rails.env}_bookmarks" + end + + def self.document_type + 'bookmark' + end + + def self.mapping + BookmarkIndexer.mapping + end + + # When we fail, we don't want to just keep adding the -klass suffix. + def self.find_elasticsearch_ids(ids) + ids.map(&:to_i) + end + + def routing_info(id) + { + "_index" => index_name, + "_id" => document_id(id) + } + end + + def document(object) + object.bookmarkable_json.merge( + sort_id: document_id(object.id) + ) + end + + def document_id(id) + "#{id}-#{klass.underscore}" + end + +end diff --git a/app/models/search/bookmarkable_query.rb b/app/models/search/bookmarkable_query.rb new file mode 100755 index 0000000..19105a3 --- /dev/null +++ b/app/models/search/bookmarkable_query.rb @@ -0,0 +1,287 @@ +class BookmarkableQuery < Query + include TaggableQuery + + attr_accessor :bookmark_query + + # Rather than compute this information twice, we rely on the BookmarkQuery + # class to calculate information about sorting. + delegate :sort_column, :sort_direction, + to: :bookmark_query + + # The "klass" function here returns the class name used to load search + # results. The BookmarkableQuery is unique among Query classes because it can + # return objects from more than one table, so we need to use a special class + # that can handle IDs of multiple types. + def klass + 'BookmarkableDecorator' + end + + def index_name + BookmarkableIndexer.index_name + end + + def document_type + BookmarkableIndexer.document_type + end + + # The BookmarkableQuery is unique among queries in that it depends wholly on + # the BookmarkQuery for all of its options. So we have a slightly different + # constructor. + def initialize(bookmark_query) + self.bookmark_query = bookmark_query + @options = bookmark_query.options + end + + # Combine the filters and queries for both the bookmark and the bookmarkable. + def filtered_query + make_bool( + # All queries/filters/exclusion filters for the bookmark are wrapped in a + # single has_child query by the bookmark_filter function: + must: bookmark_filter, + # We never sort by score, so we can always ignore the score on our + # queries, grouping them together with our filters. (Note, however, that + # the bookmark search can incorporate our score, so there is a + # distinction between queries and filters -- just not in this function.) + filter: make_list(queries, filters), + must_not: exclusion_filters + ) + end + + # Queries that apply only to the bookmarkable. Bookmark queries are handled + # in filtered_query, and should not be included here. + def queries + @queries ||= make_list( + general_query + ) + end + + # Filters that apply only to the bookmarkable. Bookmark filters are handled + # in filtered_query, and should not be included here. + def filters + @filters ||= make_list( + complete_filter, + language_filter, + filter_id_filter, + named_tag_inclusion_filter, + date_filter + ) + end + + # Exclusion filters that apply only to the bookmarkable. Exclusion filters + # for the bookmark are handled in filtered_query, and should not be included + # here. + def exclusion_filters + @exclusion_filters ||= make_list( + unposted_filter, + hidden_filter, + restricted_filter, + tag_exclusion_filter, + named_tag_exclusion_filter + ) + end + + #################### + # QUERIES + #################### + + def general_query + return nil if bookmarkable_query_text.blank? + + { query_string: { query: bookmarkable_query_text, default_operator: "AND" } } + end + + def bookmarkable_query_text + query_text = (options[:bookmarkable_query] || "").dup + escape_slashes(query_text.strip) + end + + #################### + # SORTING AND AGGREGATIONS + #################### + + # When sorting by bookmarkable date, we use the revised_at field to order the + # results. When sorting by created_at, we use _score to sort (because the + # only way to sort by a child's fields is to store the value in the _score + # field and sort by score). + def sort + if sort_column == "bookmarkable_date" + sort_hash = { revised_at: { order: sort_direction, unmapped_type: "date" } } + else + sort_hash = { _score: { order: sort_direction } } + end + + [sort_hash, { sort_id: { order: sort_direction } }] + end + + # Define the aggregations for just the bookmarkable. This is combined with + # the bookmark's aggregations below. + def bookmarkable_aggregations + aggs = {} + + if bookmark_query.facet_tags? + %w[rating archive_warning category fandom character relationship freeform].each do |facet_type| + aggs[facet_type] = { + terms: { + field: "#{facet_type}_ids" + } + } + end + end + + aggs + end + + # Combine the bookmarkable aggregations with the bookmark aggregations from + # the bookmark query. + def aggregations + aggs = bookmarkable_aggregations + + bookmark_aggregations = bookmark_query.bookmark_aggregations + if bookmark_aggregations.present? + aggs[:bookmarks] = { + # Aggregate on our child bookmarks. + children: { type: "bookmark" }, + aggs: { + filtered_bookmarks: { + filter: bookmark_bool, + aggs: bookmark_aggregations + } + } + } + end + + { aggs: aggs } if aggs.present? + end + + #################### + # BOOKMARKS + #################### + + # Create a single has_child query with ALL of the child's queries and filters + # included. In order to avoid issues with multiple bookmarks combining to + # create an (incorrect) bookmarkable match, there MUST be exactly one + # has_child query. (Plus, it probably makes it faster.) + def bookmark_filter + bool = bookmark_bool + + # If we're sorting by created_at, we actually need to fetch the bookmarks' + # created_at as the score of this query, so that we can sort by score (and + # therefore by the bookmarks' created_at). + bool = field_value_score("created_at", bool) if sort_column == "created_at" + + { + has_child: { + type: "bookmark", + score_mode: "max", + query: bool, + inner_hits: { + size: inner_hits_size, + sort: { created_at: { order: "desc", unmapped_type: "date" } } + } + } + } + end + + # The bool used in the has_child query and to filter the bookmark + # aggregations. Contains all of the constraints on bookmarks, and no + # constraints on bookmarkables. + def bookmark_bool + make_bool( + must: bookmark_query.queries, + filter: bookmark_query.filters, + must_not: bookmark_query.exclusion_filters + ) + end + + #################### + # FILTERS + #################### + + def complete_filter + term_filter(:complete, 'true') if options[:complete].present? + end + + def language_filter + term_filter(:"language_id.keyword", options[:language_id]) if options[:language_id].present? + end + + def filter_id_filter + if filter_ids.present? + filter_ids.map { |filter_id| term_filter(:filter_ids, filter_id) } + end + end + + # The date filter on the bookmarkable (i.e. when the bookmarkable was last + # updated). + def date_filter + if options[:bookmarkable_date].present? + { range: { revised_at: SearchRange.parsed(options[:bookmarkable_date]) } } + end + end + + # Exclude drafts from bookmarkable search results. + # Note that this is used as an exclusion filter, not an inclusion filter, so + # the boolean is flipped from the way you might expect. + def unposted_filter + term_filter(:posted, 'false') + end + + # Exclude items hidden by admin from bookmarkable search results. + # Note that this is used as an exclusion filter, not an inclusion filter, so + # the boolean is flipped from the way you might expect. + def hidden_filter + term_filter(:hidden_by_admin, 'true') + end + + # Exclude restricted works/series when the user isn't logged in. + # Note that this is used as an exclusion filter, not an inclusion filter, so + # the boolean is flipped from the way you might expect. + def restricted_filter + term_filter(:restricted, 'true') unless include_restricted? + end + + def tag_exclusion_filter + if exclusion_ids.present? + terms_filter(:filter_ids, exclusion_ids) + end + end + + # This filter is used to restrict our results to only include bookmarkables + # whose "tag" text matches all of the tag names in included_tag_names. This + # is useful when the user enters a non-existent tag, which would be discarded + # by the TaggableQuery.filter_ids function. + def named_tag_inclusion_filter + return if included_tag_names.blank? + match_filter(:tag, included_tag_names.join(" ")) + end + + # This set of filters is used to prevent us from matching any bookmarkables + # whose "tag" text matches one of the passed-in tag names. This is useful + # when the user enters a non-existent tag, which would be discarded by the + # TaggableQuery.exclusion_ids function. + # + # Note that we separate these into different filters to get the logic of tag + # exclusion right: if we're excluding "A B" and "C D", we want the query to + # be "not(A and B) and not(C and D)", which can't be accomplished in a single + # match query. + def named_tag_exclusion_filter + excluded_tag_names.map do |tag_name| + match_filter(:tag, tag_name) + end + end + + #################### + # HELPERS + #################### + + # The number of bookmarks to return with each bookmarkable. + def inner_hits_size + ArchiveConfig.NUMBER_OF_BOOKMARKS_SHOWN_PER_BOOKMARKABLE || 5 + end + + def include_restricted? + # Use fetch instead of || here to make sure that we don't accidentally + # override a deliberate choice not to show restricted bookmarks. + options.fetch(:show_restricted, User.current_user.present?) + end +end diff --git a/app/models/search/bookmarked_external_work_indexer.rb b/app/models/search/bookmarked_external_work_indexer.rb new file mode 100755 index 0000000..39ea759 --- /dev/null +++ b/app/models/search/bookmarked_external_work_indexer.rb @@ -0,0 +1,5 @@ +class BookmarkedExternalWorkIndexer < BookmarkableIndexer + def self.klass + "ExternalWork" + end +end diff --git a/app/models/search/bookmarked_series_indexer.rb b/app/models/search/bookmarked_series_indexer.rb new file mode 100755 index 0000000..0b86d4b --- /dev/null +++ b/app/models/search/bookmarked_series_indexer.rb @@ -0,0 +1,5 @@ +class BookmarkedSeriesIndexer < BookmarkableIndexer + def self.klass + "Series" + end +end diff --git a/app/models/search/bookmarked_work_indexer.rb b/app/models/search/bookmarked_work_indexer.rb new file mode 100755 index 0000000..3ae772b --- /dev/null +++ b/app/models/search/bookmarked_work_indexer.rb @@ -0,0 +1,18 @@ +class BookmarkedWorkIndexer < BookmarkableIndexer + def self.klass + "Work" + end + + def self.klass_with_includes + Work.includes( + :approved_collections, + :direct_filters, + :external_author_names, + :filters, + :language, + :tags, + :users, + pseuds: :user + ) + end +end diff --git a/app/models/search/index_sweeper.rb b/app/models/search/index_sweeper.rb new file mode 100755 index 0000000..865d8cb --- /dev/null +++ b/app/models/search/index_sweeper.rb @@ -0,0 +1,111 @@ +class IndexSweeper + + REDIS = AsyncIndexer::REDIS + + def self.async_cleanup(klass, expected_ids, found_ids) + deleted_ids = expected_ids.map(&:to_i).select { |id| !found_ids.include?(id) } + + if deleted_ids.any? + AsyncIndexer.index(klass, deleted_ids, "cleanup") + end + end + + def initialize(batch, indexer) + @batch = batch + @indexer = indexer + @success_ids = [] + @rerun_ids = [] + end + + def process_batch + return if @batch.nil? + + load_errors + + @batch["items"].each do |item| + process_document(item) + end + + save_errors + + if @success_ids.present? && @indexer.respond_to?(:handle_success) + @indexer.handle_success(@success_ids) + end + + if @rerun_ids.any? + AsyncIndexer.new(@indexer, "failures").enqueue_ids( + @indexer.find_elasticsearch_ids(@rerun_ids) + ) + end + end + + # Returns a list of all permanent failures associated with the given indexer. + # Used for testing purposes. (Can be used for diagnostic purposes, as well.) + def self.permanent_failures(indexer) + failures = [] + + REDIS.hgetall("#{indexer}:failures").each_pair do |id, value| + JSON.parse(value).each do |info| + if info["count"] >= 3 + failures << { id.to_s => info["error"] } + end + end + end + + failures + end + + private + + # Calculate which IDs were included in this batch. + def batch_ids + @batch_ids ||= @batch["items"].map { |item| item.values.first["_id"].to_s } + end + + # Load information about previous errors for all the items in this batch. + def load_errors + @errors = REDIS.mapped_hmget("#{@indexer}:failures", *batch_ids) + @errors.transform_values! { |value| JSON.parse(value || "[]") } + end + + # Save information about all the errors for all the items in this batch. + def save_errors + return unless @errors.present? + + # Clear out the blank errors. + blank = @errors.select { |_, v| v.blank? }.keys + REDIS.hdel("#{@indexer}:failures", blank) if blank.present? + + # Save the items with non-blank errors. + present = @errors.select { |_, v| v.present? } + present.transform_values!(&:to_json) + REDIS.mapped_hmset("#{@indexer}:failures", present) if present.present? + end + + def process_document(item) + document = item[item.keys.first] # update/index/delete + id = document["_id"] + + if document["error"] + if add_error(id, document["error"]) < 3 + @rerun_ids << id + end + else + @errors[id.to_s].clear + @success_ids << id + end + end + + # Add an error for the given document ID. Return the total number of times + # that error has occurred. + def add_error(id, error) + @errors[id.to_s].each do |info| + next unless info["error"] == error + return info["count"] += 1 + end + + # The error hasn't been seen before, so we need to add it with a count of 1. + @errors[id.to_s] << { "error" => error, "count" => 1 } + 1 # we return the count + end +end diff --git a/app/models/search/indexer.rb b/app/models/search/indexer.rb new file mode 100755 index 0000000..eb29471 --- /dev/null +++ b/app/models/search/indexer.rb @@ -0,0 +1,228 @@ +class Indexer + BATCH_SIZE = 1000 + INDEXERS_FOR_CLASS = { + Work: %w[WorkIndexer WorkCreatorIndexer BookmarkedWorkIndexer], + Bookmark: %w[BookmarkIndexer], + Tag: %w[TagIndexer], + Pseud: %w[PseudIndexer], + Series: %w[BookmarkedSeriesIndexer], + ExternalWork: %w[BookmarkedExternalWorkIndexer], + User: %w[UserIndexer] + }.freeze + + delegate :klass, :klass_with_includes, :index_name, :document_type, to: :class + + ################## + # CLASS METHODS + ################## + + def self.klass + raise "Must be defined in subclass" + end + + def self.klass_with_includes + klass.constantize + end + + def self.all + [ + BookmarkedExternalWorkIndexer, + BookmarkedSeriesIndexer, + BookmarkedWorkIndexer, + BookmarkIndexer, + PseudIndexer, + TagIndexer, + UserIndexer, + WorkIndexer, + WorkCreatorIndexer + ] + end + + # Originally added to allow IndexSweeper to find the Elasticsearch document + # ids when they do not match the associated ActiveRecord objects' ids. + # + # Override in subclasses if necessary. + def self.find_elasticsearch_ids(ids) + ids + end + + def self.delete_index + if $elasticsearch.indices.exists(index: index_name) + $elasticsearch.indices.delete(index: index_name) + end + end + + def self.create_index(shards: 5) + $elasticsearch.indices.create( + index: index_name, + body: { + settings: { + index: { + # static settings + number_of_shards: shards, + # dynamic settings + max_result_window: ArchiveConfig.MAX_SEARCH_RESULTS, + } + }.merge(settings), + mappings: mapping, + } + ) + end + + def self.prepare_for_testing + raise "Wrong environment for test prep!" unless Rails.env.test? + + delete_index + # Relevance sorting is unpredictable with multiple shards + # and small amounts of data + create_index(shards: 1) + end + + def self.refresh_index + # Refreshes are resource-intensive, we use them only in tests. + raise "Wrong environment for index refreshes!" unless Rails.env.test? + + return unless $elasticsearch.indices.exists(index: index_name) + + $elasticsearch.indices.refresh(index: index_name) + end + + # Note that the index must exist before you can set the mapping + def self.create_mapping + $elasticsearch.indices.put_mapping( + index: index_name, + body: mapping + ) + end + + def self.mapping + { + properties: { + # add properties in subclasses + } + } + end + + def self.settings + { + analyzer: { + custom_analyzer: { + # add properties in subclasses + } + } + } + end + + def self.index_all(options = {}) + unless options[:skip_delete] + delete_index + create_index + end + index_from_db + end + + def self.index_from_db + total = (indexables.count / BATCH_SIZE) + 1 + i = 1 + indexables.find_in_batches(batch_size: BATCH_SIZE) do |group| + puts "Queueing #{klass} batch #{i} of #{total}" unless Rails.env.test? + AsyncIndexer.new(self, :world).enqueue_ids(group.map(&:id)) + i += 1 + end + end + + # Add conditions here + def self.indexables + klass.constantize + end + + def self.index_name + "#{ArchiveConfig.ELASTICSEARCH_PREFIX}_#{Rails.env}_#{klass.underscore.pluralize}" + end + + def self.document_type + klass.underscore + end + + # Given a searchable object, what indexers should handle it? + # Returns an array of indexers + def self.for_object(object) + name = object.is_a?(Tag) ? 'Tag' : object.class.to_s + (INDEXERS_FOR_CLASS[name.to_sym] || []).map(&:constantize) + end + + # Should be called after a batch update, with the IDs that were successfully + # updated. Calls successful_reindex on the indexable class. + def self.handle_success(ids) + if indexables.respond_to?(:successful_reindex) + indexables.successful_reindex(ids) + end + end + + #################### + # INSTANCE METHODS + #################### + + attr_reader :ids + + def initialize(ids) + @ids = ids + end + + def objects + @objects ||= klass_with_includes.where(id: ids).inject({}) do |h, obj| + h.merge(obj.id => obj) + end + end + + def batch + return @batch if @batch + + @batch = [] + ids.each do |id| + object = objects[id.to_i] + if object.present? + @batch << { index: routing_info(id) } + @batch << document(object) + else + @batch << { delete: routing_info(id) } + end + end + @batch + end + + def index_documents + return if batch.empty? + + $elasticsearch.bulk(body: batch) + end + + def index_document(object) + info = { + index: index_name, + id: document_id(object.id), + body: document(object) + } + if respond_to?(:parent_id) + info.merge!(routing: parent_id(object.id, object)) + end + $elasticsearch.index(info) + end + + def routing_info(id) + { + "_index" => index_name, + "_id" => id + } + end + + def document(object) + object.as_json(root: false) + end + + # can be overriden by our bookmarkable indexers + def document_id(id) + id + end + +end diff --git a/app/models/search/pseud_indexer.rb b/app/models/search/pseud_indexer.rb new file mode 100755 index 0000000..14e9bd7 --- /dev/null +++ b/app/models/search/pseud_indexer.rb @@ -0,0 +1,128 @@ +class PseudIndexer < Indexer + + def self.klass + "Pseud" + end + + def self.mapping + { + properties: { + name: { + type: "text", + analyzer: "simple" + }, + # adding extra name field for sorting + sortable_name: { + type: "keyword" + }, + byline: { + type: "text", + analyzer: "standard" + }, + user_login: { + type: "text", + analyzer: "simple" + }, + fandom: { + type: "nested" + } + } + } + end + + def document(object) + object.as_json( + root: false, + only: [:id, :user_id, :name, :description, :created_at], + methods: [ + :user_login, + :byline, + :collection_ids + ] + ).merge(extras(object).as_json) + end + + def extras(pseud) + work_counts = work_counts(pseud) + { + sortable_name: pseud.name.downcase, + fandoms: fandoms(pseud), + general_bookmarks_count: general_bookmarks_count(pseud), + public_bookmarks_count: public_bookmarks_count(pseud), + general_works_count: work_counts.values.sum, + public_works_count: work_counts[false] || 0 + } + end + + private + + def fandoms(pseud) + tag_info(pseud, "Fandom") + end + + # Produces an array of hashes with the format + # [{id: 1, name: "Star Trek", count: 5}] + def tag_info(pseud, tag_type) + info = [] + info += + pseud.direct_filters.where(works: countable_works_conditions) + .by_type(tag_type).group_by(&:id) + .map do |id, tags| + { + id: id, + name: tags.first.name, + count: tags.length + } + end + info += + pseud.direct_filters.where(works: countable_works_conditions.merge(restricted: false)) + .by_type(tag_type).group_by(&:id) + .map do |id, tags| + { + id_for_public: id, + name: tags.first.name, + count: tags.length + } + end + info + end + + # The relation containing all bookmarks that should be included in the count + # for logged-in users (when restricted to a particular pseud). + def general_bookmarks + @general_bookmarks ||= + Bookmark.with_missing_bookmarkable + .or(Bookmark.with_bookmarkable_visible_to_registered_user) + .is_public + end + + # The relation containing all bookmarks that should be included in the count + # for logged-out users (when restricted to a particular pseud). + def public_bookmarks + @public_bookmarks ||= + Bookmark.with_missing_bookmarkable + .or(Bookmark.with_bookmarkable_visible_to_all) + .is_public + end + + def general_bookmarks_count(pseud) + general_bookmarks.merge(pseud.bookmarks).count + end + + def public_bookmarks_count(pseud) + public_bookmarks.merge(pseud.bookmarks).count + end + + def work_counts(pseud) + pseud.works.where(countable_works_conditions).group(:restricted).count + end + + def countable_works_conditions + { + posted: true, + hidden_by_admin: false, + in_anon_collection: false, + in_unrevealed_collection: false + } + end +end diff --git a/app/models/search/pseud_query.rb b/app/models/search/pseud_query.rb new file mode 100755 index 0000000..fd14054 --- /dev/null +++ b/app/models/search/pseud_query.rb @@ -0,0 +1,62 @@ +class PseudQuery < Query + + # The "klass" function in the query classes is used only to determine what + # type of search results to return (that is, which class the QueryResult + # class will call "load_from_elasticsearch" on). Because the Pseud search + # should always wrap Pseuds up in a PseudDecorator, we return PseudDecorator + # instead of Pseud. + def klass + 'PseudDecorator' + end + + def index_name + PseudIndexer.index_name + end + + def document_type + PseudIndexer.document_type + end + + def filters + [collection_filter, fandom_filter].flatten.compact + end + + def queries + [general_query, name_query].compact + end + + ########### + # FILTERS + ########### + + def collection_filter + { term: { collection_ids: options[:collection_id] } } if options[:collection_id] + end + + def fandom_filter + key = User.current_user.present? ? "fandoms.id" : "fandoms.id_for_public" + if options[:fandom_ids] + options[:fandom_ids].map do |fandom_id| + { term: { key => fandom_id } } + end + end + end + + ########### + # QUERIES + ########### + + def general_query + { + simple_query_string:{ + query: escape_reserved_characters(options[:query]), + fields: ["byline^5", "name^4", "user_login^2", "description"], + default_operator: "AND" + } + } if options[:query] + end + + def name_query + { match: { byline: escape_reserved_characters(options[:name]) } } if options[:name] + end +end diff --git a/app/models/search/pseud_search_form.rb b/app/models/search/pseud_search_form.rb new file mode 100755 index 0000000..ef2ff37 --- /dev/null +++ b/app/models/search/pseud_search_form.rb @@ -0,0 +1,40 @@ +class PseudSearchForm + + extend ActiveModel::Naming + include ActiveModel::Conversion + include ActiveModel::Validations + + ATTRIBUTES = [ + :query, + :name, + :collection_ids, + :fandom + ] + + attr_accessor :options + + ATTRIBUTES.each do |filterable| + define_method(filterable) { options[filterable] } + end + + def initialize(options={}) + @options = options + set_fandoms + @searcher = PseudQuery.new(@options.delete_if { |_, v| v.blank? }) + end + + def persisted? + false + end + + def search_results + @searcher.search_results + end + + def set_fandoms + return unless @options[:fandom].present? + names = @options[:fandom].split(',').map(&:squish) + @options[:fandom_ids] = Tag.where(name: names).pluck(:id) + end + +end diff --git a/app/models/search/query.rb b/app/models/search/query.rb new file mode 100755 index 0000000..e8a3395 --- /dev/null +++ b/app/models/search/query.rb @@ -0,0 +1,272 @@ +class Query + + attr_reader :options + + # Options: page, per_page + def initialize(options={}) + @options = HashWithIndifferentAccess.new(options) + end + + def search + begin + $elasticsearch.search( + index: index_name, + body: generated_query, + track_total_hits: true + ) + rescue Elastic::Transport::Transport::Errors::BadRequest + { error: "Your search failed because of a syntax error. Please try again." } + end + end + + def search_results + response = search + QueryResult.new(klass, response, { page: page, per_page: per_page }) + end + + # Perform a count query based on the given options + def count + $elasticsearch.count( + index: index_name, + body: { query: generated_query[:query] } + )['count'] + end + + # Retrieve a randomly sampled selection of results: + def sample(count: 5) + response = $elasticsearch.search( + index: index_name, + body: { + query: { + function_score: { + query: filtered_query, + random_score: {}, + boost_mode: "replace" + } + }, + size: count + } + ) + + QueryResult.new(klass, response, { page: 1, per_page: count }) + end + + # Perform a specific aggregation: + def aggregation_search(aggregation) + $elasticsearch.search( + index: index_name, + body: { + query: filtered_query, + size: 0, # aggregations only + aggs: { aggregation: aggregation } + } + ).dig("aggregations", "aggregation") + end + + # Use a composite aggregation to get all values that a particular field can + # take on. Returns a hash mapping from values to counts. + def field_values(field_name, batch_size: 100) + aggregation = { + composite: { + size: batch_size, + sources: [{ field_value: { terms: { field: field_name } } }] + } + } + + counts = {} + + loop do + results = aggregation_search(aggregation) + + results["buckets"].each do |info| + counts[info.dig("key", "field_value")] = info.dig("doc_count") + end + + after_key = results["after_key"] + return counts if after_key.nil? + + aggregation[:composite][:after] = after_key + end + end + + # Return (an approximation of) the number of distinct values that a + # particular field can take on: + def field_count(field_name, precision_threshold: 1000) + aggregation_search( + cardinality: { + field: field_name, + precision_threshold: precision_threshold + } + ).dig("value") + end + + # Sort by relevance by default, override in subclasses as necessary + def sort + { _score: { order: "desc" } } + end + + # Search query with filters + def generated_query + q = { + query: filtered_query, + size: per_page, + from: pagination_offset, + sort: sort + } + if (aggs = aggregations).present? + q.merge!(aggs) + end + q + end + + # Combine the filters and queries, with a fallback in case there are no + # filters or queries: + def filtered_query + make_bool( + must: queries, # required, score calculated + filter: filters, # required, score ignored + must_not: exclusion_filters # disallowed, score ignored + ) || { match_all: {} } + end + + # Define specifics in subclasses + + def filters + @filters + end + + def term_filter(field, value, options={}) + { term: options.merge(field => value) } + end + + def terms_filter(field, value, options={}) + { terms: options.merge(field => value) } + end + + def exists_filter(field) + { exists: { field: field } } + end + + # A filter used to match all words in a particular field, most frequently + # used for matching non-existent tags. The match query doesn't allow + # negation/or/and/wildcards, so it should only be used on fields where the + # users are expected to enter, e.g. canonical tags. + def match_filter(field, value, options = {}) + { match: { field => { query: value, operator: "and" }.merge(options) } } + end + + # Replaces the existing scores for a query with the value of a field. The + # optional value "missing" determines what score value should be used if the + # specified field is missing from a document. + def field_value_score(field, query, missing: 0) + { + function_score: { + query: query, + field_value_factor: { + field: field, + missing: missing + }, + boost_mode: :replace + } + } + end + + def bool_value(str) + %w(true 1 T).include?(str.to_s) + end + + def exclusion_filters + @exclusion_filters + end + + def queries + end + + def aggregations + end + + def index_name + end + + def document_type + end + + def per_page + options[:per_page] || ArchiveConfig.ITEMS_PER_PAGE + end + + # Example: if the limit is 3 results, and we're displaying 2 per page, + # disallow pages beyond page 2. + def page + [ + options[:page] || 1, + (ArchiveConfig.MAX_SEARCH_RESULTS / per_page.to_f).ceil + ].min + end + + def pagination_offset + (page * per_page) - per_page + end + + # Only escape if it isn't already escaped + def escape_slashes(word) + word.gsub(/([^\\])\//) { |s| $1 + '\\/' } + end + + def escape_reserved_characters(word) + word = escape_slashes(word) + word.gsub!('!', '\\!') + word.gsub!('+', '\\\\+') + word.gsub!('-', '\\-') + word.gsub!('?', '\\?') + word.gsub!("~", '\\~') + word.gsub!("(", '\\(') + word.gsub!(")", '\\)') + word.gsub!("[", '\\[') + word.gsub!("]", '\\]') + word.gsub!(':', '\\:') + word + end + + def split_query_text_phrases(fieldname, text) + str = "" + return str if text.blank? + text.split(",").map(&:squish).each do |phrase| + str << " #{fieldname}:\"#{phrase}\"" + end + str + end + + def split_query_text_words(fieldname, text) + str = "" + return str if text.blank? + text.split(" ").each do |word| + if word.length >= 2 && word[0] == "-" + str << " NOT" + word.slice!(0) + end + word = escape_reserved_characters(word) + str << " #{fieldname}:#{word}" + end + str + end + + def make_bool(query) + query.reject! { |_, value| value.blank? } + query[:minimum_should_match] = 1 if query[:should].present? + + if query.empty? + nil + elsif query.values.flatten.size == 1 && (query[:must] || query[:should]) + # There's only one clause in our boolean, so we might as well skip the + # bool and just require it. + query.values.flatten.first + else + { bool: query } + end + end + + def make_list(*args) + args.flatten.compact + end +end diff --git a/app/models/search/query_cleaner.rb b/app/models/search/query_cleaner.rb new file mode 100755 index 0000000..ccd4085 --- /dev/null +++ b/app/models/search/query_cleaner.rb @@ -0,0 +1,103 @@ +# This is currently being tested without loading most of Rails +# so beware of changes that rely on other classes or Rails methods +class QueryCleaner + + attr_reader :params + + SORT_OPTIONS = [ + %w[Creator authors_to_sort_on], + %w[Title title_to_sort_on], + ['Date Posted', 'created_at'], + ['Date Updated', 'revised_at'], + ['Word Count', 'word_count'], + %w[Hits hits], + %w[Kudos kudos_count], + %w[Comments comments_count], + %w[Bookmarks bookmarks_count] + ].freeze + + def initialize(params = {}) + @params = params.dup + end + + def clean + return params if params[:query].nil? || params[:query].empty? + unescape_angle_brackets + extract_countables + set_sorting + add_quotes_to_categories + escape_angle_brackets + clean_up_query + + params + end + + private + + def unescape_angle_brackets + params[:query] = params[:query].gsub('>', '>').gsub('<', '<') + end + + def escape_angle_brackets + params[:query] = params[:query].gsub('>', '>').gsub('<', '<') + end + + # extract countable params + def extract_countables + %w(word kudo comment bookmark hit).each do |term| + count_regex = /#{term}s?\s*(?:\_?count)?\s*:?\s*((?:<|>|=|:)\s*\d+(?:\-\d+)?)/i + m = params[:query].match(count_regex) + next if m.nil? + params[:query] = params[:query].gsub(count_regex, '') + # pluralize, add _count, convert to symbol + term = term.pluralize unless term == 'word' + term += '_count' unless term == 'hits' + term = term.to_sym + + value = m[1].gsub(/^(:|=)/, '').strip # get rid of : and = + # don't overwrite if submitting from advanced search? + params[term] = value if params[term].nil? || params[term].empty? + end + end + + # get sort-by + def set_sorting + sort_regex = /sort(?:ed)?\s*(?:by)?\s*:?\s*(<|>|=|:)\s*(\w+)\s*(ascending|descending)?/i + return unless m = params[:query].match(sort_regex) + params[:query] = params[:query].gsub(sort_regex, '') + sortdir = m[3] || m[1] + # turn word_count or word count or words into just "word" eg + sortby = m[2].gsub(/\s*_?count/, '').singularize + + sort_column = SORT_OPTIONS.find { |opt, _| opt =~ /#{sortby}/i }&.last + params[:sort_column] = sort_column unless sort_column.nil? + params[:sort_direction] = sort_direction(sortdir) + end + + def sort_direction(sortdir) + if sortdir == '>' || sortdir == 'ascending' + 'asc' + elsif sortdir == '<' || sortdir == 'descending' + 'desc' + end + end + + # put categories into quotes + # don't match if the letters are part of larger words (ie, "Tom/Mark") + def add_quotes_to_categories + qr = Regexp.new('(?:"|\')?') + %w(m/m f/f f/m m/f).each do |cat| + cr = Regexp.new("(\\A|\\s)#{qr}#{cat}#{qr}(\\z|\\s)", Regexp::IGNORECASE) + params[:query] = params[:query].gsub(cr, " \"#{cat}\" ") + end + end + + # If we've stripped out everything in the query, null it out + def clean_up_query + if params[:query] =~ /^\s*$/ + params[:query] = nil + else + params[:query] = params[:query].strip + end + end +end diff --git a/app/models/search/query_facet.rb b/app/models/search/query_facet.rb new file mode 100755 index 0000000..0afb4e2 --- /dev/null +++ b/app/models/search/query_facet.rb @@ -0,0 +1,2 @@ +class QueryFacet < Struct.new(:id, :name, :count) +end diff --git a/app/models/search/query_result.rb b/app/models/search/query_result.rb new file mode 100755 index 0000000..1dc7c87 --- /dev/null +++ b/app/models/search/query_result.rb @@ -0,0 +1,130 @@ +class QueryResult + + include Enumerable + + attr_reader :klass, :response, :current_page, :per_page, :error, :notice + + def initialize(model_name, response, options={}) + @klass = model_name.classify.constantize + @response = response + @current_page = options[:page] || 1 + @per_page = options[:per_page] || ArchiveConfig.ITEMS_PER_PAGE + @error = response[:error] + @notice = max_search_results_notice + end + + def hits + response.dig('hits', 'hits') + end + + def items + return [] if response[:error] + if @items.nil? + @items = klass.load_from_elasticsearch(hits, scopes: @scopes) + end + @items + end + + def scope(*args) + @scopes ||= [] + @scopes += args + @items = nil # reset the items in case we already loaded them + self # for chaining + end + + def each(&block) + items.each(&block) + end + + def empty? + items.empty? + end + + def size + items.size + end + alias :length :size + + def [](index) + items[index] + end + + def to_ary + items + end + + def load_tag_facets(type, info) + @facets[type] = [] + buckets = info["buckets"] + ids = buckets.map { |result| result['key'] } + tags = Tag.where(id: ids).group_by(&:id) + buckets.each do |facet| + unless tags[facet['key'].to_i].blank? + @facets[type] << QueryFacet.new(facet['key'], tags[facet['key'].to_i].first.name, facet['doc_count']) + end + end + end + + def load_collection_facets(info) + @facets["collections"] = [] + buckets = info["buckets"] + ids = buckets.map { |result| result['key'] } + collections = Collection.where(id: ids).group_by(&:id) + buckets.each do |facet| + unless collections[facet['key'].to_i].blank? + @facets["collections"] << QueryFacet.new(facet['key'], collections[facet['key'].to_i].first.title, facet['doc_count']) + end + end + end + + def load_facets(aggregations) + aggregations.each_pair do |term, results| + if Tag::TYPES.include?(term.classify) || term == "tag" + load_tag_facets(term, results) + elsif term == "collections" + load_collection_facets(results) + elsif term == "bookmarks" + load_facets(results["filtered_bookmarks"]) + elsif term == "bookmarkable" + load_facets(results) + end + end + end + + def facets + return if response["aggregations"].nil? + + if @facets.nil? + @facets = {} + load_facets(response["aggregations"]) + end + + @facets + end + + def total_pages + (total_entries / per_page.to_f).ceil rescue 0 + end + + # For pagination / fetching results. + def total_entries + [unlimited_total_entries, ArchiveConfig.MAX_SEARCH_RESULTS].min + end + + def unlimited_total_entries + response.dig('hits', 'total', 'value') || 0 + end + + def offset + (current_page * per_page) - per_page + end + + def max_search_results_notice + # if we're on the last page of search results AND there are more results than we can show + return unless current_page >= total_pages && unlimited_total_entries > total_entries + ActionController::Base.helpers.ts("Displaying %{displayed} results out of %{total}. Please use the filters or edit your search to customize this list further.", + displayed: total_entries, + total: unlimited_total_entries + ).html_safe + end +end diff --git a/app/models/search/search_counts.rb b/app/models/search/search_counts.rb new file mode 100755 index 0000000..4d60c2d --- /dev/null +++ b/app/models/search/search_counts.rb @@ -0,0 +1,126 @@ +module SearchCounts + module_function + + ###################################################################### + # COUNTS OF ITEMS IN COLLECTIONS + ###################################################################### + + def collection_works_query(collection) + WorkQuery.new(collection_ids: [collection.id], + show_restricted: User.current_user.present?) + end + + def collection_bookmarks_query(collection) + BookmarkQuery.new(collection_ids: [collection.id], + show_restricted: User.current_user.present?) + end + + def work_count_for_collection(collection) + Rails.cache.fetch(collection_cache_key(collection, :works), + collection_cache_options) do + collection_works_query(collection).count + end + end + + def bookmarkable_count_for_collection(collection) + Rails.cache.fetch(collection_cache_key(collection, :bookmarkables), + collection_cache_options) do + collection_bookmarks_query(collection).bookmarkable_query.count + end + end + + def fandom_count_for_collection(collection) + Rails.cache.fetch(collection_cache_key(collection, :fandom_count), + collection_cache_options) do + collection_works_query(collection).field_count(:fandom_ids) + end + end + + def fandom_ids_for_collection(collection) + Rails.cache.fetch(collection_cache_key(collection, :fandom_ids), + collection_cache_options) do + collection_works_query(collection).field_values(:fandom_ids) + end + end + + def collection_cache_key(collection, key) + "collection_count_#{collection.id}_#{key}_#{logged_in}" + end + + ###################################################################### + # WORK COUNTS FOR USER/PSEUD DASHBOARD + ###################################################################### + + def work_count_for_user(user) + Rails.cache.fetch(work_cache_key(user), dashboard_cache_options) do + WorkQuery.new(user_ids: [user.id]).count + end + end + + def work_count_for_pseud(pseud) + Rails.cache.fetch(work_cache_key(pseud), dashboard_cache_options) do + WorkQuery.new(pseud_ids: [pseud.id]).count + end + end + + # If we want to invalidate cached counts whenever the owner (which for + # this method can only be a user or a pseud) has a new work, we can use + # "#{owner.works_index_cache_key}" instead of "#{owner.model_name.cache_key}_#{owner.id}". + # See lib/works_owner.rb. + def work_cache_key(owner) + "work_count_#{owner.model_name.cache_key}_#{owner.id}_#{logged_in}" + end + + ###################################################################### + # BOOKMARK COUNTS FOR USER/PSEUD DASHBOARD + ###################################################################### + + def bookmark_count_for_user(user) + show_private = User.current_user.is_a?(Admin) || user == User.current_user + + Rails.cache.fetch(bookmark_cache_key(user, show_private), dashboard_cache_options) do + BookmarkQuery.new(user_ids: [user.id], show_private: show_private).count + end + end + + def bookmark_count_for_pseud(pseud) + show_private = User.current_user.is_a?(Admin) || pseud.user == User.current_user + + Rails.cache.fetch(bookmark_cache_key(pseud, show_private), dashboard_cache_options) do + BookmarkQuery.new(pseud_ids: [pseud.id], show_private: show_private).count + end + end + + def bookmark_cache_key(owner, show_private) + private_status = show_private ? "_private" : "" + "bookmark_count_#{owner.model_name.cache_key}_#{owner.id}_#{logged_in}#{private_status}" + end + + ###################################################################### + # USEFUL FUNCTIONS + ###################################################################### + + def logged_in + User.current_user ? :logged_in : :logged_out + end + + ###################################################################### + # CACHE OPTIONS + ###################################################################### + + # Options for the dashboard (user/pseud) caches. + def dashboard_cache_options + { + expires_in: ArchiveConfig.SECONDS_UNTIL_DASHBOARD_COUNTS_EXPIRE.seconds, + race_condition_ttl: 10.seconds + } + end + + # Options for the collection caches. + def collection_cache_options + { + expires_in: ArchiveConfig.SECONDS_UNTIL_COLLECTION_COUNTS_EXPIRE.seconds, + race_condition_ttl: 10.seconds + } + end +end diff --git a/app/models/search/stat_counter_indexer.rb b/app/models/search/stat_counter_indexer.rb new file mode 100755 index 0000000..398c5a3 --- /dev/null +++ b/app/models/search/stat_counter_indexer.rb @@ -0,0 +1,65 @@ +# A class for reindexing work stats. + +# Does not inherit from the standard Indexer, because it needs to do updates to +# existing records rather than creating whole records from scratch. +class StatCounterIndexer + attr_reader :ids + + # Find StatCounter elasticsearch ids (StatCounters are stored by their + # associated work_id) from provided StatCounter ActiveRecord object ids. + def self.find_elasticsearch_ids(ids) + StatCounter.where(work_id: ids).pluck(:id) + end + + def initialize(ids) + @ids = ids + end + + def objects + # Since we're updating works, the IDs of the individual stat counters don't + # matter very much. If one of the stat counters that we're supposed to + # reindex is missing from the database, there's nothing for us to delete -- + # it would only be destroyed if the corresponding work was destroyed, and + # we're not responsible for cleaning up old works. (That's the + # WorkIndexer's job.) + @objects ||= StatCounter.where(id: ids).to_a + end + + def batch + return @batch if @batch + + @batch = [] + objects.each do |object| + @batch << { update: routing_info(object) } + @batch << document(object) + end + @batch + end + + def index_documents + return if batch.empty? + + $elasticsearch.bulk(body: batch) + end + + # Use the routing information from the WorkIndexer, since we don't have an + # index of our own. And use the work_id rather than our own id. + def routing_info(stat_counter) + { + "_index" => WorkIndexer.index_name, + "_id" => stat_counter.work_id + } + end + + # Since we're doing an update instead of an index, nest the values. + def document(stat_counter) + { + doc: { + hits: stat_counter.hit_count, + comments_count: stat_counter.comments_count, + kudos_count: stat_counter.kudos_count, + bookmarks_count: stat_counter.bookmarks_count + } + } + end +end diff --git a/app/models/search/tag_indexer.rb b/app/models/search/tag_indexer.rb new file mode 100755 index 0000000..2dbb890 --- /dev/null +++ b/app/models/search/tag_indexer.rb @@ -0,0 +1,90 @@ +class TagIndexer < Indexer + + def self.klass + "Tag" + end + + def self.mapping + { + properties: { + name: { + type: "text", + analyzer: "tag_name_analyzer", + fields: { + exact: { + type: "text", + analyzer: "exact_tag_analyzer" + }, + keyword: { + type: "keyword", + normalizer: "keyword_lowercase" + } + } + }, + tag_type: { type: "keyword" }, + sortable_name: { type: "keyword" }, + uses: { type: "integer" }, + unwrangled: { type: "boolean" } + } + } + end + + def self.settings + { + analysis: { + analyzer: { + tag_name_analyzer: { + type: "custom", + tokenizer: "standard", + filter: [ + "lowercase" + ] + }, + exact_tag_analyzer: { + type: "custom", + tokenizer: "keyword", + filter: [ + "lowercase" + ] + } + }, + normalizer: { + keyword_lowercase: { + type: "custom", + filter: ["lowercase"] + } + } + } + } + end + + def document(object) + object.as_json( + root: false, + only: [ + :id, :name, :sortable_name, :merger_id, :canonical, :created_at, + :unwrangleable + ] + ).merge( + has_posted_works: object.has_posted_works?, + tag_type: object.type, + uses: object.taggings_count_cache, + unwrangled: object.unwrangled? + ).merge(parent_data(object)) + end + + # Index parent data for tag wrangling searches + def parent_data(tag) + data = {} + %w(Media Fandom Character).each do |parent_type| + if tag.parent_types.include?(parent_type) + key = "#{parent_type.downcase}_ids" + data[key] = tag.parents.by_type(parent_type).pluck(:id) + next if parent_type == "Media" + data["pre_#{key}"] = tag.suggested_parent_ids(parent_type) + end + end + data + end + +end diff --git a/app/models/search/tag_query.rb b/app/models/search/tag_query.rb new file mode 100755 index 0000000..05e6bc9 --- /dev/null +++ b/app/models/search/tag_query.rb @@ -0,0 +1,161 @@ +class TagQuery < Query + + def klass + 'Tag' + end + + def index_name + TagIndexer.index_name + end + + def document_type + TagIndexer.document_type + end + + def filters + [ + type_filter, + wrangling_status_filter, + unwrangleable_filter, + posted_works_filter, + media_filter, + fandom_filter, + character_filter, + suggested_fandom_filter, + suggested_character_filter, + in_use_filter, + unwrangled_filter + ].flatten.compact + end + + def exclusion_filters + [ + wrangled_filter + ].compact + end + + def queries + [name_query].compact + end + + # Tags have a different default per_page value: + def per_page + options[:per_page] || ArchiveConfig.TAGS_PER_SEARCH_PAGE || 50 + end + + def sort + direction = options[:sort_direction]&.downcase + case options[:sort_column] + when "taggings_count_cache", "uses" + column = "uses" + direction ||= "desc" + when "created_at" + column = "created_at" + direction ||= "desc" + else + column = "name.keyword" + direction ||= "asc" + end + sort_hash = { column => { order: direction } } + + if column == "created_at" + sort_hash[column][:unmapped_type] = "date" + end + + sort_by_id = { id: { order: direction } } + + return [sort_hash, { "name.keyword" => { order: "asc" } }, sort_by_id] if column == "uses" + + [sort_hash, sort_by_id] + end + + ################ + # FILTERS + ################ + + def type_filter + { term: { tag_type: options[:type] } } if options[:type] + end + + def wrangling_status_filter + case options[:wrangling_status] + when "canonical" + term_filter(:canonical, true) + when "noncanonical" + term_filter(:canonical, false) + when "synonymous" + [exists_filter("merger_id"), term_filter(:canonical, false)] + when "canonical_synonymous" + { bool: { should: [exists_filter("merger_id"), term_filter(:canonical, true)] } } + when "noncanonical_nonsynonymous" + [{ bool: { must_not: exists_filter("merger_id") } }, term_filter(:canonical, false)] + end + end + + def unwrangleable_filter + term_filter(:unwrangleable, bool_value(options[:unwrangleable])) unless options[:unwrangleable].nil? + end + + def posted_works_filter + term_filter(:has_posted_works, bool_value(options[:has_posted_works])) unless options[:has_posted_works].nil? + end + + def media_filter + terms_filter(:media_ids, options[:media_ids]) if options[:media_ids] + end + + def fandom_filter + options[:fandom_ids]&.map { |fandom_id| term_filter(:fandom_ids, fandom_id) } + end + + def character_filter + terms_filter(:character_ids, options[:character_ids]) if options[:character_ids] + end + + def suggested_fandom_filter + terms_filter(:pre_fandom_ids, options[:pre_fandom_ids]) if options[:pre_fandom_ids] + end + + def suggested_character_filter + terms_filter(:pre_character_ids, options[:pre_character_ids]) if options[:pre_character_ids] + end + + # Canonical tags are treated as used even if they technically aren't + def in_use_filter + return if options[:in_use].nil? + + unless options[:in_use] + # Check if not used AND not canonical + return [term_filter(:uses, 0), term_filter(:canonical, false)] + end + + # Check if used OR canonical + { bool: { should: [{ range: { uses: { gt: 0 } } }, term_filter(:canonical, true)] } } + end + + def unwrangled_filter + term_filter(:unwrangled, bool_value(options[:unwrangled])) unless options[:unwrangled].nil? + end + + # Filter to only include tags that have no assigned fandom_ids. Checks that + # the fandom exists, because this particular filter is included in the + # exclusion_filters section. + def wrangled_filter + exists_filter("fandom_ids") unless options[:wrangled].nil? + end + + ################ + # QUERIES + ################ + + def name_query + return unless options[:name] + { + query_string: { + query: escape_reserved_characters(options[:name]), + fields: ["name.exact^2", "name"], + default_operator: "and" + } + } + end +end diff --git a/app/models/search/tag_search_form.rb b/app/models/search/tag_search_form.rb new file mode 100755 index 0000000..e2312b7 --- /dev/null +++ b/app/models/search/tag_search_form.rb @@ -0,0 +1,78 @@ +class TagSearchForm + + extend ActiveModel::Naming + include ActiveModel::Conversion + include ActiveModel::Validations + + ATTRIBUTES = [ + :query, + :name, + :canonical, + :wrangling_status, + :fandoms, + :type, + :created_at, + :uses, + :sort_column, + :sort_direction + ].freeze + + attr_accessor :options + + ATTRIBUTES.each do |filterable| + define_method(filterable) { options[filterable] } + end + + def initialize(options={}) + @options = options + set_fandoms + set_wrangling_status + @searcher = TagQuery.new(@options.delete_if { |_, v| v.blank? }) + end + + def persisted? + false + end + + def search_results + @searcher.search_results + end + + def set_fandoms + return if @options[:fandoms].blank? + + names = @options[:fandoms].split(",").map(&:squish) + @options[:fandom_ids] = Tag.where(name: names).pluck(:id) + end + + def bool_value(str) + %w[true 1 T].include?(str.to_s) + end + + def set_wrangling_status + return if @options[:canonical].blank? + + # Match old behavior for canonical param + @options[:wrangling_status] = bool_value(@options[:canonical]) ? "canonical" : "noncanonical" + end + + def sort_columns + options[:sort_column] || "name" + end + + def sort_direction + options[:sort_direction] || default_sort_direction + end + + def sort_options + [ + %w[Name name], + ["Date Created", "created_at"], + %w[Uses uses] + ] + end + + def default_sort_direction + %w[created_at uses].include?(sort_column) ? "desc" : "asc" + end +end diff --git a/app/models/search/taggable_query.rb b/app/models/search/taggable_query.rb new file mode 100755 index 0000000..16e1599 --- /dev/null +++ b/app/models/search/taggable_query.rb @@ -0,0 +1,82 @@ +# Shared methods for work and bookmarkable queries +module TaggableQuery + + def filter_ids + return @filter_ids if @filter_ids.present? + @filter_ids = options[:filter_ids] || [] + %w(fandom rating archive_warning category character relationship freeform).each do |tag_type| + if options["#{tag_type}_ids".to_sym].present? + ids = options["#{tag_type}_ids".to_sym] + @filter_ids += ids.is_a?(Array) ? ids : [ids] + end + end + @filter_ids += parsed_included_tags[:ids] + @filter_ids = @filter_ids.uniq + end + + def exclusion_ids + return @exclusion_ids if @exclusion_ids.present? + return if options[:excluded_tag_names].blank? && options[:excluded_tag_ids].blank? + + ids = options[:excluded_tag_ids] || [] + ids += parsed_excluded_tags[:ids] + @exclusion_ids = ids.uniq.compact + end + + # Returns a list of tag names that should be included in all results. Only + # returns the ones that aren't in the database, because the ones that are in + # the database will be covered by the filter_ids function. + def included_tag_names + parsed_included_tags[:missing] + end + + # Returns parse_named_tags of all of the fields used to include tag names. + def parsed_included_tags + @parsed_included_tags ||= parse_named_tags( + %i[fandom_names character_names relationship_names freeform_names + other_tag_names] + ) + end + + # Returns a list of tag names that should be excluded from all results. Only + # returns the ones that aren't in the database, because the ones that are in + # the database will be covered by the exclusion_ids function. + def excluded_tag_names + parsed_excluded_tags[:missing] + end + + # Returns parse_named_tags of all of the fields used to exclude tag names. + def parsed_excluded_tags + @parsed_excluded_tags ||= parse_named_tags(%i[excluded_tag_names]) + end + + # Uses the database to look up all of the tag names listed in the passed-in + # fields. Returns a hash with the following format: + # { + # ids: [1, 2, 3], + # missing: ["missing tag name", "other missing"] + # } + def parse_named_tags(fields) + names = all_tag_names(fields) + found = if names.present? + Tag.where(name: names).pluck(:id, :name) + else + [] + end + + { + ids: found.map(&:first), + missing: (names - found.map(&:second)).uniq + } + end + + # Parse the options for each of the passed-in fields, treating each one as a + # comma-separated list of tags. Returns the list of all tags, with blank and + # duplicate tags removed. + def all_tag_names(fields) + fields.flat_map do |field| + next if options[field].blank? + options[field].split(",").map(&:squish) + end.reject(&:blank?).uniq + end +end diff --git a/app/models/search/user_indexer.rb b/app/models/search/user_indexer.rb new file mode 100755 index 0000000..5f1d37e --- /dev/null +++ b/app/models/search/user_indexer.rb @@ -0,0 +1,79 @@ +class UserIndexer < Indexer + def self.klass + "User" + end + + def self.klass_with_includes + User.includes(:pseuds, :roles, :audits) + end + + def self.index_all(options = {}) + unless options[:skip_delete] + delete_index + create_index(shards: ArchiveConfig.USER_SHARDS) + end + options[:skip_delete] = true + super(options) + end + + def self.mapping + { + properties: { + login: { + type: "keyword", + normalizer: "keyword_normalizer" + }, + email: { + type: "keyword", + normalizer: "keyword_normalizer" + }, + names: { + type: "keyword", + normalizer: "keyword_normalizer" + }, + all_names: { + type: "keyword", + normalizer: "keyword_normalizer" + }, + all_emails: { + type: "keyword", + normalizer: "keyword_normalizer" + } + } + } + end + + def self.settings + { + analysis: { + normalizer: { + keyword_normalizer: { + type: "custom", + filter: %w[lowercase asciifolding] + } + } + } + } + end + + def document(object) + object.as_json( + root: false, + only: [:id, :login, :email, :created_at], + methods: [:role_ids] + ).merge(extra_info(object)) + end + + def extra_info(object) + names = ([object.login] + object.pseuds.map(&:name)).uniq + past_names = object.historic_values("login") + past_emails = object.historic_values("email") + + { + active: object.active?, + names: names, + all_names: (names + past_names).uniq, + all_emails: ([object.email] + past_emails).uniq + } + end +end diff --git a/app/models/search/user_query.rb b/app/models/search/user_query.rb new file mode 100755 index 0000000..44a2bcc --- /dev/null +++ b/app/models/search/user_query.rb @@ -0,0 +1,59 @@ +class UserQuery < Query + def klass + "User" + end + + def index_name + UserIndexer.index_name + end + + def document_type + UserIndexer.document_type + end + + def filters + @filters ||= [ + id_filter, + inactive_filter, + role_filter, + email_filter, + name_filter + ].flatten.compact + end + + def sort + [{ login: { order: :asc } }, { id: { order: :asc } }] + end + + ################ + # FILTERS + ################ + + def id_filter + { term: { id: options[:user_id] } } if options[:user_id].present? + end + + def inactive_filter + { term: { active: false } } if options[:inactive].present? + end + + def role_filter + { term: { role_ids: options[:role_id] } } if options[:role_id].present? + end + + def name_filter + return if options[:name].blank? + + field = options[:search_past].present? ? :all_names : :names + + { wildcard: { field => options[:name] } } + end + + def email_filter + return if options[:email].blank? + + field = options[:search_past].present? ? :all_emails : :email + + { wildcard: { field => options[:email] } } + end +end diff --git a/app/models/search/work_creator_indexer.rb b/app/models/search/work_creator_indexer.rb new file mode 100755 index 0000000..0f9456e --- /dev/null +++ b/app/models/search/work_creator_indexer.rb @@ -0,0 +1,47 @@ +# A class for reindexing private work creator info (info that should not be +# available during normal searches). +class WorkCreatorIndexer < Indexer + def self.klass + "Work" + end + + def self.klass_with_includes + Work.includes(:pseuds, :users) + end + + def self.mapping + WorkIndexer.mapping + end + + # When we fail, we don't want to just keep adding the -klass suffix. + def self.find_elasticsearch_ids(ids) + ids.map(&:to_i) + end + + def routing_info(id) + { + "_index" => index_name, + "_id" => document_id(id), + "routing" => parent_id(id, nil) + } + end + + def document_id(id) + "#{id}-creator" + end + + def parent_id(id, _object) + id + end + + def document(object) + { + private_user_ids: object.user_ids, + private_pseud_ids: object.pseud_ids, + creator_join: { + name: :creator, + parent: object.id + } + } + end +end diff --git a/app/models/search/work_indexer.rb b/app/models/search/work_indexer.rb new file mode 100755 index 0000000..c3b65eb --- /dev/null +++ b/app/models/search/work_indexer.rb @@ -0,0 +1,135 @@ +class WorkIndexer < Indexer + def self.klass + "Work" + end + + def self.klass_with_includes + Work.includes( + :approved_collections, + :direct_filters, + :external_author_names, + :filters, + :language, + :stat_counter, + :tags, + :users, + :relationships, + fandoms: { meta_tags: :meta_tags, merger: { meta_tags: :meta_tags } }, + pseuds: :user, + serial_works: :series + ) + end + + def self.index_all(options = {}) + unless options[:skip_delete] + delete_index + create_index(shards: ArchiveConfig.WORKS_SHARDS) + end + options[:skip_delete] = true + super(options) + end + + def self.mapping + { + properties: { + creator_join: { + type: :join, + relations: { work: :creator } + }, + title: { + type: "text", + analyzer: "standard" + }, + creators: { + type: "text" + }, + tag: { + type: "text" + }, + series: { + type: "object" + }, + authors_to_sort_on: { + type: "keyword" + }, + title_to_sort_on: { + type: "keyword" + }, + imported_from_url: { + type: "keyword" + }, + work_types: { + type: "keyword" + }, + posted: { type: "boolean" }, + restricted: { type: "boolean" }, + hidden_by_admin: { type: "boolean" }, + complete: { type: "boolean" }, + in_anon_collection: { type: "boolean" }, + in_unrevealed_collection: { type: "boolean" } + } + } + end + + def document(object) + object.as_json( + root: false, + only: [ + :id, :expected_number_of_chapters, :created_at, :updated_at, + :major_version, :minor_version, :posted, :restricted, + :title, :summary, :notes, :word_count, :hidden_by_admin, :revised_at, + :title_to_sort_on, :backdate, :endnotes, + :imported_from_url, :complete, :work_skin_id, :in_anon_collection, + :in_unrevealed_collection, + ], + methods: [ + :authors_to_sort_on, + :rating_ids, + :archive_warning_ids, + :category_ids, + :fandom_ids, + :character_ids, + :relationship_ids, + :freeform_ids, + :filter_ids, + :tag, + :collection_ids, + :hits, + :comments_count, + :kudos_count, + :bookmarks_count, + :creators, + :crossover, + :otp, + :work_types, + :nonfiction + ] + ).merge( + language_id: object.language&.short, + series: series_data(object), + creator_join: { name: :work } + ).merge(creator_data(object)) + end + + def creator_data(work) + if work.anonymous? || work.unrevealed? + {} + else + { + user_ids: work.user_ids, + pseud_ids: work.pseud_ids + } + end + end + + # Format the id, title, and position of each series as a hash: + def series_data(object) + object.serial_works.map do |sw| + { + id: sw.series_id, + title: sw.series&.title, + position: sw.position + } + end + end +end diff --git a/app/models/search/work_query.rb b/app/models/search/work_query.rb new file mode 100755 index 0000000..dd6d0ec --- /dev/null +++ b/app/models/search/work_query.rb @@ -0,0 +1,370 @@ +class WorkQuery < Query + include TaggableQuery + + def klass + 'Work' + end + + def index_name + WorkIndexer.index_name + end + + def document_type + WorkIndexer.document_type + end + + # Combine the available filters + def filters + add_owner + + @filters ||= ( + visibility_filters + + work_filters + + creator_filters + + collection_filters + + tag_filters + + range_filters + ).flatten.compact + end + + def exclusion_filters + @exclusion_filters ||= [ + tag_exclusion_filter, + named_tag_exclusion_filter + ].flatten.compact + end + + # Combine the available queries + # In this case, name is the only text field + def queries + @queries = [ + general_query + ].flatten.compact + end + + def add_owner + owner = options[:works_parent] + + if owner.is_a?(Language) + options[:language_id] = owner.short + return + end + + field = case owner + when Tag + :filter_ids + when Pseud + :pseud_ids + when User + :user_ids + when Collection + :collection_ids + end + return unless field.present? + options[field] ||= [] + options[field] << owner.id + end + + #################### + # GROUPS OF FILTERS + #################### + + def visibility_filters + [ + posted_filter, + hidden_filter, + restricted_filter, + unrevealed_filter, + anon_filter + ] + end + + def work_filters + [ + complete_filter, + single_chapter_filter, + language_filter, + crossover_filter, + type_filter + ] + end + + def creator_filters + [user_filter, pseud_filter] + end + + def collection_filters + [collection_filter] + end + + def tag_filters + [ + filter_id_filter, + named_tag_inclusion_filter + ].flatten.compact + end + + def range_filters + ranges = [] + [:word_count, :hits, :kudos_count, :comments_count, :bookmarks_count, :revised_at].each do |countable| + if options[countable].present? + ranges << { range: { countable => SearchRange.parsed(options[countable]) } } + end + end + ranges += [date_range_filter, word_count_filter].compact + ranges + end + + #################### + # FILTERS + #################### + + def posted_filter + term_filter(:posted, 'true') + end + + def hidden_filter + term_filter(:hidden_by_admin, 'false') + end + + def restricted_filter + term_filter(:restricted, 'false') unless include_restricted? + end + + def unrevealed_filter + term_filter(:in_unrevealed_collection, 'false') unless include_unrevealed? + end + + def anon_filter + term_filter(:in_anon_collection, 'false') unless include_anon? + end + + def complete_filter + term_filter(:complete, bool_value(options[:complete])) if options[:complete].present? + end + + def single_chapter_filter + term_filter(:expected_number_of_chapters, 1) if options[:single_chapter].present? + end + + def language_filter + term_filter(:"language_id.keyword", options[:language_id]) if options[:language_id].present? + end + + def crossover_filter + term_filter(:crossover, bool_value(options[:crossover])) if options[:crossover].present? + end + + def type_filter + terms_filter(:work_type, options[:work_types]) if options[:work_types] + end + + def user_filter + return if user_ids.blank? + + if viewing_own_collected_works_page? + { + has_child: { + type: "creator", + query: terms_filter(:private_user_ids, user_ids) + } + } + else + terms_filter(:user_ids, user_ids) + end + end + + def pseud_filter + terms_filter(:pseud_ids, pseud_ids) if pseud_ids.present? + end + + def collection_filter + terms_filter(:collection_ids, options[:collection_ids]) if options[:collection_ids].present? + end + + def filter_id_filter + if filter_ids.present? + filter_ids.map { |filter_id| term_filter(:filter_ids, filter_id) } + end + end + + def tag_exclusion_filter + if exclusion_ids.present? + exclusion_ids.map { |exclusion_id| term_filter(:filter_ids, exclusion_id) } + end + end + + # This filter is used to restrict our results to only include works + # whose "tag" text matches all of the tag names in included_tag_names. This + # is useful when the user enters a non-existent tag, which would be discarded + # by the TaggableQuery.filter_ids function. + def named_tag_inclusion_filter + return if included_tag_names.blank? + match_filter(:tag, included_tag_names.join(" ")) + end + + # This set of filters is used to prevent us from matching any works whose + # "tag" text matches one of the passed-in tag names. This is useful when the + # user enters a non-existent tag, which would be discarded by the + # TaggableQuery.exclusion_ids function. + # + # Unlike the inclusion filter, we must separate these into different match + # filters to get the results that we want (that is, excluding "A B" and "C D" + # is the same as "not(A and B) and not(C and D)"). + def named_tag_exclusion_filter + excluded_tag_names.map do |tag_name| + match_filter(:tag, tag_name) + end + end + + def date_range_filter + return unless options[:date_from].present? || options[:date_to].present? + begin + range = {} + range[:gte] = clamp_search_date(options[:date_from].to_date) if options[:date_from].present? + range[:lte] = clamp_search_date(options[:date_to].to_date) if options[:date_to].present? + { range: { revised_at: range } } + rescue ArgumentError + nil + end + end + + def word_count_filter + return unless options[:words_from].present? || options[:words_to].present? + range = {} + range[:gte] = options[:words_from].delete(",._").to_i if options[:words_from].present? + range[:lte] = options[:words_to].delete(",._").to_i if options[:words_to].present? + { range: { word_count: range } } + end + + #################### + # QUERIES + #################### + + # Search for a tag by name + # Note that fields don't need to be explicitly included in the + # field list to be searchable directly (ie, "complete:true" will still work) + def general_query + input = (options[:q] || options[:query] || "").dup + query = generate_search_text(input) + + return { + query_string: { + query: query, + fields: ["creators^5", "title^7", "endnotes", "notes", "summary", "tag", "series.title"], + default_operator: "AND" + } + } unless query.blank? + end + + def generate_search_text(query = '') + search_text = query + %i[title creators].each do |field| + search_text << split_query_text_words(field, options[field]) + end + + if options[:series_titles].present? + search_text << split_query_text_words("series.title", options[:series_titles]) + end + + if options[:collection_ids].blank? && collected? + search_text << " collection_ids:*" + end + escape_slashes(search_text.strip) + end + + def sort + column = options[:sort_column].present? ? options[:sort_column] : default_sort + direction = options[:sort_direction].present? ? options[:sort_direction] : 'desc' + sort_hash = { column => { order: direction } } + + if column == 'revised_at' + sort_hash[column][:unmapped_type] = 'date' + end + + [sort_hash, { id: { order: direction } }] + end + + # When searching outside of filters, use relevance instead of date + def default_sort + facet_tags? || collected? ? 'revised_at' : '_score' + end + + def aggregations + aggs = {} + if collected? + aggs[:collections] = { terms: { field: 'collection_ids' } } + end + + if facet_tags? + %w(rating archive_warning category fandom character relationship freeform).each do |facet_type| + aggs[facet_type] = { terms: { field: "#{facet_type}_ids" } } + end + end + + { aggs: aggs } + end + + def works_per_language(languages_count) + response = $elasticsearch.search(index: index_name, body: { + size: 0, + query: filtered_query, + aggregations: { + languages: { + terms: { field: "language_id.keyword", size: languages_count } + } + } + }) + language_counts = response.dig("aggregations", "languages", "buckets") || [] + language_counts.map(&:values).to_h + end + + #################### + # HELPERS + #################### + + def facet_tags? + options[:faceted] + end + + def collected? + options[:collected] + end + + def viewing_own_collected_works_page? + collected? && options[:works_parent].present? && + options[:works_parent] == User.current_user + end + + def include_restricted? + User.current_user.present? || options[:show_restricted] + end + + # Include unrevealed works only if we're on a collection page + # OR the collected works page of a user + def include_unrevealed? + options[:collection_ids].present? || collected? + end + + # Include anonymous works if we're not on a user/pseud page + # OR if the user is viewing their own collected works + def include_anon? + (user_ids.blank? && pseud_ids.blank?) || + viewing_own_collected_works_page? + end + + def user_ids + options[:user_ids] + end + + def pseud_ids + options[:pseud_ids] + end + + # By default, ES6 expects yyyy-MM-dd and can't parse years with 4+ digits. + def clamp_search_date(date) + return date.change(year: 0) if date.year.negative? + return date.change(year: 9999) if date.year > 9999 + date + end +end diff --git a/app/models/search/work_search_form.rb b/app/models/search/work_search_form.rb new file mode 100755 index 0000000..d8ab552 --- /dev/null +++ b/app/models/search/work_search_form.rb @@ -0,0 +1,228 @@ +class WorkSearchForm + + extend ActiveModel::Naming + include ActiveModel::Conversion + include ActiveModel::Validations + + ATTRIBUTES = [ + :query, + :title, + :creators, + :collected, + :faceted, + :revised_at, + :language_id, + :complete, + :crossover, + :single_chapter, + :word_count, + :hits, + :kudos_count, + :bookmarks_count, + :comments_count, + :pseud_ids, + :collection_ids, + :tag, + :excluded_tag_names, + :excluded_tag_ids, + :other_tag_names, + :filter_ids, + :fandom_names, + :fandom_ids, + :rating_ids, + :category_ids, + :archive_warning_ids, + :character_names, + :character_ids, + :relationship_names, + :relationship_ids, + :freeform_names, + :freeform_ids, + :date_from, + :date_to, + :words_from, + :words_to, + :sort_column, + :sort_direction, + :page + ].freeze + + attr_accessor :options + + ATTRIBUTES.each do |filterable| + define_method(filterable) { options[filterable] } + end + + def initialize(opts={}) + @options = opts + process_options + @searcher = WorkQuery.new(@options) + end + + def process_options + @options.delete_if { |k, v| v == "0" || v.blank? } + standardize_creator_queries + standardize_language_ids + set_sorting + clean_up_angle_brackets + rename_warning_field + end + + # Make the creator/creators change backwards compatible + def standardize_creator_queries + return unless @options[:query].present? + @options[:query] = @options[:query].gsub('creator:', 'creators:') + end + + def standardize_language_ids + # Maintain backward compatibility for old work searches/filters: + + # - Using language IDs in the "Language" dropdown + if @options[:language_id].present? && @options[:language_id].to_i != 0 + language = Language.find_by(id: options[:language_id]) + options[:language_id] = language.short if language.present? + end + + # - Using language IDs in "Any field" (search) or "Search within results" (filters) + if @options[:query].present? + @options[:query] = @options[:query].gsub(/\blanguage_id\s*:\s*(\d+)/) do + lang = Language.find_by(id: Regexp.last_match[1]) + lang = Language.default if lang.blank? + "language_id: " + lang.short + end + end + end + + def set_sorting + @options[:sort_column] ||= default_sort_column + @options[:sort_direction] ||= default_sort_direction + end + + def clean_up_angle_brackets + [:word_count, :hits, :kudos_count, :comments_count, :bookmarks_count, :revised_at, :query].each do |countable| + next unless @options[countable].present? + str = @options[countable] + @options[countable] = str.gsub(">", ">").gsub("<", "<") + end + end + + def rename_warning_field + if @options[:warning_ids].present? + @options[:archive_warning_ids] = @options.delete(:warning_ids) + end + end + + def persisted? + false + end + + def summary + summary = [] + if @options[:query].present? + summary << @options[:query].gsub('creators:', 'creator:') + end + if @options[:title].present? + summary << "Title: #{@options[:title]}" + end + if @options[:creators].present? + summary << "Creator: #{@options[:creators]}" + end + tags = @searcher.included_tag_names + all_tag_ids = @searcher.filter_ids + unless all_tag_ids.empty? + tags << Tag.where(id: all_tag_ids).pluck(:name).join(", ") + end + unless tags.empty? + summary << "Tags: #{tags.uniq.join(", ")}" + end + if complete.to_s == "T" + summary << "Complete" + elsif complete.to_s == "F" + summary << "Incomplete" + end + if crossover.to_s == "T" + summary << "Only Crossovers" + elsif crossover.to_s == "F" + summary << "No Crossovers" + end + if %w(1 true).include?(self.single_chapter.to_s) + summary << "Single Chapter" + end + if @options[:language_id].present? + language = Language.find_by(short: @options[:language_id]) + if language.present? + summary << "Language: #{language.name}" + end + end + [:word_count, :hits, :kudos_count, :comments_count, :bookmarks_count, :revised_at].each do |countable| + if @options[countable].present? + summary << "#{countable.to_s.humanize.downcase}: #{@options[countable]}" + end + end + if @options[:sort_column].present? + # Use pretty name if available, otherwise fall back to plain column name + pretty_sort_name = name_for_sort_column(@options[:sort_column]) + direction = if @options[:sort_direction].present? + @options[:sort_direction] == "asc" ? " ascending" : " descending" + else + "" + end + summary << ("sort by: #{pretty_sort_name&.downcase || @options[:sort_column]}" + direction) + end + summary.join(" ") + end + + def search_results + @searcher.search_results + end + + ############### + # SORTING + ############### + + SORT_OPTIONS = [ + ["Best Match", "_score"], + %w[Creator authors_to_sort_on], + %w[Title title_to_sort_on], + ["Date Posted", "created_at"], + ["Date Updated", "revised_at"], + ["Word Count", "word_count"], + %w[Hits hits], + %w[Kudos kudos_count], + %w[Comments comments_count], + %w[Bookmarks bookmarks_count] + ].freeze + + def sort_columns + options[:sort_column] || default_sort_column + end + + def sort_direction + options[:sort_direction] || default_sort_direction + end + + def sort_options + options[:faceted] || options[:collected] ? SORT_OPTIONS[1..-1] : SORT_OPTIONS + end + + def sort_values + sort_options.map{ |option| option.last } + end + + # extract the pretty name + def name_for_sort_column(sort_column) + Hash[SORT_OPTIONS.map { |v| [v[1], v[0]] }][sort_column] + end + + def default_sort_column + options[:faceted] || options[:collected] ? 'revised_at' : '_score' + end + + def default_sort_direction + if %w[authors_to_sort_on title_to_sort_on].include?(sort_column) + 'asc' + else + 'desc' + end + end +end diff --git a/app/models/search_range.rb b/app/models/search_range.rb new file mode 100755 index 0000000..ab28d79 --- /dev/null +++ b/app/models/search_range.rb @@ -0,0 +1,118 @@ +class SearchRange + + attr_accessor :text_range + + TIME_REGEX = /^([<>]*)\s*([\d -]+)\s*(year|week|month|day|hour)s?(\s*ago)?\s*$/ + NUMBER_REGEX = /^([<>]*)\s*([\d,. -]+)\s*$/ + OUT_OF_RANGE_DATE = 1000.years.ago + + # Takes a string that includes a time or number range and + # returns it as a hash that can be used in elasticsearch queries + def self.parsed(str) + new(str).parse + end + + def initialize(str) + @text_range = str || "" + end + + def parse + standardize_text + range = {} + if match = text_range.match(TIME_REGEX) + range = time_range(match[1], match[2], match[3]) + elsif match = text_range.match(NUMBER_REGEX) + range = numerical_range(match[1], match[2].gsub(",", "")) + end + range + end + + private + + def standardize_text + @text_range = @text_range.gsub(">", ">"). + gsub("<", "<"). + downcase + end + + + # create numerical range from operand and string + # operand can be "<", ">" or "" + # string must be an integer unless operand is "" + # in which case it can be two numbers connected by "-" + def numerical_range(operand, string) + case operand + when "<" + { lt: string.to_i } + when ">" + { gt: string.to_i } + when "" + match = string.match(/-/) + if match + { gte: match.pre_match.to_i, lte: match.post_match.to_i } + else + { gte: string.to_i, lte: string.to_i } + end + end + end + + # create time range from operand, amount and period + # period must be one known by time_from_string + def time_range(operand, amount, period) + case operand + when "<" + time = time_from_string(amount, period) + { gt: time } + when ">" + time = time_from_string(amount, period) + { lt: time } + when "" + match = amount.match(/-/) + if match + time1 = time_from_string(match.pre_match, period) + time2 = time_from_string(match.post_match, period) + { gte: time2, lte: time1 } + else + range_from_string(amount, period) + end + end + end + + # helper method to create times from two strings + # Elasticsearch gets grumpy with negative years, so the simple fix + # is just to go back a thousand years + # TODO: rework date query formats if Homer ever starts posting his stuff to AO3 + def time_from_string(amount, period) + date = amount.to_i.send(period).ago + date.year.negative? ? OUT_OF_RANGE_DATE : date + end + + # Generate a range based on one number + # Interval is based on period used, ie 1 month ago = range from beginning to end of month + def range_from_string(amount, period) + case period + when /year/ + a = amount.to_i.year.ago.beginning_of_year + a2 = a.end_of_year + when /month/ + a = amount.to_i.month.ago.beginning_of_month + a2 = a.end_of_month + when /week/ + a = amount.to_i.week.ago.beginning_of_week + a2 = a.end_of_week + when /day/ + a = amount.to_i.day.ago.beginning_of_day + a2 = a.end_of_day + when /hour/ + a = amount.to_i.hour.ago.change(min: 0, sec: 0, usec: 0) + a2 = (a + 60.minutes) + else + raise "unknown period: " + period + end + a, a2 = [a, a2].map do |date| + date.year.negative? ? OUT_OF_RANGE_DATE : date + end + { gte: a, lte: a2 } + end + +end diff --git a/app/models/serial_work.rb b/app/models/serial_work.rb new file mode 100755 index 0000000..ae19798 --- /dev/null +++ b/app/models/serial_work.rb @@ -0,0 +1,50 @@ +class SerialWork < ApplicationRecord + belongs_to :series, touch: true + belongs_to :work, touch: true + validates_uniqueness_of :work_id, scope: [:series_id] + acts_as_list scope: :series + + after_create :adjust_series_visibility + after_destroy :adjust_series_visibility + after_destroy :delete_empty_series + after_create :update_series_index, :update_work_index + after_destroy :update_series_index, :update_work_index + + scope :in_order, -> { order(:position) } + + # If you add or remove a work from a series, make sure restricted? is still accurate + def adjust_series_visibility + self.series.adjust_restricted unless self.series.blank? + end + + # If you delete a work from a series and it was the last one, delete the series too + def delete_empty_series + if self.series.present? && self.series.serial_works.blank? + self.series.destroy + end + end + + # Reindex works added to or removed from a series + def update_work_index + work&.enqueue_to_index + end + + # Ensure series bookmarks are reindexed when a new work is added to a series + def update_series_index + return if series.blank? + series.enqueue_to_index + IndexQueue.enqueue_ids(Bookmark, series.bookmarks.pluck(:id), :main) + end + + after_create :update_series_creatorships + def update_series_creatorships + return unless work && series + + work.pseuds_after_saving.each do |pseud| + creatorship = series.creatorships.find_or_initialize_by(pseud: pseud) + creatorship.approved = true + creatorship.enable_notifications = true + creatorship.save + end + end +end diff --git a/app/models/series.rb b/app/models/series.rb new file mode 100755 index 0000000..96726ed --- /dev/null +++ b/app/models/series.rb @@ -0,0 +1,315 @@ +class Series < ApplicationRecord + include Bookmarkable + include Searchable + include Creatable + + has_many :serial_works, dependent: :destroy + has_many :works, through: :serial_works + has_many :work_tags, -> { distinct }, through: :works, source: :tags + has_many :work_pseuds, -> { distinct }, through: :works, source: :pseuds + + has_many :taggings, as: :taggable, dependent: :destroy + has_many :tags, through: :taggings, source: :tagger, source_type: 'Tag' + + has_many :subscriptions, as: :subscribable, dependent: :destroy + + validates_presence_of :title + validates_length_of :title, + minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} letters long.", min: ArchiveConfig.TITLE_MIN) + + validates_length_of :title, + maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.TITLE_MAX) + + # return title.html_safe to overcome escaping done by sanitiser + def title + read_attribute(:title).try(:html_safe) + end + + validates_length_of :summary, + allow_blank: true, + maximum: ArchiveConfig.SUMMARY_MAX, + too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.SUMMARY_MAX) + + validates_length_of :series_notes, + allow_blank: true, + maximum: ArchiveConfig.NOTES_MAX, + too_long: ts("must be less than %{max} letters long.", max: ArchiveConfig.NOTES_MAX) + + after_save :adjust_restricted + after_update_commit :expire_caches, :update_work_index + + scope :visible_to_registered_user, -> { where(hidden_by_admin: false).order('series.updated_at DESC') } + scope :visible_to_all, -> { where(hidden_by_admin: false, restricted: false).order('series.updated_at DESC') } + + scope :exclude_anonymous, -> { + joins("INNER JOIN `serial_works` ON (`series`.`id` = `serial_works`.`series_id`) + INNER JOIN `works` ON (`works`.`id` = `serial_works`.`work_id`)"). + group("series.id"). + having("MAX(works.in_anon_collection) = 0 AND MAX(works.in_unrevealed_collection) = 0") + } + + scope :for_pseud, lambda { |pseud| + joins(:approved_creatorships).where(creatorships: { pseud: pseud }) + } + + scope :for_user, lambda { |user| + joins(approved_creatorships: :pseud).where(pseuds: { user: user }) + } + + scope :for_blurb, -> { includes(:work_tags, :pseuds) } + + def posted_works + self.works.posted + end + + def works_in_order + works.order("serial_works.position") + end + + # Get the filters for the works in this series + def filters + Tag.joins("JOIN filter_taggings ON tags.id = filter_taggings.filter_id + JOIN works ON works.id = filter_taggings.filterable_id + JOIN serial_works ON serial_works.work_id = works.id"). + where("serial_works.series_id = #{self.id} AND + works.posted = 1 AND + filter_taggings.filterable_type = 'Work'"). + group("tags.id") + end + + def direct_filters + filters.where("filter_taggings.inherited = 0") + end + + # visibility aped from the work model + def visible?(user = User.current_user) + return true if user.is_a?(Admin) + + if posted && !hidden_by_admin + user.is_a?(User) || !restricted + else + user_is_owner_or_invited?(user) + end + end + + # Override the default definition to check whether the user was invited to + # any works in the series. + def user_is_owner_or_invited?(user) + return false unless user.is_a?(User) + return true if super + + works.joins(:creatorships).merge(user.creatorships).exists? || + works.joins(chapters: :creatorships).merge(user.creatorships).exists? + end + + def visible_work_count + if User.current_user.nil? + self.works.posted.unrestricted.count + else + self.works.posted.count + end + end + + def visible_word_count + if User.current_user.nil? + # visible_works_wordcount = self.works.posted.unrestricted.sum(:word_count) + visible_works_wordcount = self.works.posted.unrestricted.pluck(:word_count).compact.sum + else + # visible_works_wordcount = self.works.posted.sum(:word_count) + visible_works_wordcount = self.works.posted.pluck(:word_count).compact.sum + end + visible_works_wordcount + end + + def anonymous? + !self.works.select { |work| work.anonymous? }.empty? + end + + def unrevealed? + !self.works.select { |work| work.unrevealed? }.empty? + end + + # if the series includes an unrestricted work, restricted should be false + # if the series includes no unrestricted works, restricted should be true + def adjust_restricted + unless self.restricted? == !(self.works.where(restricted: false).count > 0) + self.restricted = !(self.works.where(restricted: false).count > 0) + self.save!(validate: false) + end + end + + # Visibility has changed, which means we need to reindex + # the series' bookmarker pseuds, to update their bookmark counts. + def should_reindex_pseuds? + pertinent_attributes = %w[id restricted hidden_by_admin] + destroyed? || (saved_changes.keys & pertinent_attributes).present? + end + + def expire_caches + self.works.touch_all + end + + def expire_byline_cache + [true, false].each do |only_path| + Rails.cache.delete("#{cache_key}/byline-nonanon/#{only_path}") + end + end + + # Change the positions of the serial works in the series + def reorder_list(positions) + SortableList.new(self.serial_works.in_order).reorder_list(positions) + end + + def position_of(work) + serial_works.where(work_id: work.id).pluck(:position).first + end + + # return list of pseuds on this series + def allpseuds + works.collect(&:pseuds).flatten.compact.uniq.sort + end + + # Remove a user (and all their pseuds) as an author of this series. + # + # We call Work#remove_author before destroying the series creatorships to + # make sure that we can handle tricky chapter creatorship cases. + def remove_author(author_to_remove) + pseuds_with_author_removed = pseuds.where.not(user_id: author_to_remove.id) + + if pseuds_with_author_removed.empty? + errors.add(:base, ts("Sorry, we can't remove all creators of a series.")) + raise ActiveRecord::RecordInvalid, self + end + + transaction do + authored_works_in_series = self.works.merge(author_to_remove.works) + + authored_works_in_series.each do |work| + work.remove_author(author_to_remove) + end + + creatorships.where(pseud: author_to_remove.pseuds).destroy_all + end + end + + # returns list of fandoms on this series + def allfandoms + works.collect(&:fandoms).flatten.compact.uniq.sort + end + + def author_tags + self.work_tags.select{|t| t.type == "Relationship"}.sort + self.work_tags.select{|t| t.type == "Character"}.sort + self.work_tags.select{|t| t.type == "Freeform"}.sort + end + + def tag_groups + self.work_tags.group_by { |t| t.type.to_s } + end + + # Grabs the earliest published_at date of the visible works in the series + def published_at + if self.works.visible.posted.blank? + self.created_at + else + Work.in_series(self).visible.collect(&:published_at).compact.uniq.sort.first + end + end + + def revised_at + if self.works.visible.posted.blank? + self.updated_at + else + Work.in_series(self).visible.collect(&:revised_at).compact.uniq.sort.last + end + end + + ###################### + # SEARCH + ###################### + + def bookmarkable_json + as_json( + root: false, + only: [ + :title, :summary, :hidden_by_admin, :restricted, :created_at, + :complete + ], + methods: [ + :revised_at, :posted, :tag, :filter_ids, :rating_ids, + :archive_warning_ids, :category_ids, :fandom_ids, :character_ids, + :relationship_ids, :freeform_ids, :creators, + :word_count, :work_types] + ).merge( + language_id: language&.short, + anonymous: anonymous?, + unrevealed: unrevealed?, + pseud_ids: anonymous? || unrevealed? ? nil : pseud_ids, + user_ids: anonymous? || unrevealed? ? nil : user_ids, + bookmarkable_type: 'Series', + bookmarkable_join: { name: "bookmarkable" } + ) + end + + def update_work_index + self.works.each(&:enqueue_to_index) if saved_change_to_title? + end + + def word_count + self.works.posted.pluck(:word_count).compact.sum + end + + # FIXME: should series have their own language? + def language + works.first.language if works.present? + end + + def posted + !posted_works.empty? + end + alias_method :posted?, :posted + + # Simple name to make it easier for people to use in full-text search + def tag + (work_tags + filters).uniq.map{ |t| t.name } + end + + # Index all the filters for pulling works + def filter_ids + (work_tags.pluck(:id) + filters.pluck(:id)).uniq + end + + # Index only direct filters (non meta-tags) for facets + def filters_for_facets + @filters_for_facets ||= direct_filters + end + def rating_ids + filters_for_facets.select{ |t| t.type.to_s == 'Rating' }.map{ |t| t.id } + end + def archive_warning_ids + filters_for_facets.select{ |t| t.type.to_s == 'ArchiveWarning' }.map{ |t| t.id } + end + def category_ids + filters_for_facets.select{ |t| t.type.to_s == 'Category' }.map{ |t| t.id } + end + def fandom_ids + filters_for_facets.select{ |t| t.type.to_s == 'Fandom' }.map{ |t| t.id } + end + def character_ids + filters_for_facets.select{ |t| t.type.to_s == 'Character' }.map{ |t| t.id } + end + def relationship_ids + filters_for_facets.select{ |t| t.type.to_s == 'Relationship' }.map{ |t| t.id } + end + def freeform_ids + filters_for_facets.select{ |t| t.type.to_s == 'Freeform' }.map{ |t| t.id } + end + + def creators + anonymous? ? ['Anonymous'] : pseuds.map(&:byline) + end + + def work_types + works.map(&:work_types).flatten.uniq + end +end diff --git a/app/models/skin.rb b/app/models/skin.rb new file mode 100755 index 0000000..0a41733 --- /dev/null +++ b/app/models/skin.rb @@ -0,0 +1,602 @@ +require 'fileutils' + +class Skin < ApplicationRecord + include HtmlCleaner + include CssCleaner + include SkinCacheHelper + include SkinWizard + + TYPE_OPTIONS = [ + [ts("Site Skin"), "Skin"], + [ts("Work Skin"), "WorkSkin"], + ] + + # any media types that are not a single alphanumeric word have to be specially + # handled in get_media_for_filename/parse_media_from_filename + MEDIA = %w(all screen handheld speech print braille embossed projection tty tv) + [ + "only screen and (max-width: 42em)", + "only screen and (max-width: 62em)", + "(prefers-color-scheme: dark)", + "(prefers-color-scheme: light)" + ] + IE_CONDITIONS = %w(IE IE5 IE6 IE7 IE8 IE9 IE8_or_lower) + ROLES = %w(user override) + ROLE_NAMES = {"user" => "add on to archive skin", "override" => "replace archive skin entirely"} + # We don't show some roles to users + ALL_ROLES = ROLES + %w(admin translator site) + DEFAULT_ROLE = "user" + DEFAULT_ROLES_TO_INCLUDE = %w(user override site) + DEFAULT_MEDIA = ["all"] + + SKIN_PATH = 'stylesheets/skins/' + SITE_SKIN_PATH = 'stylesheets/site/' + + belongs_to :author, class_name: 'User' + has_many :preferences + + serialize :media, type: Array, coder: YAML, yaml: { permitted_classes: [String] } + + # a skin can be both parent and child + has_many :skin_parents, foreign_key: 'child_skin_id', + class_name: 'SkinParent', + dependent: :destroy, inverse_of: :child_skin + has_many :parent_skins, -> { order("skin_parents.position ASC") }, through: :skin_parents, inverse_of: :child_skins + + has_many :skin_children, foreign_key: 'parent_skin_id', + class_name: 'SkinParent', dependent: :destroy, inverse_of: :parent_skin + has_many :child_skins, through: :skin_children, inverse_of: :parent_skins + + accepts_nested_attributes_for :skin_parents, allow_destroy: true, reject_if: proc { |attrs| attrs[:position].blank? || (attrs[:parent_skin_title].blank? && attrs[:parent_skin_id].blank?) } + + has_one_attached :icon do |attachable| + attachable.variant(:standard, resize_to_limit: [100, 100], loader: { n: -1 }) + end + + # i18n-tasks-use t("errors.attributes.icon.invalid_format") + # i18n-tasks-use t("errors.attributes.icon.too_large") + validates :icon, attachment: { + allowed_formats: %r{image/\S+}, + maximum_size: ArchiveConfig.ICON_SIZE_KB_MAX.kilobytes + } + + after_save :skin_invalidate_cache + def skin_invalidate_cache + skin_chooser_expire_cache + skin_cache_version_update(id) + + # Work skins can't have children, but site skins (which have type nil) + # might have children that need expiration: + return unless type.nil? + + SkinParent.get_all_child_ids(id).each do |child_id| + skin_cache_version_update(child_id) + end + end + + validates_length_of :icon_alt_text, allow_blank: true, maximum: ArchiveConfig.ICON_ALT_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.ICON_ALT_MAX) + + validates_length_of :description, allow_blank: true, maximum: ArchiveConfig.SUMMARY_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.SUMMARY_MAX) + + validates_length_of :css, allow_blank: true, maximum: ArchiveConfig.CONTENT_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.CONTENT_MAX) + + before_validation :clean_media + def clean_media + # handle bizarro cucumber-only error that prevents media from deserializing correctly when attachments are made + if media && media.is_a?(Array) && !media.empty? + new_media = media.flatten.compact.collect {|m| m.gsub(/\["(\w+)"\]/, '\1')} + self.media = new_media + end + end + + validate :valid_media + def valid_media + if media && media.is_a?(Array) && media.any? {|m| !MEDIA.include?(m)} + errors.add( + :base, + :invalid_media, + media: media.join(", ") + ) + end + end + + validates :ie_condition, inclusion: {in: IE_CONDITIONS, allow_nil: true, allow_blank: true} + validates :role, inclusion: {in: ALL_ROLES, allow_blank: true, allow_nil: true } + + validate :valid_public_preview + def valid_public_preview + return true if self.official? || !self.public? || self.icon.attached? + errors.add(:base, :no_public_preview) + end + + validates :title, presence: true, uniqueness: { case_sensitive: false } + validate :allowed_title + def allowed_title + return true unless self.title.match(/archive/i) + + authorized_roles = if self.is_a?(WorkSkin) + %w[superadmin support] + else + %w[superadmin] + end + + return true if (User.current_user.roles & authorized_roles).present? + + errors.add(:base, :archive_in_title) + end + + validates_numericality_of :margin, :base_em, allow_nil: true + validate :valid_font + def valid_font + return if self.font.blank? + self.font.split(',').each do |subfont| + if sanitize_css_font(subfont).blank? + errors.add(:font, "cannot use #{subfont}.") + end + end + end + + validate :valid_colors + def valid_colors + + if !self.background_color.blank? && sanitize_css_value(self.background_color).blank? + errors.add(:background_color, "uses a color that is not allowed.") + end + + if !self.foreground_color.blank? && sanitize_css_value(self.foreground_color).blank? + errors.add(:foreground_color, "uses a color that is not allowed.") + end + end + + validate :clean_css + def clean_css + return if self.css.blank? + self.css = clean_css_code(self.css) + end + + scope :public_skins, -> { where(public: true) } + scope :approved_skins, -> { where(official: true, public: true) } + scope :unapproved_skins, -> { where(public: true, official: false, rejected: false) } + scope :rejected_skins, -> { where(public: true, official: false, rejected: true) } + scope :site_skins, -> { where(type: nil) } + scope :wizard_site_skins, -> { where("type IS NULL AND ( + margin IS NOT NULL OR + background_color IS NOT NULL OR + foreground_color IS NOT NULL OR + font IS NOT NULL OR + base_em IS NOT NULL OR + paragraph_margin IS NOT NULL OR + headercolor IS NOT NULL OR + accent_color IS NOT NULL + ) + ") } + + def self.cached + where(cached: true) + end + + def self.in_chooser + where(in_chooser: true) + end + + def self.featured + where(featured: true) + end + + def self.approved_or_owned_by(user = User.current_user) + if user.nil? + approved_skins + else + approved_or_owned_by_any([user]) + end + end + + def self.approved_or_owned_by_any(users) + where("(public = 1 AND official = 1) OR author_id in (?)", users.map(&:id)) + end + + def self.usable + where(unusable: false) + end + + def self.sort_by_recent + order("updated_at DESC") + end + + def self.sort_by_recent_featured + order("featured DESC, updated_at DESC") + end + + def approved_or_owned_by?(user) + self.public? && self.official? || author_id == user.id + end + + def remove_me_from_preferences + Preference.where(skin_id: self.id).update_all(skin_id: AdminSetting.default_skin_id) + end + + def editable? + if self.filename.present? + return false + elsif self.official && self.public + return true if User.current_user.is_a? Admin + elsif self.author == User.current_user + return true + else + return false + end + end + + def byline + if self.author.is_a? User + author.login + else + ArchiveConfig.APP_SHORT_NAME + end + end + + def wizard_settings? + margin.present? || font.present? || background_color.present? || foreground_color.present? || base_em.present? || paragraph_margin.present? || headercolor.present? || accent_color.present? + end + + # create the minimal number of files we can, containing all the css for this entire skin + def cache! + self.clear_cache! + self.public = true + self.official = true + save! + css_to_cache = "" + last_role = "" + file_count = 1 + skin_dir = Skin.skins_dir + skin_dirname + FileUtils.mkdir_p skin_dir + (get_all_parents + [self]).each do |next_skin| + if next_skin.get_sheet_role != last_role + # save to file + if css_to_cache.present? + cache_filename = skin_dir + "#{file_count}_#{last_role}.css" + file_count+=1 + File.open(cache_filename, 'w') {|f| f.write(css_to_cache)} + css_to_cache = "" + end + last_role = next_skin.get_sheet_role + end + css_to_cache += next_skin.get_css + end + # TODO this repetition is all wrong but my brain is fried + if css_to_cache.present? + cache_filename = skin_dir + "#{file_count}_#{last_role}.css" + File.open(cache_filename, 'w') {|f| f.write(css_to_cache)} + css_to_cache = "" + end + self.cached = true + save! + end + + def clear_cache! + skin_dir = Skin.skins_dir + skin_dirname + FileUtils.rm_rf skin_dir # clear out old if exists + self.cached = false + save! + end + + def recache_children! + child_ids = SkinParent.get_all_child_ids(id) + Skin.where(cached: true, id: child_ids).find_each(&:cache!) + end + + def get_sheet_role + "#{get_role}_#{get_media_for_filename}_#{ie_condition}" + end + + # have to handle any media types that aren't a single alphanumeric word here + def get_media_for_filename + ((media.nil? || media.empty?) ? DEFAULT_MEDIA : media).map {|m| + case + when m.match(/max-width: 42em/) + "narrow" + when m.match(/max-width: 62em/) + "midsize" + when m.match(/prefers-color-scheme: dark/) + "dark" + when m.match(/prefers-color-scheme: light/) + "light" + else + m + end + }.join(".") + end + + def parse_media_from_filename(media_string) + media_string.gsub(/narrow/, "only screen and (max-width: 42em)") + .gsub(/midsize/, "only screen and (max-width: 62em)") + .gsub(/dark/, "(prefers-color-scheme: dark)") + .gsub(/light/, "(prefers-color-scheme: light)") + .gsub(".", ", ") + end + + def parse_sheet_role(role_string) + (sheet_role, sheet_media, sheet_ie_condition) = role_string.split('_') + sheet_media = parse_media_from_filename(sheet_media) + [sheet_role, sheet_media, sheet_ie_condition] + end + + def get_css + if filename + File.read(Rails.public_path.join(filename)) + else + css + end + end + + def get_media(separator=", ") + ((media.nil? || media.empty?) ? DEFAULT_MEDIA : media).join(separator) + end + + def get_role + self.role || DEFAULT_ROLE + end + + def get_all_parents + all_parents = [] + parent_skins.each do |parent| + all_parents += parent.get_all_parents + all_parents << parent + end + all_parents + end + + # This is the main function that actually returns code to be embedded in a page + def get_style(roles_to_include = DEFAULT_ROLES_TO_INCLUDE) + style = "" + + if self.get_role != "override" && self.get_role != "site" && + self.id != AdminSetting.default_skin_id && + AdminSetting.default_skin.is_a?(Skin) + style += AdminSetting.default_skin.get_style(roles_to_include) + end + + style += self.get_style_block(roles_to_include) + style.html_safe + end + + def get_ie_comment(style, ie_condition = self.ie_condition) + if ie_condition.present? + ie_comment= "" + else + style + end + end + + # This builds the stylesheet, so the order is important + def get_wizard_settings + style = "" + + style += font_size_styles(base_em) if base_em.present? + + style += font_styles(font) if font.present? + + style += background_color_styles(background_color) if background_color.present? + + style += paragraph_margin_styles(paragraph_margin) if paragraph_margin.present? + + style += foreground_color_styles(foreground_color) if foreground_color.present? + + style += header_styles(headercolor) if headercolor.present? + + style += accent_color_styles(accent_color) if accent_color.present? + + style += work_margin_styles(margin) if margin.present? + + style + end + + def get_style_block(roles_to_include) + block = "" + if self.cached? + # cached skin in a directory + block = get_cached_style(roles_to_include) + else + # recursively get parents + parent_skins.each do |parent| + block += parent.get_style_block(roles_to_include) + "\n" + end + + # finally get this skin + if roles_to_include.include?(get_role) + if self.filename.present? + block += get_ie_comment(stylesheet_link(self.filename, get_media)) + else + if (wizard_block = get_wizard_settings).present? + block += '' + end + if self.css.present? + block += get_ie_comment('') + end + end + end + end + return block + end + + def get_cached_style(roles_to_include) + block = "" + self_skin_dir = Skin.skins_dir + self.skin_dirname + Skin.skin_dir_entries(self_skin_dir, /^\d+_(.*)\.css$/).each do |sub_file| + if sub_file.match(/^\d+_(.*)\.css$/) + (sheet_role, sheet_media, sheet_ie_condition) = parse_sheet_role($1) + if roles_to_include.include?(sheet_role) + block += get_ie_comment(stylesheet_link(SKIN_PATH + self.skin_dirname + sub_file, sheet_media), sheet_ie_condition) + "\n" + end + end + end + block + end + + def stylesheet_link(file, media) + # we want one and only one / in the url path + '' + end + + def self.naturalized(string) + string.scan(/[^\d]+|[\d]+/).collect { |f| f.match(/\d+(\.\d+)?/) ? f.to_f : f } + end + + def self.load_site_css + Skin.skin_dir_entries(Skin.site_skins_dir, /^\d+\.\d+$/).each do |version| + version_dir = "#{Skin.site_skins_dir + version}/" + if File.directory?(version_dir) + # let's load up the file + skins = [] + Skin.skin_dir_entries(version_dir, /^(\d+)-(.*)\.css/).each do |skin_file| + filename = SITE_SKIN_PATH + version + '/' + skin_file + skin_file.match(/^(\d+)-(.*)\.css/) + position = $1.to_i + title = $2 + title.gsub!(/(\-|\_)/, ' ') + description = "Version #{version} of the #{title} component (#{position}) of the default archive site design." + firstline = File.open(version_dir + skin_file, &:readline) + skin_role = "site" + if firstline.match(/ROLE: (\w+)/) + skin_role = $1 + end + skin_media = ["screen"] + if firstline.match(/MEDIA: (.*?) ENDMEDIA/) + skin_media = $1.split(/,\s?/) + elsif firstline.match(/MEDIA: (\w+)/) + skin_media = [$1] + end + skin_ie = "" + if firstline.match(/IE_CONDITION: (\w+)/) + skin_ie = $1 + end + + full_title = "Archive #{version}: (#{position}) #{title}" + skin = Skin.find_by(title: full_title) + if skin.nil? + skin = Skin.new + end + + # update the attributes + skin.title ||= full_title + skin.filename = filename + skin.description = description + skin.public = true + skin.media = skin_media + skin.role = skin_role + skin.ie_condition = skin_ie + skin.unusable = true + skin.official = true + skin.icon.attach(io: File.open("#{version_dir}preview.png", "rb"), content_type: "image/png", filename: "preview.png") + skin.save!(validate: false) + skins << skin + end + + # set up the parent relationship of all the skins in this version + top_skin = Skin.find_by(title: "Archive #{version}") + if top_skin + top_skin.clear_cache! if top_skin.cached? + top_skin.skin_parents.delete_all + else + top_skin = Skin.new(title: "Archive #{version}", css: "", description: "Version #{version} of the default Archive style.", + public: true, role: "site", media: ["screen"]) + end + top_skin.icon.attach(io: File.open("#{version_dir}preview.png", "rb"), content_type: "image/png", filename: "preview.png") + top_skin.official = true + top_skin.save!(validate: false) + skins.each_with_index do |skin, index| + skin_parent = top_skin.skin_parents.build(child_skin: top_skin, parent_skin: skin, position: index+1) + skin_parent.save! + end + if %w(staging unproduction).include? Rails.env + top_skin.cache! + end + end + end + end + + # get the directory name for the skin file + def skin_dirname + "skin_#{self.id}_#{self.title.gsub(/[^\w]/, '_')}/".downcase + end + + def self.skins_dir + Rails.public_path.join(SKIN_PATH).to_s + end + + def self.skin_dir_entries(dir, regex) + Dir.entries(dir).select {|f| f.match(regex)}.sort_by {|f| Skin.naturalized(f.to_s)} + end + + def self.site_skins_dir + Rails.public_path.join(SITE_SKIN_PATH).to_s + end + + # Get the most recent version and find the topmost skin + def self.get_current_version + Skin.skin_dir_entries(Skin.site_skins_dir, /^\d+\.\d+$/).last + end + + def self.get_current_site_skin + current_version = Skin.get_current_version + if current_version + Skin.find_by(title: "Archive #{Skin.get_current_version}", official: true) + else + nil + end + end + + def self.default + Skin.find_by(title: "Default", official: true) || Skin.create_default + end + + def self.create_default + transaction do + skin = Skin.find_or_initialize_by(title: "Default") + + skin.official = true + skin.public = true + skin.role = "site" + skin.css = "" + skin.set_thumbnail_from_current_version + + skin.save! + skin + end + end + + def self.set_default_to_current_version + transaction do + default_skin = default + + default_skin.set_thumbnail_from_current_version + + parent_skin = get_current_site_skin + if parent_skin && default_skin.parent_skins != [parent_skin] + default_skin.skin_parents.destroy_all + default_skin.skin_parents.build(parent_skin: parent_skin, position: 1) + end + + default_skin.save! + end + end + + def set_thumbnail_from_current_version + current_version = self.class.get_current_version + + icon_path = if current_version + self.class.site_skins_dir + current_version + "/preview.png" + else + self.class.site_skins_dir + "preview.png" + end + + self.icon.attach(io: File.open(icon_path), content_type: "image/png", filename: "preview.png") + end +end diff --git a/app/models/skin_parent.rb b/app/models/skin_parent.rb new file mode 100755 index 0000000..d733157 --- /dev/null +++ b/app/models/skin_parent.rb @@ -0,0 +1,77 @@ +class SkinParent < ApplicationRecord + belongs_to :child_skin, class_name: "Skin", touch: true + belongs_to :parent_skin, class_name: "Skin" + + validates :position, + uniqueness: {scope: [:child_skin_id, :parent_skin_id], message: ts("^Position has to be unique for each parent.")}, + numericality: {only_integer: true, greater_than: 0} + + validates_presence_of :child_skin, :parent_skin + + validate :no_site_parent + def no_site_parent + return unless parent_skin&.get_role == "site" && %w[override site].exclude?(child_skin.get_role) + + errors.add(:base, :site_parent, title: parent_skin.title) + end + + validate :no_circular_skin + def no_circular_skin + if parent_skin == child_skin + errors.add(:base, ts("^You can't make a skin its own parent")) + end + parent_ids = SkinParent.get_all_parent_ids(self.child_skin_id) + if parent_ids.include?(self.parent_skin_id) + errors.add(:base, ts("^%{parent_title} is already a parent of %{child_title}", child_title: child_skin.title, parent_title: parent_skin.title)) + end + + child_ids = SkinParent.get_all_child_ids(self.child_skin_id) + if child_ids.include?(self.parent_skin_id) + errors.add(:base, ts("^%{parent_title} is a child of %{child_title}", child_title: child_skin.title, parent_title: parent_skin.title)) + end + + # also don't allow duplication + + end + + # Takes as argument the ID of the skin to start at, and a block that should + # take a list of skin IDs and produce a list of "adjacent" skin IDs (i.e. + # parents or children). + def self.search_skin_ids(root_id) + found = Set.new([root_id]) + boundary = [root_id] + + until boundary.empty? + new_boundary = yield boundary + + boundary = [] + + new_boundary.each do |skin_id| + boundary << skin_id if found.add?(skin_id) + end + end + + found.delete(root_id) + found.to_a + end + + def self.get_all_parent_ids(skin_id) + search_skin_ids(skin_id) do |skin_ids| + SkinParent.where(child_skin_id: skin_ids).pluck(:parent_skin_id) + end + end + + def self.get_all_child_ids(skin_id) + search_skin_ids(skin_id) do |skin_ids| + SkinParent.where(parent_skin_id: skin_ids).pluck(:child_skin_id) + end + end + + def parent_skin_title + self.parent_skin.try(:title) || "" + end + + def parent_skin_title=(title) + self.parent_skin = Skin.find_by(title: title) + end +end diff --git a/app/models/spam_report.rb b/app/models/spam_report.rb new file mode 100755 index 0000000..f4510f2 --- /dev/null +++ b/app/models/spam_report.rb @@ -0,0 +1,75 @@ +class SpamReport + attr_reader :recent_date, :new_date + + def self.run + new.run + end + + def initialize + @recent_date = 14.days.ago + @new_date = 1.day.ago + end + + def run + spam = {} + users.each do |user| + new_works, score = score_user(user) + if score > ArchiveConfig.SPAM_THRESHOLD + spam[user.id] = { score: score, work_ids: new_works } + end + end + spam = Hash[spam.sort_by { |_user_id, info| info[:score] }.reverse] + if spam.length > 0 + AdminMailer.send_spam_alert(spam).deliver_later + end + end + + private + + def all_new_works + Work.where("created_at > ?", new_date).posted.unhidden + end + + def users + all_new_works.map { |w| w.users }.flatten.uniq + end + + # Scoring rules: + # For every new spam work, add 4 to the score + # For every new non-spam work, add 1 + # For every older non-spam work, + # decrease the score by 2 + # Add the number of different ip addresses used to post + def score_user(user) + new_works = [] + ips = [] + score = 0 + works = user.works. + visible_to_registered_user. + where("works.created_at > ?", new_date) + works.each do |work| + unless work.spam_checked? + work.check_for_spam + end + + if work.created_at > new_date + new_works << work.id + ips << work.ip_address + if work.spam? + score += 4 + else + score += 1 + end + end + end + + count = user.works. + where("works.created_at > ? AND works.created_at < ?", + recent_date, + new_date). + posted.not_spam.size + score -= (count * 2) + score += ips.uniq.length + [new_works, score] + end +end diff --git a/app/models/stat_counter.rb b/app/models/stat_counter.rb new file mode 100755 index 0000000..f362907 --- /dev/null +++ b/app/models/stat_counter.rb @@ -0,0 +1,14 @@ +class StatCounter < ApplicationRecord + belongs_to :work + + after_commit :enqueue_to_index, on: :update + + def enqueue_to_index + IndexQueue.enqueue(self, :stats) + end + + # Specify the indexer that should be used for this class + def indexers + [StatCounterIndexer] + end +end diff --git a/app/models/status.rb b/app/models/status.rb new file mode 100644 index 0000000..cb7ca12 --- /dev/null +++ b/app/models/status.rb @@ -0,0 +1,5 @@ +class Status < ApplicationRecord + belongs_to :user + has_one_attached :icon +end + diff --git a/app/models/story_parser.rb b/app/models/story_parser.rb new file mode 100755 index 0000000..f7d2d35 --- /dev/null +++ b/app/models/story_parser.rb @@ -0,0 +1,981 @@ +# Parse stories from other websites and uploaded files, looking for metadata to harvest +# and put into the archive. +# +class StoryParser + require 'timeout' + require 'nokogiri' + require 'mechanize' + require 'open-uri' + include HtmlCleaner + + OPTIONAL_META = {notes: 'Note', + freeform_string: 'Tag', + fandom_string: 'Fandom', + rating_string: 'Rating', + archive_warning_string: 'Warning', + relationship_string: 'Relationship|Pairing', + character_string: 'Character' }.freeze + REQUIRED_META = { title: 'Title', + summary: 'Summary', + revised_at: 'Date|Posted|Posted on|Posted at', + chapter_title: 'Chapter Title' }.freeze + + # Use this for raising custom error messages + # (so that we can distinguish them from unexpected exceptions due to + # faulty code) + class Error < StandardError + end + + # These attributes need to be moved from the work to the chapter + # format: {work_attribute_name: :chapter_attribute_name} (can be the same) + CHAPTER_ATTRIBUTES_ONLY = {} + + # These attributes need to be copied from the work to the chapter + CHAPTER_ATTRIBUTES_ALSO = { revised_at: :published_at }.freeze + + ### NOTE ON KNOWN SOURCES + # These lists will stop with the first one it matches, so put more-specific matches + # towards the front of the list. + + # places for which we have a custom parse_story_from_[source] method + # for getting information out of the downloaded text + KNOWN_STORY_PARSERS = %w[deviantart dw lj].freeze + + # places for which we have a custom parse_author_from_[source] method + # which returns an external_author object including an email address + KNOWN_AUTHOR_PARSERS = %w[lj].freeze + + # places for which we have a download_story_from_[source] + # used to customize the downloading process + KNOWN_STORY_LOCATIONS = %w[lj].freeze + + # places for which we have a download_chaptered_from + # to get a set of chapters all together + CHAPTERED_STORY_LOCATIONS = %w[ffnet thearchive_net efiction quotev].freeze + + # regular expressions to match against the URLS + SOURCE_LJ = '((live|dead|insane)journal\.com)|journalfen(\.net|\.com)|dreamwidth\.org'.freeze + SOURCE_DW = 'dreamwidth\.org'.freeze + SOURCE_FFNET = '(^|[^A-Za-z0-9-])fanfiction\.net'.freeze + SOURCE_DEVIANTART = 'deviantart\.com'.freeze + SOURCE_THEARCHIVE_NET = 'the\-archive\.net'.freeze + SOURCE_EFICTION = 'viewstory\.php'.freeze + SOURCE_QUOTEV = 'quotev\.com'.freeze + + # time out if we can't download fast enough + STORY_DOWNLOAD_TIMEOUT = 60 + MAX_CHAPTER_COUNT = 200 + + # To check for duplicate chapters, take a slice this long out of the story + # (in characters) + DUPLICATE_CHAPTER_LENGTH = 10_000 + + + # Import many stories + def import_many(urls, options = {}) + # Try to get the works + works = [] + failed_urls = [] + errors = [] + @options = options + urls.each do |url| + begin + response = download_and_parse_work(url, options) + work = response[:work] + if response[:status] == :created + if work && work.save + work.chapters.each(&:save) + works << work + else + failed_urls << url + errors << work.errors.values.join(", ") + work.delete if work + end + elsif response[:status] == :already_imported + raise StoryParser::Error, response[:message] + end + rescue Timeout::Error + failed_urls << url + errors << "Import has timed out. This may be due to connectivity problems with the source site. Please try again in a few minutes, or check Known Issues to see if there are import problems with this site." + work.delete if work + rescue Error => exception + failed_urls << url + errors << "We couldn't successfully import that work, sorry: #{exception.message}" + work.delete if work + end + end + [works, failed_urls, errors] + end + + # Downloads a story and passes it on to the parser. + # If the URL of the story is from a site for which we have special rules + # (eg, downloading from a livejournal clone, you want to use ?format=light + # to get a nice and consistent post format), it will pre-process the url + # according to the rules for that site. + def download_and_parse_work(location, options = {}) + status = :created + message = "" + work = Work.find_by_url(location) + if work.nil? + @options = options + source = get_source_if_known(CHAPTERED_STORY_LOCATIONS, location) + if source.nil? + story = download_text(location) + work = parse_story(story, location, options) + else + work = download_and_parse_chaptered_story(source, location, options) + end + else + status = :already_imported + message = "A work has already been imported from #{location}." + end + { + status: status, + message: message, + work: work + } + end + + # Given an array of urls for chapters of a single story, + # download them all and combine into a single work + def import_chapters_into_story(locations, options = {}) + status = :created + work = Work.find_by_url(locations.first) + if work.nil? + chapter_contents = [] + @options = options + locations.each do |location| + chapter_contents << download_text(location) + end + work = parse_chapters_into_story(locations.first, chapter_contents, options) + message = "Successfully created work \"" + work.title + "\"." + else + status = :already_imported + message = "A work has already been imported from #{locations.first}." + end + { + status: status, + message: message, + work: work + } + end + + + ### OLD PARSING METHODS + + # Import many stories + def import_from_urls(urls, options = {}) + # Try to get the works + works = [] + failed_urls = [] + errors = [] + @options = options + urls.each do |url| + begin + work = download_and_parse_story(url, options) + if work && work.save + work.chapters.each(&:save) + works << work + else + failed_urls << url + errors << work.errors.values.join(", ") + work.delete if work + end + rescue Timeout::Error + failed_urls << url + errors << "Import has timed out. This may be due to connectivity problems with the source site. Please try again in a few minutes, or check Known Issues to see if there are import problems with this site." + work.delete if work + rescue Error => exception + failed_urls << url + errors << "We couldn't successfully import that work, sorry: #{exception.message}" + work.delete if work + end + end + [works, failed_urls, errors] + end + + # Downloads a story and passes it on to the parser. + # If the URL of the story is from a site for which we have special rules + # (eg, downloading from a livejournal clone, you want to use ?format=light + # to get a nice and consistent post format), it will pre-process the url + # according to the rules for that site. + def download_and_parse_story(location, options = {}) + check_for_previous_import(location) + @options = options + source = get_source_if_known(CHAPTERED_STORY_LOCATIONS, location) + if source.nil? + story = download_text(location) + work = parse_story(story, location, options) + else + work = download_and_parse_chaptered_story(source, location, options) + end + work + end + + # Given an array of urls for chapters of a single story, + # download them all and combine into a single work + def download_and_parse_chapters_into_story(locations, options = {}) + check_for_previous_import(locations.first) + chapter_contents = [] + @options = options + locations.each do |location| + chapter_contents << download_text(location) + end + parse_chapters_into_story(locations.first, chapter_contents, options) + end + + ### PARSING METHODS + + # Parses the text of a story, optionally from a given location. + def parse_story(story, location, options = {}) + work_params = parse_common(story, location, options[:encoding], options[:detect_tags]) + + # move any attributes from work to chapter if necessary + set_work_attributes(Work.new(work_params), location, options) + end + + # parses and adds a new chapter to the end of the work + def parse_chapter_of_work(work, chapter_content, location, options = {}) + tmp_work_params = parse_common(chapter_content, location, options[:encoding], options[:detect_tags]) + chapter = get_chapter_from_work_params(tmp_work_params) + work.chapters << set_chapter_attributes(work, chapter) + work + end + + def parse_chapters_into_story(location, chapter_contents, options = {}) + work = nil + chapter_contents.each do |content| + work_params = parse_common(content, location, options[:encoding], options[:detect_tags]) + if work.nil? + # create the new work + work = Work.new(work_params) + else + new_chapter = get_chapter_from_work_params(work_params) + work.chapters << set_chapter_attributes(work, new_chapter) + end + end + set_work_attributes(work, location, options) + end + + # Everything below here is protected and should not be touched by outside + # code -- please use the above functions to parse external works. + + protected + + # tries to create an external author for a given url + def parse_author(location, ext_author_name, ext_author_email) + if location.present? && ext_author_name.blank? && ext_author_email.blank? + source = get_source_if_known(KNOWN_AUTHOR_PARSERS, location) + if source.nil? + raise Error, "No external author name or email specified" + else + send("parse_author_from_#{source.downcase}", location) + end + else + parse_author_common(ext_author_email, ext_author_name) + end + end + + # download an entire story from an archive type where we know how to parse multi-chaptered works + # this should only be called from download_and_parse_story + def download_and_parse_chaptered_story(source, location, options = {}) + chapter_contents = send("download_chaptered_from_#{source.downcase}", location) + parse_chapters_into_story(location, chapter_contents, options) + end + + # our custom url finder checks for previously imported URL in almost any format it may have been presented + def check_for_previous_import(location) + if Work.find_by_url(location).present? + raise Error, "A work has already been imported from #{location}." + end + end + + def set_chapter_attributes(work, chapter) + chapter.position = work.chapters.length + 1 + chapter.posted = true + chapter + end + + def set_work_attributes(work, location = "", options = {}) + raise Error, "Work could not be downloaded" if work.nil? + + @options = options + work.imported_from_url = location + work.ip_address = options[:ip_address] + work.expected_number_of_chapters = work.chapters.length + work.revised_at = work.chapters.last.published_at + if work.revised_at && work.revised_at.to_date < Date.current + work.backdate = true + end + + # set authors for the works + pseuds = [] + pseuds << User.current_user.default_pseud unless options[:do_not_set_current_author] || User.current_user.nil? + pseuds << options[:archivist].default_pseud if options[:archivist] + pseuds << options[:pseuds] if options[:pseuds] + pseuds = pseuds.flatten.compact.uniq + raise Error, "A work must have at least one author specified" if pseuds.empty? + pseuds.each do |pseud| + work.creatorships.build(pseud: pseud, enable_notifications: true) + work.chapters.each do |chapter| + chapter.creatorships.build(pseud: pseud) + end + end + + # handle importing works for others + # build an external creatorship for each author + if options[:importing_for_others] + external_author_names = options[:external_author_names] || parse_author(location, options[:external_author_name], options[:external_author_email]) + # convert to an array if not already one + external_author_names = [external_author_names] if external_author_names.is_a?(ExternalAuthorName) + if options[:external_coauthor_name].present? + external_author_names << parse_author(location, options[:external_coauthor_name], options[:external_coauthor_email]) + end + external_author_names.each do |external_author_name| + next if !external_author_name || external_author_name.external_author.blank? + if external_author_name.external_author.do_not_import + # we're not allowed to import works from this address + raise Error, "Author #{external_author_name.name} at #{external_author_name.external_author.email} does not allow importing their work to this archive." + end + work.external_creatorships.build(external_author_name: external_author_name, archivist: (options[:archivist] || User.current_user)) + end + end + + # lock to registered users if specified or importing for others + work.restricted = options[:restricted] || options[:importing_for_others] || false + + # set comment permissions + work.comment_permissions = options[:comment_permissions] || "enable_all" + work.moderated_commenting_enabled = options[:moderated_commenting_enabled] || false + + # set default values for required tags + work.fandom_string = meta_or_default(work.fandom_string, options[:fandom], ArchiveConfig.FANDOM_NO_TAG_NAME) + work.rating_string = meta_or_default(work.rating_string, options[:rating], ArchiveConfig.RATING_DEFAULT_TAG_NAME) + work.archive_warning_strings = meta_or_default(work.archive_warning_strings, options[:archive_warning], ArchiveConfig.WARNING_DEFAULT_TAG_NAME) + work.category_string = meta_or_default(work.category_string, options[:category], []) + work.character_string = meta_or_default(work.character_string, options[:character], []) + work.relationship_string = meta_or_default(work.relationship_string, options[:relationship], []) + work.freeform_string = meta_or_default(work.freeform_string, options[:freeform], []) + + # set default value for title + work.title = meta_or_default(work.title, options[:title], "Untitled Imported Work") + work.summary = meta_or_default(work.summary, options[:summary], '') + work.notes = meta_or_default(work.notes, options[:notes], '') + + # set collection name if present + work.collection_names = get_collection_names(options[:collection_names]) if options[:collection_names].present? + + # set default language (English) + work.language_id = options[:language_id] || Language.default.id + + work.posted = true if options[:post_without_preview] + work.chapters.each do |chapter| + if chapter.content.length > ArchiveConfig.CONTENT_MAX + # TODO: eventually: insert a new chapter + chapter.content.truncate(ArchiveConfig.CONTENT_MAX, omission: "WARNING: import truncated automatically because chapter was too long! Please add a new chapter for remaining content.", separator: "

    ") + elsif chapter.content.empty? + raise Error, "Chapter #{chapter.position} of \"#{work.title}\" is blank." + end + + chapter.posted = true # do not save - causes the chapters to exist even if work doesn't get created! + end + work + end + + def parse_author_from_lj(location) + return if location !~ %r{^(?:http:\/\/)?(?[^.]*).(?livejournal\.com|dreamwidth\.org|insanejournal\.com|journalfen.net)} + email = "" + lj_name = Regexp.last_match[:lj_name] + site_name = Regexp.last_match[:site_name] + if lj_name == "community" + # whups + post_text = download_text(location) + doc = Nokogiri.parse(post_text) + lj_name = doc.xpath("/html/body/div[2]/div/div/div/table/tbody/tr/td[2]/span/a[2]/b").content + end + profile_url = "http://#{lj_name}.#{site_name}/profile" + lj_profile = download_text(profile_url) + doc = Nokogiri.parse(lj_profile) + contact = doc.css('div.contact').inner_html + if contact.present? + contact.gsub! '

    Contact:

    ', "" + contact.gsub! /<\/?(span|i)>/, "" + contact.delete! "\n" + contact.gsub! "
    ", "" + if contact =~ /(.*@.*\..*)/ + email = Regexp.last_match[1] + end + end + email = "#{lj_name}@#{site_name}" if email.blank? + parse_author_common(email, lj_name) + end + + def parse_author_from_unknown(_location) + # for now, nothing + nil + end + + def parse_author_common(email, name) + errors = [] + + errors << "No author name specified" if name.blank? + + if email.present? + external_author = ExternalAuthor.find_or_create_by(email: email) + errors += external_author.errors.full_messages + else + errors << "No author email specified" + end + + raise Error, errors.join("\n") if errors.present? + + # convert to ASCII and strip out invalid characters (everything except alphanumeric characters, _, @ and -) + redacted_name = name.to_ascii.gsub(/[^\w[ \-@.]]/u, "") + if redacted_name.present? + external_author.names.find_or_create_by(name: redacted_name) + else + external_author.default_name + end + end + + def get_chapter_from_work_params(work_params) + @chapter = Chapter.new(work_params[:chapter_attributes]) + # don't override specific chapter params (eg title) with work params + chapter_params = work_params.delete_if do |name, _param| + !@chapter.attribute_names.include?(name.to_s) || !@chapter.send(name.to_s).blank? + end + @chapter.update(chapter_params) + @chapter + end + + def download_text(location) + source = get_source_if_known(KNOWN_STORY_LOCATIONS, location) + if source.nil? + download_with_timeout(location) + else + send("download_from_#{source.downcase}", location) + end + end + + # canonicalize the url for downloading from lj or clones + def download_from_lj(location) + url = location + url.gsub!(/\#(.*)$/, "") # strip off any anchor information + url.gsub!(/\?(.*)$/, "") # strip off any existing params at the end + url.gsub!('_', '-') # convert underscores in usernames to hyphens + url += "?format=light" # go to light format + text = download_with_timeout(url) + + if text.match(/adult_check/) + Timeout::timeout(STORY_DOWNLOAD_TIMEOUT) { + begin + agent = Mechanize.new + url.include?("dreamwidth") ? form = agent.get(url).forms.first : form = agent.get(url).forms.third + page = agent.submit(form, form.buttons.first) # submits the adult concepts form + text = page.body.force_encoding(agent.page.encoding) + rescue + text = "" + end + } + end + text + end + + # grab all the chapters of the story from ff.net + def download_chaptered_from_ffnet(_location) + raise Error, "Sorry, Fanfiction.net does not allow imports from their site." + end + + def download_chaptered_from_quotev(_location) + raise Error, "Sorry, Quotev.com does not allow imports from their site." + end + + # this is an efiction archive but it doesn't handle chapters normally + # best way to handle is to get the full story printable version + # We have to make it a download-chaptered because otherwise it gets sent to the + # generic efiction version since chaptered sources are checked first + def download_chaptered_from_thearchive_net(location) + if location.match(/^(.*)\/.*viewstory\.php.*[^p]sid=(\d+)($|&)/i) + location = "#{$1}/viewstory.php?action=printable&psid=#{$2}" + end + text = download_with_timeout(location) + text.sub!('', '') unless text.match('') + [text] + end + + # grab all the chapters of a story from an efiction-based site + def download_chaptered_from_efiction(location) + chapter_contents = [] + if location.match(/^(?.*)\/.*viewstory\.php.*sid=(?\d+)($|&)/i) + site = Regexp.last_match[:site] + storyid = Regexp.last_match[:storyid] + chapnum = 1 + last_body = "" + Timeout::timeout(STORY_DOWNLOAD_TIMEOUT) do + loop do + url = "#{site}/viewstory.php?action=printable&sid=#{storyid}&chapter=#{chapnum}" + body = download_with_timeout(url) + # get a section to check that this isn't a duplicate of previous chapter + body_to_check = body.slice(10, DUPLICATE_CHAPTER_LENGTH) + if body.nil? || body_to_check == last_body || chapnum > MAX_CHAPTER_COUNT || body.match(/
    by <\/div>/) || body.match(/Access denied./) || body.match(/Chapter : /) + break + end + # save the value to check for duplicate chapter + last_body = body_to_check + + # clean up the broken head in many efiction printable sites + body.sub!('', '') unless body.match('') + chapter_contents << body + chapnum += 1 + end + end + end + chapter_contents + end + + + # This is the heavy lifter, invoked by all the story and chapter parsers. + # It takes a single string containing the raw contents of a story, parses it with + # Nokogiri into the @doc object, and then and calls a subparser. + # + # If the story source can be identified as one of the sources we know how to parse in some custom/ + # special way, parse_common calls the customized parse_story_from_[source] method. + # Otherwise, it falls back to parse_story_from_unknown. + # + # This produces a hash equivalent to the params hash that is normally created by the standard work + # upload form. + # + # parse_common then calls sanitize_params (which would also be called on the standard work upload + # form results) and returns the final sanitized hash. + # + def parse_common(story, location = nil, encoding = nil, detect_tags = true) + work_params = { title: "Untitled Imported Work", chapter_attributes: { content: "" } } + + # Encode as HTML - the dummy "foo" tag will be stripped out by the sanitizer but forces Nokogiri to + # preserve line breaks in plain text documents + # Rescue all errors as Nokogiri complains about things the sanitizer will fix later + story.prepend("") + @doc = + begin + Nokogiri::HTML5.parse(story, encoding: encoding) + rescue StandardError + Nokogiri::HTML5.parse("") + end + + # Try to convert all relative links to absolute + base = @doc.at_css("base") ? @doc.css("base")[0]["href"] : location.split("?").first + if base.present? + @doc.css("a").each do |link| + next if link["href"].blank? || link["href"].start_with?("#") + begin + query = link["href"].match(/(\?.*)$/) ? $1 : "" + link["href"] = URI.join(base, link["href"].gsub(/(\?.*)$/, "")).to_s + query + rescue +# ignored + end + end + end + + # Extract metadata (unless detect_tags is false) + if location && (source = get_source_if_known(KNOWN_STORY_PARSERS, location)) + params = send("parse_story_from_#{source.downcase}", story, detect_tags) + work_params.merge!(params) + else + work_params.merge!(parse_story_from_unknown(story, detect_tags)) + end + + shift_chapter_attributes(sanitize_params(work_params)) + end + + # our fallback: parse a story from an unknown source, so we have no special + # rules. + def parse_story_from_unknown(story, detect_tags = true) + work_params = { chapter_attributes: {} } + story_head = "" + story_head = @doc.css("head").inner_html if @doc.css("head") + + # Story content - Look for progressively less specific containers or grab everything + element = @doc.at_css('.chapter-content') || @doc.at_css('body') || @doc.at_css('html') || @doc + storytext = element ? element.inner_html : story + + meta = {} + meta.merge!(scan_text_for_meta(story_head, detect_tags)) unless story_head.blank? + meta.merge!(scan_text_for_meta(story, detect_tags)) + meta[:title] ||= @doc.css('title').inner_html + work_params[:chapter_attributes][:title] = meta.delete(:chapter_title) + work_params[:chapter_attributes][:content] = clean_storytext(storytext) + work_params.merge!(meta) + end + + # Parses a story from livejournal or a livejournal equivalent (eg, dreamwidth, insanejournal) + # Assumes that we have downloaded the story from one of those equivalents (ie, we've downloaded + # it in format=light which is a stripped-down plaintext version.) + # + def parse_story_from_lj(_story, detect_tags = true) + work_params = { chapter_attributes: {} } + + # in LJ "light" format, the story contents are in the second div + # inside the body. + body = @doc.css("body") + storytext = body.css("article.b-singlepost-body").inner_html + storytext = body.css("div.aentry-post__text").inner_html if storytext.empty? + storytext = body.inner_html if storytext.empty? + + # cleanup the text + # storytext.gsub!(//i, "\n") # replace the breaks with newlines + storytext = clean_storytext(storytext) + + work_params[:chapter_attributes][:content] = storytext + work_params[:title] = @doc.css("title").inner_html + work_params[:title].gsub! /^[^:]+: /, "" + work_params.merge!(scan_text_for_meta(storytext, detect_tags)) + + date = @doc.css("time.b-singlepost-author-date") + date = @doc.css("p.aentry-head__date/time") if date.empty? + work_params[:revised_at] = convert_revised_at(date.first.inner_text) unless date.empty? + + work_params + end + + def parse_story_from_dw(_story, detect_tags = true) + work_params = { chapter_attributes: {} } + + body = @doc.css("body") + content_divs = body.css("div.contents") + + if content_divs[0].present? + # Get rid of the DW metadata table + content_divs[0].css("div.currents, ul.entry-management-links, div.header.inner, span.restrictions, h3.entry-title").each(&:remove) + storytext = content_divs[0].inner_html + else + storytext = body.inner_html + end + + # cleanup the text + storytext = clean_storytext(storytext) + + work_params[:chapter_attributes][:content] = storytext + work_params[:title] = @doc.css("title").inner_html + work_params[:title].gsub! /^[^:]+: /, "" + work_params.merge!(scan_text_for_meta(storytext, detect_tags)) + + font_blocks = @doc.xpath('//font') + unless font_blocks.empty? + date = font_blocks.first.inner_text + work_params[:revised_at] = convert_revised_at(date) + end + + # get the date + date = @doc.css("span.date").inner_text + work_params[:revised_at] = convert_revised_at(date) + + work_params + end + + def parse_story_from_deviantart(_story, detect_tags = true) + work_params = { chapter_attributes: {} } + storytext = "" + notes = "" + + body = @doc.css("body") + title = @doc.css("title").inner_html.gsub /\s*on deviantart$/i, "" + + # Find the image (original size) if it's art + image_full = body.css("div.dev-view-deviation img.dev-content-full") + unless image_full[0].nil? + storytext = "
    " + end + + # Find the fic text if it's fic (needs the id for disambiguation, the "deviantART loves you" bit in the footer has the same class path) + text_table = body.css(".grf-indent > div:nth-child(1)")[0] + unless text_table.nil? + # Try to remove some metadata (title and author) from the work's text, if possible + # Try to remove the title: if it exists, and if it's the same as the browser title + if text_table.css("h1")[0].present? && title && title.match(text_table.css("h1")[0].text) + text_table.css("h1")[0].remove + end + + # Try to remove the author: if it exists, and if it follows a certain pattern + if text_table.css("small")[0].present? && text_table.css("small")[0].inner_html.match(/by ~.*?}i, "\n") # replace the breaks with newlines + storytext = clean_storytext(storytext) + work_params[:chapter_attributes][:content] = storytext + + # Find the notes + content_divs = body.css("div.text-ctrl div.text") + notes = content_divs[0].inner_html unless content_divs[0].nil? + + # cleanup the notes + notes.gsub!(%r{}i, "\n") # replace the breaks with newlines + notes = clean_storytext(notes, "notes") + work_params[:notes] = notes + + work_params.merge!(scan_text_for_meta(notes, detect_tags)) + work_params[:title] = title + + body.css("div.dev-title-container h1 a").each do |node| + if node["class"] != "u" + work_params[:title] = node.inner_html + end + end + + tags = [] + @doc.css("div.dev-about-cat-cc a.h").each { |node| tags << node.inner_html } + work_params[:freeform_string] = clean_tags(tags.join(ArchiveConfig.DELIMITER_FOR_OUTPUT)) + + details = @doc.css("div.dev-right-bar-content span[title]") + unless details[0].nil? + work_params[:revised_at] = convert_revised_at(details[0].inner_text) + end + + work_params + end + + # Move and/or copy any meta attributes that need to be on the chapter rather + # than on the work itself + def shift_chapter_attributes(work_params) + CHAPTER_ATTRIBUTES_ONLY.each_pair do |work_attrib, chapter_attrib| + if work_params[work_attrib] && !work_params[:chapter_attributes][chapter_attrib] + work_params[:chapter_attributes][chapter_attrib] = work_params[work_attrib] + work_params.delete(work_attrib) + end + end + + # copy any attributes from work to chapter as necessary + CHAPTER_ATTRIBUTES_ALSO.each_pair do |work_attrib, chapter_attrib| + if work_params[work_attrib] && !work_params[:chapter_attributes][chapter_attrib] + work_params[:chapter_attributes][chapter_attrib] = work_params[work_attrib] + end + end + + work_params + end + + # Find any cases of the given pieces of meta in the given text + # and return a hash of meta values + def scan_text_for_meta(text, detect_tags = true) + # break up the text with some extra newlines to make matching more likely + # and strip out some tags + text = text.gsub(/
    /, '') + + meta = {} + metapatterns = detect_tags ? REQUIRED_META.merge(OPTIONAL_META) : REQUIRED_META + is_tag = {}.tap do |h| + %w[fandom_string relationship_string freeform_string rating_string archive_warning_string].each do |c| + h[c.to_sym] = true + end + end + handler = {}.tap do |h| + %w[rating_string revised_at].each do |c| + h[c.to_sym] = "convert_#{c.to_s.downcase}" + end + end + + # 1. Look for Pattern: (whatever), optionally followed by a closing p or div tag + # 2. Set meta[:metaname] = whatever + # eg, if it finds Fandom: Stargate SG-1 it will set meta[:fandom] = Stargate SG-1 + # 3. convert_ for cleanup if such a function is defined (eg convert_rating_string) + metapatterns.each do |metaname, pattern| + metapattern = Regexp.new("(?:#{pattern}|#{pattern.pluralize})\s*:\s*(.*?)(?:)?$", Regexp::IGNORECASE) + if text.match(metapattern) + value = Regexp.last_match[1] + value = clean_tags(value) if is_tag[metaname] + value = clean_close_html_tags(value) + value.strip! # lose leading/trailing whitespace + value = send(handler[metaname], value) if handler[metaname] + + meta[metaname] = value + end + end + post_process_meta meta + end + + def download_with_timeout(location, limit = 10) + story = "" + Timeout.timeout(STORY_DOWNLOAD_TIMEOUT) do + begin + # we do a little cleanup here in case the user hasn't included the 'http://' + # or if they've used capital letters or an underscore in the hostname + uri = UrlFormatter.new(location).standardized + raise Error, I18n.t("story_parser.on_archive") if ArchiveConfig.PERMITTED_HOSTS.include?(uri.host) + + response = Net::HTTP.get_response(uri) + case response + when Net::HTTPSuccess + story = response.body + when Net::HTTPRedirection + if limit.positive? + new_uri = URI.parse(response["location"]) + new_uri = URI.join(uri, new_uri) if new_uri.relative? + story = download_with_timeout(new_uri.to_s, limit - 1) + end + else + Rails.logger.error("------- STORY PARSER: download_with_timeout: response is not success or redirection ------") + nil + end + rescue Errno::ECONNREFUSED, SocketError, EOFError => e + Rails.logger.error("------- STORY PARSER: download_with_timeout: error rescue: \n#{e.inspect} ------") + nil + end + end + if story.blank? + raise Error, "We couldn't download anything from #{location}. Please make sure that the URL is correct and complete, and try again." + end + + # clean up any erroneously included string terminator (AO3-2251) + story.delete("\000") + end + + def get_last_modified(location) + Timeout.timeout(STORY_DOWNLOAD_TIMEOUT) do + resp = open(location) + resp.last_modified + end + end + + def get_source_if_known(known_sources, location) + known_sources.each do |source| + pattern = Regexp.new(eval("SOURCE_#{source.upcase}"), Regexp::IGNORECASE) + return source if location.match(pattern) + end + nil + end + + def clean_close_html_tags(value) + # if there are any closing html tags at the start of the value let's ditch them + value.gsub(/^(\s*<\/[^>]+>)+/, '') + end + + # We clean the text as if it had been submitted as the content of a chapter + def clean_storytext(storytext, field = "content") + storytext = storytext.encode("UTF-8", invalid: :replace, undef: :replace, replace: "") unless storytext.encoding.name == "UTF-8" + sanitize_value(field, storytext) + end + + # works conservatively -- doesn't split on + # spaces and truncates instead. + def clean_tags(tags) + tags = Sanitize.clean(tags.force_encoding("UTF-8")) # no html allowed in tags + tags_list = tags =~ /,/ ? tags.split(/,/) : [tags] + new_list = [] + tags_list.each do |tag| + tag.gsub!(/[*<>]/, '') + tag = truncate_on_word_boundary(tag, ArchiveConfig.TAG_MAX) + new_list << tag unless tag.blank? + end + new_list.join(ArchiveConfig.DELIMITER_FOR_OUTPUT) + end + + def truncate_on_word_boundary(text, max_length) + return if text.blank? + words = text.split + truncated = words.first + if words.length > 1 + words[1..words.length].each do |word| + truncated += " " + word if truncated.length + word.length + 1 <= max_length + end + end + truncated[0..max_length - 1] + end + + # convert space-separated tags to comma-separated + def clean_and_split_tags(tags) + tags = tags.split(/\s+/).join(',') if !tags.match(/,/) && tags.match(/\s/) + clean_tags(tags) + end + + # Convert the common ratings into whatever ratings we're + # using on this archive. + def convert_rating_string(rating) + rating = rating.downcase + if rating =~ /^(nc-?1[78]|x|ma|explicit)/ + ArchiveConfig.RATING_EXPLICIT_TAG_NAME + elsif rating =~ /^(r|m|mature)/ + ArchiveConfig.RATING_MATURE_TAG_NAME + elsif rating =~ /^(pg-?1[35]|t|teen)/ + ArchiveConfig.RATING_TEEN_TAG_NAME + elsif rating =~ /^(pg|g|k+|k|general audiences)/ + ArchiveConfig.RATING_GENERAL_TAG_NAME + else + ArchiveConfig.RATING_DEFAULT_TAG_NAME + end + end + + def convert_revised_at(date_string) + begin + date = nil + if date_string =~ /^(\d+)$/ + # probably seconds since the epoch + date = Time.at(Regex.last_match[1].to_i) + end + date ||= Date.parse(date_string) + return '' if date > Date.current + return date + rescue ArgumentError, TypeError + return '' + end + end + + # Additional processing for meta - currently to make sure warnings + # that aren't Archive warnings become additional tags instead + def post_process_meta(meta) + if meta[:archive_warning_string] + result = process_warnings(meta[:archive_warning_string], meta[:freeform_string]) + meta[:archive_warning_string] = result[:archive_warning_string] + meta[:freeform_string] = result[:freeform_string] + end + meta + end + + def process_warnings(warning_string, freeform_string) + result = { + archive_warning_string: warning_string, + freeform_string: freeform_string + } + new_warning = '' + result[:archive_warning_string].split(/\s?,\s?/).each do |warning| + if ArchiveWarning.warning? warning + new_warning += ', ' unless new_warning.blank? + new_warning += warning + else + result[:freeform_string] = (result[:freeform_string] || '') + ", #{warning}" + end + end + result[:archive_warning_string] = new_warning + result + end + + # tries to find appropriate existing collections and converts them to comma-separated collection names only + def get_collection_names(collection_string) + collections = "" + collection_string.split(',').map(&:squish).each do |collection_name| + collection = Collection.find_by(name: collection_name) || Collection.find_by(title: collection_name) + if collection + collections += ", " unless collections.blank? + collections += collection.name + end + end + collections + end + + # determine which value to use for a metadata field + def meta_or_default(detected_field, provided_field, default = nil) + if @options[:override_tags] || detected_field.blank? + if provided_field.blank? + detected_field.blank? ? default : detected_field + else + provided_field + end + else + detected_field + end + end +end diff --git a/app/models/subscription.rb b/app/models/subscription.rb new file mode 100755 index 0000000..8ad19d7 --- /dev/null +++ b/app/models/subscription.rb @@ -0,0 +1,55 @@ +class Subscription < ApplicationRecord + VALID_SUBSCRIBABLES = %w(Work User Series).freeze + + belongs_to :user + belongs_to :subscribable, polymorphic: true + + validates_presence_of :user + + validates :subscribable_type, inclusion: { in: VALID_SUBSCRIBABLES } + # Without the condition, you get a 500 error instead of a validation error + # if there's an invalid subscribable type + validates :subscribable, presence: true, + if: proc { |s| VALID_SUBSCRIBABLES.include?(s.subscribable_type) } + + # Get the subscriptions associated with this work + # currently: users subscribed to work, users subscribed to creator of work + scope :for_work, lambda {|work| + where(["(subscribable_id = ? AND subscribable_type = 'Work') + OR (subscribable_id IN (?) AND subscribable_type = 'User') + OR (subscribable_id IN (?) AND subscribable_type = 'Series')", + work.id, + work.pseuds.pluck(:user_id), + work.serial_works.pluck(:series_id)]). + group(:user_id) + } + + # The name of the object to which the user is subscribed + def name + if subscribable.respond_to?(:login) + subscribable.login + elsif subscribable.respond_to?(:name) + subscribable.name + elsif subscribable.respond_to?(:title) + subscribable.title + else + I18n.t("subscriptions.deleted") + end + end + + def subject_text(creation) + authors = if self.class.anonymous_creation?(creation) + "Anonymous" + else + creation.pseuds.map(&:byline).to_sentence + end + chapter_text = creation.is_a?(Chapter) ? "#{creation.chapter_header} of " : "" + work_title = creation.is_a?(Chapter) ? creation.work.title : creation.title + text = "#{authors} posted #{chapter_text}#{work_title}" + text += subscribable_type == "Series" ? " in the #{self.name} series" : "" + end + + def self.anonymous_creation?(creation) + (creation.is_a?(Work) && creation.anonymous?) || (creation.is_a?(Chapter) && creation.work.anonymous?) + end +end diff --git a/app/models/tag.rb b/app/models/tag.rb new file mode 100755 index 0000000..10c1a06 --- /dev/null +++ b/app/models/tag.rb @@ -0,0 +1,1254 @@ +require "unicode_utils/casefold" + +class Tag < ApplicationRecord + include Searchable + include StringCleaner + include WorksOwner + include Wrangleable + include Rails.application.routes.url_helpers + + NAME = "Tag" + + # Note: the order of this array is important. + # It is the order that tags are shown in the header of a work + # (banned tags are not shown) + TYPES = ['Rating', 'ArchiveWarning', 'Category', 'Media', 'Fandom', 'Relationship', 'Character', 'Freeform', 'Banned' ] + + # these tags can be filtered on + FILTERS = TYPES - ['Banned', 'Media'] + + # these tags show up on works + VISIBLE = TYPES - ['Media', 'Banned'] + + # these are tags which have been created by users + # the order is important, and it is the order in which they appear in the tag wrangling interface + USER_DEFINED = ['Fandom', 'Character', 'Relationship', 'Freeform'] + + def self.label_name + to_s.pluralize + end + + delegate :document_type, to: :class + + def document_json + TagIndexer.new({}).document(self) + end + + def self.taggings_count_expiry(count) + # What we are trying to do here is work out a resonable amount of time for a work to be cached for + # This should take the number of taggings and divide it by TAGGINGS_COUNT_CACHE_DIVISOR ( defaults to 1500 ) + # such that for example 1500, would be naturally be tagged for one minute while 105,000 would be cached for + # 70 minutes. However we then apply a filter such that the minimum amount of time we will cache something for + # would be TAGGINGS_COUNT_MIN_TIME ( defaults to 3 minutes ) and the maximum amount of time would be + # TAGGINGS_COUNT_MAX_TIME ( defaulting to an hour ). + expiry_time = count / (ArchiveConfig.TAGGINGS_COUNT_CACHE_DIVISOR || 1500) + [[expiry_time, (ArchiveConfig.TAGGINGS_COUNT_MIN_TIME || 3)].max, (ArchiveConfig.TAGGINGS_COUNT_MAX_TIME || 50) + count % 20 ].min + end + + def taggings_count_cache_key + "/v1/taggings_count/#{id}" + end + + def write_taggings_to_redis(value) + # Atomically set the value while extracting the old value. + old_redis_value = REDIS_GENERAL.getset("tag_update_#{id}_value", value).to_i + + # If the value hasn't changed from the saved version or the REDIS version, + # there's no need to write an update to the database, so let's just bail + # out. + return value if value == old_redis_value && value == taggings_count_cache + + # If we've reached here, then the value has changed, and we need to make + # sure that the new value is written to the database. + REDIS_GENERAL.sadd("tag_update", id) + value + end + + def taggings_count=(value) + expiry_time = Tag.taggings_count_expiry(value) + # Only write to the cache if there are more than a number of uses. + Rails.cache.write(taggings_count_cache_key, value, race_condition_ttl: 10, expires_in: expiry_time.minutes) if value >= ArchiveConfig.TAGGINGS_COUNT_MIN_CACHE_COUNT + write_taggings_to_redis(value) + end + + def taggings_count + cache_read = Rails.cache.read(taggings_count_cache_key) + return cache_read unless cache_read.nil? + real_value = taggings.count + self.taggings_count = real_value + real_value + end + + def update_tag_cache + cache_read = Rails.cache.read(taggings_count_cache_key) + taggings_count if cache_read.nil? || (cache_read < ArchiveConfig.TAGGINGS_COUNT_MIN_CACHE_COUNT) + end + + def update_counts_cache(id) + tag = Tag.find(id) + tag.taggings_count = tag.taggings.count + end + + acts_as_commentable + def commentable_name + self.name + end + + # For a tag, the commentable owners are the wranglers of the fandom(s) + def commentable_owners + # if the tag is a fandom, grab its wranglers or the wranglers of its canonical merger + if self.is_a?(Fandom) + self.canonical? ? self.wranglers : (self.merger_id ? self.merger.wranglers : []) + # if the tag is any other tag, try to grab all the wranglers of all its parent fandoms, if applicable + else + begin + self.fandoms.collect {|f| f.wranglers}.compact.flatten.uniq + rescue + [] + end + end + end + + has_many :mergers, foreign_key: 'merger_id', class_name: 'Tag' + belongs_to :merger, class_name: "Tag" + belongs_to :fandom + belongs_to :media + belongs_to :last_wrangler, polymorphic: true + + has_many :filter_taggings, foreign_key: 'filter_id', dependent: :destroy + has_many :filtered_works, through: :filter_taggings, source: :filterable, source_type: 'Work' + has_many :filtered_external_works, through: :filter_taggings, source: :filterable, source_type: "ExternalWork" + has_many :filtered_collections, through: :filter_taggings, source: :filterable, source_type: "Collection" + + has_one :filter_count, foreign_key: 'filter_id' + has_many :direct_filter_taggings, + -> { where(inherited: 0) }, + class_name: "FilterTagging", + foreign_key: 'filter_id' + + # not used anymore? has_many :direct_filtered_works, through: :direct_filter_taggings, source: :filterable, source_type: 'Work' + + has_many :common_taggings, foreign_key: 'common_tag_id', dependent: :destroy + has_many :child_taggings, class_name: 'CommonTagging', as: :filterable + has_many :children, through: :child_taggings, source: :common_tag + has_many :parents, + through: :common_taggings, + source: :filterable, + source_type: 'Tag', + before_remove: :destroy_common_tagging, + after_remove: :update_wrangler + + has_many :meta_taggings, foreign_key: 'sub_tag_id', dependent: :destroy + has_many :meta_tags, through: :meta_taggings, source: :meta_tag, before_remove: :destroy_meta_tagging + has_many :sub_taggings, class_name: 'MetaTagging', foreign_key: 'meta_tag_id', dependent: :destroy + has_many :sub_tags, through: :sub_taggings, source: :sub_tag, before_remove: :destroy_sub_tagging + has_many :direct_meta_tags, -> { where('meta_taggings.direct = 1') }, through: :meta_taggings, source: :meta_tag + has_many :direct_sub_tags, -> { where('meta_taggings.direct = 1') }, through: :sub_taggings, source: :sub_tag + has_many :taggings, as: :tagger + has_many :works, through: :taggings, source: :taggable, source_type: 'Work' + has_many :collections, through: :taggings, source: :taggable, source_type: "Collection" + + has_many :bookmarks, through: :taggings, source: :taggable, source_type: 'Bookmark' + has_many :external_works, through: :taggings, source: :taggable, source_type: 'ExternalWork' + has_many :approved_collections, through: :filtered_works + + has_many :favorite_tags, dependent: :destroy + + has_many :set_taggings, dependent: :destroy + has_many :tag_sets, through: :set_taggings + has_many :owned_tag_sets, through: :tag_sets + + has_many :tag_set_associations, dependent: :destroy + has_many :parent_tag_set_associations, class_name: 'TagSetAssociation', foreign_key: 'parent_tag_id', dependent: :destroy + + validates :name, presence: true + validates :name, uniqueness: true + validates :name, + length: { minimum: 1, + message: "cannot be blank." } + validates :name, + length: { maximum: ArchiveConfig.TAG_MAX, + message: "^Tag name '%{value}' is too long -- try using less than %{count} characters or using commas to separate your tags." } + validates :name, + format: { with: /\A[^,,、*<>^{}=`\\%]+\z/, + message: "^Tag name '%{value}' cannot include the following restricted characters: , ^ * < > { } = ` , 、 \\ %" } + validates :name, + format: { without: /\A\p{Cf}+\z/, + message: "^Tag name cannot be blank." } + validates :sortable_name, presence: true + + validate :unwrangleable_status + def unwrangleable_status + return unless unwrangleable? + + self.errors.add(:unwrangleable, "can't be set on a canonical or synonymized tag.") if canonical? || merger_id.present? + self.errors.add(:unwrangleable, "can't be set on an unsorted tag.") if is_a?(UnsortedTag) + end + + before_validation :check_synonym + def check_synonym + if !self.new_record? && self.name_changed? + # ordinary wranglers can change case and accents but not punctuation or the actual letters in the name + # admins can change tags with no restriction + unless User.current_user.is_a?(Admin) || only_case_changed? + self.errors.add(:name, "can only be changed by an admin.") + end + end + if self.merger_id + if self.canonical? + self.errors.add(:base, "A canonical can't be a synonym") + end + if self.merger_id == self.id + self.errors.add(:base, "A tag can't be a synonym of itself.") + end + unless self.merger.class == self.class + self.errors.add(:base, "A tag can only be a synonym of a tag in the same category as itself.") + end + end + end + + before_validation :squish_name + def squish_name + self.name = name.squish if self.name + end + + before_validation :set_sortable_name + def set_sortable_name + if sortable_name.blank? + self.sortable_name = remove_articles_from_string(self.name) + end + end + + after_update :queue_flush_work_cache + def queue_flush_work_cache + async_after_commit(:flush_work_cache) if saved_change_to_name? || saved_change_to_type? + end + + def flush_work_cache + self.work_ids.each do |work| + Work.expire_work_blurb_version(work) + end + end + + # queue_flush_work_cache will update the cached work (bookmarkable) info for + # bookmarks, but we still need to expire the portion of bookmark blurbs that + # contains the bookmarker's tags. + after_update :queue_flush_bookmark_cache + def queue_flush_bookmark_cache + async_after_commit(:flush_bookmark_cache) if saved_change_to_name? + end + + def flush_bookmark_cache + self.bookmarks.each do |bookmark| + ActionController::Base.new.expire_fragment("bookmark-owner-blurb-#{bookmark.cache_key}-v3") + ActionController::Base.new.expire_fragment("bookmark-blurb-#{bookmark.cache_key}-v3") + end + end + + before_save :set_last_wrangler + def set_last_wrangler + unless User.current_user.nil? + self.last_wrangler = User.current_user + end + end + def update_wrangler(tag) + unless User.current_user.nil? + self.update(last_wrangler: User.current_user) + end + end + + after_save :check_type_changes, if: :saved_change_to_type? + def check_type_changes + return if type_before_last_save.nil? + + retyped = Tag.find(self.id) + + # Clean up invalid CommonTaggings. + retyped.common_taggings.destroy_invalid + retyped.child_taggings.destroy_invalid + + # If the tag has just become a Fandom, it needs the Uncategorized media + # added to it manually (the after_save hook on Fandom won't take effect, + # since it's not a Fandom yet) + retyped.add_media_for_uncategorized if retyped.is_a?(Fandom) + end + + # Callback for has_many :parents. + # Destroy the common tagging so we trigger CommonTagging's callbacks when a + # parent is removed. We're specifically interested in the update_search + # callback that will reindex the tag and return it to the unwrangled bin. + def destroy_common_tagging(parent) + self.common_taggings.find_by(filterable_id: parent.id).try(:destroy) + end + + scope :id_only, -> { select("tags.id") } + + scope :canonical, -> { where(canonical: true) } + scope :noncanonical, -> { where(canonical: false) } + scope :nonsynonymous, -> { noncanonical.where(merger_id: nil) } + scope :synonymous, -> { noncanonical.where("merger_id IS NOT NULL") } + scope :unfilterable, -> { nonsynonymous.where(unwrangleable: false) } + scope :unwrangleable, -> { where(unwrangleable: true) } + + scope :in_use, -> { where("canonical = 1 OR taggings_count_cache > 0") } + scope :first_class, -> { joins("LEFT JOIN `meta_taggings` ON meta_taggings.sub_tag_id = tags.id").where("meta_taggings.id IS NULL") } + + # Tags that have sub tags + scope :meta_tag, -> { joins(:sub_taggings).where("meta_taggings.id IS NOT NULL").group("tags.id") } + # Tags that don't have sub tags + scope :non_meta_tag, -> { joins(:sub_taggings).where("meta_taggings.id IS NULL").group("tags.id") } + + scope :by_popularity, -> { order('taggings_count_cache DESC') } + scope :by_name, -> { order('sortable_name ASC') } + scope :by_date, -> { order('created_at DESC') } + scope :visible, -> { where('type in (?)', VISIBLE).by_name } + + scope :by_pseud, lambda {|pseud| + joins(works: :pseuds). + where(pseuds: {id: pseud.id}) + } + + scope :by_type, lambda {|*types| where(types.first.blank? ? "" : {type: types.first})} + scope :with_type, lambda {|type| where({type: type}) } + + # This will return all tags that have one of the given tags as a parent + scope :with_parents, lambda {|parents| + joins(:common_taggings).where("filterable_id in (?)", parents.first.is_a?(Integer) ? parents : (parents.respond_to?(:pluck) ? parents.pluck(:id) : parents.collect(&:id))) + } + + scope :with_no_parents, -> { + joins("LEFT JOIN common_taggings ON common_taggings.common_tag_id = tags.id"). + where("filterable_id IS NULL") + } + + scope :starting_with, lambda {|letter| where('SUBSTR(name,1,1) = ?', letter)} + + scope :visible_to_all_with_count, -> { + joins(:filter_count). + select("tags.*, filter_counts.public_works_count as count"). + where('filter_counts.public_works_count > 0 AND tags.canonical = 1') + } + + scope :visible_to_registered_user_with_count, -> { + joins(:filter_count). + select("tags.*, filter_counts.unhidden_works_count as count"). + where('filter_counts.unhidden_works_count > 0 AND tags.canonical = 1') + } + + scope :public_top, lambda { |tag_count| + visible_to_all_with_count. + limit(tag_count). + order('filter_counts.public_works_count DESC') + } + + scope :unhidden_top, lambda { |tag_count| + visible_to_registered_user_with_count. + limit(tag_count). + order('filter_counts.unhidden_works_count DESC') + } + + scope :popular, -> { + (User.current_user.is_a?(Admin) || User.current_user.is_a?(User)) ? + visible_to_registered_user_with_count.order('filter_counts.unhidden_works_count DESC') : + visible_to_all_with_count.order('filter_counts.public_works_count DESC') + } + + scope :random, -> { + (User.current_user.is_a?(Admin) || User.current_user.is_a?(User)) ? + visible_to_registered_user_with_count.random_order : + visible_to_all_with_count.random_order + } + + scope :with_count, -> { + (User.current_user.is_a?(Admin) || User.current_user.is_a?(User)) ? + visible_to_registered_user_with_count : visible_to_all_with_count + } + + scope :for_collections, lambda { |collections| + joins(filtered_works: :approved_collection_items).merge(Work.posted) + .where("collection_items.collection_id IN (?)", collections.collect(&:id)) + } + + scope :for_collection, lambda { |collection| for_collections([collection]) } + + scope :for_collections_with_count, lambda { |collections| + for_collections(collections). + select("tags.*, count(tags.id) as count"). + group(:id). + order(:name) + } + + scope :with_scoped_count, lambda { + select("tags.*, count(tags.id) as count"). + group(:id) + } + + scope :by_relationships, lambda {|relationships| + select("DISTINCT tags.*"). + joins(:children). + where('children_tags.id IN (?)', relationships.collect(&:id)) + } + + # Get the tags for a challenge's signups, checking both the main tag set + # and the optional tag set for each prompt + def self.in_challenge(collection, prompt_type=nil) + ['', 'optional_'].map { |tag_set_type| + join = "INNER JOIN set_taggings ON (tags.id = set_taggings.tag_id) + INNER JOIN tag_sets ON (set_taggings.tag_set_id = tag_sets.id) + INNER JOIN prompts ON (prompts.#{tag_set_type}tag_set_id = tag_sets.id) + INNER JOIN challenge_signups ON (prompts.challenge_signup_id = challenge_signups.id)" + + tags = self.joins(join).where("challenge_signups.collection_id = ?", collection.id) + tags = tags.where("prompts.type = ?", prompt_type) if prompt_type.present? + tags + }.flatten.compact.uniq + end + + scope :requested_in_challenge, lambda {|collection| + in_challenge(collection, 'Request') + } + + scope :offered_in_challenge, lambda {|collection| + in_challenge(collection, 'Offer') + } + + # Code for delayed jobs: + include AsyncWithActiveJob + self.async_job_class = TagMethodJob + + # Class methods + + + def self.in_prompt_restriction(restriction) + joins("INNER JOIN set_taggings ON set_taggings.tag_id = tags.id + INNER JOIN tag_sets ON tag_sets.id = set_taggings.tag_set_id + INNER JOIN owned_tag_sets ON owned_tag_sets.tag_set_id = tag_sets.id + INNER JOIN owned_set_taggings ON owned_set_taggings.owned_tag_set_id = owned_tag_sets.id + INNER JOIN prompt_restrictions ON (prompt_restrictions.id = owned_set_taggings.set_taggable_id AND owned_set_taggings.set_taggable_type = 'PromptRestriction')"). + where("prompt_restrictions.id = ?", restriction.id) + end + + def self.by_name_without_articles(fieldname = "name") + fieldname = "name" unless fieldname.match(/^([\w]+\.)?[\w]+$/) + order(Arel.sql("case when lower(substring(#{fieldname} from 1 for 4)) = 'the ' then substring(#{fieldname} from 5) + when lower(substring(#{fieldname} from 1 for 2)) = 'a ' then substring(#{fieldname} from 3) + when lower(substring(#{fieldname} from 1 for 3)) = 'an ' then substring(#{fieldname} from 4) + else #{fieldname} + end")) + end + + def self.in_tag_set(tag_set) + if tag_set.is_a?(OwnedTagSet) + joins(:set_taggings).where("set_taggings.tag_set_id = ?", tag_set.tag_set_id) + else + joins(:set_taggings).where("set_taggings.tag_set_id = ?", tag_set.id) + end + end + + # gives you [parent_name, child_name], [parent_name, child_name], ... + def self.parent_names(parent_type = 'fandom') + joins(:parents).where("parents_tags.type = ?", parent_type.capitalize). + select("parents_tags.name as parent_name, tags.name as child_name"). + by_name_without_articles("parent_name"). + by_name_without_articles("child_name") + end + + # Because this can be called by a gigantor tag set and all we need are names not objects, + # we do an end-run around ActiveRecord and just get the results straight from the db, but + # we borrow the sql from parent_names above + # returns a hash[parent_name] = child_names + def self.names_by_parent(child_relation, parent_type = 'fandom') + hash = {} + results = ActiveRecord::Base.connection.execute(child_relation.parent_names(parent_type).to_sql) + results.each {|row| hash[row.first] ||= Array.new; hash[row.first] << row.second} + hash + end + + # Used for associations, such as work.fandoms.string + # Yields a comma-separated list of tag names + def self.string + all.map{|tag| tag.name}.join(ArchiveConfig.DELIMITER_FOR_OUTPUT) + end + + # Use the tag name in urls and escape url-unfriendly characters + def to_param + # can't find a tag with a name that hasn't been saved yet + saved_name = self.name_changed? ? self.name_was : self.name + saved_name.gsub('/', '*s*').gsub('&', '*a*').gsub('.', '*d*').gsub('?', '*q*').gsub('#', '*h*') + end + + def display_name + name + end + + # Make sure that the global ID doesn't depend on the type, so that we don't + # experience errors when switching types: + def to_global_id(options = {}) + GlobalID.create(becomes(Tag), options) + end + + ## AUTOCOMPLETE + # set up autocomplete and override some methods + include AutocompleteSource + def autocomplete_prefixes + prefixes = [ "autocomplete_tag_#{type.downcase}", "autocomplete_tag_all" ] + prefixes + end + + def add_to_autocomplete(score = nil) + if eligible_for_fandom_autocomplete? + parents.each do |parent| + add_to_fandom_autocomplete(parent, score) if parent.is_a?(Fandom) + end + end + super + end + + def add_to_fandom_autocomplete(fandom, score = nil) + score ||= autocomplete_score + REDIS_AUTOCOMPLETE.zadd(self.transliterate("autocomplete_fandom_#{fandom.name.downcase}_#{type.downcase}"), score, autocomplete_value) + end + + def remove_from_autocomplete + super + + return unless was_eligible_for_fandom_autocomplete? + + parents.each do |parent| + remove_from_fandom_autocomplete(parent) if parent.is_a?(Fandom) + end + end + + def remove_from_fandom_autocomplete(fandom) + REDIS_AUTOCOMPLETE.zrem(self.transliterate("autocomplete_fandom_#{fandom.name.downcase}_#{type.downcase}"), autocomplete_value) + end + + def eligible_for_fandom_autocomplete? + (self.is_a?(Character) || self.is_a?(Relationship)) && canonical + end + + def was_eligible_for_fandom_autocomplete? + (self.is_a?(Character) || self.is_a?(Relationship)) && (canonical || canonical_before_last_save) + end + + def remove_stale_from_autocomplete + super + + return unless was_eligible_for_fandom_autocomplete? + + parents.each do |parent| + REDIS_AUTOCOMPLETE.zrem(self.transliterate("autocomplete_fandom_#{parent.name.downcase}_#{type.downcase}"), autocomplete_value_before_last_save) if parent.is_a?(Fandom) + end + end + + def self.parse_autocomplete_value(current_autocomplete_value) + current_autocomplete_value.split(AUTOCOMPLETE_DELIMITER, 2) + end + + + def autocomplete_score + taggings_count_cache + end + + # look up tags that have been wrangled into a given fandom + def self.autocomplete_fandom_lookup(options = {}) + options.reverse_merge!({term: "", tag_type: "character", fandom: "", fallback: true}) + search_param = options[:term] + tag_type = options[:tag_type] + fandoms = Tag.get_search_terms(options[:fandom]) + + # fandom sets are too small to bother breaking up + # we're just getting ALL the tags in the set(s) for the fandom(s) and then manually matching + results = [] + fandoms.each do |single_fandom| + if search_param.blank? + # just return ALL the characters + results += REDIS_AUTOCOMPLETE.zrevrange(self.transliterate("autocomplete_fandom_#{single_fandom}_#{tag_type}"), 0, -1) + else + search_regex = Tag.get_search_regex(search_param) + results += REDIS_AUTOCOMPLETE.zrevrange(self.transliterate("autocomplete_fandom_#{single_fandom}_#{tag_type}"), 0, -1).select { |tag| tag.match(search_regex) } + end + end + if options[:fallback] && results.empty? && search_param.length > 0 + # do a standard tag lookup instead + Tag.autocomplete_lookup(search_param: search_param, autocomplete_prefix: "autocomplete_tag_#{tag_type}") + else + results + end + end + + ## END AUTOCOMPLETE + + # Substitute characters that are particularly prone to cause trouble in urls + def self.find_by_name(string) + return unless string.is_a? String + + self.find_by(name: from_param(string)) + end + + def self.find_by_name!(string) + return unless string.is_a? String + + self.find_by!(name: from_param(string)) + end + + def self.from_param(string) + string.gsub( + /\*[sadqh]\*/, + '*s*' => '/', + '*a*' => '&', + '*d*' => '.', + '*q*' => '?', + '*h*' => '#' + ) + end + + # If a tag by this name exists in another class, add a suffix to disambiguate them + def self.find_or_create_by_name(new_name) + if new_name && new_name.is_a?(String) + new_name.squish! + tag = Tag.find_by_name(new_name) + # if the tag exists and has the proper class, or it is an unsorted tag and it can be sorted to the self class + if tag && (tag.class == self || tag.class == UnsortedTag && tag = tag.recategorize(self.to_s)) + tag + elsif tag + self.find_or_create_by_name(new_name + " - " + self.to_s) + else + self.create(name: new_name, type: self.to_s) + end + end + end + + def self.create_canonical(name, adult=false) + tag = self.find_or_create_by_name(name) + raise "how did this happen?" unless tag + tag.update_attribute(:canonical,true) + tag.update_attribute(:adult, adult) + raise "how did this happen?" unless tag.canonical? + return tag + end + + # Inherited tag classes can set this to indicate types of tags with which they may have a parent/child + # relationship (ie. media: parent, fandom: child; fandom: parent, character: child) + def parent_types + [] + end + def child_types + [] + end + + # Instance methods that are common to all subclasses (may be overridden in the subclass) + + def unfilterable? + !(self.canonical? || self.unwrangleable? || self.merger_id.present? || self.mergers.any?) + end + + # Returns true if a tag has been used in posted works that are revealed and not hidden + def has_posted_works? # rubocop:disable Naming/PredicateName + self.works.posted.revealed.unhidden.any? + end + + # sort tags by name + def <=>(another_tag) + name.downcase <=> another_tag.name.downcase + end + + # only allow changing the tag type for unwrangled tags not used in any tag sets or on any works + def can_change_type? + self.unfilterable? && self.set_taggings.count == 0 && self.works.count == 0 + end + + # tags having their type changed need to be reloaded to be seen as an instance of the proper subclass + def recategorize(new_type) + self.update_attribute(:type, new_type) + # return a new instance of the tag, with the correct class + Tag.find(self.id) + end + + #### FILTERING #### + + before_update :reindex_associated_for_name_or_type_change + def reindex_associated_for_name_or_type_change + return unless name_changed? || type_changed? + + reindex_pseuds = (type == "Fandom") || (type_was == "Fandom") + async_after_commit(:reindex_associated, reindex_pseuds) + end + + # Reindex anything even remotely related to this tag. This is overkill in + # most cases, but necessary when something fundamental like the name or type + # of a tag has changed. + def reindex_associated(reindex_pseuds = false) + works.reindex_all + external_works.reindex_all + bookmarks.reindex_all + + filtered_works.reindex_all + filtered_external_works.reindex_all + + Series.joins(works: :taggings) + .merge(self.taggings).reindex_all + Series.joins(works: :filter_taggings) + .merge(self.filter_taggings).reindex_all + + # We only want to reindex pseuds if this tag is a Fandom. Unfortunately, we + # can't just check the current type, because tags can change type, and we'd + # still need to reindex if the old type was Fandom. So we have an option to + # control it. + if reindex_pseuds + Pseud.joins(works: :filter_taggings) + .merge(self.direct_filter_taggings).reindex_all + end + end + + # The version of the tag that should be used for filtering, if any + def filter + self.canonical? ? self : ((self.merger && self.merger.canonical?) ? self.merger : nil) + end + + # Update filters for all works and external works directly tagged with this + # tag. + def update_filters_for_taggables + works.update_filters + external_works.update_filters + collections.update_filters + end + + # Update filters for all works and external works that already have this tag + # as one of their filters. + def update_filters_for_filterables + filtered_works.update_filters + filtered_external_works.update_filters + filtered_collections.update_filters + end + + # When canonical or merger_id changes, only the items directly tagged with + # this tag need their filters updated, so we queue up a call to + # update_filters_for_taggables after commit. + # + # Note that when a tag becomes non-canonical, all of its filter-taggings need + # to be deleted. But when a tag becomes non-canonical, all of its mergers and + # sub-tags will be deleted, which will result in the necessary items having + # their filters fixed. + after_update :update_filters_for_canonical_or_merger_change + def update_filters_for_canonical_or_merger_change + return unless saved_change_to_canonical? || saved_change_to_merger_id? + + async_after_commit(:update_filters_for_taggables) + end + + # Recalculate the inherited metatags for this tag, and once those changes + # are committed, update the filters for every work or external work that's + # filter-tagged with this tag. + def update_inherited_meta_tags + MetaTagging.transaction do + InheritedMetaTagUpdater.new(self).update + + sub_tags.find_each do |sub_tag| + InheritedMetaTagUpdater.new(sub_tag).update + end + end + + async_after_commit(:update_filters_for_filterables) + end + + # When deleting a metatag, we destroy the meta-tagging first to trigger the + # appropriate destroy callback. + def destroy_meta_tagging(meta_tag) + meta_taggings.find_by(meta_tag: meta_tag)&.destroy + end + + # When deleting a subtag, we destroy the sub-tagging first to trigger the + # appropriate destroy callback. + def destroy_sub_tagging(sub_tag) + sub_taggings.find_by(sub_tag: sub_tag)&.destroy + end + + def reset_filter_count + FilterCount.enqueue_filter(filter) + end + + #### END FILTERING #### + + # methods for counting visible + + def visible_works_count + User.current_user.nil? ? self.works.posted.unhidden.unrestricted.count : self.works.posted.unhidden.count + end + + def visible_bookmarks_count + self.bookmarks.is_public.count + end + + def visible_external_works_count + self.external_works.where(hidden_by_admin: false).count + end + + def banned + self.is_a?(Banned) + end + + def synonyms + self.canonical? ? self.mergers : [self.merger] + self.merger.mergers - [self] + end + + # Add a common tagging association + def add_association(tag) + build_association(tag).save + end + + def has_parent?(tag) + self.common_taggings.where(filterable_id: tag.id).count > 0 + end + + def has_child?(tag) + self.child_taggings.where(common_tag_id: tag.id).count > 0 + end + + def associations_to_remove; @associations_to_remove ? @associations_to_remove : []; end + def associations_to_remove=(taglist) + taglist.reject {|tid| tid.blank?}.each do |tag_id| + remove_association(tag_id) + end + end + + # Determine how two tags are related and divorce them from each other + def remove_association(tag_id) + tag = Tag.find(tag_id) + + if tag.class == self.class + tag.update(merger: nil) if tag.merger == self + meta_taggings.where(direct: true, meta_tag: tag).destroy_all + sub_taggings.where(direct: true, sub_tag: tag).destroy_all + else + common_taggings.where(filterable: tag).destroy_all + child_taggings.where(common_tag: tag).destroy_all + end + + tag.touch + self.touch + end + + # When canonical or merger is changed, we need to make sure that the + # associations (parents, children, metatags, mergers) are fixed. Note that + # these are all async calls, so we use async_after_commit to reduce the + # likelihood of issues with stale data. + before_update :update_associations_for_canonical_or_merger_change + def update_associations_for_canonical_or_merger_change + if (merger_id_changed? && merger_id.present?) || + (canonical_changed? && !canonical?) + async_after_commit(:transfer_or_remove_favorite_tags) + async_after_commit(:transfer_or_remove_associations) + end + end + + # Make it possible to go from a synonym to a canonical in one step. + before_validation :reset_merger_when_becoming_canonical + def reset_merger_when_becoming_canonical + return unless self.canonical_changed? && self.canonical? + + self.merger_id = nil + end + + # If this tag has a canonical merger, transfer associations to the merger. + # Then, regardless of whether it has a merger, delete all canonical + # associations (i.e. meta taggings, and associations where this tag is the + # parent). + def transfer_or_remove_associations + transaction do + # Try to prevent some concurrency issues. + lock! + + # Abort if the tag has changed back to being canonical between the time + # this was enqueued and the time it ran. + return if self.canonical? + + add_associations_to_merger if self.merger&.canonical? + + self.mergers.find_each { |tag| tag.update(merger_id: nil) } + self.child_taggings.destroy_all + self.sub_taggings.destroy_all + self.meta_taggings.destroy_all + end + end + + # When we make this tag a synonym of another canonical tag, we want to move + # all the associations this tag has (subtags, metatags, etc) over to that + # canonical tag. + # + # The callbacks that occur when changing the associations will trigger the + # necessary reindexing, so we don't need to call extra reindexing code here. + def add_associations_to_merger + self.parents.find_each do |tag| + self.merger.add_association(tag) + end + + self.children.find_each do |tag| + self.merger.add_association(tag) + end + + self.mergers.find_each { |tag| tag.update(merger: self.merger) } + + merger.parents.where(type: %w[Media Fandom]).find_each do |tag| + self.add_association(tag) + end + + self.direct_meta_tags.find_each do |tag| + meta_tagging = self.merger.meta_taggings.find_or_initialize_by(meta_tag: tag) + meta_tagging.update(direct: true) + end + + self.direct_sub_tags.find_each do |tag| + sub_tagging = self.merger.sub_taggings.find_or_initialize_by(sub_tag: tag) + sub_tagging.update(direct: true) + end + end + + # If this tag has a canonical merger, move all favorite tags to the merger. + # Otherwise, delete all favorite tags. + def transfer_or_remove_favorite_tags + if merger&.canonical + favorite_tags.find_each do |ft| + ft.update(tag_id: merger_id) + end + end + + # We perform this after the if (instead of as a separate branch) because + # updating the tag_id can fail if the user has both this tag and its merger + # as favorite tags. So we want to clean up any failures, which just so + # happens to be exactly the same thing we need to do if there's no + # canonical merger to transfer the favorite tags to. + favorite_tags.find_each(&:destroy) + end + + attr_reader :meta_tag_string, :sub_tag_string, :merger_string + + # Uses the value of parent_types to determine whether the passed-in tag + # should be added as a parent or a child, and then generates the association + # (if it doesn't already exist). If it does already exist, returns the + # existing CommonTagging object. + def build_association(tag) + if parent_types.include?(tag&.type) + common_taggings.find_or_initialize_by(filterable: tag) + else + child_taggings.find_or_initialize_by(common_tag: tag) + end + end + + # Splits up the passed-in string into a sequence of individual tag names, + # then finds (and yields) the tag for each. Used by add_association_string, + # meta_tag_string=, and sub_tag_string=. + def parse_tag_string(tag_string) + tag_string.split(",").map(&:squish).each do |name| + yield name, Tag.find_by_name(name) + end + end + + # Try to create new associations with the tags of type tag_type whose names + # are listed in tag_string. + def add_association_string(tag_type, tag_string) + parse_tag_string(tag_string) do |name, parent| + prefix = "Cannot add association to '#{name}':" + if parent && parent.type != tag_type + errors.add(:base, "#{prefix} #{parent.type} added in #{tag_type} field.") + else + association = build_association(parent) + save_and_gather_errors(association, prefix) + end + end + end + + # Save an item to the database, if it's valid. If it's invalid, read in the + # error messages from the item and copy them over to this tag. + def save_and_gather_errors(item, prefix) + return unless item.new_record? || item.changed? + return if item.valid? && item.save + + item.errors.full_messages.each do |message| + errors.add(:base, "#{prefix} #{message}") + end + end + + # Find and destroy all invalid CommonTaggings and MetaTaggings associated + # with this tag. + def destroy_invalid_associations + common_taggings.destroy_invalid + child_taggings.destroy_invalid + meta_taggings.destroy_invalid + sub_taggings.destroy_invalid + end + + # defines fandom_string=, media_string=, character_string=, relationship_string=, freeform_string= + %w(Fandom Media Character Relationship Freeform).each do |tag_type| + attr_reader "#{tag_type.downcase}_string" + + define_method("#{tag_type.downcase}_string=") do |tag_string| + add_association_string(tag_type, tag_string) + end + end + + def meta_tag_string=(tag_string) + parse_tag_string(tag_string) do |name, parent| + meta_tagging = meta_taggings.find_or_initialize_by(meta_tag: parent) + meta_tagging.direct = true + save_and_gather_errors(meta_tagging, "Invalid metatag '#{name}':") + end + end + + def sub_tag_string=(tag_string) + parse_tag_string(tag_string) do |name, sub| + sub_tagging = sub_taggings.find_or_initialize_by(sub_tag: sub) + sub_tagging.direct = true + save_and_gather_errors(sub_tagging, "Invalid subtag '#{name}':") + end + end + + def syn_string + self.merger.name if self.merger + end + + # Make this tag a synonym of another tag -- tag_string is the name of the other tag (which should be canonical) + # NOTE for potential confusion + # "merger" is the canonical tag of which this one will be a synonym + # "mergers" are the tags which are (currently) synonyms of THIS one + def syn_string=(tag_string) + # If the tag_string is blank, our tag should be given no merger + if tag_string.blank? + self.merger_id = nil + return + end + + new_merger = Tag.find_by(name: tag_string) + + # Bail out if the new merger is the same as the current merger + return if new_merger && new_merger == self.merger + + # Return an error if a non-admin tries to make a canonical into a synonym + if self.canonical? && !User.current_user.is_a?(Admin) + self.errors.add(:base, "Only an admin can make a canonical tag into a synonym of another tag.") + return + end + + if new_merger && new_merger == self + self.errors.add(:base, tag_string + " is considered the same as " + self.name + " by the database.") + elsif new_merger && !new_merger.canonical? + self.errors.add(:base, "
    #{new_merger.name} is not a canonical tag. Please make it canonical before adding synonyms to it.") + elsif new_merger && new_merger.class != self.class + self.errors.add(:base, new_merger.name + " is a #{new_merger.type.to_s.downcase}. Synonyms must belong to the same category.") + elsif !new_merger + new_merger = self.class.new(name: tag_string, canonical: true) + unless new_merger.save + self.errors.add(:base, tag_string + " could not be saved. Please make sure that it's a valid tag name.") + end + end + + # If we don't have any errors, update the tag to add the new merger + if new_merger && self.errors.empty? + self.canonical = false + self.merger_id = new_merger.id + end + end + + def merger_string=(tag_string) + names = tag_string.split(',').map(&:squish) + names.each do |name| + syn = Tag.find_by_name(name) + if syn && !syn.canonical? + syn.update(merger_id: self.id) + end + end + end + + # unwrangleable: + # - A boolean stored in the tags table + # - Default false + # - Set to true by wranglers on tags that should be excluded from the wrangling process altogether. Example: freeform tags like "idk how to explain it but trust me" + # + # unwrangled: + # - A computed value + # - True for "orphan" tags yet to be tied to something (fandom, character, etc.) by wranglers + # - Exact meaning may change depending on the nature of the tag (search for definitions of unwrangled? overriding this one) + # + def unwrangled? + common_taggings.empty? + end + + ################################# + ## SEARCH ####################### + ################################# + + def unwrangled_query(tag_type, options = {}) + self_type = %w[Character Fandom Media].include?(self.type) ? self.type.downcase : "fandom" + TagQuery.new(options.merge( + type: tag_type, + unwrangleable: false, + wrangled: false, + has_posted_works: true, + "pre_#{self_type}_ids": [self.id], + per_page: Tag.per_page + )) + end + + def unwrangled_tags(tag_type, options = {}) + unwrangled_query(tag_type, options).search_results + end + + def unwrangled_tag_count(tag_type) + key = "unwrangled_#{tag_type}_#{self.id}_#{self.updated_at}" + Rails.cache.fetch(key, expires_in: 4.hours) do + unwrangled_query(tag_type).count + end + end + + def suggested_parent_tags(parent_type, options = {}) + limit = options[:limit] || 50 + work_ids = works.limit(limit).pluck(:id) + Tag.distinct.joins(:taggings).where( + "tags.type" => parent_type, + taggings: { + taggable_type: 'Work', + taggable_id: work_ids + } + ) + end + + # For works that haven't been wrangled yet, get the fandom/character tags + # that are used on their works as a place to start + def suggested_parent_ids(parent_type) + return [] if !parent_types.include?(parent_type) || + unwrangleable? || + parents.by_type(parent_type).exists? + + suggested_parent_tags(parent_type).pluck(:id, :merger_id). + flatten.compact.uniq + end + + def queue_child_tags_for_reindex + all_with_child_type = Tag.where(type: child_types & Tag::USER_DEFINED) + works.select(:id).find_in_batches do |batch| + relevant_taggings = Tagging.where(taggable: batch) + tag_ids = all_with_child_type.joins(:taggings).merge(relevant_taggings).distinct.pluck(:id) + IndexQueue.enqueue_ids(Tag, tag_ids, :background) + end + end + + after_create :after_create + def after_create + tag = self + if tag.canonical + tag.add_to_autocomplete + end + end + + after_update :after_update + def after_update + tag = self + if tag.saved_change_to_canonical? + if tag.canonical + # newly canonical tag + tag.add_to_autocomplete + else + # decanonicalised tag + tag.remove_from_autocomplete + end + else + tag.refresh_autocomplete + end + + # Expire caching when a merger is added or removed + if tag.saved_change_to_merger_id? + if tag.merger_id_before_last_save.present? + old = Tag.find(tag.merger_id_before_last_save) + old.update_works_index_timestamp! + end + if tag.merger_id.present? + tag.merger.update_works_index_timestamp! + end + async_after_commit(:queue_child_tags_for_reindex) + end + + # if type has changed, expire the tag's parents' children cache (it stores the children's type) + if tag.saved_change_to_type? + tag.parents.each do |parent_tag| + ActionController::Base.new.expire_fragment("views/tags/#{parent_tag.id}/children") + end + end + + # Reindex immediately to update the unwrangled bin. + if tag.saved_change_to_unwrangleable? + tag.reindex_document + end + end + + def refresh_autocomplete + return unless canonical + + remove_stale_from_autocomplete + add_to_autocomplete + end + + before_destroy :before_destroy + def before_destroy + tag = self + if Tag::USER_DEFINED.include?(tag.type) && tag.canonical + tag.remove_from_autocomplete + end + end + + private + + after_save :update_tag_nominations + def update_tag_nominations + TagNomination.where(tagname: name).update_all( + canonical: canonical, + synonym: merger.nil? ? nil : merger.name, + parented: false, # we'll fix this later in the callback + exists: true + ) + + if canonical? + # Calculate the fandoms associated with this tag, because we'll set any + # TagNominations with a matching parent_tagname to have parented: true. + parent_names = parents.where(type: "Fandom").pluck(:name) + + # If this tag has any fandoms at all, we also want to count it as parented + # for nominations with a blank parent_tagname. See the set_parented + # function in TagNominations for the calculation that we're trying to mimic + # here. + parent_names << "" if parent_names.present? + + TagNomination.where(tagname: name, parent_tagname: parent_names).update_all(parented: true) + end + + return unless saved_change_to_name? && name_before_last_save.present? + + # Act as if the tag with the previous name was deleted and mirror clear_tag_nominations + TagNomination.where(tagname: name_before_last_save).update_all( + canonical: false, + exists: false, + parented: false, + synonym: nil + ) + end + + before_destroy :clear_tag_nominations + def clear_tag_nominations + TagNomination.where(tagname: name).update_all( + canonical: false, + exists: false, + parented: false, + synonym: nil + ) + end + + def only_case_changed? + new_normalized_name = normalize_for_tag_comparison(self.name) + old_normalized_name = normalize_for_tag_comparison(self.name_was) + (self.name.downcase == self.name_was.downcase) || + (new_normalized_name == old_normalized_name) + end + + def normalize_for_tag_comparison(string) + UnicodeUtils.casefold(string).mb_chars.unicode_normalize(:nfkd).gsub(/[\u0300-\u036F]/u, "") + end +end diff --git a/app/models/tagging.rb b/app/models/tagging.rb new file mode 100755 index 0000000..63a1617 --- /dev/null +++ b/app/models/tagging.rb @@ -0,0 +1,45 @@ +class Tagging < ApplicationRecord + belongs_to :tagger, polymorphic: true, inverse_of: :taggings, autosave: true + belongs_to :taggable, polymorphic: true, touch: true, inverse_of: :taggings + + validates_presence_of :tagger, :taggable + + # When we create or destroy a tagging, it may change the taggings count. + after_create :update_taggings_count + after_destroy :update_taggings_count + after_commit :update_search + + after_create :update_filters + after_destroy :update_filters + + def update_filters + return unless taggable.is_a?(Filterable) + + taggable.update_filters + end + + def self.find_by_tag(taggable, tag) + Tagging.find_by(tagger_id: tag.id, taggable_id: taggable.id, tagger_type: 'Tag', taggable_type: taggable.class.name) + end + + # Most of the time, we don't need the taggings_count_cache stored in the + # database to be perfectly accurate. But because of the way Tag.in_use is + # defined and used, the difference between a value of 0 and a value of 1 is + # important. So we make sure to poke the taggings_count cache every time we + # create or destroy a tagging. If it's a large tag, it'll fall back on the + # cached value. If it's a small tag, it'll recompute -- and make sure that it + # handles the transition from 0 uses to 1 use properly. + def update_taggings_count + tagger.update_tag_cache unless tagger.blank? || tagger.destroyed? + end + + def update_search + return unless tagger && Tag::USER_DEFINED.include?(tagger.type) + + # Reindex the tag for updated suggested tags. + # Suggested tags help wranglers figure out where to wrangle new tags + # and if it's necessary to disambiguate existing canonical/unfilterable tags + # in multiple fandoms. + tagger.enqueue_to_index if tagger.taggings_count < ArchiveConfig.TAGGINGS_COUNT_REINDEX_LIMIT + end +end diff --git a/app/models/tagset_models/cast_nomination.rb b/app/models/tagset_models/cast_nomination.rb new file mode 100755 index 0000000..4600934 --- /dev/null +++ b/app/models/tagset_models/cast_nomination.rb @@ -0,0 +1,43 @@ +class CastNomination < TagNomination + belongs_to :tag_set_nomination + has_one :owned_tag_set, through: :tag_set_nomination + belongs_to :fandom_nomination + + validate :known_fandom, unless: :blank_tagname? + def known_fandom + return true if (!parent_tagname.blank? || self.fandom_nomination || from_fandom_nomination) + return true if (tag = Tag.find_by_name(self.tagname)) && tag.parents.any? {|p| p.is_a?(Fandom)} + errors.add(:base, ts("^We need to know what fandom %{tagname} belongs in.", tagname: self.tagname)) + end + + before_save :set_tag_set_nomination + def set_tag_set_nomination + if fandom_nomination && !tag_set_nomination + self.tag_set_nomination = fandom_nomination.tag_set_nomination + end + end + + def get_parent_tagname + self.fandom_nomination ? self.fandom_nomination.tagname : ( + self.parent_tagname.present? ? self.parent_tagname : + Tag.find_by_name(self.tagname).try(:parents).try(:first).try(:name)) + end + + def get_owned_tag_set + @tag_set || self.tag_set_nomination ? self.tag_set_nomination.owned_tag_set : self.fandom_nomination.get_owned_tag_set + end + + def set_approval_status + set_noms = tag_set_nomination + set_noms = fandom_nomination.tag_set_nomination if !set_noms && from_fandom_nomination + # if the fandom is rejected so are we + self.rejected = (from_fandom_nomination && set_noms.owned_tag_set.already_rejected?(get_parent_tagname)) || set_noms.owned_tag_set.already_rejected?(tagname) || false + if self.rejected + self.approved = false + else + self.approved = set_noms.owned_tag_set.already_in_set?(tagname) || (synonym && set_noms.owned_tag_set.already_in_set?(synonym)) || false + end + true + end + +end \ No newline at end of file diff --git a/app/models/tagset_models/character_nomination.rb b/app/models/tagset_models/character_nomination.rb new file mode 100755 index 0000000..1b6c6ec --- /dev/null +++ b/app/models/tagset_models/character_nomination.rb @@ -0,0 +1,5 @@ +class CharacterNomination < CastNomination + belongs_to :tag_set_nomination + belongs_to :fandom_nomination, inverse_of: :character_nominations + has_one :owned_tag_set, through: :tag_set_nomination +end \ No newline at end of file diff --git a/app/models/tagset_models/fandom_nomination.rb b/app/models/tagset_models/fandom_nomination.rb new file mode 100755 index 0000000..bacf92c --- /dev/null +++ b/app/models/tagset_models/fandom_nomination.rb @@ -0,0 +1,34 @@ +class FandomNomination < TagNomination + belongs_to :tag_set_nomination + has_one :owned_tag_set, through: :tag_set_nomination + + has_many :character_nominations, dependent: :destroy, inverse_of: :fandom_nomination + accepts_nested_attributes_for :character_nominations, allow_destroy: true, reject_if: proc { |attrs| attrs[:tagname].blank? && attrs[:id].blank? } + + has_many :relationship_nominations, dependent: :destroy, inverse_of: :fandom_nomination + accepts_nested_attributes_for :relationship_nominations, allow_destroy: true, reject_if: proc { |attrs| attrs[:tagname].blank? && attrs[:id].blank? } + + + def character_tagnames + CharacterNomination.for_tag_set(owned_tag_set).where(parent_tagname: tagname).pluck :tagname + end + + def relationship_tagnames + RelationshipNomination.for_tag_set(owned_tag_set).where(parent_tagname: tagname).pluck :tagname + end + + after_save :reject_children, if: :rejected? + def reject_children + character_nominations.each {|char| char.rejected = true; char.save} + relationship_nominations.each {|rel| rel.rejected = true; rel.save} + true + end + + after_save :update_child_parent_tagnames, if: Proc.new { |nom| nom.saved_change_to_tagname? } + def update_child_parent_tagnames + self.character_nominations.readonly(false).each {|char| char.parent_tagname = self.tagname; char.save} + self.relationship_nominations.readonly(false).each {|rel| rel.parent_tagname = self.tagname; rel.save} + true + end + +end diff --git a/app/models/tagset_models/freeform_nomination.rb b/app/models/tagset_models/freeform_nomination.rb new file mode 100755 index 0000000..c1063af --- /dev/null +++ b/app/models/tagset_models/freeform_nomination.rb @@ -0,0 +1,5 @@ +class FreeformNomination < TagNomination + belongs_to :tag_set_nomination #, inverse_of: :freeform_nominations + has_one :owned_tag_set, through: :tag_set_nomination #, inverse_of: :freeform_nominations + +end \ No newline at end of file diff --git a/app/models/tagset_models/owned_set_tagging.rb b/app/models/tagset_models/owned_set_tagging.rb new file mode 100755 index 0000000..39a8815 --- /dev/null +++ b/app/models/tagset_models/owned_set_tagging.rb @@ -0,0 +1,6 @@ +class OwnedSetTagging < ApplicationRecord + belongs_to :owned_tag_set + belongs_to :set_taggable, polymorphic: :true + + validates_uniqueness_of :owned_tag_set_id, scope: [:set_taggable_id, :set_taggable_type], message: ts("^That tag set is already being used here.") +end diff --git a/app/models/tagset_models/owned_tag_set.rb b/app/models/tagset_models/owned_tag_set.rb new file mode 100755 index 0000000..89382a8 --- /dev/null +++ b/app/models/tagset_models/owned_tag_set.rb @@ -0,0 +1,279 @@ +class OwnedTagSet < ApplicationRecord + # Rather than use STI or polymorphic associations, since really what we want to do here + # is build an extra layer of functionality on top of the generic tag set structure, + # I've gone with creating a separate model and making it contain a generic tag set + # as a member. This way we don't have to duplicate the tag set code or functionality + # and can just add on the extra stuff without cramming the tag set table full of empty + # unused fields and having the controller have to sift out all the generic tag sets + # being used in prompts. + # -- NN May 2011 + + belongs_to :tag_set, dependent: :destroy + accepts_nested_attributes_for :tag_set + + # delegate the tag set commands + delegate :tags, :with_type, :has_type?, to: :tag_set, allow_nil: true + + has_many :tag_set_associations, dependent: :destroy + accepts_nested_attributes_for :tag_set_associations, allow_destroy: true, + reject_if: proc { |attrs| !attrs[:create_association] || attrs[:tag_id].blank? || (attrs[:parent_tag_id].blank? && attrs[:parent_tagname].blank?) } + + has_many :tag_set_nominations, dependent: :destroy + has_many :tag_nominations, through: :tag_set_nominations, dependent: :destroy + has_many :fandom_nominations, through: :tag_set_nominations + has_many :character_nominations, through: :tag_set_nominations + has_many :relationship_nominations, through: :tag_set_nominations + has_many :freeform_nominations, through: :tag_set_nominations + + has_many :tag_set_ownerships, dependent: :destroy + has_many :moderators, -> { where('tag_set_ownerships.owner = ?', false) }, through: :tag_set_ownerships, source: :pseud + has_many :owners, -> { where('tag_set_ownerships.owner = ?', true) }, through: :tag_set_ownerships, source: :pseud + + has_many :owned_set_taggings, dependent: :destroy + has_many :set_taggables, through: :owned_set_taggings + + validates_presence_of :title, message: ts("^Please enter a title for your tag set.") + validates :title, uniqueness: { message: ts("^Sorry, that name is already taken. Try again, please!") } + validates_length_of :title, + minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) + validates_length_of :title, + maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) + validates_format_of :title, + with: /\A[^,*<>^{}=`\\%]+\z/, + message: '^The title of a tag set cannot include the following restricted characters: , ^ * < > { } = ` \\ %' + + validates_length_of :description, + allow_blank: true, + maximum: ArchiveConfig.SUMMARY_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.SUMMARY_MAX) + + validates_numericality_of :fandom_nomination_limit, :character_nomination_limit, :relationship_nomination_limit, :freeform_nomination_limit, + only_integer: true, less_than_or_equal_to: 20, greater_than_or_equal_to: 0, + message: ts('must be an integer between 0 and 20.') + + + after_update :cleanup_outdated_associations + def cleanup_outdated_associations + tag_ids = SetTagging.where(tag_set_id: self.tag_set.id).collect(&:tag_id) + TagSetAssociation.where(owned_tag_set_id: self.id).where("tag_id NOT IN (?) OR parent_tag_id NOT IN (?)", tag_ids, tag_ids).delete_all + end + + validate :no_midstream_nomination_changes + def no_midstream_nomination_changes + if !self.tag_set_nominations.empty? && + %w(fandom_nomination_limit character_nomination_limit relationship_nomination_limit freeform_nomination_limit).any? {|field| self.changed.include?(field)} + errors.add(:base, ts("You cannot make changes to nomination settings when nominations already exist. Please review and delete existing nominations first.")) + end + end + + def add_tagnames(tag_type, tagnames_to_add) + return true if tagnames_to_add.blank? + self.tag_set.send("#{tag_type}_tagnames_to_add=", tagnames_to_add) + return false unless self.tag_set.save && self.save + + # update the nominations -- approve any where an approved tag was either a synonym or the tag itself + TagNomination.for_tag_set(self).where(type: "#{tag_type.classify}Nomination").where("tagname IN (?)", tagnames_to_add).where(rejected: false).update_all(approved: true) + true + end + + def remove_tagnames(tag_type, tagnames_to_remove) + return true if tagnames_to_remove.blank? + self.tag_set.tagnames_to_remove = tagnames_to_remove.join(',') + return false unless self.save + TagNomination.for_tag_set(self).where(type: "#{tag_type.classify}Nomination").where("tagname IN (?)", tagnames_to_remove).where(approved: false).update_all(rejected: true) + + if tag_type == "fandom" + # reject children of rejected fandom + TagNomination.for_tag_set(self).where(type: "#{tag_type.classify}Nomination").where("tagname IN (?)", tagnames_to_remove).each do |rejected_fandom_nom| + rejected_fandom_nom.reject_children + end + end + + true + end + + def self.owned_by(user = User.current_user) + if user.is_a?(User) + select("DISTINCT owned_tag_sets.*"). + joins("INNER JOIN tag_set_ownerships ON owned_tag_sets.id = tag_set_ownerships.owned_tag_set_id + INNER JOIN pseuds ON tag_set_ownerships.pseud_id = pseuds.id + INNER JOIN users ON pseuds.user_id = users.id"). + where("users.id = ?", user.id) + end + end + + def self.visible(user = User.current_user) + if user.is_a?(User) + select("DISTINCT owned_tag_sets.*"). + joins("INNER JOIN tag_set_ownerships ON owned_tag_sets.id = tag_set_ownerships.owned_tag_set_id + INNER JOIN pseuds ON tag_set_ownerships.pseud_id = pseuds.id + INNER JOIN users ON pseuds.user_id = users.id"). + where("owned_tag_sets.visible = true OR users.id = ?", user.id) + else + where("owned_tag_sets.visible = true") + end + end + + def self.usable(user = User.current_user) + if user.is_a?(User) + select("DISTINCT owned_tag_sets.*"). + joins("INNER JOIN tag_set_ownerships ON owned_tag_sets.id = tag_set_ownerships.owned_tag_set_id + INNER JOIN pseuds ON tag_set_ownerships.pseud_id = pseuds.id + INNER JOIN users ON pseuds.user_id = users.id"). + where("owned_tag_sets.usable = true OR users.id = ?", user.id) + else + where("owned_tag_sets.usable = true") + end + end + + def self.in_prompt_restriction(restriction) + joins(:owned_set_taggings). + where("owned_set_taggings.set_taggable_type = ?", restriction.class.to_s). + where("owned_set_taggings.set_taggable_id = ?", restriction.id) + end + + #### MODERATOR/OWNER + + def user_is_owner?(user) + user.is_a?(User) && !(owners & user.pseuds).empty? + end + + def user_is_moderator?(user) + user.is_a?(User) && (user_is_owner?(user) || !(moderators & user.pseuds).empty?) + end + + def add_owner(pseud) + tag_set_ownerships.build({pseud: pseud, owner: true}) + end + + def add_moderator(pseud) + tag_set_ownerships.build({pseud: pseud, owner: false}) + end + + def owner_changes=(pseud_list) + Pseud.parse_bylines(pseud_list)[:pseuds].each do |pseud| + if self.owners.include?(pseud) + self.owners -= [pseud] if self.owners.count > 1 + else + self.moderators -= [pseud] if self.moderators.include?(pseud) + add_owner(pseud) + end + end + end + + def moderator_changes=(pseud_list) + Pseud.parse_bylines(pseud_list)[:pseuds].each do |pseud| + if self.moderators.include?(pseud) + self.moderators -= [pseud] + else + add_moderator(pseud) unless self.owners.include?(pseud) + end + end + end + + def owner_changes; nil; end + def moderator_changes; nil; end + + ##### MANAGING NOMINATIONS + + # we can use redis to speed this up since tagset data is loaded there for autocomplete + def already_in_set?(tagname) + tags_in_set.where("tags.name = ?", tagname).exists? + end + + # returns an array of arrays [id, name] + def tags_in_set + Tag.joins(:set_taggings).where("set_taggings.tag_set_id = ?", self.tag_set.id) + end + + def already_nominated?(tagname) + TagNomination.joins(tag_set_nomination: :owned_tag_set).where("tag_set_nominations.owned_tag_set_id = ?", self.id).exists?(tagname: tagname) + end + + def already_rejected?(tagname) + TagNomination.joins(tag_set_nomination: :owned_tag_set).where("tag_set_nominations.owned_tag_set_id = ?", self.id).exists?(tagname: tagname, rejected: true) + end + + def already_approved?(tagname) + TagNomination.joins(tag_set_nomination: :owned_tag_set).where("tag_set_nominations.owned_tag_set_id = ?", self.id).exists?(tagname: tagname, approved: true) + end + + def clear_nominations! + TagSetNomination.where(owned_tag_set_id: self.id).delete_all + end + + + ##### MANAGING ASSOCIATIONS + + def associations_to_remove=(assoc_ids) + TagSetAssociation.for_tag_set(self).where(id: assoc_ids).delete_all + end + + def load_batch_associations!(batch_associations, options = {}) + options.reverse_merge!({do_relationships: false}) + association_lines = batch_associations.split("\n") + fandom_tagnames_to_add = [] + child_tagnames_to_add = [] + assocs_to_save = [] + failed = [] + canonical = [] + + association_lines.each do |line| + children_names = line.split(',') + parent_name = children_names.shift.strip + parent_tag_id = Fandom.where(name: parent_name).pluck(:id).first + unless parent_tag_id + failed << line + next + end + failed_children = [] + added_parent = false + children_names.map {|c| c.strip}.each_with_index do |child_name| + child_tag_id = (options[:do_relationships] ? Relationship : Character).where(name: child_name).pluck(:id).first + unless child_tag_id + failed_children << child_name + next + end + assoc = tag_set_associations.build(tag_id: child_tag_id, parent_tag_id: parent_tag_id) + unless assoc.valid? + failed_children << child_name + next + end + assocs_to_save << assoc + child_tagnames_to_add << child_name + fandom_tagnames_to_add << parent_name unless added_parent + added_parent = true + end + failed << "#{parent_name},#{failed_children.join(',')}" unless failed_children.empty? + end + + # add the tags to the set + tag_set.fandom_tagnames_to_add = fandom_tagnames_to_add + tag_set.send (options[:do_relationships] ? :relationship_tagnames_to_add= : :character_tagnames_to_add=), child_tagnames_to_add + + if tag_set.save + # save the associations + assocs_to_save.each {|assoc| assoc.save} + else + # whoops, nothing worked + failed = association_lines + end + + return failed + end + + # Turn our various tag nomination limits into a single hash object + def limits + limit_hash = {} + %w(fandom character relationship freeform).each do |tag_type| + limit_hash[tag_type] = send("#{tag_type}_nomination_limit") + end + limit_hash.with_indifferent_access + end + + def includes_fandoms? + fandom_nomination_limit > 0 + end +end diff --git a/app/models/tagset_models/relationship_nomination.rb b/app/models/tagset_models/relationship_nomination.rb new file mode 100755 index 0000000..81a92b9 --- /dev/null +++ b/app/models/tagset_models/relationship_nomination.rb @@ -0,0 +1,5 @@ +class RelationshipNomination < CastNomination + belongs_to :tag_set_nomination + belongs_to :fandom_nomination, inverse_of: :relationship_nominations + has_one :owned_tag_set, through: :tag_set_nomination +end \ No newline at end of file diff --git a/app/models/tagset_models/set_tagging.rb b/app/models/tagset_models/set_tagging.rb new file mode 100755 index 0000000..898f53a --- /dev/null +++ b/app/models/tagset_models/set_tagging.rb @@ -0,0 +1,6 @@ +class SetTagging < ApplicationRecord + belongs_to :tag + belongs_to :tag_set + + validates_uniqueness_of :tag_id, scope: [:tag_set_id], message: ts("^That tag already seems to be in this set.") +end diff --git a/app/models/tagset_models/tag_nomination.rb b/app/models/tagset_models/tag_nomination.rb new file mode 100755 index 0000000..5095a6d --- /dev/null +++ b/app/models/tagset_models/tag_nomination.rb @@ -0,0 +1,183 @@ +class TagNomination < ApplicationRecord + belongs_to :tag_set_nomination, inverse_of: :tag_nominations + has_one :owned_tag_set, through: :tag_set_nomination + + attr_accessor :from_fandom_nomination + + validates_length_of :tagname, + maximum: ArchiveConfig.TAG_MAX, + message: ts("^Tag nominations must be between 1 and #{ArchiveConfig.TAG_MAX} characters.") + + validates_format_of :tagname, + if: Proc.new { |tag_nomination| !tag_nomination.tagname.blank? }, + with: /\A[^,*<>^{}=`\\%]+\z/, + message: ts("^Tag nominations cannot include the following restricted characters: , ^ * < > { } = ` \\ %") + + validate :type_validity, unless: :blank_tagname? + def type_validity + return unless (tag = Tag.find_by_name(tagname)) && "#{tag.type}Nomination" != self.type + + errors.add(:base, ts("^The tag %{tagname} is already in the archive as a #{tag.type} tag. (All tags have to be unique.) Try being more specific, for instance tacking on the medium or the fandom.", tagname: self.tagname)) + end + + validate :not_already_reviewed, on: :update + def not_already_reviewed + # allow mods and the archive code to update + unless (!User.current_user || (User.current_user && User.current_user.is_a?(User) && owned_tag_set.user_is_moderator?(User.current_user))) + if tagname_changed? && (self.approved || self.rejected) && (tagname != tagname_was) && !tagname_was.blank? + errors.add(:base, ts("^You cannot change %{tagname_was} to %{tagname} because that nomination has already been reviewed.", tagname_was: self.tagname_was, tagname: self.tagname)) + tagname = self.tagname_was + end + end + end + + # This makes sure no tagnames are nominated for different parents in this tag set + validate :require_unique_tagname_with_parent, unless: :blank_tagname? + def require_unique_tagname_with_parent + query = TagNomination.for_tag_set(get_owned_tag_set).where(tagname: self.tagname).where("parent_tagname != ?", (self.get_parent_tagname || '')) + # let people change their own! + query = query.where("tag_nominations.id != ?", self.id) if !(self.new_record?) + if query.exists? + other_parent = query.pluck(:parent_tagname).uniq.join(", ") # should only be one but just in case + errors.add(:base, ts("^Someone else has already nominated the tag %{tagname} for this set but in fandom %{other_parent}. (All nominations have to be unique for the approval process to work.) Try making your nomination more specific, for instance tacking on (%{fandom}).", tagname: self.tagname, other_parent: other_parent, fandom: self.get_parent_tagname || 'Fandom')) + end + end + + def get_owned_tag_set + @tag_set || self.tag_set_nomination.owned_tag_set + end + + def blank_tagname? + tagname.blank? + end + + before_save :set_tag_status, unless: :blank_tagname? + def set_tag_status + if (tag = Tag.find_by_name(tagname)) + self.exists = true + self.tagname = tag.name + self.canonical = tag.canonical + self.synonym = tag.merger ? tag.merger.name : nil + else + self.exists = false + self.canonical = false + self.synonym = nil + end + true + end + + before_save :set_parented, unless: :blank_tagname? + def set_parented + self.parented = true and return if type == "FreeformNomination" + + self.parent_tagname ||= get_parent_tagname + + tag = Tag.find_by_name(tagname) + unless tag + self.parented = false + return + end + + self.parented = tag.canonical? && + ((!tag.parents.empty? && get_parent_tagname.blank?) || + tag.parents.pluck(:name).include?(get_parent_tagname)) + end + + # sneaky bit: if the tag set moderator has already rejected or approved this tag, don't + # show it to them again. + before_save :set_approval_status, unless: :blank_tagname? + def set_approval_status + set_noms = tag_set_nomination + set_noms = fandom_nomination.tag_set_nomination if !set_noms && from_fandom_nomination + self.rejected = set_noms.owned_tag_set.already_rejected?(tagname) || false + if self.rejected + self.approved = false + elsif synonym && set_noms.owned_tag_set.already_in_set?(synonym) + self.tagname = synonym + self.synonym = nil + self.approved = true + else + self.approved = set_noms.owned_tag_set.already_in_set?(tagname) || false + end + true + end + + after_save :destroy_if_blank + def destroy_if_blank + self.destroy if blank_tagname? + end + + def self.for_tag_set(tag_set) + joins(tag_set_nomination: :owned_tag_set). + where("owned_tag_sets.id = ?", tag_set.id) + end + + def self.names_with_count + select("tagname, count(*) as count").group("tagname").order("tagname") + end + + def self.unreviewed + where(approved: false).where(rejected: false) + end + + # returns an array of all the parent tagnames for the given tag + # can be chained with other queries but must come at the end + def self.nominated_parents(child_tagname, parent_search_term="") + parents = where(tagname: child_tagname).where("parent_tagname != ''") + unless parent_search_term.blank? + parents = parents.where("parent_tagname LIKE ?", "%#{parent_search_term}%") + end + parents.group("parent_tagname").order("count_id DESC").count('id').keys + end + + # We need this manual join in order to do a query over multiple types of tags + # (ie, via TagNomination.where(type: ...)) + def self.join_fandom_nomination + joins("INNER JOIN tag_nominations fandom_nominations_tag_nominations ON + fandom_nominations_tag_nominations.id = tag_nominations.fandom_nomination_id AND + fandom_nominations_tag_nominations.type = 'FandomNomination'") + end + + # Can we change the name to this new name? + def change_tagname?(new_tagname) + self.tagname = new_tagname + if self.valid? + return true + else + return false + end + end + + # If the mod is changing our name, change all other noms in this set as well + def self.change_tagname!(owned_tag_set_to_change, old_tagname, new_tagname) + TagNomination.for_tag_set(owned_tag_set_to_change).where(tagname: old_tagname).readonly(false).each do |tagnom| + tagnom.tagname = new_tagname + tagnom.save or return false + end + return true + end + + # here so we can override it in char/relationship noms + def get_parent_tagname + self.parent_tagname.present? ? self.parent_tagname : nil + end + + def unreviewed? + !approved && !rejected + end + + def reviewed? + approved || rejected + end + + def approve! + self.approved = true + self.rejected = false + self.owned_tag_set.tag_set.send("#{self.class.to_s.gsub(/Nomination/,'').downcase}_tagnames_to_add=", self.tagname) + self.owned_tag_set.tag_set.save + end + + def times_nominated(tag_set) + TagNomination.for_tag_set(tag_set).where(tagname: self.tagname).count + end +end diff --git a/app/models/tagset_models/tag_set.rb b/app/models/tagset_models/tag_set.rb new file mode 100755 index 0000000..8a237d2 --- /dev/null +++ b/app/models/tagset_models/tag_set.rb @@ -0,0 +1,297 @@ +class TagSet < ApplicationRecord + # a complete match is numerically represented with ALL + ALL = -1 + + TAG_TYPES = %w(fandom character relationship freeform category rating archive_warning) + TAG_TYPES_INITIALIZABLE = %w(fandom character relationship freeform) + TAG_TYPES_RESTRICTED_TO_FANDOM = %w(character relationship) + TAGS_AS_CHECKBOXES = %w(category rating archive_warning) + + attr_accessor :from_owned_tag_set + + has_many :set_taggings, dependent: :destroy + has_many :tags, through: :set_taggings + + has_one :owned_tag_set + + has_one :prompt, autosave: false + + # how this works: we don't want to set the actual "tags" variable initially because that will + # create SetTaggings even if the tags are not canonical or wrong. So we need to create a temporary + # virtual attribute "tagnames" to use instead until after validation. + attr_writer :tagnames + def tagnames + @tagnames || tags.select('tags.name').order('tags.name').collect(&:name).join(ArchiveConfig.DELIMITER_FOR_OUTPUT) + end + + def taglist + @tagnames ? tagnames_to_list(@tagnames) : tags + end + + attr_writer :tagnames_to_remove + def tagnames_to_remove + @tagnames_to_remove || "" + end + + # this code just sets up functions fandom_tagnames/fandom_tagnames=, character_tagnames... etc + # that work like tagnames above, except on separate types. + # + # NOTE: you can't use both these individual + # setters and tagnames in the same form -- ie, if you set tagnames and then you set fandom_tagnames, you + # will wipe out the fandom tagnames set in tagnames. + # + TAG_TYPES.each do |type| + attr_writer "#{type}_tagnames".to_sym + + define_method("#{type}_tagnames") do + self.instance_variable_get("@#{type}_tagnames") || (self.new_record? ? self.tags.select {|t| t.type == type.classify}.collect(&:name).join(ArchiveConfig.DELIMITER_FOR_OUTPUT) : + self.tags.with_type(type.classify).select('tags.name').order('tags.name').collect(&:name).join(ArchiveConfig.DELIMITER_FOR_OUTPUT)) + end + + define_method("#{type}_taglist") do + self.instance_variable_get("@#{type}_tagnames") ? tagnames_to_list(self.instance_variable_get("@#{type}_tagnames"), type) : with_type(type) + end + + # _to_add/remove only + attr_writer "#{type}_tagnames_to_add".to_sym + define_method("#{type}_tagnames_to_add") do + self.instance_variable_get("@#{type}_tagnames_to_add") || "" + end + + attr_writer "#{type}_tags_to_remove".to_sym + define_method("#{type}_tags_to_remove") do + self.instance_variable_get("@#{type}_tags_to_remove") || "" + end + + end + + # this actually runs and saves the tags and updates the autocomplete + # NOTE: if more than one is set, the precedence is as follows: + # tagnames= + # tagnames_to_add/_remove + # [type]_tagnames + # [type]_tagnames_to_add/_remove + after_save :assign_tags + def assign_tags + tags_to_add = [] + tags_to_remove = [] + + TAG_TYPES.each do |type| + if self.instance_variable_get("@#{type}_tagnames") + # explicitly set the list of type_tagnames + new_tags = self.send("#{type}_taglist") + old_tags = self.with_type(type.classify) + tags_to_add += (new_tags - old_tags) + tags_to_remove += (old_tags - new_tags) + else + # + unless self.instance_variable_get("@#{type}_tagnames_to_add").blank? + tags_to_add += tagnames_to_list(self.instance_variable_get("@#{type}_tagnames_to_add"), type) + end + unless self.instance_variable_get("@#{type}_tags_to_remove").blank? + tagclass = type.classify.constantize # Safe constantize itterating over TAG_TYPES + tags_to_remove += (self.instance_variable_get("@#{type}_tags_to_remove").map {|tag_id| tag_id.blank? ? nil : tagclass.find(tag_id)}.compact) + end + end + end + + # This overrides the type-specific + if @tagnames_to_remove.present? + tags_to_remove = @tagnames_to_remove.split(ArchiveConfig.DELIMITER_FOR_INPUT).map {|tname| Tag.find_by_name(tname.squish)}.compact + end + + # And this overrides the add/remove-specific + if @tagnames + new_tags = tagnames_to_list(@tagnames) + tags_to_add = new_tags - self.tags + tags_to_remove = (self.tags - new_tags) + end + + # actually remove and add the tags, and update autocomplete + remove_from_set(tags_to_remove.uniq) + add_to_set(tags_to_add.uniq) + end + + def remove_from_set(tags_to_remove) + return unless tags_to_remove.present? + self.set_taggings.where(tag_id: tags_to_remove.map(&:id)).delete_all + remove_tags_from_autocomplete(tags_to_remove) + owned_tag_set&.touch + end + + def add_to_set(tags_to_add) + return unless tags_to_add.present? + existing_ids = self.set_taggings.where(tag_id: tags_to_add.map(&:id)).pluck(:tag_id) + tags_to_add.each do |tag| + next if existing_ids.include?(tag.id) + self.set_taggings.create(tag_id: tag.id) + end + add_tags_to_autocomplete(tags_to_add) + owned_tag_set&.touch + end + + # Tags must already exist unless they are being added to an owned tag set + validate :tagnames_must_exist, unless: :from_owned_tag_set + def tagnames_must_exist + nonexist = [] + if @tagnames + nonexist += @tagnames.split(ArchiveConfig.DELIMITER_FOR_INPUT).select {|t| !Tag.where(name: t.squish).exists?} + end + if owned_tag_set.nil? + TAG_TYPES.each do |type| + if (tagnames = self.instance_variable_get("@#{type}_tagnames_to_add")) + tagnames = (tagnames.is_a?(Array) ? tagnames : tagnames.split(ArchiveConfig.DELIMITER_FOR_INPUT)).map {|t| t.squish} + nonexist += tagnames.select {|t| !t.blank? && !Tag.where(name: t).exists?} + end + end + end + + unless nonexist.empty? + errors.add(:tagnames, ts("^The following tags don't exist and can't be used: %{taglist}", taglist: nonexist.join(", ") )) + end + end + + ### Various utility methods + + def +(other) + TagSet.new(tags: (self.tags + other.tags)) + end + + def -(other) + TagSet.new(tags: (self.tags - other.tags)) + end + + def with_type(type) + # this is required because otherwise tag sets created on the fly (eg with + during potential match generation) + # that are not saved in the database will return empty list. + # We use Tag.where so that we can still chain this with other AR queries + return self.new_record? ? Tag.where(id: self.tags.select {|t| t.type == type.classify}.collect(&:id)) : self.tags.with_type(type) + end + + def has_type?(type) + with_type(type).exists? + end + + def empty? + self.tags.empty? + end + + ### Matching + + # Computes the "match rank" of the two arrays. The match rank is ALL if the + # request tags are a subset of (or equal to) the offer tags, and otherwise is + # equal to the size of the overlap between the two. + def self.match_array_rank(request, offer) + return ALL if request.nil? || request.empty? + return 0 if offer.nil? || offer.empty? + overlap = request & offer + overlap.size == request.size ? ALL : overlap.size + end + + # Creates a hash mapping from tag types (lowercase) to lists of tag ids. + # Stores the result as an instance variable, to make sure that we only + # perform the work once. (This is only used by the matching algorithm, which + # doesn't update any tag set information, so it's okay to cache the results + # of this computation. Particularly since we want matching to go as fast as + # possible.) + def tag_ids_by_type + if @tag_ids_by_type.nil? + @tag_ids_by_type = tags.group_by { |tag| tag.type.underscore } + @tag_ids_by_type.each_value { |tag_list| tag_list.map!(&:id) } + end + + @tag_ids_by_type + end + + # Computes the match rank of the two tag sets, in the given type. (Or in all + # types, if type is nil.) + def match_rank(another, type = nil) + request = type ? tag_ids_by_type[type] : tags.map(&:id) + offer = type ? another.tag_ids_by_type[type] : another.tags.map(&:id) + TagSet.match_array_rank(request, offer) + end + + ### protected + + protected + def tagnames_to_list(taglist, type=nil) + taglist = (taglist.kind_of?(String) ? taglist.split(ArchiveConfig.DELIMITER_FOR_INPUT) : taglist).uniq + if type + raise "Redshirt: Attempted to constantize invalid class initialize tagnames_to_list #{type}" unless TAG_TYPES.include?(type) + if Tag::USER_DEFINED.include?(type.classify) + # allow users to create these + taglist.reject {|tagname| tagname.blank? }.map {|tagname| (type.classify.constantize).find_or_create_by_name(tagname.squish)} # Safe constantize checked above + else + taglist.reject {|tagname| tagname.blank? }.map {|tagname| (type.classify.constantize).find_by(name: tagname.squish)}.compact # Safe constantize checked above + end + else + taglist.reject {|tagname| tagname.blank? }.map {|tagname| Tag.find_by_name(tagname.squish) || Freeform.find_or_create_by_name(tagname.squish)} + end + end + + ### autocomplete + public + + # set up autocomplete and override some methods + include AutocompleteSource + + def autocomplete_prefixes + prefixes = [ ] + prefixes + end + + def add_to_autocomplete(score = nil) + add_tags_to_autocomplete(self.tags) + end + + def remove_from_autocomplete + REDIS_AUTOCOMPLETE.del("autocomplete_tagset_#{self.id}") + end + + def add_tags_to_autocomplete(tags_to_add) + tags_to_add.each do |tag| + value = tag.autocomplete_value + REDIS_AUTOCOMPLETE.zadd("autocomplete_tagset_all_#{self.id}", 0, value) + REDIS_AUTOCOMPLETE.zadd("autocomplete_tagset_#{tag.type.downcase}_#{self.id}", 0, value) + end + end + + def remove_tags_from_autocomplete(tags_to_remove) + tags_to_remove.each do |tag| + value = tag.autocomplete_value + REDIS_AUTOCOMPLETE.zrem("autocomplete_tagset_all_#{self.id}", value) + REDIS_AUTOCOMPLETE.zrem("autocomplete_tagset_#{tag.type.downcase}_#{self.id}", value) + end + end + + # returns tags that are in ANY or ALL of the specified tag sets + def self.autocomplete_lookup(options={}) + options.reverse_merge!({term: "", tag_type: "all", tag_set: "", in_any: true}) + tag_type = options[:tag_type] + search_param = options[:term] + tag_sets = TagSet.get_search_terms(options[:tag_set]) + + combo_key = "autocomplete_tagset_combo_#{tag_sets.join('_')}" + + # get the intersection of the wrangled fandom and the associations from the various tag sets + keys_to_lookup = tag_sets.map {|set| "autocomplete_tagset_#{tag_type}_#{set}"}.flatten + + if options[:in_any] + # get the union since we want tags in ANY of these sets + REDIS_AUTOCOMPLETE.zunionstore(combo_key, keys_to_lookup, aggregate: :max) + else + # take the intersection of ALL of these sets + REDIS_AUTOCOMPLETE.zinterstore(combo_key, keys_to_lookup, aggregate: :max) + end + results = REDIS_AUTOCOMPLETE.zrevrange(combo_key, 0, -1) + # expire fast + REDIS_AUTOCOMPLETE.expire combo_key, 1 + + unless search_param.blank? + search_regex = Tag.get_search_regex(search_param) + return results.select {|tag| tag.match(search_regex)} + else + return results + end + end +end diff --git a/app/models/tagset_models/tag_set_association.rb b/app/models/tagset_models/tag_set_association.rb new file mode 100755 index 0000000..37399b1 --- /dev/null +++ b/app/models/tagset_models/tag_set_association.rb @@ -0,0 +1,132 @@ +class TagSetAssociation < ApplicationRecord + belongs_to :owned_tag_set + belongs_to :tag + belongs_to :parent_tag, class_name: "Tag" + + validates_uniqueness_of :tag_id, scope: [:owned_tag_set_id, :parent_tag_id], message: ts("^You have already associated those tags in your set.") + validates_presence_of :tag_id, :parent_tag_id, :owned_tag_set_id + + attr_accessor :create_association + + def to_s + "#{tag.name} (#{parent_tag.name})" + end + + # sort by names stripping off the articles + def self.by_name_without_articles(fieldname = "name") + fieldname = "name" unless fieldname.match(/^([\w]+\.)?[\w]+$/) + order(Arel.sql("case when lower(substring(#{fieldname} from 1 for 4)) = 'the ' then substring(#{fieldname} from 5) + when lower(substring(#{fieldname} from 1 for 2)) = 'a ' then substring(#{fieldname} from 3) + when lower(substring(#{fieldname} from 1 for 3)) = 'an ' then substring(#{fieldname} from 4) + else #{fieldname} + end")) + end + + def self.for_tag_set(tagset) + where(owned_tag_set_id: tagset.id) + end + + # almost exactly like the same code in tag.rb + def self.parent_names(child_type, parent_type = "fandom") + joins(:tag, :parent_tag).where("tags.type = ? AND parent_tags_tag_set_associations.type = ?", child_type.capitalize, parent_type.capitalize). + select("parent_tags_tag_set_associations.name as parent_name, tags.name as child_name"). + by_name_without_articles("parent_name"). + by_name_without_articles("child_name") + end + + def self.names_by_parent(child_relation, child_type, parent_type = "fandom") + hash = {} + results = ActiveRecord::Base.connection.execute(child_relation.parent_names(child_type, parent_type).to_sql) + results.each {|row| hash[row.first] ||= Array.new; hash[row.first] << row.second} + hash + end + + def parent_tagname + @parent_tagname || self.parent_tag.name + end + + def parent_tagname=(parent_tagname) + self.parent_tag = Tag.find_by_name(parent_tagname) + end + + def make_official! + tag.add_association(parent_tag) + self.destroy + end + + after_save :add_to_autocomplete + before_destroy :remove_from_autocomplete + + ## AUTOCOMPLETE + # set up autocomplete and override some methods + include AutocompleteSource + + def autocomplete_prefixes + prefixes = [ ] + prefixes + end + + # the value and score in autocomplete are the value/score of the child tag + def autocomplete_value + tag.autocomplete_value + end + + def autocomplete_score + tag.autocomplete_score + end + + def self.parse_autocomplete_value(current_autocomplete_value) + Tag.parse_autocomplete_value(current_autocomplete_value) + end + + def add_to_autocomplete(score = nil) + score ||= autocomplete_score + REDIS_AUTOCOMPLETE.zadd("autocomplete_association_#{tag.type.downcase}_#{owned_tag_set.tag_set_id}_#{parent_tag.name.downcase}", score, autocomplete_value) + end + + def remove_from_autocomplete + REDIS_AUTOCOMPLETE.zrem("autocomplete_association_#{tag.type.downcase}_#{owned_tag_set.tag_set_id}_#{parent_tag.name.downcase}", autocomplete_value) + end + + # returns tags that have been associated with a given fandom OR wrangled + def self.autocomplete_lookup(options = {}) + options.reverse_merge!({term: "", tag_type: "character", tag_set: "", fandom: "", include_wrangled: "true"}) + search_param = options[:term] + tag_type = options[:tag_type] + fandoms = TagSetAssociation.get_search_terms(options[:fandom]) + tag_sets = TagSetAssociation.get_search_terms(options[:tag_set]) + + combo_key = "autocomplete_association_combo_#{tag_type}_#{tag_sets.join('_')}_#{fandoms.join('_')}" + + # get the union of the wrangled fandom and the associations from the various tag sets + keys_to_lookup = tag_sets.map {|set| fandoms.map {|fandom| "autocomplete_association_#{tag_type}_#{set}_#{fandom}"}}.flatten + keys_to_lookup += fandoms.map {|fandom| "autocomplete_fandom_#{fandom}_#{tag_type}"}.flatten + return [] if keys_to_lookup.empty? + + # if we don't want tags that aren't in the tag set(s), we need to first + # get the union of all the tags in the tag set(s), then get the intersection + # of those tags, and the associated tags + if options[:include_wrangled] == "false" + combo_key2 = combo_key + "2" + combo_key3 = combo_key + "3" + keys_for_intersect = tag_sets.map {|set| "autocomplete_tagset_#{tag_type}_#{set}"}.flatten + REDIS_AUTOCOMPLETE.zunionstore(combo_key2, keys_to_lookup, aggregate: :max) + REDIS_AUTOCOMPLETE.zunionstore(combo_key3, keys_for_intersect, aggregate: :max) + REDIS_AUTOCOMPLETE.zinterstore(combo_key, [combo_key2, combo_key3], aggregate: :max) + REDIS_AUTOCOMPLETE.expire combo_key2, 1 + REDIS_AUTOCOMPLETE.expire combo_key3, 1 + else + REDIS_AUTOCOMPLETE.zunionstore(combo_key, keys_to_lookup, aggregate: :max) + end + + results = REDIS_AUTOCOMPLETE.zrevrange(combo_key, 0, -1) + REDIS_AUTOCOMPLETE.expire combo_key, 1 + + unless search_param.blank? + search_regex = Tag.get_search_regex(search_param) + results.select! {|tag| tag.match(search_regex)} + end + return results + end + +end diff --git a/app/models/tagset_models/tag_set_nomination.rb b/app/models/tagset_models/tag_set_nomination.rb new file mode 100755 index 0000000..eb279f1 --- /dev/null +++ b/app/models/tagset_models/tag_set_nomination.rb @@ -0,0 +1,102 @@ +class TagSetNomination < ApplicationRecord + belongs_to :pseud + belongs_to :owned_tag_set, inverse_of: :tag_set_nominations + + has_many :tag_nominations, dependent: :destroy, inverse_of: :tag_set_nomination + has_many :fandom_nominations, dependent: :destroy, inverse_of: :tag_set_nomination + has_many :character_nominations, dependent: :destroy, inverse_of: :tag_set_nomination + has_many :relationship_nominations, dependent: :destroy, inverse_of: :tag_set_nomination + has_many :freeform_nominations, dependent: :destroy, inverse_of: :tag_set_nomination + + accepts_nested_attributes_for :fandom_nominations, :character_nominations, :relationship_nominations, :freeform_nominations, { + allow_destroy: true, + reject_if: proc { |attrs| attrs[:tagname].blank? && attrs[:id].blank? } + } + + validates_presence_of :owned_tag_set_id + validates_presence_of :pseud_id + + validates_uniqueness_of :owned_tag_set_id, scope: [:pseud_id], message: ts("You have already submitted nominations for that tag set. Try editing them instead.") + + validate :can_nominate + def can_nominate + unless owned_tag_set.nominated + errors.add(:base, ts("%{title} is not currently accepting nominations.", title: owned_tag_set.title)) + end + end + + validate :nomination_limits + def nomination_limits + TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| + limit = self.owned_tag_set.send("#{tag_type}_nomination_limit") + if count_by_fandom?(tag_type) + if self.fandom_nominations.any? {|fandom_nom| fandom_nom.send("#{tag_type}_nominations").try(:count) > limit} + errors.add(:base, ts("You can only nominate %{limit} #{tag_type} tags per fandom.", limit: limit)) + end + else + count = self.send("#{tag_type}_nominations").count + errors.add(:base, ts("You can only nominate %{limit} #{tag_type} tags", limit: limit)) if count > limit + end + end + end + + # This makes sure a single user doesn't nominate the same tagname twice + validate :require_unique_tagnames + def require_unique_tagnames + noms = self.fandom_nominations + self.freeform_nominations + if self.fandom_nominations.empty? + noms += self.character_nominations + self.relationship_nominations + else + noms += self.fandom_nominations.collect(&:character_nominations).flatten + noms += self.fandom_nominations.collect(&:relationship_nominations).flatten + end + tagnames = noms.map(&:tagname).reject {|t| t.blank?} + duplicates = tagnames.group_by {|tagname| tagname}.select {|k,v| v.size > 1}.keys + errors.add(:base, ts("You seem to be trying to nominate %{duplicates} more than once.", duplicates: duplicates.join(', '))) unless duplicates.empty? + end + + # Have NONE of the nominations been reviewed? + def unreviewed? + TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| + return false if self.send("#{tag_type}_nominations").any? {|tn| tn.reviewed?} + end + return true + end + + # Have ALL the nominations been reviewed? + def reviewed? + TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| + return false if self.send("#{tag_type}_nominations").any? {|tn| tn.unreviewed?} + end + return true + end + + def count_by_fandom?(tag_type) + %w(character relationship).include?(tag_type) && self.owned_tag_set.fandom_nomination_limit > 0 + end + + def self.owned_by(user = User.current_user) + select("DISTINCT tag_set_nominations.*"). + joins(pseud: :user). + where("users.id = ?", user.id) + end + + def self.for_tag_set(tag_set) + where(owned_tag_set_id: tag_set.id) + end + + def nominated_tags(tag_type = "fandom", index = -1) + if count_by_fandom?(tag_type) + if index == -1 + # send ALL the collected char/relationship nominations per fandom + self.fandom_nominations.collect(&("#{tag_type}_nominations".to_sym)).flatten + else + # send just the nominations for this fandom + self.fandom_nominations[index].send("#{tag_type}_nominations") + end + else + self.send("#{tag_type}_nominations") + end + end + +end diff --git a/app/models/tagset_models/tag_set_ownership.rb b/app/models/tagset_models/tag_set_ownership.rb new file mode 100755 index 0000000..5330f4b --- /dev/null +++ b/app/models/tagset_models/tag_set_ownership.rb @@ -0,0 +1,4 @@ +class TagSetOwnership < ApplicationRecord + belongs_to :pseud + belongs_to :owned_tag_set +end diff --git a/app/models/unsorted_tag.rb b/app/models/unsorted_tag.rb new file mode 100755 index 0000000..a6fd16b --- /dev/null +++ b/app/models/unsorted_tag.rb @@ -0,0 +1,3 @@ +class UnsortedTag < Tag + NAME = "Unsorted Tag" +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100755 index 0000000..c9b0f2f --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,626 @@ +class User < ApplicationRecord + audited redacted: [:encrypted_password, :password_salt] + include Justifiable + include WorksOwner + include PasswordResetsLimitable + include UserLoggable + include Searchable + + devise :database_authenticatable, + :confirmable, + :registerable, + :rememberable, + :trackable, + :validatable, + :lockable, + :recoverable + devise :pwned_password unless Rails.env.test? + + # Must come after Devise modules in order to alias devise_valid_password? + # properly + include BackwardsCompatiblePasswordDecryptor + + # Allows other models to get the current user with User.current_user + thread_cattr_accessor :current_user + + # Authorization plugin + acts_as_authorized_user + acts_as_authorizable + has_many :roles_users + has_many :roles, through: :roles_users, dependent: :destroy + + ### BETA INVITATIONS ### + has_many :invitations, as: :creator + has_one :invitation, as: :invitee + has_many :user_invite_requests, dependent: :destroy + + attr_accessor :invitation_token + # attr_accessible :invitation_token + after_create :mark_invitation_redeemed, :remove_from_queue + + has_many :external_authors, dependent: :destroy + has_many :external_creatorships, foreign_key: "archivist_id" + + has_many :fannish_next_of_kins, dependent: :delete_all, inverse_of: :kin, foreign_key: :kin_id + has_one :fannish_next_of_kin, dependent: :destroy + + has_many :favorite_tags, dependent: :destroy + + has_one :default_pseud, -> { where(is_default: true) }, class_name: "Pseud", inverse_of: :user + delegate :id, to: :default_pseud, prefix: true + + has_many :pseuds, dependent: :destroy + validates_associated :pseuds + + has_one :profile, dependent: :destroy + validates_associated :profile + + has_one :preference, dependent: :destroy + validates_associated :preference + has_many :statuses, dependent: :destroy + has_many :blocks_as_blocked, class_name: "Block", dependent: :delete_all, inverse_of: :blocked, foreign_key: :blocked_id + has_many :blocks_as_blocker, class_name: "Block", dependent: :delete_all, inverse_of: :blocker, foreign_key: :blocker_id + has_many :blocked_users, through: :blocks_as_blocker, source: :blocked + + # The block (if it exists) with this user as the blocker and + # User.current_user as the blocked: + has_one :block_of_current_user, + -> { where(blocked: User.current_user) }, + class_name: "Block", foreign_key: :blocker_id, inverse_of: :blocker + + # The block (if it exists) with User.current_user as the blocker and this + # user as the blocked: + has_one :block_by_current_user, + -> { where(blocker: User.current_user) }, + class_name: "Block", foreign_key: :blocked_id, inverse_of: :blocked + + has_many :mutes_as_muted, class_name: "Mute", dependent: :delete_all, inverse_of: :muted, foreign_key: :muted_id + has_many :mutes_as_muter, class_name: "Mute", dependent: :delete_all, inverse_of: :muter, foreign_key: :muter_id + has_many :muted_users, through: :mutes_as_muter, source: :muted + + # The mute (if it exists) with User.current_user as the muter and this + # user as the muted: + has_one :mute_by_current_user, + -> { where(muter: User.current_user) }, + class_name: "Mute", foreign_key: :muted_id, inverse_of: :muted + + has_many :skins, foreign_key: "author_id", dependent: :nullify + has_many :work_skins, foreign_key: "author_id", dependent: :nullify + + before_create :create_default_associateds + before_destroy :remove_user_from_kudos + + before_update :add_renamed_at, if: :will_save_change_to_login? + after_update :update_pseud_name + after_update :send_wrangler_username_change_notification, if: :is_tag_wrangler? + after_update :log_change_if_login_was_edited, if: :saved_change_to_login? + after_update :log_email_change, if: :saved_change_to_email? + + after_commit :reindex_user_creations_after_rename + + has_many :collection_participants, through: :pseuds + has_many :collections, through: :collection_participants + has_many :invited_collections, -> { where("collection_participants.participant_role = ?", CollectionParticipant::INVITED) }, through: :collection_participants, source: :collection + has_many :participated_collections, -> { where("collection_participants.participant_role IN (?)", [CollectionParticipant::OWNER, CollectionParticipant::MODERATOR, CollectionParticipant::MEMBER]) }, through: :collection_participants, source: :collection + has_many :maintained_collections, -> { where("collection_participants.participant_role IN (?)", [CollectionParticipant::OWNER, CollectionParticipant::MODERATOR]) }, through: :collection_participants, source: :collection + has_many :owned_collections, -> { where("collection_participants.participant_role = ?", CollectionParticipant::OWNER) }, through: :collection_participants, source: :collection + + has_many :challenge_signups, through: :pseuds + has_many :offer_assignments, through: :pseuds + has_many :pinch_hit_assignments, through: :pseuds + has_many :request_claims, class_name: "ChallengeClaim", foreign_key: "claiming_user_id", inverse_of: :claiming_user + has_many :gifts, -> { where(rejected: false) }, through: :pseuds + has_many :gift_works, -> { distinct }, through: :pseuds + has_many :rejected_gifts, -> { where(rejected: true) }, class_name: "Gift", through: :pseuds + has_many :rejected_gift_works, -> { distinct }, through: :pseuds + has_many :readings, dependent: :delete_all + has_many :bookmarks, through: :pseuds + has_many :bookmark_collection_items, through: :bookmarks, source: :collection_items + has_many :comments, through: :pseuds + has_many :kudos + + # Nested associations through creatorships got weird after 3.0.x + has_many :creatorships, through: :pseuds + + has_many :works, -> { distinct }, through: :pseuds + has_many :series, -> { distinct }, through: :pseuds + has_many :chapters, through: :pseuds + has_many :related_works, through: :works + has_many :parent_work_relationships, through: :works + + has_many :tags, through: :works + has_many :filters, through: :works + has_many :direct_filters, through: :works + + has_many :bookmark_tags, through: :bookmarks, source: :tags + + has_many :subscriptions, dependent: :destroy + has_many :followings, + class_name: "Subscription", + as: :subscribable, + dependent: :destroy + has_many :subscribed_users, + through: :subscriptions, + source: :subscribable, + source_type: "User" + has_many :subscribers, + through: :followings, + source: :user + + thread_cattr_accessor :should_update_wrangling_activity + has_many :wrangling_assignments, dependent: :destroy + has_many :fandoms, through: :wrangling_assignments + has_many :wrangled_tags, class_name: "Tag", as: :last_wrangler + has_one :last_wrangling_activity, dependent: :destroy + + has_many :inbox_comments, dependent: :destroy + has_many :feedback_comments, -> { where(is_deleted: false, approved: true).order(created_at: :desc) }, through: :inbox_comments + + has_many :log_items, dependent: :destroy + validates_associated :log_items + + after_update :expire_caches + + def expire_caches + return unless saved_change_to_login? + series.each(&:expire_byline_cache) + chapters.each(&:expire_byline_cache) + self.works.each do |work| + work.touch + work.expire_caches + end + end + + def remove_user_from_kudos + # TODO: AO3-2195 Display orphaned kudos (no users; no IPs so not counted as guest kudos). + Kudo.where(user: self).update_all(user_id: nil) + end + + def read_inbox_comments + inbox_comments.where(read: true) + end + def unread_inbox_comments + inbox_comments.where(read: false) + end + def unread_inbox_comments_count + unread_inbox_comments.with_bad_comments_removed.count + end + + scope :alphabetical, -> { order(:login) } + scope :starting_with, -> (letter) { where('login like ?', "#{letter}%") } + scope :valid, -> { where(banned: false, suspended: false) } + scope :out_of_invites, -> { where(out_of_invites: true) } + + validates :login, + length: { within: ArchiveConfig.LOGIN_LENGTH_MIN..ArchiveConfig.LOGIN_LENGTH_MAX }, + format: { + with: /\A[A-Za-z0-9]\w*[A-Za-z0-9]\Z/, + min_login: ArchiveConfig.LOGIN_LENGTH_MIN, + max_login: ArchiveConfig.LOGIN_LENGTH_MAX + }, + uniqueness: true, + not_forbidden_name: { if: :will_save_change_to_login? } + validate :username_is_not_recently_changed, if: :will_save_change_to_login? + validate :admin_username_generic, if: :will_save_change_to_login? + + # allow nil so can save existing users + validates_length_of :password, + within: ArchiveConfig.PASSWORD_LENGTH_MIN..ArchiveConfig.PASSWORD_LENGTH_MAX, + allow_nil: true, + too_short: ts("is too short (minimum is %{min_pwd} characters)", + min_pwd: ArchiveConfig.PASSWORD_LENGTH_MIN), + too_long: ts("is too long (maximum is %{max_pwd} characters)", + max_pwd: ArchiveConfig.PASSWORD_LENGTH_MAX) + + validates :email, email_format: true, uniqueness: true + + # Virtual attribute for age check, data processing agreement, and terms of service + attr_accessor :age_over_13, :data_processing, :terms_of_service + + validates :data_processing, acceptance: { allow_nil: false, if: :first_save? } + validates :age_over_13, acceptance: { allow_nil: false, if: :first_save? } + validates :terms_of_service, acceptance: { allow_nil: false, if: :first_save? } + + def to_param + login + end + + # Override of Devise method to allow user to login with login OR username as + # well as to make login case insensitive without losing user-preferred case + # for login display + def self.find_first_by_auth_conditions(tainted_conditions, options = {}) + conditions = devise_parameter_filter.filter(tainted_conditions).merge(options) + login = conditions.delete(:login) + relation = self.where(conditions) + + if login.present? + # MySQL is case-insensitive with utf8mb4_unicode_ci so we don't have to use + # lowercase values + relation = relation.where(["login = :value OR email = :value", + value: login]) + end + + relation.first + end + + def self.for_claims(claims_ids) + joins(:request_claims). + where("challenge_claims.id IN (?)", claims_ids) + end + + scope :with_includes_for_admin_index, -> { includes(:roles, :fannish_next_of_kin) } + + def self.search_multiple_by_email(emails = []) + # Normalise and dedupe emails + all_emails = emails.map(&:downcase) + unique_emails = all_emails.uniq + # Find users and their email addresses + users = User.where(email: unique_emails) + found_emails = users.map(&:email).map(&:downcase) + # Remove found users from the total list of unique emails and count duplicates + not_found_emails = unique_emails - found_emails + num_duplicates = emails.size - unique_emails.size + + [users, not_found_emails, num_duplicates] + end + + ### AUTHENTICATION AND PASSWORDS + def active? + !confirmed_at.nil? + end + + def activate + return false if self.active? + self.update_attribute(:confirmed_at, Time.now.utc) + end + + def create_default_associateds + self.pseuds << Pseud.new(name: self.login, is_default: true) + self.profile = Profile.new + self.preference = Preference.new(locale: Locale.default) + end + + def prevent_password_resets? + is_protected_user? || no_resets? + end + + protected + + def first_save? + self.new_record? + end + + # Override of Devise method for email sending to set I18n.locale + # Based on https://github.com/heartcombo/devise/blob/v4.9.3/lib/devise/models/authenticatable.rb#L200 + def send_devise_notification(notification, *args) + I18n.with_locale(preference.locale_for_mails) do + devise_mailer.send(notification, self, *args).deliver_now + end + end + + public + + # Returns an array (of pseuds) of this user's co-authors + def coauthors + works.collect(&:pseuds).flatten.uniq - pseuds + end + + # Gets the user's most recent unposted work + def unposted_work + return @unposted_work if @unposted_work + @unposted_work = unposted_works.first + end + + def unposted_works + return @unposted_works if @unposted_works + @unposted_works = works.where(posted: false).order("works.created_at DESC") + end + + # removes ALL unposted works + def wipeout_unposted_works + works.where(posted: false).destroy_all + end + + # Removes all of the user's series that don't have any listed works. + def destroy_empty_series + series.left_joins(:serial_works).where(serial_works: { id: nil }). + destroy_all + end + + # Checks authorship of any sort of object + def is_author_of?(item) + if item.respond_to?(:pseud_id) + pseud_ids.include?(item.pseud_id) + elsif item.respond_to?(:user_id) + id == item.user_id + elsif item.respond_to?(:pseuds) + item.pseuds.pluck(:user_id).include?(id) + elsif item.respond_to?(:author) + self == item.author + elsif item.respond_to?(:creator_id) + self.id == item.creator_id + else + false + end + end + + # Gets the number of works by this user that the current user can see + def visible_work_count + Work.owned_by(self).visible_to_user(User.current_user).revealed.non_anon.distinct.count(:id) + end + + # Gets the user account for authored objects if orphaning is enabled + def self.orphan_account + User.fetch_orphan_account if ArchiveConfig.ORPHANING_ALLOWED + end + + # Is this user an authorized tag wrangler? + def tag_wrangler + self.is_tag_wrangler? + end + + def is_tag_wrangler? + has_role?(:tag_wrangler) + end + + # Is this user an authorized archivist? + def archivist + self.is_archivist? + end + + def is_archivist? + has_role?(:archivist) + end + + # Is this user an authorized official? + def official + has_role?(:official) + end + + # Is this user a protected user? These are users experiencing certain types + # of harassment. + def protected_user + self.is_protected_user? + end + + def is_protected_user? + has_role?(:protected_user) + end + + # Is this user assigned the no resets role? These users do not wish to receive + # password resets. + def no_resets? + has_role?(:no_resets) + end + + # Should this user's comments be spam-checked? + def should_spam_check_comments? + # When account_age_threshold_for_comment_spam_check is 0, no users' comments should be spam-checked + (Time.current - created_at).seconds.in_days.to_i < AdminSetting.current.account_age_threshold_for_comment_spam_check + end + + # Creates log item tracking changes to user + def create_log_item(options = {}) + options.reverse_merge! note: "System Generated", user_id: self.id + LogItem.create(options) + end + + def update_last_wrangling_activity + return unless is_tag_wrangler? + + last_activity = LastWranglingActivity.find_or_create_by(user: self) + last_activity.touch + end + + # Returns true if user is the sole author of a work + # Should also be true if the user has used more than one of their pseuds on a work + def is_sole_author_of?(item) + other_pseuds = item.pseuds - pseuds + self.is_author_of?(item) && other_pseuds.blank? + end + + # Returns array of works where the user is the sole author + def sole_authored_works + @sole_authored_works = [] + works.where(posted: 1).each do |w| + if self.is_sole_author_of?(w) + @sole_authored_works << w + end + end + return @sole_authored_works + end + + # Returns array of the user's co-authored works + def coauthored_works + @coauthored_works = [] + works.where(posted: 1).each do |w| + unless self.is_sole_author_of?(w) + @coauthored_works << w + end + end + return @coauthored_works + end + + # Returns array of collections where the user is the sole author + def sole_owned_collections + self.collections.to_a.delete_if { |collection| !(collection.all_owners - pseuds).empty? } + end + + ### BETA INVITATIONS ### + + #If a new user has an invitation_token (meaning they were invited), the method sets the redeemed_at column for that invitation to Time.now + def mark_invitation_redeemed + unless self.invitation_token.blank? + invitation = Invitation.find_by(token: self.invitation_token) + if invitation + self.update_attribute(:invitation_id, invitation.id) + invitation.mark_as_redeemed(self) + end + end + end + + # Existing users should be removed from the invitations queue + def remove_from_queue + invite_request = InviteRequest.find_by(email: self.email) + invite_request.destroy if invite_request + end + + def fix_user_subscriptions + # Delete any subscriptions the user has to deleted items because this causes + # the user's subscription page to error + @subscriptions = subscriptions.includes(:subscribable) + @subscriptions.to_a.each do |sub| + if sub.name.nil? + sub.destroy + end + end + end + + def set_user_work_dates + # Fix user stats page error caused by the existence of works with nil revised_at dates + works.each do |work| + if work.revised_at.nil? + work.save + end + IndexQueue.enqueue(work, :main) + end + end + + def reindex_user_creations + IndexQueue.enqueue_ids(Work, works.pluck(:id), :main) + IndexQueue.enqueue_ids(Bookmark, bookmarks.pluck(:id), :main) + IndexQueue.enqueue_ids(Series, series.pluck(:id), :main) + IndexQueue.enqueue_ids(Pseud, pseuds.pluck(:id), :main) + end + + # Function to make it easier to retrieve info from the audits table. + # + # Looks up all past values of the given field, excluding the current value of + # the field: + def historic_values(field) + field = field.to_s + + audits.filter_map do |audit| + audit.audited_changes[field] + end.flatten.uniq.without(self[field]) + end + + private + + # Override the default Justifiable enabled check, because we only need to justify + # username changes at the moment. + def justification_enabled? + User.current_user.is_a?(Admin) && login_changed? + end + + # Create and/or return a user account for holding orphaned works + def self.fetch_orphan_account + orphan_account = User.find_or_create_by(login: "orphan_account") + if orphan_account.new_record? + Rails.logger.fatal "You must have a User with the login 'orphan_account'. Please create one." + end + orphan_account + end + + def update_pseud_name + return unless saved_change_to_login? && login_before_last_save.present? + old_pseud = pseuds.where(name: login_before_last_save).first + if login.downcase == login_before_last_save.downcase + old_pseud.name = login + old_pseud.save! + else + new_pseud = pseuds.where(name: login).first + # do nothing if they already have the matching pseud + if new_pseud.blank? + if old_pseud.present? + # change the old pseud to match + old_pseud.name = login + old_pseud.save!(validate: false) + else + # shouldn't be able to get here, but just in case + Pseud.create!(name: login, user_id: id) + end + end + end + end + + def reindex_user_creations_after_rename + return unless saved_change_to_login? && login_before_last_save.present? + # Everything is indexed with the user's byline, + # which has the old username, so they all need to be reindexed. + reindex_user_creations + end + + def add_renamed_at + if User.current_user == self + self.renamed_at = Time.current + else + self.admin_renamed_at = Time.current + end + end + + def log_change_if_login_was_edited + current_admin = User.current_user if User.current_user.is_a?(Admin) + options = { + action: ArchiveConfig.ACTION_RENAME, + admin: current_admin + } + options[:note] = if current_admin + "Old Username: #{login_before_last_save}, New Username: #{login}, Changed by: #{current_admin.login}, Ticket ID: ##{ticket_number}" + else + "Old Username: #{login_before_last_save}; New Username: #{login}" + end + create_log_item(options) + end + + def send_wrangler_username_change_notification + return unless saved_change_to_login? && login_before_last_save.present? + + TagWranglingSupervisorMailer.wrangler_username_change_notification(login_before_last_save, login).deliver_now + end + + def log_email_change + current_admin = User.current_user if User.current_user.is_a?(Admin) + options = { + action: ArchiveConfig.ACTION_NEW_EMAIL, + admin_id: current_admin&.id + } + options[:note] = "Change made by #{current_admin&.login}" if current_admin + create_log_item(options) + end + + def remove_stale_from_autocomplete + self.class.remove_from_autocomplete(self.autocomplete_search_string_was, self.autocomplete_prefixes, self.autocomplete_value_was) + end + + def username_is_not_recently_changed + return if User.current_user.is_a?(Admin) + + change_interval_days = ArchiveConfig.USER_RENAME_LIMIT_DAYS + return unless renamed_at && change_interval_days.days.ago <= renamed_at + + errors.add(:login, + :changed_too_recently, + count: change_interval_days, + renamed_at: I18n.l(renamed_at)) + end + + def admin_username_generic + return unless User.current_user.is_a?(Admin) + + errors.add(:login, :admin_must_use_default) unless login == "user#{id}" + end + + # Extra callback to make sure readings are deleted in an order consistent + # with the ReadingsJob. + # + # TODO: In the long term, it might be better to change the indexes on the + # readings table so that it deletes things in the correct order by default if + # we just set dependent: :delete_all, but for now we need to explicitly sort + # by work_id to make sure that the readings are locked in the correct order. + before_destroy :clear_readings, prepend: true + def clear_readings + readings.order(:work_id).each(&:delete) + end +end + diff --git a/app/models/user_invite_request.rb b/app/models/user_invite_request.rb new file mode 100755 index 0000000..754e240 --- /dev/null +++ b/app/models/user_invite_request.rb @@ -0,0 +1,34 @@ +class UserInviteRequest < ApplicationRecord + MAX_USER_INVITE_REQUEST = ArchiveConfig.MAX_USER_INVITE_REQUEST + + belongs_to :user + validates_presence_of :quantity + validates_presence_of :reason + validates :quantity, numericality: {less_than_or_equal_to: MAX_USER_INVITE_REQUEST} + + before_update :check_status, :grant_request + + scope :not_handled, -> { where(handled: false) } + + private + + #Mark the request granted and/or handled as appropriate + def check_status + self.handled = true + if self.quantity > 0 + self.granted = true + end + end + + #Create new invitations for the user who requested them + def grant_request + if self.granted? + self.quantity.times do + self.user.invitations.create + end + I18n.with_locale(self.user.preference.locale_for_mails) do + UserMailer.invite_increase_notification(self.user.id, self.quantity).deliver_after_commit + end + end + end +end diff --git a/app/models/user_manager.rb b/app/models/user_manager.rb new file mode 100755 index 0000000..271aefe --- /dev/null +++ b/app/models/user_manager.rb @@ -0,0 +1,134 @@ +# Allows admins to manage user status via the admin users interface +class UserManager + attr_reader :admin, + :user, + :admin_note, + :admin_action, + :suspension_length, + :errors, + :successes + + PERMITTED_ACTIONS = %w[note warn suspend unsuspend ban unban spamban].freeze + + def initialize(admin, user, params) + @admin = admin + @user = user + @admin_note = params[:admin_note] + @admin_action = params[:admin_action] + @suspension_length = params[:suspend_days] + @errors = [] + @successes = [] + end + + def save + validate_user_and_admin && + validate_orphan_account && + validate_admin_note && + validate_suspension && + save_admin_action + end + + def success_message + successes.join(" ") + end + + def error_message + errors.join(" ") + end + + private + + def validate_user_and_admin + if user && admin + true + else + errors << "Must have a valid user and admin account to proceed." + false + end + end + + def validate_orphan_account + if user == User.orphan_account + errors << "orphan_account cannot be warned, suspended, or banned." + false + else + true + end + end + + def validate_admin_note + return true if admin_note.present? || admin_action.blank? + + if admin_action == "spamban" + @admin_note = "Banned for spam" + elsif admin_action.present? + errors << "You must include notes in order to perform this action." + false + end + end + + def validate_suspension + if admin_action == "suspend" && suspension_length.blank? + errors << "Please enter the number of days for which the user should be suspended." + false + else + true + end + end + + def save_admin_action + return true if admin_action.blank? + + send("#{admin_action}_user") if PERMITTED_ACTIONS.include?(admin_action) + end + + def note_user + log_action(ArchiveConfig.ACTION_NOTE) + successes << "Note was recorded." + end + + def warn_user + log_action(ArchiveConfig.ACTION_WARN) + successes << "Warning was recorded." + end + + def suspend_user + user.suspended = true + user.suspended_until = suspension_length.to_i.days.from_now + user.save! + log_action(ArchiveConfig.ACTION_SUSPEND, enddate: user.suspended_until) + successes << "User has been temporarily suspended." + end + + def unsuspend_user + user.suspended = false + user.suspended_until = nil + user.save! + log_action(ArchiveConfig.ACTION_UNSUSPEND) + successes << "Suspension has been lifted." + end + + def ban_user + user.banned = true + user.save! + log_action(ArchiveConfig.ACTION_BAN) + successes << "User has been permanently suspended." + end + alias spamban_user ban_user + + def unban_user + user.banned = false + user.save! + log_action(ArchiveConfig.ACTION_UNSUSPEND) + successes << "Suspension has been lifted." + end + + def log_action(message, options = {}) + options.merge!( + action: message, + note: admin_note, + admin_id: admin.id + ) + user.create_log_item(options) + end +end diff --git a/app/models/work.rb b/app/models/work.rb new file mode 100755 index 0000000..36ec2ee --- /dev/null +++ b/app/models/work.rb @@ -0,0 +1,1324 @@ +class Work < ApplicationRecord + include Filterable + include CreationNotifier + include Collectible + include Bookmarkable + include Searchable + include BookmarkCountCaching + include WorkChapterCountCaching + include Creatable + + ######################################################################## + # ASSOCIATIONS + ######################################################################## + + has_many :external_creatorships, as: :creation, dependent: :destroy, inverse_of: :creation + has_many :archivists, through: :external_creatorships + has_many :external_author_names, through: :external_creatorships, inverse_of: :works + has_many :external_authors, -> { distinct }, through: :external_author_names + + # we do NOT use dependent => destroy here because we want to destroy chapters in REVERSE order + has_many :chapters, inverse_of: :work, autosave: true + + has_many :serial_works, dependent: :destroy + has_many :series, through: :serial_works + + has_many :related_works, as: :parent + has_many :approved_related_works, -> { where(reciprocal: 1) }, as: :parent, class_name: "RelatedWork" + has_many :parent_work_relationships, class_name: "RelatedWork", dependent: :destroy + has_many :children, through: :related_works, source: :work + has_many :approved_children, through: :approved_related_works, source: :work + + accepts_nested_attributes_for :parent_work_relationships, allow_destroy: true, reject_if: proc { |attrs| attrs.values_at(:url, :author, :title).all?(&:blank?) } + + has_many :gifts, dependent: :destroy + accepts_nested_attributes_for :gifts, allow_destroy: true + + has_many :subscriptions, as: :subscribable, dependent: :destroy + + has_many :challenge_assignments, as: :creation + has_many :challenge_claims, as: :creation + accepts_nested_attributes_for :challenge_claims + + acts_as_commentable + has_many :total_comments, class_name: 'Comment', through: :chapters + has_many :kudos, as: :commentable, dependent: :destroy + + has_many :original_creators, class_name: "WorkOriginalCreator", dependent: :destroy + + belongs_to :language + belongs_to :work_skin + validate :work_skin_allowed, on: :save + def work_skin_allowed + unless self.users.include?(self.work_skin.author) || (self.work_skin.public? && self.work_skin.official?) + errors.add(:base, ts("You do not have permission to use that custom work stylesheet.")) + end + end + # statistics + has_one :stat_counter, dependent: :destroy + after_create :create_stat_counter + def create_stat_counter + counter = self.build_stat_counter + counter.save + end + # moderation + has_one :moderated_work, dependent: :destroy + + ######################################################################## + # VIRTUAL ATTRIBUTES + ######################################################################## + + # Virtual attribute to use as a placeholder for pseuds before the work has been saved + # Can't write to work.pseuds until the work has an id + attr_accessor :new_parent, :url_for_parent + attr_accessor :new_gifts + attr_accessor :preview_mode + + # Virtual attribute for whether the hidden-for-spam email has been sent, so the normal work-hidden email should not be sent + attr_accessor :notified_of_hiding_for_spam + + # return title.html_safe to overcome escaping done by sanitiser + def title + read_attribute(:title).try(:html_safe) + end + + ######################################################################## + # VALIDATION + ######################################################################## + validates_presence_of :title + validates_length_of :title, + minimum: ArchiveConfig.TITLE_MIN, + too_short: ts("must be at least %{min} characters long.", min: ArchiveConfig.TITLE_MIN) + + validates_length_of :title, + maximum: ArchiveConfig.TITLE_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.TITLE_MAX) + + validates_length_of :summary, + allow_blank: true, + maximum: ArchiveConfig.SUMMARY_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.SUMMARY_MAX) + + validates_length_of :notes, + allow_blank: true, + maximum: ArchiveConfig.NOTES_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.NOTES_MAX) + + validates_length_of :endnotes, + allow_blank: true, + maximum: ArchiveConfig.NOTES_MAX, + too_long: ts("must be less than %{max} characters long.", max: ArchiveConfig.NOTES_MAX) + + validate :language_present_and_supported + + def language_present_and_supported + errors.add(:base, ts("Language cannot be blank.")) if self.language.blank? + end + + # Makes sure the title has no leading spaces + validate :clean_and_validate_title + + def clean_and_validate_title + unless self.title.blank? + self.title = self.title.strip + if self.title.length < ArchiveConfig.TITLE_MIN + errors.add(:base, ts("Title must be at least %{min} characters long without leading spaces.", min: ArchiveConfig.TITLE_MIN)) + throw :abort + else + self.title_to_sort_on = self.sorted_title + end + end + end + + def validate_published_at + return unless first_chapter + + if !self.first_chapter.published_at + self.first_chapter.published_at = Date.current + elsif self.first_chapter.published_at > Date.current + errors.add(:base, ts("Publication date can't be in the future.")) + throw :abort + end + end + + validates :fandom_string, + presence: { message: "^Please fill in at least one fandom." } + validates :archive_warning_string, + presence: { message: "^Please select at least one warning." } + validates :rating_string, + presence: { message: "^Please choose a rating." } + + validate :only_one_rating + def only_one_rating + return unless split_tag_string(rating_string).count > 1 + + errors.add(:base, ts("Only one rating is allowed.")) + end + + # rephrases the "chapters is invalid" message + after_validation :check_for_invalid_chapters + def check_for_invalid_chapters + if self.errors[:chapters].any? + self.errors.add(:base, ts("Please enter your story in the text field below.")) + self.errors.delete(:chapters) + end + end + + validates :user_defined_tags_count, + at_most: { maximum: proc { ArchiveConfig.USER_DEFINED_TAGS_MAX } } + + # If the recipient doesn't allow gifts, it should not be possible to give them + # a gift work unless it fulfills a gift exchange assignment or non-anonymous + # prompt meme claim for the recipient. + # We don't want the work to save if the gift shouldn't exist, but the gift + # model can't access a work's challenge_assignments or challenge_claims until + # the work and its assignments and claims are saved. Gifts are created after + # the work is saved, so it's too late then to prevent the work from saving. + # Additionally, the work's assignments and claims don't appear to be available + # by the time gift validations run, which means the gift is never created if + # the user doesn't allow them. + validate :new_recipients_allow_gifts + + def new_recipients_allow_gifts + return if self.new_gifts.blank? + + self.new_gifts.each do |gift| + next if gift.pseud.blank? + next if gift.pseud&.user&.preference&.allow_gifts? + next if challenge_bypass(gift) + + self.errors.add(:base, :blocked_gifts, byline: gift.pseud.byline) + end + end + + validate :new_recipients_have_not_blocked_gift_giver + def new_recipients_have_not_blocked_gift_giver + return if self.new_gifts.blank? + + self.new_gifts.each do |gift| + # Already dealt with in #new_recipients_allow_gifts + next if gift.pseud&.user&.preference && !gift.pseud.user.preference.allow_gifts? + + next if challenge_bypass(gift) + + blocked_users = gift.pseud&.user&.blocked_users || [] + next if blocked_users.empty? + + pseuds_after_saving.each do |pseud| + next unless blocked_users.include?(pseud.user) + + if User.current_user == pseud.user + self.errors.add(:base, :blocked_your_gifts, byline: gift.pseud.byline) + else + self.errors.add(:base, :blocked_gifts, byline: gift.pseud.byline) + end + end + end + end + + enum :comment_permissions, { + enable_all: 0, + disable_anon: 1, + disable_all: 2 + }, suffix: :comments, default: 1 + + ######################################################################## + # HOOKS + # These are methods that run before/after saves and updates to ensure + # consistency and that associated variables are updated. + ######################################################################## + + before_save :clean_and_validate_title, :validate_published_at, :ensure_revised_at + + after_save :post_first_chapter + before_save :set_word_count + + after_save :save_chapters, :save_new_gifts + + before_create :set_anon_unrevealed + after_create :notify_after_creation + + after_update :adjust_series_restriction, :notify_after_update + + before_save :hide_spam + after_save :moderate_spam + after_save :notify_of_hiding + + after_save :notify_recipients, :expire_caches, :update_pseud_index, :update_tag_index, :touch_series, :touch_related_works + after_destroy :expire_caches, :update_pseud_index + + before_destroy :send_deleted_work_notification, prepend: true + def send_deleted_work_notification + return unless self.posted? && users.present? + + orphan_account = User.orphan_account + users.each do |user| + next if user == orphan_account + + I18n.with_locale(user.preference.locale_for_mails) do + # Check to see if this work is being deleted by an Admin + if User.current_user.is_a?(Admin) + # this has to use the synchronous version because the work is going to be destroyed + UserMailer.admin_deleted_work_notification(user, self).deliver_now + else + # this has to use the synchronous version because the work is going to be destroyed + UserMailer.delete_work_notification(user, self, User.current_user).deliver_now + end + end + end + end + + def expire_caches + pseuds.each do |pseud| + pseud.update_works_index_timestamp! + pseud.user.update_works_index_timestamp! + end + + collections.each do |this_collection| + collection = this_collection + # Flush this collection and all its parents + loop do + collection.update_works_index_timestamp! + collection = collection.parent + break unless collection + end + end + + filters.each do |tag| + tag.update_works_index_timestamp! + end + + tags.each do |tag| + tag.update_tag_cache + end + + series.each(&:expire_caches) + + Work.expire_work_blurb_version(id) + Work.flush_find_by_url_cache unless imported_from_url.blank? + end + + def update_pseud_index + return unless should_reindex_pseuds? + IndexQueue.enqueue_ids(Pseud, pseud_ids, :background) + end + + # Visibility has changed, which means we need to reindex + # the work's pseuds, to update their work counts, as well as + # the work's bookmarker pseuds, to update their bookmark counts. + def should_reindex_pseuds? + pertinent_attributes = %w(id posted restricted in_anon_collection + in_unrevealed_collection hidden_by_admin) + destroyed? || (saved_changes.keys & pertinent_attributes).present? + end + + # If the work gets posted, (un)hidden, or (un)revealed, we should (potentially) reindex the tags, + # so they get the correct visibility status. + def update_tag_index + return unless saved_change_to_posted? || saved_change_to_hidden_by_admin? || saved_change_to_in_unrevealed_collection? + + taggings.each(&:update_search) + end + + def self.work_blurb_version_key(id) + "/v4/work_blurb_tag_cache_key/#{id}" + end + + def self.work_blurb_version(id) + Rails.cache.fetch(Work.work_blurb_version_key(id), raw: true) { rand(1..1000) } + end + + def self.expire_work_blurb_version(id) + Rails.cache.increment(Work.work_blurb_version_key(id)) + end + + # When works are done being reindexed, expire the appropriate caches + def self.successful_reindex(ids) + CacheMaster.expire_caches(ids) + tag_ids = FilterTagging.where(filterable_id: ids, filterable_type: 'Work'). + group(:filter_id). + pluck(:filter_id) + + collection_ids = CollectionItem.where(item_id: ids, item_type: 'Work'). + group(:collection_id). + pluck(:collection_id) + + pseuds = Pseud.select("pseuds.id, pseuds.user_id"). + joins(:creatorships). + where(creatorships: { + creation_id: ids, + creation_type: 'Work' + } + ) + + pseuds.each { |p| p.update_works_index_timestamp! } + User.expire_ids(pseuds.map(&:user_id).uniq) + Tag.expire_ids(tag_ids) + Collection.expire_ids(collection_ids) + end + + def touch_series + series.touch_all if saved_change_to_in_anon_collection? + end + + after_destroy :destroy_chapters_in_reverse + def destroy_chapters_in_reverse + chapters.sort_by(&:position).reverse.each(&:destroy) + end + + after_destroy :clean_up_assignments + def clean_up_assignments + self.challenge_assignments.each {|a| a.creation = nil; a.save!} + end + + ######################################################################## + # RESQUE + ######################################################################## + + include AsyncWithResque + @queue = :utilities + + ######################################################################## + # IMPORTING + ######################################################################## + + def self.find_by_url_generation_key + "/v1/find_by_url_generation_key" + end + + def self.find_by_url_generation + Rails.cache.fetch(Work.find_by_url_generation_key, raw: true) { rand(1..1000) } + end + + def self.flush_find_by_url_cache + Rails.cache.increment(Work.find_by_url_generation_key) + end + + def self.find_by_url_cache_key(url) + url = UrlFormatter.new(url) + "/v1/find_by_url/#{Work.find_by_url_generation}/#{url.encoded}" + end + + # Match `url` to a work's imported_from_url field using progressively fuzzier matching: + # 1. first exact match + # 2. first exact match with variants of the provided url + # 3. first match on variants of both the imported_from_url and the provided url if there is a partial match + + def self.find_by_url_uncached(url) + url = UrlFormatter.new(url) + Work.where(imported_from_url: url.original).first || + Work.where(imported_from_url: [url.minimal, + url.with_http, url.with_https, + url.no_www, url.with_www, + url.encoded, url.decoded, + url.minimal_no_protocol_no_www]).first || + Work.where("imported_from_url LIKE ? or imported_from_url LIKE ?", + "http://#{url.minimal_no_protocol_no_www}%", + "https://#{url.minimal_no_protocol_no_www}%").select do |w| + work_url = UrlFormatter.new(w.imported_from_url) + %w[original minimal no_www with_www with_http with_https encoded decoded].any? do |method| + work_url.send(method) == url.send(method) + end + end.first + end + + def self.find_by_url(url) + Rails.cache.fetch(Work.find_by_url_cache_key(url)) do + find_by_url_uncached(url) + end + end + + # Remove all pseuds associated with a particular user. Raises an exception if + # this would result in removing all creators from the work. + # + # Callbacks handle most of the work when deleting creatorships, but we do + # have one special case: if a co-created work has a chapter that only has + # one listed creator, and that creator removes themselves from the work, we + # need to update the chapter to add the other creators on the work. + def remove_author(author_to_remove) + pseuds_with_author_removed = pseuds.where.not(user_id: author_to_remove.id) + + if pseuds_with_author_removed.empty? + errors.add(:base, ts("Sorry, we can't remove all creators of a work.")) + raise ActiveRecord::RecordInvalid, self + end + + transaction do + chapters.each do |chapter| + if (chapter.pseuds - author_to_remove.pseuds).empty? + pseuds_with_author_removed.each do |new_pseud| + chapter.creatorships.find_or_create_by(pseud: new_pseud) + end + end + + chapter.creatorships.where(pseud: author_to_remove.pseuds).destroy_all + end + + creatorships.where(pseud: author_to_remove.pseuds).destroy_all + end + end + + # Override the default behavior so that we also check for creatorships + # associated with one of the chapters. + def user_is_owner_or_invited?(user) + return false unless user.is_a?(User) + return true if super + + chapters.joins(:creatorships).merge(user.creatorships).exists? + end + + def set_challenge_info + # if this is fulfilling a challenge, add the collection and recipient + challenge_assignments.each do |assignment| + add_to_collection(assignment.collection) + self.gifts << Gift.new(pseud: assignment.requesting_pseud) unless (assignment.requesting_pseud.blank? || recipients && recipients.include?(assignment.request_byline)) + end + end + + # If this is fulfilling a challenge claim, add the collection. + # + # Unlike set_challenge_info, we don't automatically add the prompter as a + # recipient, because (a) some prompters are anonymous, so there has to be a + # prompter notification (separate from the recipient notification) ensuring + # that anonymous prompters are notified, and (b) if the prompter is not + # anonymous, they'll receive two notifications with roughly the same info + # (gift notification + prompter notification). + def set_challenge_claim_info + challenge_claims.each do |claim| + add_to_collection(claim.collection) + end + end + + def challenge_assignment_ids + challenge_assignments.map(&:id) + end + + def challenge_claim_ids + challenge_claims.map(&:id) + end + + # Only allow a work to fulfill an assignment assigned to one of this work's authors + def challenge_assignment_ids=(ids) + valid_users = (self.users + [User.current_user]).compact + + self.challenge_assignments = + ChallengeAssignment.where(id: ids) + .select { |assign| valid_users.include?(assign.offering_user) } + end + + def recipients=(recipient_names) + new_gifts = [] + gifts = [] # rebuild the list of associated gifts using the new list of names + # add back in the rejected gift recips; we don't let users delete rejected gifts in order to prevent regifting + recip_names = recipient_names.split(',') + self.gifts.are_rejected.collect(&:recipient) + recip_names.uniq.each do |name| + name.strip! + gift = self.gifts.for_name_or_byline(name).first + if gift + gifts << gift # new gifts are added after saving, not now + new_gifts << gift unless self.posted # all gifts are new if work not posted + else + g = self.gifts.new(recipient: name) + if g.valid? + new_gifts << g # new gifts are added after saving, not now + else + g.errors.full_messages.each { |msg| self.errors.add(:base, msg) } + end + end + end + self.gifts = gifts + self.new_gifts = new_gifts + end + + def recipients(for_form = false) + names = (for_form ? self.gifts.not_rejected : self.gifts).collect(&:recipient) + names << self.new_gifts.collect(&:recipient) if self.new_gifts.present? + names.flatten.uniq.join(",") + end + + def save_new_gifts + return if self.new_gifts.blank? + + self.new_gifts.each do |gift| + next if self.gifts.for_name_or_byline(gift.recipient).present? + + # Recreate the gift once the work is saved. This ensures the work_id is + # set properly. + Gift.create(recipient: gift.recipient, work: self) + end + end + + def marked_for_later?(user) + Reading.where(work_id: self.id, user_id: user.id, toread: true).exists? + end + + ######################################################################## + # VISIBILITY + ######################################################################## + + def visible?(user = User.current_user) + return true if user.is_a?(Admin) + + if posted && !hidden_by_admin + user.is_a?(User) || !restricted + else + user_is_owner_or_invited?(user) + end + end + + def unrevealed?(user=User.current_user) + # eventually here is where we check if it's in a challenge that hasn't been made public yet + #!self.collection_items.unrevealed.empty? + in_unrevealed_collection? + end + + def anonymous?(user = User.current_user) + # here we check if the story is in a currently-anonymous challenge + #!self.collection_items.anonymous.empty? + in_anon_collection? + end + + before_update :bust_anon_caching + def bust_anon_caching + if in_anon_collection_changed? + async(:poke_cached_creator_comments) + end + end + + # This work's collections and parent collections + def all_collections + Collection.where(id: self.collection_ids) || [] + end + + ######################################################################## + # VERSIONS & REVISION DATES + ######################################################################## + + def set_revised_at(date=nil) + date ||= self.chapters.where(posted: true).maximum('published_at') || + self.revised_at || self.created_at || Time.current + + if date.instance_of?(Date) + # We need a time, not a Date. So if the date is today, set it to the + # current time; otherwise, set it to noon UTC (so that almost every + # single time zone will have the revised_at date match the published_at + # date, and those that don't will have revised_at follow published_at). + date = (date == Date.current) ? Time.current : date.to_time(:utc).noon + end + + self.revised_at = date + end + + def set_revised_at_by_chapter(chapter) + # Invalidate chapter count cache + self.invalidate_work_chapter_count(self) + return if self.posted? && !chapter.posted? + + unless self.posted_changed? + if chapter.posted_changed? + self.major_version = self.major_version + 1 + else + self.minor_version = self.minor_version + 1 + end + end + + if (self.new_record? || chapter.posted_changed?) && chapter.published_at == Date.current + self.set_revised_at(Time.current) # a new chapter is being posted, so most recent update is now + else + # Calculate the most recent chapter publication date: + max_date = self.chapters.where('id != ? AND posted = 1', chapter.id).maximum('published_at') + max_date = max_date.nil? ? chapter.published_at : [max_date, chapter.published_at].max + + # Update revised_at to match the chapter publication date unless the + # dates already match: + set_revised_at(max_date) unless revised_at && revised_at.to_date == max_date + end + end + + # Just to catch any cases that haven't gone through set_revised_at + def ensure_revised_at + self.set_revised_at if self.revised_at.nil? + end + + def published_at + self.first_chapter.published_at + end + + # ensure published_at date is correct: reset its value for non-backdated works + # "chapter" arg should be the unsaved session instance of the work's first chapter + def reset_published_at(chapter) + if !self.backdate + if self.backdate_changed? # work was backdated but now it's not + # so reset its date to our best guess at its original pub date: + chapter.published_at = self.created_at.to_date + else # pub date may have changed without user's explicitly setting backdate option + # so reset it to the previous value: + chapter.published_at = chapter.published_at_was || Date.current + end + end + end + + def default_date + backdate = first_chapter.try(:published_at) if self.backdate + backdate || Date.current + end + + ######################################################################## + # SERIES + ######################################################################## + + # Virtual attribute for series + def series_attributes=(attributes) + if !attributes[:id].blank? + old_series = Series.find(attributes[:id]) + if old_series.pseuds.none? { |pseud| pseud.user == User.current_user } + errors.add(:base, ts("You can't add a work to that series.")) + return + end + unless old_series.blank? || self.series.include?(old_series) + self.serial_works.build(series: old_series) + end + elsif !attributes[:title].blank? + new_series = Series.new + new_series.title = attributes[:title] + new_series.restricted = self.restricted + (User.current_user.pseuds & self.pseuds_after_saving).each do |pseud| + # Only add the current user's pseuds now -- the after_create callback + # on the serial work will do the rest. + new_series.creatorships.build(pseud: pseud) + end + self.serial_works.build(series: new_series) + end + end + + # Make sure the series restriction level is in line with its works + def adjust_series_restriction + unless self.series.blank? + self.series.each {|s| s.adjust_restricted } + end + end + + ######################################################################## + # CHAPTERS + ######################################################################## + + # Save chapter data when the work is updated + def save_chapters + !self.chapters.first.save(validate: false) + end + + # If the work is posted, the first chapter should be posted too + def post_first_chapter + chapter_one = self.first_chapter + + return unless self.saved_change_to_posted? && self.posted + return if chapter_one&.posted + + chapter_one.published_at = Date.current unless self.backdate + chapter_one.posted = true + chapter_one.save + end + + # Virtual attribute for first chapter + def chapter_attributes=(attributes) + self.new_record? ? self.chapters.build(attributes) : self.chapters.first.attributes = attributes + self.chapters.first.posted = self.posted + end + + # Virtual attribute for # of chapters + def wip_length + self.expected_number_of_chapters.nil? ? "?" : self.expected_number_of_chapters + end + + def wip_length=(number) + number = number.to_i + self.expected_number_of_chapters = (number != 0 && number >= self.chapters.length) ? number : nil + end + + # Change the positions of the chapters in the work + def reorder_list(positions) + SortableList.new(chapters_in_order(include_drafts: true)).reorder_list(positions) + # We're caching the chapter positions in the comment blurbs + # so we need to expire them + async(:poke_cached_comments) + end + + def poke_cached_comments + self.comments.each { |c| c.touch } + end + + def poke_cached_creator_comments + self.creator_comments.each { |c| c.touch } + end + + # Get the total number of chapters for a work + def number_of_chapters + Rails.cache.fetch(key_for_chapter_total_counting(self)) do + self.chapters.count + end + end + + # Get the total number of posted chapters for a work + # Issue 1316: total number needs to reflect the actual number of chapters posted + # rather than the total number of chapters indicated by user + def number_of_posted_chapters + Rails.cache.fetch(key_for_chapter_posted_counting(self)) do + self.chapters.posted.count + end + end + + def chapters_in_order(include_drafts: false, include_content: true) + # in order + chapters = self.chapters.order('position ASC') + # only posted chapters unless specified + chapters = chapters.where(posted: true) unless include_drafts + # when doing navigation pass false as contents are not needed + chapters = chapters.select('published_at, id, work_id, title, position, posted') unless include_content + chapters + end + + # Gets the current first chapter + def first_chapter + if self.new_record? + self.chapters.first || self.chapters.build + else + self.chapters.order('position ASC').first + end + end + + # Gets the current last chapter + def last_chapter + self.chapters.order('position DESC').first + end + + # Gets the current last posted chapter + def last_posted_chapter + self.chapters.posted.order('position DESC').first + end + + # Returns true if a work has or will have more than one chapter + def chaptered? + self.expected_number_of_chapters != 1 + end + + # Returns true if a work has more than one chapter + def multipart? + self.number_of_chapters > 1 + end + + after_save :update_complete_status + # Note: this can mark a work complete but it can also mark a complete work + # as incomplete if its status has changed + def update_complete_status + # self.chapters.posted.count ( not self.number_of_posted_chapter , here be dragons ) + self.complete = self.chapters.posted.count == expected_number_of_chapters + if self.will_save_change_to_attribute?(:complete) + Work.where(id: id).update_all(["complete = ?", complete]) + end + end + + # Returns true if a work is not yet complete + def is_wip + self.expected_number_of_chapters.nil? || self.expected_number_of_chapters != self.number_of_posted_chapters + end + + # Returns true if a work is complete + def is_complete + return !self.is_wip + end + + # Set the value of word_count to reflect the length of the chapter content + # Called before_save + def set_word_count(preview = false) + if self.new_record? || preview + self.word_count = 0 + chapters.each do |chapter| + self.word_count += chapter.set_word_count + end + else + # AO3-3498: For posted works, the word count is visible to people other than the creator and + # should only include posted chapters. For drafts, we can count everything. + self.word_count = if self.posted + Chapter.select("SUM(word_count) AS work_word_count").where(work_id: self.id, posted: true).first.work_word_count + else + Chapter.select("SUM(word_count) AS work_word_count").where(work_id: self.id).first.work_word_count + end + end + end + + ####################################################################### + # TAGGING + # Works are taggable objects. + ####################################################################### + + # When the filters on a work change, we need to perform some extra checks. + def self.reindex_for_filter_changes(ids, filter_taggings, queue) + # The crossover/OTP status of a work can change without actually changing + # the filters (e.g. if you have a work tagged with canonical fandom A and + # unfilterable fandom B, synning B to A won't change the work's filters, + # but the work will immediately stop qualifying as a crossover). So we want + # to reindex all works whose filters were checked, not just the works that + # had their filters changed. + IndexQueue.enqueue_ids(Work, ids, queue) + + # Only works are included in the filter count, so if a work's + # filter-taggings change, the FilterCount probably needs updating. + FilterCount.enqueue_filters(filter_taggings.map(&:filter_id)) + + # From here, we only want to update works whose filter_taggings have + # actually changed. + changed_ids = filter_taggings.map(&:filterable_id) + return unless changed_ids.present? + + # Reindex any series associated with works whose filters have changed. + series_ids = SerialWork.where(work_id: changed_ids).pluck(:series_id) + IndexQueue.enqueue_ids(Series, series_ids, queue) + + # Reindex any pseuds associated with works whose filters have changed. + pseud_ids = Creatorship.where(creation_id: changed_ids, + creation_type: "Work", + approved: true).pluck(:pseud_id) + IndexQueue.enqueue_ids(Pseud, pseud_ids, queue) + end + + # FILTERING CALLBACKS + after_save :adjust_filter_counts + + # We need to do a recount for our filters if: + # - the work is brand new + # - the work is posted from a draft + # - the work is hidden or unhidden by an admin + # - the work's restricted status has changed + # Note that because the two filter counts both include unrevealed works, we + # don't need to check whether in_unrevealed_collection has changed -- it + # won't change the counts either way. + # (Modelled on Work.should_reindex_pseuds?) + def should_reset_filters? + pertinent_attributes = %w(id posted restricted hidden_by_admin) + (saved_changes.keys & pertinent_attributes).present? + end + + # Recalculates filter counts on all the work's filters + def adjust_filter_counts + FilterCount.enqueue_filters(filters.reload) if should_reset_filters? + end + + ################################################################################ + # COMMENTING & BOOKMARKS + # We don't actually have comments on works currently but on chapters. + # Comment support -- work acts as a commentable object even though really we + # override to consolidate the comments on all the chapters. + ################################################################################ + + # Gets all comments for all chapters in the work + def find_all_comments + Comment.where( + parent_type: 'Chapter', + parent_id: self.chapters.pluck(:id) + ) + end + + # Returns number of comments + # Hidden and deleted comments are referenced in the view because of + # the threading system - we don't necessarily need to + # hide their existence from other users + def count_all_comments + find_all_comments.count + end + + # Count the number of comment threads visible to the user (i.e. excluding + # threads that have been marked as spam). Used on the work stats page. + def comment_thread_count + comments.where(approved: true).count + end + + # returns the top-level comments for all chapters in the work + def comments + Comment.where( + commentable_type: 'Chapter', + commentable_id: self.chapters.pluck(:id) + ) + end + + # All comments left by the creators of this work + def creator_comments + pseud_ids = Pseud.where(user_id: self.pseuds.pluck(:user_id)).pluck(:id) + find_all_comments.where(pseud_id: pseud_ids) + end + + def guest_kudos_count + Rails.cache.fetch "works/#{id}/guest_kudos_count-v2" do + kudos.by_guest.count + end + end + + def all_kudos_count + Rails.cache.fetch "works/#{id}/kudos_count-v2" do + kudos.count + end + end + + def update_stat_counter + counter = self.stat_counter || self.create_stat_counter + counter.update( + kudos_count: self.kudos.count, + comments_count: self.count_visible_comments_uncached, + bookmarks_count: self.bookmarks.where(private: false).count + ) + end + + ######################################################################## + # RELATED WORKS + # These are for inspirations/remixes/etc + ######################################################################## + + def parents_after_saving + parent_work_relationships.reject(&:marked_for_destruction?) + end + + def touch_related_works + return unless saved_change_to_in_unrevealed_collection? + + # Make sure download URLs of child and parent works expire to preserve anonymity. + children.touch_all + parents_after_saving.each { |rw| rw.parent.touch } + end + + ################################################################################# + # + # In this section we define various named scopes that can be chained together + # to do finds in the database + # + ################################################################################# + + public + + scope :id_only, -> { select("works.id") } + + scope :ordered_by_title_desc, -> { order("title_to_sort_on DESC") } + scope :ordered_by_title_asc, -> { order("title_to_sort_on ASC") } + scope :ordered_by_word_count_desc, -> { order("word_count DESC") } + scope :ordered_by_word_count_asc, -> { order("word_count ASC") } + scope :ordered_by_hit_count_desc, -> { order("hit_count DESC") } + scope :ordered_by_hit_count_asc, -> { order("hit_count ASC") } + scope :ordered_by_date_desc, -> { order("revised_at DESC") } + scope :ordered_by_date_asc, -> { order("revised_at ASC") } + + scope :recent, lambda { |*args| where("revised_at > ?", (args.first || 4.weeks.ago.to_date)) } + scope :within_date_range, lambda { |*args| where("revised_at BETWEEN ? AND ?", (args.first || 4.weeks.ago), (args.last || Time.now)) } + scope :posted, -> { where(posted: true) } + scope :unposted, -> { where(posted: false) } + scope :not_spam, -> { where(spam: false) } + scope :restricted , -> { where(restricted: true) } + scope :unrestricted, -> { where(restricted: false) } + scope :hidden, -> { where(hidden_by_admin: true) } + scope :unhidden, -> { where(hidden_by_admin: false) } + scope :visible_to_all, -> { posted.unrestricted.unhidden } + scope :visible_to_registered_user, -> { posted.unhidden } + scope :visible_to_admin, -> { posted } + scope :visible_to_owner, -> { posted } + scope :all_with_tags, -> { includes(:tags) } + + scope :giftworks_for_recipient_name, lambda { |name| select("DISTINCT works.*").joins(:gifts).where("recipient_name = ?", name).where("gifts.rejected = FALSE") } + + scope :non_anon, -> { where(in_anon_collection: false) } + scope :unrevealed, -> { where(in_unrevealed_collection: true) } + scope :revealed, -> { where(in_unrevealed_collection: false) } + scope :latest, -> { visible_to_all. + revealed. + order("revised_at DESC"). + limit(ArchiveConfig.ITEMS_PER_PAGE) } + + # a complicated dynamic scope here: + # if the user is an Admin, we use the "visible_to_admin" scope + # if the user is not a logged-in User, we use the "visible_to_all" scope + # otherwise, we use a join to get userids and then get all posted works that are either unhidden OR belong to this user. + # Note: in that last case we have to use select("DISTINCT works.") because of cases where the same user appears twice + # on a work. + def self.visible_to_user(user=User.current_user) + case user.class.to_s + when 'Admin' + visible_to_admin + when 'User' + select("DISTINCT works.*"). + posted. + joins({pseuds: :user}). + where("works.hidden_by_admin = false OR users.id = ?", user.id) + else + visible_to_all + end + end + + # Use the current user to determine what works are visible + def self.visible(user=User.current_user) + visible_to_user(user) + end + + scope :owned_by, lambda {|user| select("DISTINCT works.*").joins({pseuds: :user}).where('users.id = ?', user.id)} + + def self.in_series(series) + joins(:series). + where("series.id = ?", series.id) + end + + scope :with_columns_for_blurb, lambda { + select(:id, :created_at, :updated_at, :expected_number_of_chapters, + :posted, :language_id, :restricted, :title, :summary, :word_count, + :hidden_by_admin, :revised_at, :complete, :in_anon_collection, + :in_unrevealed_collection, :summary_sanitizer_version) + } + + scope :with_includes_for_blurb, lambda { + includes(:pseuds, :approved_collections, :stat_counter) + } + + scope :for_blurb, -> { with_columns_for_blurb.with_includes_for_blurb } + + ######################################################################## + # SORTING + ######################################################################## + + SORTED_AUTHOR_REGEX = %r{^[\+\-=_\?!'"\.\/]} + + def authors_to_sort_on + if self.anonymous? + "Anonymous" + else + self.pseuds.sort.map(&:name).join(", ").downcase.gsub(SORTED_AUTHOR_REGEX, '') + end + end + + def sorted_title + sorted_title = self.title.downcase.gsub(/^["'\.\/]/, '') + sorted_title = sorted_title.gsub(/^(an?) (.*)/, '\2, \1') + sorted_title = sorted_title.gsub(/^the (.*)/, '\1, the') + sorted_title = sorted_title.rjust(5, "0") if sorted_title.match(/^\d/) + sorted_title + end + + # sort works by title + def <=>(another_work) + self.title_to_sort_on <=> another_work.title_to_sort_on + end + + ######################################################################## + # SPAM CHECKING + ######################################################################## + + def akismet_attributes + content = chapters_in_order(include_drafts: true).map(&:content).join + user = users.first + { + comment_type: "fanwork-post", + key: ArchiveConfig.AKISMET_KEY, + blog: ArchiveConfig.AKISMET_NAME, + user_ip: ip_address, + user_role: "user", + comment_date_gmt: created_at.to_time.iso8601, + blog_lang: language.short, + comment_author: user.login, + comment_author_email: user.email, + comment_content: content + } + end + + def spam_checked? + spam_checked_at.present? + end + + def check_for_spam + return unless %w(staging production).include?(Rails.env) + self.spam = Akismetor.spam?(akismet_attributes) + self.spam_checked_at = Time.now + save + end + + def hide_spam + return unless spam? + admin_settings = AdminSetting.current + if admin_settings.hide_spam? + return if self.hidden_by_admin + + self.hidden_by_admin = true + notify_of_hiding_for_spam + end + end + + def moderate_spam + ModeratedWork.register(self) if spam? + end + + def mark_as_spam! + update_attribute(:spam, true) + ModeratedWork.mark_reviewed(self) + # don't submit spam reports unless in production mode + Rails.env.production? && Akismetor.submit_spam(akismet_attributes) + end + + def mark_as_ham! + update(spam: false, hidden_by_admin: false) + ModeratedWork.mark_approved(self) + # don't submit ham reports unless in production mode + Rails.env.production? && Akismetor.submit_ham(akismet_attributes) + end + + def notify_of_hiding + return unless hidden_by_admin? && saved_change_to_hidden_by_admin? + return if notified_of_hiding_for_spam + + users.each do |user| + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.admin_hidden_work_notification([id], user.id).deliver_after_commit + end + end + end + + def notify_of_hiding_for_spam + users.each do |user| + I18n.with_locale(user.preference.locale_for_mails) do + UserMailer.admin_spam_work_notification(id, user.id).deliver_after_commit + end + end + self.notified_of_hiding_for_spam = true + end + + ############################################################################# + # + # SEARCH INDEX + # + ############################################################################# + + def document_json + WorkIndexer.new({}).document(self) + end + + def bookmarkable_json + as_json( + root: false, + only: [ + :title, :summary, :hidden_by_admin, :restricted, :posted, + :created_at, :revised_at, :word_count, :complete + ], + methods: [ + :tag, :filter_ids, :rating_ids, :archive_warning_ids, :category_ids, + :fandom_ids, :character_ids, :relationship_ids, :freeform_ids, + :creators, :collection_ids, :work_types + ] + ).merge( + language_id: language&.short, + anonymous: anonymous?, + unrevealed: unrevealed?, + pseud_ids: anonymous? || unrevealed? ? nil : pseud_ids, + user_ids: anonymous? || unrevealed? ? nil : user_ids, + bookmarkable_type: 'Work', + bookmarkable_join: { name: "bookmarkable" } + ) + end + + def collection_ids + approved_collections.pluck(:id, :parent_id).flatten.uniq.compact + end + + delegate :comments_count, :kudos_count, :bookmarks_count, + to: :stat_counter, allow_nil: true + + def hits + stat_counter&.hit_count + end + + def creators + if anonymous? + ["Anonymous"] + else + pseuds.map(&:byline) + external_author_names.pluck(:name) + end + end + + # A work with multiple fandoms which are not related + # to one another can be considered a crossover + def crossover + # Short-circuit the check if there's only one fandom tag: + return false if fandoms.size == 1 + + # Replace fandoms with their mergers if possible, + # as synonyms should have no meta tags themselves + all_without_syns = fandoms.map { |f| f.merger || f }.uniq + + # For each fandom, find the set of all meta tags for that fandom (including + # the fandom itself). + meta_tag_groups = all_without_syns.map do |f| + # TODO: This is more complicated than it has to be. Once the + # meta_taggings table is fixed so that the inherited meta-tags are + # correctly calculated, this can be simplified. + boundary = [f] + f.meta_tags + all_meta_tags = [] + + until boundary.empty? + all_meta_tags.concat(boundary) + boundary = boundary.flat_map(&:meta_tags).uniq - all_meta_tags + end + + all_meta_tags.uniq + end + + # Two fandoms are "related" if they share at least one meta tag. A work is + # considered a crossover if there is no single fandom on the work that all + # the other fandoms on the work are "related" to. + meta_tag_groups.none? do |meta_tags1| + meta_tag_groups.all? do |meta_tags2| + (meta_tags1 & meta_tags2).any? + end + end + end + + # Does this work have only one relationship tag? + # (not counting synonyms) + def otp + return true if relationships.size == 1 + + all_without_syns = relationships.map { |r| r.merger_id || r.id } + .uniq + all_without_syns.count == 1 + end + + # Quick and dirty categorization of the most obvious stuff + # To be replaced by actual categories + def work_types + types = [] + video_ids = [44011] # Video + audio_ids = [70308, 1098169] # Podfic, Audio Content + art_ids = [7844, 125758, 3863] # Fanart, Arts + types << "Video" if (filter_ids & video_ids).present? + types << "Audio" if (filter_ids & audio_ids).present? + types << "Art" if (filter_ids & art_ids).present? + # Very arbitrary cut off here, but wanted to make sure we + # got fic + art/podfic/video tagged as text as well + if types.empty? || (word_count && word_count > 200) + types << "Text" + end + types + end + + # To be replaced by actual category + # Can't use the 'Meta' tag since that has too many different uses + def nonfiction + nonfiction_tags = [125773, 66586, 123921, 747397] # Essays, Nonfiction, Reviews, Reference + (filter_ids & nonfiction_tags).present? + end + + # Determines if this work allows invitations to collections, + # meaning that at least one of the creators has opted-in. + def allow_collection_invitation? + users.any? { |user| user.preference.allow_collection_invitation } + end + + private + + def challenge_bypass(gift) + self.challenge_assignments.map(&:requesting_pseud).include?(gift.pseud) || + self.challenge_claims + .reject { |c| c.request_prompt.anonymous? } + .map(&:requesting_pseud) + .include?(gift.pseud) + end +end diff --git a/app/models/work_original_creator.rb b/app/models/work_original_creator.rb new file mode 100755 index 0000000..d5cd74d --- /dev/null +++ b/app/models/work_original_creator.rb @@ -0,0 +1,23 @@ +class WorkOriginalCreator < ApplicationRecord + belongs_to :work + belongs_to :user + + # Get the id and username (if still available) for the associated user. + def display + user ? "#{user_id} (#{user.login})" : user_id.to_s + end + + #################### + # DELAYED JOBS + #################### + + include AsyncWithResque + @queue = :utilities + + # Remove any original creator records that have been around for longer + # than the TTL in the archive configuration. + def self.cleanup + WorkOriginalCreator + .delete_by("updated_at <= ?", ArchiveConfig.ORIGINAL_CREATOR_TTL_HOURS.hours.ago) + end +end diff --git a/app/models/work_skin.rb b/app/models/work_skin.rb new file mode 100755 index 0000000..b44208e --- /dev/null +++ b/app/models/work_skin.rb @@ -0,0 +1,52 @@ +class WorkSkin < Skin + include SkinCacheHelper + + has_many :works + after_save :skin_invalidate_cache + + # override parent's clean_css to append a prefix + def clean_css + return if self.css.blank? + check = lambda {|ruleset, property, value| + # If it starts with --, assume the user was trying to define a custom property. + if property.match(/\A--/) + errors.add(:base, :work_skin_custom_properties) + return false + end + if value.match(/\bvar\b/i) + errors.add(:base, :work_skin_var) + return false + end + if property == "position" && value == "fixed" + # Do not internationalize the , used as a join in this error -- it's reflective of the comma used in the list of selectors, which does not change based on locale. + errors.add(:base, :work_skin_banned_value_for_property, property: property, selectors: ruleset.selectors.join(", "), value: value) + return false + end + return true + } + options = {prefix: "#workskin", caller_check: check} + self.css = clean_css_code(self.css, options) + end + + def self.model_name + # re-use the model_name of the superclass (Skin) + self.superclass.model_name + end + + def self.basic_formatting + Skin.find_by(title: "Basic Formatting", official: true) || WorkSkin.import_basic_formatting + end + + def self.import_basic_formatting + css = File.read(File.join(Rails.public_path, "/stylesheets/work_skins/basic_formatting.css")) + skin = WorkSkin.find_or_create_by(title: "Basic Formatting", css: css, role: "user", public: true, official: true) + skin.icon.attach( + io: File.open(File.join(Rails.public_path, "/images/skins/previews/basic_formatting.png"), "rb"), + filename: "basic_formatting.png", + content_type: "image/png" + ) + skin.official = true + skin.save! + skin + end +end diff --git a/app/models/wrangling_assignment.rb b/app/models/wrangling_assignment.rb new file mode 100755 index 0000000..9b488a5 --- /dev/null +++ b/app/models/wrangling_assignment.rb @@ -0,0 +1,9 @@ +class WranglingAssignment < ApplicationRecord + belongs_to :user + belongs_to :fandom + + validates_uniqueness_of :user_id, scope: :fandom_id + validates_presence_of :user_id + validates_presence_of :fandom_id + +end diff --git a/app/models/wrangling_guideline.rb b/app/models/wrangling_guideline.rb new file mode 100755 index 0000000..1d70a2e --- /dev/null +++ b/app/models/wrangling_guideline.rb @@ -0,0 +1,11 @@ +class WranglingGuideline < ApplicationRecord + acts_as_list + + validates_presence_of :content, :title + validates_length_of :content, maximum: ArchiveConfig.CONTENT_MAX, + too_long: ts('cannot be more than %{max} characters long.', max: ArchiveConfig.CONTENT_MAX) + + def self.reorder_list(positions) + SortableList.new(self.all.order(position: :asc)).reorder_list(positions) + end +end diff --git a/app/policies/admin_activity_policy.rb b/app/policies/admin_activity_policy.rb new file mode 100755 index 0000000..f6bf713 --- /dev/null +++ b/app/policies/admin_activity_policy.rb @@ -0,0 +1,9 @@ +class AdminActivityPolicy < ApplicationPolicy + PERMITTED_ROLES = %w[policy_and_abuse superadmin].freeze + + def index? + user_has_roles?(PERMITTED_ROLES) + end + + alias show? index? +end diff --git a/app/policies/admin_banner_policy.rb b/app/policies/admin_banner_policy.rb new file mode 100755 index 0000000..7f1ccff --- /dev/null +++ b/app/policies/admin_banner_policy.rb @@ -0,0 +1,16 @@ +class AdminBannerPolicy < ApplicationPolicy + ACCESS_AND_EDIT_ROLES = %w[superadmin board board_assistants_team communications development_and_membership support].freeze + CREATE_AND_DESTROY_ROLES = %w[superadmin board board_assistants_team communications support].freeze + + def index? + user_has_roles?(ACCESS_AND_EDIT_ROLES) + end + + def create? + user_has_roles?(CREATE_AND_DESTROY_ROLES) + end + + alias show? index? + alias update? index? + alias destroy? create? +end diff --git a/app/policies/admin_blacklisted_email_policy.rb b/app/policies/admin_blacklisted_email_policy.rb new file mode 100755 index 0000000..b966b55 --- /dev/null +++ b/app/policies/admin_blacklisted_email_policy.rb @@ -0,0 +1,8 @@ +class AdminBlacklistedEmailPolicy < ApplicationPolicy + def index? + user_has_roles?(%w[superadmin policy_and_abuse support]) + end + + alias create? index? + alias destroy? index? +end diff --git a/app/policies/admin_post_policy.rb b/app/policies/admin_post_policy.rb new file mode 100755 index 0000000..957e1c4 --- /dev/null +++ b/app/policies/admin_post_policy.rb @@ -0,0 +1,13 @@ +class AdminPostPolicy < ApplicationPolicy + POSTING_ROLES = %w[superadmin board board_assistants_team communications support translation].freeze + + def can_post? + user_has_roles?(POSTING_ROLES) + end + + alias new? can_post? + alias edit? can_post? + alias create? can_post? + alias update? can_post? + alias destroy? can_post? +end diff --git a/app/policies/admin_setting_policy.rb b/app/policies/admin_setting_policy.rb new file mode 100755 index 0000000..38981c8 --- /dev/null +++ b/app/policies/admin_setting_policy.rb @@ -0,0 +1,47 @@ +class AdminSettingPolicy < ApplicationPolicy + # Defines the roles that allow admins to view all settings. + SETTINGS_ROLES = %w[policy_and_abuse superadmin support tag_wrangling].freeze + + # Define which roles can update which settings. + ALLOWED_SETTINGS_BY_ROLES = { + "policy_and_abuse" => %i[ + hide_spam + invite_from_queue_enabled + invite_from_queue_number + request_invite_enabled + account_age_threshold_for_comment_spam_check + ], + "superadmin" => %i[ + account_creation_enabled + cache_expiration + creation_requires_invite + days_to_purge_unactivated + disable_support_form + disabled_support_form_text + downloads_enabled + enable_test_caching + hide_spam + guest_comments_off + account_age_threshold_for_comment_spam_check + invite_from_queue_enabled + invite_from_queue_frequency + invite_from_queue_number + request_invite_enabled + suspend_filter_counts + tag_wrangling_off + ], + "support" => %i[disable_support_form disabled_support_form_text], + "tag_wrangling" => %i[tag_wrangling_off] + }.freeze + + def can_view_settings? + user_has_roles?(SETTINGS_ROLES) + end + + def permitted_attributes + ALLOWED_SETTINGS_BY_ROLES.values_at(*user.roles).compact.flatten + end + + alias index? can_view_settings? + alias update? can_view_settings? +end diff --git a/app/policies/api_key_policy.rb b/app/policies/api_key_policy.rb new file mode 100755 index 0000000..52640c3 --- /dev/null +++ b/app/policies/api_key_policy.rb @@ -0,0 +1,14 @@ +class ApiKeyPolicy < ApplicationPolicy + PERMITTED_ROLES = %w[superadmin].freeze + + def index? + user_has_roles?(PERMITTED_ROLES) + end + + alias show? index? + alias new? index? + alias edit? index? + alias create? index? + alias update? index? + alias destroy? index? +end diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb new file mode 100755 index 0000000..a400d17 --- /dev/null +++ b/app/policies/application_policy.rb @@ -0,0 +1,59 @@ +class ApplicationPolicy + attr_reader :user, :record + + def initialize(user, record) + @user = user + @record = record + end + + def index? + false + end + + def show? + false + end + + def create? + false + end + + def new? + create? + end + + def update? + false + end + + def edit? + update? + end + + def destroy? + false + end + + def confirm_delete? + destroy? + end + + # Explicitly check that the user is an admin because regular users can have + # roles (e.g. archivist) as well, but we don't handle those with pundit. + def user_has_roles?(roles) + user&.is_a?(Admin) && user.respond_to?(:roles) && (user.roles & roles).present? + end + + class Scope + attr_reader :user, :scope + + def initialize(user, scope) + @user = user + @scope = scope + end + + def resolve + scope.all + end + end +end diff --git a/app/policies/archive_faq_policy.rb b/app/policies/archive_faq_policy.rb new file mode 100755 index 0000000..87c8a7e --- /dev/null +++ b/app/policies/archive_faq_policy.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class ArchiveFaqPolicy < ApplicationPolicy + TRANSLATION_ACCESS_ROLES = %w[superadmin docs support translation].freeze + # a subset of TRANSLATION_ACCESS_ROLES + FULL_ACCESS_ROLES = %w[superadmin docs support].freeze + + def translation_access? + user_has_roles?(TRANSLATION_ACCESS_ROLES) + end + + def full_access? + user_has_roles?(FULL_ACCESS_ROLES) + end + + alias edit? translation_access? + alias update? translation_access? + alias new? full_access? + alias create? full_access? + alias manage? full_access? + alias update_positions? full_access? + alias confirm_delete? full_access? + alias destroy? full_access? +end diff --git a/app/policies/block_policy.rb b/app/policies/block_policy.rb new file mode 100755 index 0000000..e0946df --- /dev/null +++ b/app/policies/block_policy.rb @@ -0,0 +1,5 @@ +class BlockPolicy < ApplicationPolicy + def index? + user_has_roles?(%w[policy_and_abuse support superadmin]) + end +end diff --git a/app/policies/bookmark_policy.rb b/app/policies/bookmark_policy.rb new file mode 100755 index 0000000..93894e5 --- /dev/null +++ b/app/policies/bookmark_policy.rb @@ -0,0 +1,2 @@ +class BookmarkPolicy < UserCreationPolicy +end diff --git a/app/policies/comment_policy.rb b/app/policies/comment_policy.rb new file mode 100755 index 0000000..857219c --- /dev/null +++ b/app/policies/comment_policy.rb @@ -0,0 +1,68 @@ +class CommentPolicy < ApplicationPolicy + DESTROY_COMMENT_ROLES = %w[superadmin board legal policy_and_abuse support].freeze + DESTROY_ADMIN_POST_COMMENT_ROLES = %w[superadmin board board_assistants_team communications elections legal policy_and_abuse support].freeze + FREEZE_TAG_COMMENT_ROLES = %w[superadmin tag_wrangling].freeze + FREEZE_WORK_COMMENT_ROLES = %w[superadmin policy_and_abuse].freeze + HIDE_TAG_COMMENT_ROLES = %w[superadmin legal tag_wrangling].freeze + HIDE_WORK_COMMENT_ROLES = %w[superadmin legal policy_and_abuse].freeze + SPAM_ADMIN_POST_COMMENT_ROLES = %w[superadmin board board_assistants_team communications elections policy_and_abuse support].freeze + SPAM_COMMENT_ROLES = %w[superadmin board policy_and_abuse support].freeze + + def can_destroy_comment? + case record.ultimate_parent + when AdminPost + user_has_roles?(DESTROY_ADMIN_POST_COMMENT_ROLES) + else + user_has_roles?(DESTROY_COMMENT_ROLES) + end + end + + def can_freeze_comment? + case record.ultimate_parent + when AdminPost + user&.is_a?(Admin) + when Tag + user_has_roles?(FREEZE_TAG_COMMENT_ROLES) + when Work + user_has_roles?(FREEZE_WORK_COMMENT_ROLES) + end + end + + def can_hide_comment? + case record.ultimate_parent + when AdminPost + user&.is_a?(Admin) + when Tag + user_has_roles?(HIDE_TAG_COMMENT_ROLES) + when Work + user_has_roles?(HIDE_WORK_COMMENT_ROLES) + end + end + + def can_mark_comment_spam? + case record.ultimate_parent + when AdminPost + user_has_roles?(SPAM_ADMIN_POST_COMMENT_ROLES) + else + user_has_roles?(SPAM_COMMENT_ROLES) + end + end + + def can_review_comment? + record.ultimate_parent.is_a?(AdminPost) && user&.is_a?(Admin) + end + + def can_review_all? + record.is_a?(AdminPost) && user&.is_a?(Admin) + end + + alias destroy? can_destroy_comment? + alias approve? can_mark_comment_spam? + alias reject? can_mark_comment_spam? + alias review? can_review_comment? + alias review_all? can_review_all? + + def show_email? + user_has_roles?(%w[legal policy_and_abuse support superadmin]) + end +end diff --git a/app/policies/external_work_policy.rb b/app/policies/external_work_policy.rb new file mode 100755 index 0000000..0109229 --- /dev/null +++ b/app/policies/external_work_policy.rb @@ -0,0 +1,5 @@ +class ExternalWorkPolicy < UserCreationPolicy + def update? + user_has_roles?(%w[superadmin policy_and_abuse]) + end +end diff --git a/app/policies/inbox_comment_policy.rb b/app/policies/inbox_comment_policy.rb new file mode 100755 index 0000000..8ec7d75 --- /dev/null +++ b/app/policies/inbox_comment_policy.rb @@ -0,0 +1,7 @@ +class InboxCommentPolicy < ApplicationPolicy + VIEW_INBOX_ROLES = %w[superadmin policy_and_abuse].freeze + + def show? + user_has_roles?(VIEW_INBOX_ROLES) + end +end diff --git a/app/policies/invitation_policy.rb b/app/policies/invitation_policy.rb new file mode 100755 index 0000000..8c9c3cb --- /dev/null +++ b/app/policies/invitation_policy.rb @@ -0,0 +1,7 @@ +class InvitationPolicy < ApplicationPolicy + EXTRA_INFO_ROLES = %w[superadmin open_doors policy_and_abuse support tag_wrangling].freeze + + def access_invitee_details? + user_has_roles?(EXTRA_INFO_ROLES) + end +end diff --git a/app/policies/invite_request_policy.rb b/app/policies/invite_request_policy.rb new file mode 100755 index 0000000..defbe3a --- /dev/null +++ b/app/policies/invite_request_policy.rb @@ -0,0 +1,10 @@ +class InviteRequestPolicy < ApplicationPolicy + MANAGE_ROLES = %w[superadmin policy_and_abuse support].freeze + + def can_manage? + user_has_roles?(MANAGE_ROLES) + end + + alias manage? can_manage? + alias destroy? can_manage? +end diff --git a/app/policies/known_issue_policy.rb b/app/policies/known_issue_policy.rb new file mode 100755 index 0000000..a74de07 --- /dev/null +++ b/app/policies/known_issue_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class KnownIssuePolicy < ApplicationPolicy + MANAGE_ROLES = %w[superadmin support].freeze + + def admin_index? + user_has_roles?(MANAGE_ROLES) + end + + alias destroy? admin_index? + alias edit? admin_index? + alias create? admin_index? + alias new? admin_index? + alias show? admin_index? + alias update? admin_index? +end diff --git a/app/policies/language_policy.rb b/app/policies/language_policy.rb new file mode 100755 index 0000000..37810ec --- /dev/null +++ b/app/policies/language_policy.rb @@ -0,0 +1,35 @@ +class LanguagePolicy < ApplicationPolicy + LANGUAGE_EDIT_ACCESS = %w[superadmin translation support policy_and_abuse].freeze + LANGUAGE_CREATE_ACCESS = %w[superadmin translation].freeze + + def new? + user_has_roles?(LANGUAGE_CREATE_ACCESS) + end + + def edit? + user_has_roles?(LANGUAGE_EDIT_ACCESS) + end + + # Define which roles can update which attributes + ALLOWED_ATTRIBUTES_BY_ROLES = { + "superadmin" => %i[name short support_available abuse_support_available sortable_name], + "translation" => %i[name short support_available abuse_support_available sortable_name], + "support" => %i[name short support_available sortable_name], + "policy_and_abuse" => %i[abuse_support_available] + }.freeze + + def permitted_attributes + ALLOWED_ATTRIBUTES_BY_ROLES.values_at(*user.roles).compact.flatten + end + + def can_edit_abuse_fields? + user_has_roles?(%w[superadmin translation policy_and_abuse]) + end + + def can_edit_non_abuse_fields? + user_has_roles?(%w[superadmin translation support]) + end + + alias create? new? + alias update? edit? +end diff --git a/app/policies/locale_policy.rb b/app/policies/locale_policy.rb new file mode 100755 index 0000000..2ca456c --- /dev/null +++ b/app/policies/locale_policy.rb @@ -0,0 +1,12 @@ +class LocalePolicy < ApplicationPolicy + MANAGE_LOCALES = %w[superadmin translation].freeze + + def index? + user_has_roles?(MANAGE_LOCALES) + end + + alias new? index? + alias edit? index? + alias update? index? + alias create? index? +end diff --git a/app/policies/moderated_work_policy.rb b/app/policies/moderated_work_policy.rb new file mode 100755 index 0000000..20f6a94 --- /dev/null +++ b/app/policies/moderated_work_policy.rb @@ -0,0 +1,9 @@ +class ModeratedWorkPolicy < ApplicationPolicy + MANAGE_MODERATED_WORK = %w[superadmin policy_and_abuse].freeze + + def index? + user_has_roles?(MANAGE_MODERATED_WORK) + end + + alias bulk_update? index? +end diff --git a/app/policies/mute_policy.rb b/app/policies/mute_policy.rb new file mode 100755 index 0000000..b5c559e --- /dev/null +++ b/app/policies/mute_policy.rb @@ -0,0 +1,5 @@ +class MutePolicy < ApplicationPolicy + def index? + user_has_roles?(%w[policy_and_abuse support superadmin]) + end +end diff --git a/app/policies/profile_policy.rb b/app/policies/profile_policy.rb new file mode 100755 index 0000000..dc43234 --- /dev/null +++ b/app/policies/profile_policy.rb @@ -0,0 +1,10 @@ +class ProfilePolicy < ApplicationPolicy + # Roles that allow updating a user's profile. + EDIT_ROLES = %w[superadmin policy_and_abuse].freeze + + def can_edit_profile? + user_has_roles?(EDIT_ROLES) + end + + alias update? can_edit_profile? +end diff --git a/app/policies/pseud_policy.rb b/app/policies/pseud_policy.rb new file mode 100755 index 0000000..62ebd3a --- /dev/null +++ b/app/policies/pseud_policy.rb @@ -0,0 +1,25 @@ +class PseudPolicy < ApplicationPolicy + # Roles that allow updating a pseud. + EDIT_ROLES = %w[superadmin policy_and_abuse].freeze + + def can_edit? + user_has_roles?(EDIT_ROLES) + end + + # Define which roles can update which attributes. + ALLOWED_ATTRIBUTES_BY_ROLES = { + "superadmin" => [:delete_icon, :description, :ticket_number], + "policy_and_abuse" => [:delete_icon, :description, :ticket_number] + }.freeze + + def permitted_attributes + if user.is_a?(Admin) + ALLOWED_ATTRIBUTES_BY_ROLES.values_at(*user.roles).compact.flatten + else + [:name, :description, :is_default, :icon, :delete_icon, :icon_alt_text, + :icon_comment_text] + end + end + + alias update? can_edit? +end diff --git a/app/policies/series_policy.rb b/app/policies/series_policy.rb new file mode 100755 index 0000000..d411f38 --- /dev/null +++ b/app/policies/series_policy.rb @@ -0,0 +1,2 @@ +class SeriesPolicy < UserCreationPolicy +end diff --git a/app/policies/skin_policy.rb b/app/policies/skin_policy.rb new file mode 100755 index 0000000..2fc2c14 --- /dev/null +++ b/app/policies/skin_policy.rb @@ -0,0 +1,21 @@ +class SkinPolicy < ApplicationPolicy + ACCESS_SKINS = %w[superadmin support].freeze + MANAGE_SITE_SKINS = %w[superadmin].freeze + MANAGE_WORK_SKINS = %w[superadmin support].freeze + + def index? + user_has_roles?(ACCESS_SKINS) + end + + def update? + user_has_roles?(MANAGE_SITE_SKINS) && !@record.is_a?(WorkSkin) || + user_has_roles?(MANAGE_WORK_SKINS) && @record.is_a?(WorkSkin) + end + + def set_default? + user_has_roles?(MANAGE_SITE_SKINS) + end + + alias index_approved? index? + alias index_rejected? index? +end diff --git a/app/policies/user_creation_policy.rb b/app/policies/user_creation_policy.rb new file mode 100755 index 0000000..3eb5f8b --- /dev/null +++ b/app/policies/user_creation_policy.rb @@ -0,0 +1,23 @@ +class UserCreationPolicy < ApplicationPolicy + FULL_ACCESS_ROLES = %w[superadmin legal policy_and_abuse].freeze + + def show_admin_options? + destroy? || hide? || edit? + end + + def destroy? + user_has_roles?(FULL_ACCESS_ROLES) + end + + def hide? + user_has_roles?(FULL_ACCESS_ROLES) + end + + def show_ip_address? + user_has_roles?(FULL_ACCESS_ROLES) + end + + def show_original_creators? + user_has_roles?(FULL_ACCESS_ROLES) + end +end diff --git a/app/policies/user_manager_policy.rb b/app/policies/user_manager_policy.rb new file mode 100755 index 0000000..ae4ead4 --- /dev/null +++ b/app/policies/user_manager_policy.rb @@ -0,0 +1,18 @@ +class UserManagerPolicy < ApplicationPolicy + # Roles that allow adding notes to users. + NOTE_ROLES = %w[superadmin policy_and_abuse support].freeze + + # Roles that allow warning, suspending, and banning users. + JUDGE_ROLES = %w[superadmin policy_and_abuse].freeze + + def can_manage_users? + user_has_roles?(NOTE_ROLES) || user_has_roles?(JUDGE_ROLES) + end + + def update_status? + return true if user_has_roles?(JUDGE_ROLES) + return record.admin_action == "note" if user_has_roles?(NOTE_ROLES) + + false + end +end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb new file mode 100755 index 0000000..118ca25 --- /dev/null +++ b/app/policies/user_policy.rb @@ -0,0 +1,90 @@ +class UserPolicy < ApplicationPolicy + # Roles that allow: + # - troubleshooting for a user + # - managing a user's invitations + # - updating a user's email and roles (e.g. wranglers, archivists, not admin roles) + # This is further restricted using ALLOWED_ATTRIBUTES_BY_ROLES. + MANAGE_ROLES = %w[superadmin legal policy_and_abuse open_doors support tag_wrangling].freeze + + # Roles that are allowed to set a generic username for users. + CHANGE_USERNAME_ROLES = %w[superadmin policy_and_abuse].freeze + + # Roles that allow updating the Fannish Next Of Kin of a user. + MANAGE_NEXT_OF_KIN_ROLES = %w[superadmin policy_and_abuse support].freeze + + # Roles that allow deleting all of a spammer's creations. + SPAM_CLEANUP_ROLES = %w[superadmin policy_and_abuse].freeze + + # Roles that allow viewing of past user emails and logins. + VIEW_PAST_USER_INFO_ROLES = %w[superadmin policy_and_abuse open_doors support tag_wrangling].freeze + + # Roles that allow accessing a summary of a user's works and comments. + REVIEW_CREATIONS_ROLES = %w[superadmin policy_and_abuse].freeze + + # Define which roles can update which attributes. + ALLOWED_ATTRIBUTES_BY_ROLES = { + "open_doors" => [roles: []], + "policy_and_abuse" => [:email, { roles: [] }], + "superadmin" => [:email, { roles: [] }], + "support" => [:email, { roles: [] }], + "tag_wrangling" => [roles: []] + }.freeze + + # Define which admin roles can edit which user roles. + ALLOWED_USER_ROLES_BY_ADMIN_ROLES = { + "open_doors" => %w[archivist no_resets opendoors], + "policy_and_abuse" => %w[no_resets protected_user], + "superadmin" => %w[archivist no_resets official opendoors protected_user tag_wrangler], + "support" => %w[no_resets], + "tag_wrangling" => %w[tag_wrangler] + }.freeze + + def can_manage_users? + user_has_roles?(MANAGE_ROLES) + end + + def can_manage_next_of_kin? + user_has_roles?(MANAGE_NEXT_OF_KIN_ROLES) + end + + def can_destroy_spam_creations? + user_has_roles?(SPAM_CLEANUP_ROLES) + end + + def can_view_past? + user_has_roles?(VIEW_PAST_USER_INFO_ROLES) + end + + def can_access_creation_summary? + user_has_roles?(REVIEW_CREATIONS_ROLES) + end + + def can_change_username? + user_has_roles?(CHANGE_USERNAME_ROLES) + end + + def permitted_attributes + ALLOWED_ATTRIBUTES_BY_ROLES.values_at(*user.roles).compact.flatten + end + + def can_edit_user_role?(role) + ALLOWED_USER_ROLES_BY_ADMIN_ROLES.values_at(*user.roles).compact.flatten.include?(role.name) + end + + alias index? can_manage_users? + alias bulk_search? can_manage_users? + alias show? can_manage_users? + alias update? can_manage_users? + alias change_username? can_change_username? + alias changed_username? can_change_username? + + alias update_next_of_kin? can_manage_next_of_kin? + + alias confirm_delete_user_creations? can_destroy_spam_creations? + alias destroy_user_creations? can_destroy_spam_creations? + + alias creations? can_access_creation_summary? + + alias troubleshoot? can_manage_users? + alias activate? can_manage_users? +end diff --git a/app/policies/work_policy.rb b/app/policies/work_policy.rb new file mode 100755 index 0000000..afa1de1 --- /dev/null +++ b/app/policies/work_policy.rb @@ -0,0 +1,28 @@ +class WorkPolicy < UserCreationPolicy + def show_admin_options? + super || edit_tags? || set_spam? + end + + # Allow admins to edit work tags and languages. + # Include support admins due to AO3-4932. + def update_tags? + user_has_roles?(%w[superadmin policy_and_abuse support]) + end + + alias edit_tags? update_tags? + + # Support admins need to be able to delete duplicate works. + def destroy? + super || user_has_roles?(%w[support]) + end + + def set_spam? + user_has_roles?(%w[superadmin policy_and_abuse]) + end + + def remove_pseud? + user_has_roles?(%w[superadmin support policy_and_abuse]) + end + + alias confirm_remove_pseud? remove_pseud? +end diff --git a/app/policies/wrangling_policy.rb b/app/policies/wrangling_policy.rb new file mode 100755 index 0000000..ba17ced --- /dev/null +++ b/app/policies/wrangling_policy.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class WranglingPolicy < ApplicationPolicy + FULL_ACCESS_ROLES = %w[superadmin tag_wrangling].freeze + READ_ACCESS_ROLES = (FULL_ACCESS_ROLES + %w[policy_and_abuse]).freeze + + def full_access? + user_has_roles?(FULL_ACCESS_ROLES) + end + + def read_access? + user_has_roles?(READ_ACCESS_ROLES) + end + + alias create? full_access? + alias destroy? full_access? + alias mass_update? full_access? + alias show? full_access? + alias report_csv? full_access? + alias new? full_access? + alias edit? full_access? + alias manage? full_access? + alias update? full_access? + alias update_positions? full_access? +end diff --git a/app/sweepers/collection_sweeper.rb b/app/sweepers/collection_sweeper.rb new file mode 100755 index 0000000..da0b9db --- /dev/null +++ b/app/sweepers/collection_sweeper.rb @@ -0,0 +1,61 @@ +class CollectionSweeper < ActionController::Caching::Sweeper + observe Collection, CollectionItem, CollectionParticipant, CollectionProfile, Work + + def after_create(record) + record.add_to_autocomplete if record.is_a?(Collection) + end + + def after_update(record) + if record.is_a?(Collection) && (record.saved_change_to_name? || record.saved_change_to_title?) + record.remove_stale_from_autocomplete + record.add_to_autocomplete + end + end + + def after_save(record) + expire_collection_cache_for(record) + end + + def before_destroy(record) + record.remove_from_autocomplete if record.is_a?(Collection) + end + + def after_destroy(record) + expire_collection_cache_for(record) + end + + private + # return one or many collections associated with the changed record + # converted into an array + def get_collections_from_record(record) + if record.is_a?(Collection) + # send collection, its parent, and any children + ([record, record.parent] + record.children).compact + elsif record.respond_to?(:collection) && !record.collection.nil? + ([record.collection, record.collection.parent] + record.collection.children).compact + elsif record.respond_to?(:collections) + (record.collections + record.collections.collect(&:parent) + record.collections.collect(&:children).flatten).compact + else + [] + end + end + + # Whenever these records are updated, we need to blank out the collections cache + def expire_collection_cache_for(record) + collections = get_collections_from_record(record) + collections.each do |collection| + CollectionSweeper.expire_collection_blurb_and_profile(collection) + end + end + + # Expire the collection blurb and profile + def self.expire_collection_blurb_and_profile(collection) + # Expire both versions of the blurb, whether the user is logged in or not. + %w[logged-in logged-out].each do |logged_in| + cache_key = "collection-blurb-#{logged_in}-#{collection.id}-v4" + ActionController::Base.new.expire_fragment(cache_key) + end + + ActionController::Base.new.expire_fragment("collection-profile-#{collection.id}") + end +end diff --git a/app/sweepers/feed_sweeper.rb b/app/sweepers/feed_sweeper.rb new file mode 100755 index 0000000..3377d61 --- /dev/null +++ b/app/sweepers/feed_sweeper.rb @@ -0,0 +1,35 @@ +class FeedSweeper < ActionController::Caching::Sweeper + include Rails.application.routes.url_helpers + + observe Chapter, Work + + def after_create(record) + if record.posted? && (record.is_a?(Work) || (record.is_a?(Chapter) && record.work.present? && record.work.posted?)) + expire_caches(record) + end + end + + def after_update(record) + if record.posted? + expire_caches(record) + end + end + + private + + # When a chapter or work is created, updated or destroyed, expire: + # - the cached feed page for each of its canonical tags + # - the works index caches for its canonical tags, pseuds, users and collections + def expire_caches(record) + work = record + work = record.work if record.is_a?(Chapter) + + return unless work.present? + + work.filters.each do |tag| + # expire the atom feed page for the tags on the work and the corresponding filter tags + ActionController::Base.expire_page feed_tag_path(tag.id, format: 'atom') + end + end + +end diff --git a/app/sweepers/pseud_sweeper.rb b/app/sweepers/pseud_sweeper.rb new file mode 100755 index 0000000..293119e --- /dev/null +++ b/app/sweepers/pseud_sweeper.rb @@ -0,0 +1,43 @@ +class PseudSweeper < ActionController::Caching::Sweeper + observe User, Pseud + + def after_create(record) + record.add_to_autocomplete if record.is_a?(Pseud) + end + + def before_update(record) + if record.changed.include?("name") || record.changed.include?("login") + if record.is_a?(User) + record.pseuds.each(&:remove_stale_from_autocomplete_before_save) + else + if record.user.saved_changes.any? + # In this case, `remove_stale_from_autocomplete` needs to look at the + # changed attributes on the pseud's user as if it were an after_* + # callback on the user instead of a before_* callback on the pseud. + record.remove_stale_from_autocomplete + else + record.remove_stale_from_autocomplete_before_save + end + end + end + end + + def after_update(record) + if record.saved_changes.keys.include?("name") || record.saved_changes.keys.include?("login") + if record.is_a?(User) + record.pseuds.each do |pseud| + # have to reload the pseud from the db otherwise it has the outdated login + pseud.reload + pseud.add_to_autocomplete + end + else + record.add_to_autocomplete + end + end + end + + def before_destroy(record) + record.remove_from_autocomplete if record.is_a?(Pseud) + end + +end diff --git a/app/sweepers/tag_set_sweeper.rb b/app/sweepers/tag_set_sweeper.rb new file mode 100755 index 0000000..b4bb9a7 --- /dev/null +++ b/app/sweepers/tag_set_sweeper.rb @@ -0,0 +1,40 @@ +class TagSetSweeper < ActionController::Caching::Sweeper + observe TagSet, TagSetAssociation, OwnedTagSet + + def after_create(record) + expire_cache_for(record) + end + + def after_update(record) + expire_cache_for(record) + end + + def after_destroy(record) + expire_cache_for(record) + end + + private + + def get_tagset_from_record(record) + case record.class.to_s + when "TagSetAssociation" + record.owned_tag_set ? record.owned_tag_set.tag_set : nil + when "OwnedTagSet" + record.tag_set + when "TagSet" + record + else + nil + end + end + + def expire_cache_for(record) + tag_set = get_tagset_from_record(record) + unless tag_set.nil? + # expire the tag_set show page and fragments + ActionController::Base.new.expire_fragment("tag_set_show_#{tag_set.id}") + TagSet::TAG_TYPES.each {|type| ActionController::Base.new.expire_fragment("tag_set_show_#{tag_set.id}_#{type}")} + end + end + +end diff --git a/app/validators/at_most_validator.rb b/app/validators/at_most_validator.rb new file mode 100755 index 0000000..7a0a118 --- /dev/null +++ b/app/validators/at_most_validator.rb @@ -0,0 +1,17 @@ +# This validator is very similar to the less_than_or_equal_to option for the +# numericality validator, but it computes the difference between the value and +# the maximum so that it can be included in the error message. +class AtMostValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + maximum = options[:maximum] + maximum = record.send(maximum) if maximum.is_a?(Symbol) + maximum = maximum.call(record) if maximum.is_a?(Proc) + + return unless value > maximum + + record.errors.add( + attribute, :at_most, + value: value, count: maximum, diff: value - maximum + ) + end +end diff --git a/app/validators/attachment_validator.rb b/app/validators/attachment_validator.rb new file mode 100755 index 0000000..79fa026 --- /dev/null +++ b/app/validators/attachment_validator.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Custom validator to ensure that a field using ActiveStorage +# * matches the given formats, specified with regex or by a list (leave empty to allow any) +# * is less than the given maximum (if none is given, the default is 500kb) +class AttachmentValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + return unless value&.attached? + + allowed_formats = options[:allowed_formats] + maximum_size = options[:maximum_size] || 500.kilobytes + + case allowed_formats + when Regexp + record.errors.add(attribute, :invalid_format) unless allowed_formats.match?(value.content_type) + when Array + record.errors.add(attribute, :invalid_format) unless allowed_formats.include?(value.content_type) + end + + record.errors.add(attribute, :too_large, maximum_size: maximum_size.to_fs(:human_size)) unless value.blob.byte_size < maximum_size + + value.purge if record.errors[attribute].any? + end +end diff --git a/app/validators/email_blacklist_validator.rb b/app/validators/email_blacklist_validator.rb new file mode 100755 index 0000000..79af00b --- /dev/null +++ b/app/validators/email_blacklist_validator.rb @@ -0,0 +1,10 @@ +class EmailBlacklistValidator < ActiveModel::EachValidator + def validate_each(record,attribute,value) + if AdminBlacklistedEmail.is_blacklisted?(value) + record.errors.add(attribute, options[:message] || I18n.t("validators.email.blacklist")) + return false + else + return true + end + end +end diff --git a/app/validators/email_format_validator.rb b/app/validators/email_format_validator.rb new file mode 100755 index 0000000..673fe60 --- /dev/null +++ b/app/validators/email_format_validator.rb @@ -0,0 +1,30 @@ +# From Authlogic, to mimic old behavior +# +# https://github.com/binarylogic/authlogic/blob/v3.6.0/lib/authlogic/regex.rb#L13 +# +# https://github.com/binarylogic/authlogic/blob/v3.6.0/lib/authlogic/acts_as_authentic/email.rb#L90 +# +class EmailFormatValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + email_regex ||= begin + email_name_regex = '[A-Z0-9_\.&%\+\-\']+' + domain_head_regex = '(?:[A-Z0-9\-]+\.)+' + domain_tld_regex = '(?:[A-Z]{2,25})' + /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i + end + + if (options[:allow_blank] && value.blank?) || (value.present? && value.match(email_regex)) + result = true + else + result = false + end + + unless result + if options[:allow_blank] + record.errors.add(attribute, options[:message] || I18n.t("validators.email.format.allow_blank")) + else + record.errors.add(attribute, options[:message] || I18n.t("validators.email.format.no_blank")) + end + end + end +end diff --git a/app/validators/not_blocked_validator.rb b/app/validators/not_blocked_validator.rb new file mode 100755 index 0000000..a751e3f --- /dev/null +++ b/app/validators/not_blocked_validator.rb @@ -0,0 +1,25 @@ +class NotBlockedValidator < ActiveModel::EachValidator + include BlockHelper + + def validate_each(record, attribute, value) + return if value.nil? + + blocker = options[:by] + case blocker + when Symbol + blocker = record.send(blocker) + when Proc + blocker = blocker.call(record) + end + + blocker_users = users_for(blocker) + blocked_users = users_for(value) + + # You can't be blocked from interacting with your own things: + return if (blocked_users - blocker_users).empty? + + return unless Block.exists?(blocker: blocker_users, blocked: blocked_users) + + record.errors.add(attribute, options.fetch(:message, :blocked)) + end +end diff --git a/app/validators/not_forbidden_name_validator.rb b/app/validators/not_forbidden_name_validator.rb new file mode 100755 index 0000000..54541ff --- /dev/null +++ b/app/validators/not_forbidden_name_validator.rb @@ -0,0 +1,9 @@ +class NotForbiddenNameValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + return if value.nil? + return unless ArchiveConfig.FORBIDDEN_USERNAMES.include?(value.downcase) + + # i18n-tasks-use t("activerecord.errors.messages.forbidden") + record.errors.add(attribute, :forbidden, **options.merge(value: value)) + end +end diff --git a/app/validators/url_active_validator.rb b/app/validators/url_active_validator.rb new file mode 100755 index 0000000..9a07476 --- /dev/null +++ b/app/validators/url_active_validator.rb @@ -0,0 +1,27 @@ +require 'timeout' +require 'uri' + +class UrlActiveValidator < ActiveModel::EachValidator + + # Checks the status of the webpage at the given url + # To speed things up we ONLY request the head and not the entire page. + # Bypass check for fanfiction.net and ficbook.net because of ip block + def validate_each(record,attribute,value) + return true if value.match("fanfiction.net") || value.match("ficbook.net") + + inactive_url_msg = "could not be reached. If the URL is correct and the site is currently down, please try again later." + inactive_url_timeout = 10 # seconds + begin + status = Timeout::timeout(options[:timeout] || inactive_url_timeout) { + url = Addressable::URI.parse(value) + response_code = Net::HTTP.start(url.host, url.port) {|http| http.head(url.path.blank? ? '/' : url.path).code} + active_status = %w[200 301 302 307 308] + active_status.include? response_code + } + rescue + status = false + end + record.errors.add(attribute, options[:message] || inactive_url_msg) unless status + end + +end diff --git a/app/validators/url_format_validator.rb b/app/validators/url_format_validator.rb new file mode 100755 index 0000000..4020ba0 --- /dev/null +++ b/app/validators/url_format_validator.rb @@ -0,0 +1,20 @@ +# Validate format of URLs +class UrlFormatValidator < ActiveModel::EachValidator + + # will be validated with active it if works + # just do a fast and dirty check. + def validate_each(record,attribute,value) + return true if (value.blank? && options[:allow_blank]) + # http (optional s) :// domain . tld (optional port) / anything + regexp = /^https?:\/\/[_a-z\d\-]+\.[._a-z\d\-]+(:\d+)?\/?.+/i + unless value.match regexp + record.errors.add(attribute, options[:message] || :invalid) + end + + begin + Addressable::URI.heuristic_parse(value) + rescue Addressable::URI::InvalidURIError + record.errors.add(attribute, options[:message] || :invalid) + end + end +end diff --git a/app/views/abuse_reports/new.html.erb b/app/views/abuse_reports/new.html.erb new file mode 100755 index 0000000..2c1b79f --- /dev/null +++ b/app/views/abuse_reports/new.html.erb @@ -0,0 +1,17 @@ + +

    <%= t(".heading.page_title") %>

    +<%= error_messages_for :abuse_report %> + + + +

    <%= t("a11y.navigation") %>

    +<%= render "home/tos_navigation" %> + + + +

    <%= t(".page_content_landmark") %>

    +
    +Please email me at femslashclub@proton.me with the subject ABUSE REPORT: [subject of your report.] Thanks! + +
    + diff --git a/app/views/admin/_admin_nav.html.erb b/app/views/admin/_admin_nav.html.erb new file mode 100755 index 0000000..e705ea4 --- /dev/null +++ b/app/views/admin/_admin_nav.html.erb @@ -0,0 +1,41 @@ +

    <%= t(".landmark") %>

    + diff --git a/app/views/admin/_admin_options.html.erb b/app/views/admin/_admin_options.html.erb new file mode 100755 index 0000000..4b6800c --- /dev/null +++ b/app/views/admin/_admin_options.html.erb @@ -0,0 +1,74 @@ + +
    + + <% item_type = item.class.to_s.tableize.singularize %> + +

    <%= t(".landmark") %>

    +
      + <% if policy(item).hide? %> +
    • + <% if item.hidden_by_admin? %> + <%= link_to t(".unhide.#{item_type}"), + hide_admin_user_creation_path(item, creation_type: item.class, hidden: "false"), + method: :put %> + <% else %> + <%= link_to t(".hide.#{item_type}"), + hide_admin_user_creation_path(item, creation_type: item.class, hidden: "true"), + method: :put %> + <% end %> +
    • + <% end %> + <% if @work.present? %> + <% if policy(@work).edit_tags? %> +
    • + <%= link_to t(".edit_tags"), edit_tags_work_path(@work) %> +
    • + <% end %> + <% if policy(@work).set_spam? %> +
    • + <% if @work.spam? %> + <%= link_to t(".not_spam"), + set_spam_admin_user_creation_path(@work.id, creation_type: @work.class, spam: "false"), + method: :put %> + <% else %> + <%= link_to t(".spam"), + set_spam_admin_user_creation_path(@work.id, creation_type: @work.class, spam: "true"), + method: :put %> + <% end %> +
    • + <% end %> + <% if policy(@work).remove_pseud? %> + <% orphan_pseuds = @work.orphan_pseuds %> + <% if orphan_pseuds.length == 1 %> +
    • + <%= link_to t(".remove_pseud"), + confirm_remove_pseud_admin_user_creation_path(@work), + data: { confirm: t(".remove_pseud_confirmation") } %> +
    • + <% elsif orphan_pseuds.length > 1 %> +
    • + <%= link_to t(".remove_pseud"), confirm_remove_pseud_admin_user_creation_path(@work) %> +
    • + <% end %> + <% end %> + <% end %> + <% if item.class == ExternalWork %> + <% if policy(item).edit? %> +
    • + <%= link_to t(".edit.#{item_type}"), edit_external_work_path(item) %> +
    • + <% end %> + <% end %> + <% if policy(item).destroy? %> +
    • + <%= link_to t(".delete.#{item_type}"), + admin_user_creation_path(item, creation_type: item.class), + data: { + confirm: t(".delete.confirmation") + }, + method: :delete %> +
    • + <% end %> +
    +
    + diff --git a/app/views/admin/_header.html.erb b/app/views/admin/_header.html.erb new file mode 100755 index 0000000..9c7ae29 --- /dev/null +++ b/app/views/admin/_header.html.erb @@ -0,0 +1,82 @@ + diff --git a/app/views/admin/activities/index.html.erb b/app/views/admin/activities/index.html.erb new file mode 100755 index 0000000..6a5948c --- /dev/null +++ b/app/views/admin/activities/index.html.erb @@ -0,0 +1,41 @@ +
    + +

    <%= t(".page_heading") %>

    + + + + + + +
    + "> + + + + + + + + + + + + + + + <% for admin_activity in @activities %> + + + + + + + <% end %> + +
    <%= t(".activities_table.caption") %>
    <%= t(".activities_table.date") %><%= t(".activities_table.admin") %><%= t(".activities_table.action") %><%= t(".activities_table.target") %>
    <%= link_to admin_activity.created_at, admin_activity %><%= admin_activity_login_string(admin_activity) %><%= admin_activity.action %><%= admin_activity_target_link(admin_activity) %>
    +
    + + + <%= will_paginate @activities %> + +
    diff --git a/app/views/admin/activities/show.html.erb b/app/views/admin/activities/show.html.erb new file mode 100755 index 0000000..98264a5 --- /dev/null +++ b/app/views/admin/activities/show.html.erb @@ -0,0 +1,33 @@ +
    + +

    <%= t(".page_heading") %>

    + + + + + + + +

    <%= t(".landmark.details") %>

    +
    +
    +
    <%= t(".date") %>
    +
    <%= @activity.created_at %>
    + +
    <%= t(".admin") %>
    +
    <%= admin_activity_login_string(@activity) %>
    + +
    <%= t(".action") %>
    +
    <%= @activity.action %>
    + +
    <%= t(".target") %>
    +
    <%= admin_activity_target_link(@activity) %>
    + +
    <%= t(".summary") %>
    +
    <%= admin_activity_summary(@activity) %>
    +
    +
    + +
    diff --git a/app/views/admin/admin_invitations/find.html.erb b/app/views/admin/admin_invitations/find.html.erb new file mode 100755 index 0000000..1921b28 --- /dev/null +++ b/app/views/admin/admin_invitations/find.html.erb @@ -0,0 +1,30 @@ + +

    <%= t(".page_heading") %>

    + + + + + + +<%= form_tag url_for(controller: "admin/admin_invitations", action: "find"), autocomplete: "off", class: "invitation simple search", method: :get do %> +
    +
    <%= label_tag "invitation[user_name]", t(".username") %>
    +
    <%= text_field_tag "invitation[user_name]", params[:invitation][:user_name] %>
    +
    <%= label_tag "invitation[token]", t(".token") %>
    +
    <%= text_field_tag "invitation[token]", params[:invitation][:token] %>
    +
    <%= label_tag "invitee_email", t(".email") %>
    +
    <%= text_field_tag "invitation[invitee_email]", params[:invitation][:invitee_email], id: "invitee_email" %>
    +
    +

    <%= submit_tag t(".search") %>

    +<% end %> + +<% if @user %> +

    <%= t(".invitations_for_html", user_invitations_link: link_to(@user.login, user_invitations_path(@user))) %>

    +<% end %> +<% if @invitations %> +<%= render "invitations/user_invitations", invitations: @invitations %> +<% end %> + + + + diff --git a/app/views/admin/admin_invitations/index.html.erb b/app/views/admin/admin_invitations/index.html.erb new file mode 100755 index 0000000..e65a803 --- /dev/null +++ b/app/views/admin/admin_invitations/index.html.erb @@ -0,0 +1,76 @@ + +

    <%= t(".page_heading") %>

    +<%= error_messages_for @invitation %> + + + + + +<%= form_tag url_for(controller: "admin/admin_invitations", action: :create), class: "invitation simple post", autocomplete: "off" do %> +
    +

    <%= t(".send_to_email.heading") %>

    +

    + <%= t(".send_to_email.description") %> + <%= text_field_tag "invitation[invitee_email]", + (@invitation.try(:invitee_email) || ""), + title: t(".send_to_email.invite_by_email_title") %> + <%= submit_tag t(".send_to_email.invite_user") %> +

    +
    +<% end %> + +<%= form_tag url_for(controller: "admin/admin_invitations", action: :invite_from_queue), class: "queue invitation simple post", autocomplete: "off" do %> +
    +

    + <%= t(".invite_from_queue.heading_html", + invitations_queue_link: link_to(t(".invite_from_queue.invitations_queue"), invite_requests_path)) %> +

    +

    <%= t(".invite_from_queue.requests_in_queue", count: InviteRequest.count) %>

    +

    + <%= label_tag "invitation[invite_from_queue]", t(".invite_from_queue.number_to_invite") %> + <%= text_field_tag "invitation[invite_from_queue]" %> + <%= submit_tag t(".invite_from_queue.invite_from_queue") %> +

    +
    +<% end %> + +<%= form_tag url_for(controller: "admin/admin_invitations", action: :grant_invites_to_users), class: "bulk invitation simple post", autocomplete: "off" do %> +
    +

    <%= t(".grant_invites.heading") %>

    +
    +
    <%= label_tag "invitation[number_of_invites]", t(".grant_invites.number_of_invitations") %>
    +
    <%= text_field_tag "invitation[number_of_invites]" %>
    +
    <%= label_tag "invitation[user_group]", t(".grant_invites.users") %>
    +
    + <%= select_tag "invitation[user_group]", + options_for_select([[t(".grant_invites.all"), "All"], + [t(".grant_invites.with_no_unused"), "With no unused invitations"]], + "All") %> +
    +
    <%= t(".grant_invites.landmark_submit") %>
    +
    <%= submit_tag t(".grant_invites.generate_invitations") %>
    +
    +
    +<% end %> + +<%= form_tag url_for(controller: "admin/admin_invitations", action: :find), class: "invitation simple search", autocomplete: "off", method: :get do %> +
    +

    <%= t(".find.heading") %>

    +
    +
    <%= label_tag "invitation[user_name]", t(".find.username") %>
    +
    <%= text_field_tag "invitation[user_name]" %>
    +
    <%= label_tag "invitation[token]", t(".find.invite_token") %>
    +
    <%= text_field_tag "invitation[token]" %>
    +
    <%= label_tag "track_invitation_invitee_email", t(".find.email") %>
    +
    <%= text_field_tag "invitation[invitee_email]", nil, id: "track_invitation_invitee_email" %>
    +
    <%= t(".find.landmark_submit") %>
    +
    <%= submit_tag t(".find.search") %>
    +
    +
    +<% end %> + diff --git a/app/views/admin/admin_invitations/new.html.erb b/app/views/admin/admin_invitations/new.html.erb new file mode 100755 index 0000000..74d6a72 --- /dev/null +++ b/app/views/admin/admin_invitations/new.html.erb @@ -0,0 +1,16 @@ + +

    <%= t('.invite_user', :default => "Invite a User") %>

    + + + + + + +<%= form_for :invitation, @invitation, :url => { :controller => 'admin/admin_invitations', :action => :create } do |f| %> +

    <%= f.label :recipient_email, t('.email_address', :default => "Email address") %> <%= f.text_field :recipient_email %>

    +

    <%= f.submit t('.submit', :default => "Invite!") %>

    +<% end %> + + + + diff --git a/app/views/admin/admin_users/_user_creations_summary.html.erb b/app/views/admin/admin_users/_user_creations_summary.html.erb new file mode 100755 index 0000000..a69164a --- /dev/null +++ b/app/views/admin/admin_users/_user_creations_summary.html.erb @@ -0,0 +1,21 @@ +<% unless @user.works.empty? %> + <%# Checking @user.items.empty? rather than @items.empty? allows us to display +# an empty listbox with pagination if the admin manually enters the wrong URL. +# This is consistent with pagination on other site pages. %> +
    +

    <%= search_header(@works, nil, "Work") %>

    + <%= render "works/work_abbreviated_list", works: works %> + <%= will_paginate(works, param_name: "works_page", params: { anchor: "works-summary" }) %> +
    +<% end %> + +<% unless @user.comments.empty? %> + <%# We use comments rather than comment as the class because .comment:after +# create a clear that causes wonky styling when there are only a few +# comments. %> +
    +

    <%= search_header(@comments, nil, "Comment") %>

    + <%= render "comments/comment_abbreviated_list", comments: comments %> + <%= will_paginate(comments, param_name: "comments_page", params: { anchor: "comments-summary" }) %> +
    +<% end %> diff --git a/app/views/admin/admin_users/_user_form.html.erb b/app/views/admin/admin_users/_user_form.html.erb new file mode 100755 index 0000000..addc627 --- /dev/null +++ b/app/views/admin/admin_users/_user_form.html.erb @@ -0,0 +1,25 @@ + + +<%= form_tag action: "update", controller: "admin/admin_users" do %> + <%= hidden_field_tag :query, params[:query] %> + <%= hidden_field_tag :role, params[:role] %> + <%= hidden_field_tag "id", user.login %> + <% # HACK: We need the user param to be present so we can remove all roles. + # However, if we simply submit the form with all roles unchecked, the user + # param is stripped. Therefore, we need a placeholder. %> + <%= hidden_field_tag "user[roles][]", "", disabled: !admin_can_update_user_roles? %> + <%= link_to user.login, user_path(user) %> + <%= text_field_tag "user[email]", user.email, title: ts("Email"), disabled: !admin_can_update_user_email? %> + <% for role in @roles %> + + <%= check_box_tag "user[roles][]", role.id, user.roles.include?(role), title: role.name, id: "user_roles_#{role.id}", disabled: !policy(User).can_edit_user_role?(role) %> + + <% end %> + + <% unless user.fannish_next_of_kin.blank? %> + <%= link_to user.fannish_next_of_kin.kin_name, user_path(user.fannish_next_of_kin.kin_name) %> + <% end %> + + <%= submit_tag ts("Update") %> + <%= link_to ts("Details"), admin_user_path(user) %> +<% end %> diff --git a/app/views/admin/admin_users/_user_history.html.erb b/app/views/admin/admin_users/_user_history.html.erb new file mode 100755 index 0000000..74724d1 --- /dev/null +++ b/app/views/admin/admin_users/_user_history.html.erb @@ -0,0 +1,51 @@ +

    <%= t("admin.admin_users.history.heading") %>

    +
    + "> + + + + + + + + + + + + + + + + + + + + <% unless @log_items.blank? + @log_items.each do |item| %> + + + + + + <% end %> + <% end %> + + + + + + +
    <%= t("admin.admin_users.history.table.caption") %>
    <%= t("admin.admin_users.history.table.head.date") %><%= t("admin.admin_users.history.table.head.action") %><%= t("admin.admin_users.history.table.head.details") %>
    <%= @user.current_sign_in_at.nil? ? "" : @user.current_sign_in_at %><%= t("admin.admin_users.history.table.sign_in.current.action") %> + <% if @user.current_sign_in_at.nil? %> + <%= t("admin.admin_users.history.table.sign_in.current.no_details") %> + <% else %> + <%= t("admin.admin_users.history.table.sign_in.details", ip: @user.current_sign_in_ip) %> + <% end %> +
    <%= @user.last_sign_in_at.nil? ? "" : @user.last_sign_in_at %><%= t("admin.admin_users.history.table.sign_in.last.action") %> + <% if @user.last_sign_in_at.nil? %> + <%= t("admin.admin_users.history.table.sign_in.last.no_details") %> + <% else %> + <%= t("admin.admin_users.history.table.sign_in.details", ip: @user.last_sign_in_ip) %> + <% end %> +
    <%= item.created_at %><%= log_item_action_name(item) %><%= item.role&.name %><%= item.enddate %><%= item.note %>
    <%= @user.created_at %><%= t("admin.admin_users.history.table.creation.action") %><%= t("admin.admin_users.history.table.creation.details") %>
    +
    diff --git a/app/views/admin/admin_users/_user_listing.html.erb b/app/views/admin/admin_users/_user_listing.html.erb new file mode 100755 index 0000000..7570407 --- /dev/null +++ b/app/views/admin/admin_users/_user_listing.html.erb @@ -0,0 +1,8 @@ +<%= user.login.html_safe %> +"><%= user.email.html_safe %> +<%= ts("Tag Wrangler") if user.tag_wrangler %> +<%= ts("Archivist") if user.archivist %> +<%= ts("Suspended") if user.suspended %> +<%= ts("Banned") if user.banned %> +<%= link_to ts("Edit"), { url: edit_admin_user_path(user), method: :get }, remote: true, href: edit_admin_user_path(user) %> +<%= ts("Delete") %> diff --git a/app/views/admin/admin_users/_user_table.html.erb b/app/views/admin/admin_users/_user_table.html.erb new file mode 100755 index 0000000..fb4f9be --- /dev/null +++ b/app/views/admin/admin_users/_user_table.html.erb @@ -0,0 +1,33 @@ +

    <%= ts("#{pluralize(@users.total_entries, 'user')} found") %>

    +<% if @users.size > 0 %> +
    + "> + + + + + + + + + + <% for role in @roles %> + + <% end %> + + + + + + + <% @users.each do |user| %> + + <%= render "user_form", user: user %> + + <% end %> + +
    <%= ts("List of Users") %>
    <%= ts("Username") %><%= ts("Email") %><%= role.name.try(:titleize) %><%= ts("Fannish Next of Kin") %><%= ts("Update") %><%= ts("Details") %>
    +
    + <%= will_paginate @users %> +<% end %> + diff --git a/app/views/admin/admin_users/bulk_search.html.erb b/app/views/admin/admin_users/bulk_search.html.erb new file mode 100755 index 0000000..e1b16e0 --- /dev/null +++ b/app/views/admin/admin_users/bulk_search.html.erb @@ -0,0 +1,46 @@ +
    + +

    <%= ts("Bulk Email Search") %>

    + + + +
    +

    <%= ts("Please enter a list of email addresses to search below. This form will search for exact matches.").html_safe %>

    +
    + + <%= form_tag url_for(controller: "admin/admin_users", action: :bulk_search, method: :post), class: "search", role: "search" do %> +
    + <%= ts("Email addresses") %> +
    +
    <%= label_tag "emails", ts("Email addresses *") %>
    +
    <%= text_area_tag "emails", @emails ? @emails.join("\n") : "", rows: 10, cols: 70, "aria-describedby" => "email-field-description" %> +

    + <%= ts("Email addresses to find; one per line.").html_safe %> +

    +
    +
    +
    + +
    + <%= ts("Find") %> +

    + <%= submit_tag ts("Download CSV"), name: "download_button" %> + <%= submit_tag ts("Find") %> +

    +
    + <% end %> + + <% if @results[:not_found_emails] || @results[:users] %> +

    <%= ts("#{pluralize(@results[:total], "email")} entered. #{@results[:searched]} searched. " + + "#{@results[:found_users].size} found. #{@results[:not_found_emails].size} not found. #{pluralize(@results[:duplicates], "duplicate")}.") %>

    + + <% if @results[:not_found_emails]&.any? %> +

    <%= ts("Not found") %>

    +

    <%= @results[:not_found_emails].join(", ") %>

    + <% end %> + + <% if @users %> + <%= render "user_table", users: @users %> + <% end %> + <% end %> +
    diff --git a/app/views/admin/admin_users/confirm_delete_user_creations.html.erb b/app/views/admin/admin_users/confirm_delete_user_creations.html.erb new file mode 100755 index 0000000..9a40a81 --- /dev/null +++ b/app/views/admin/admin_users/confirm_delete_user_creations.html.erb @@ -0,0 +1,17 @@ + +

    <%= t(".page_heading") %>

    + + +<%= form_tag destroy_user_creations_admin_user_path(@user), method: :post, class: "simple destroy" do %> + +

    + <%= t(".caution_html", bookmarks: @bookmarks.size, series: @series.size, collections: @collections.size) %> +

    + + <%= render "user_creations_summary", works: @works, comments: @comments %> + +

    + <%= submit_tag t(".submit"), data: { confirm: t(".confirm") } %> +

    +<% end %> + diff --git a/app/views/admin/admin_users/creations.html.erb b/app/views/admin/admin_users/creations.html.erb new file mode 100755 index 0000000..9ac8030 --- /dev/null +++ b/app/views/admin/admin_users/creations.html.erb @@ -0,0 +1,24 @@ +
    + +

    <%= t(".page_heading", user: @user.login) %>

    + + + + + + + + <% if @user.works.empty? && @user.comments.empty? %> +

    <%= t(".no_creations") %>

    + <% else %> + <%= render "user_creations_summary", works: @works, comments: @comments %> + <% end %> + +
    diff --git a/app/views/admin/admin_users/index.html.erb b/app/views/admin/admin_users/index.html.erb new file mode 100755 index 0000000..258dae7 --- /dev/null +++ b/app/views/admin/admin_users/index.html.erb @@ -0,0 +1,78 @@ +
    + +

    <%= ts("Find Users") %>

    + + + + <%= form_tag url_for(controller: "admin/admin_users", action: "index"), method: :get, class: "search", role: "search" do %> +
    +
    <%= label_tag "name", ts("Name") %>
    +
    + <%= text_field_tag "name", params[:name], "aria-describedby": "name-field-description" %> +

    + <%= ts("Search for users with matching usernames or pseuds.") %> +

    +
    +
    <%= label_tag "email", ts("Email") %>
    +
    <%= text_field_tag "email", params[:email] %>
    +
    <%= label_tag "user_id", ts("User ID") %>
    +
    + <%= text_field_tag "user_id", params[:user_id], "aria-describedby": "user-id-field-description" %> +

    + <%= ts("Search for user with exact ID.") %> +

    +
    +
    <%= label_tag "role_id", t(".role") %>
    +
    <%= select_tag "role_id", options_for_select(@role_values, params[:role_id].to_i), include_blank: true %>
    +
    <%= label_tag "status", ts("Status") %>
    +
    + <%= check_box_tag "inactive", "1", params[:inactive].present? %> + <%= label_tag "inactive", ts("Not yet activated") %> +
    + <% if policy(User).can_view_past? %> +
    <%= label_tag "settings", t(".settings.label") %>
    +
    + <%= check_box_tag "search_past", "1", params[:search_past].present? %> + <%= label_tag "search_past", t(".settings.past") %> +
    + <% end %> +
    +

    <%= submit_tag ts("Find") %>

    + <% end %> + + <% if @users %> +

    <%= ts("#{pluralize(@users.total_entries, 'user')} found") %>

    + <% if @users.size > 0 %> +
    + "> + + + + + + + + + + <% for role in @roles %> + + <% end %> + + + + + + + <% @users.each do |user| %> + + <%= render "user_form", user: user %> + + <% end %> + +
    <%= ts("List of Users") %>
    <%= ts("Username") %><%= ts("Email") %><%= role.name.try(:titleize) %><%= ts("Fannish Next of Kin") %><%= ts("Update") %><%= ts("Details") %>
    +
    + <% end %> + <%= will_paginate @users %> + <% end %> + +
    diff --git a/app/views/admin/admin_users/show.html.erb b/app/views/admin/admin_users/show.html.erb new file mode 100755 index 0000000..a910978 --- /dev/null +++ b/app/views/admin/admin_users/show.html.erb @@ -0,0 +1,144 @@ +
    + +

    <%= t(".page_heading", login: @user.login, id: @user.id) %>

    + + + + + + + +

    <%= t(".note") %>

    +

    <%= t(".info.heading") %>

    +
    +
    +
    <%= t(".info.email") %>
    +
    <%= @user.email %>
    +
    <%= t(".info.invitation") %>
    +
    <%= @user.invitation ? link_to(@user.invitation.id, invitation_path(@user.invitation.id)) : t(".info.no_invitation") %>
    +
    <%= t(".info.role", count: @user.roles.size) %>
    +
    <%= @user.roles.any? ? @user.roles.map { |role| t("activerecord.attributes.role.#{role.name}") }.to_sentence : t(".info.no_role") %>
    + <% if policy(User).can_view_past? %> + <% past_logins = @user.historic_values("login") %> + <% if past_logins.present? %> +
    <%= t(".info.past_logins", count: past_logins.size) %>
    +
    + <%= past_logins.to_sentence %> +
    + <% end %> + <% past_emails = @user.historic_values("email") %> + <% if past_emails.present? %> +
    <%= t(".info.past_emails", count: past_emails.size) %>
    +
    + <%= past_emails.to_sentence %> +
    + <% end %> + <% end %> +
    +
    + +

    <%= t(".fnok.heading") %>

    + <%= form_tag action: "update_next_of_kin", controller: "admin/admin_users" do %> + <%= error_messages_for @user.fannish_next_of_kin %> + <%= hidden_field_tag "user_login", @user.login %> + <%= field_set_tag t(".fnok.heading"), disabled: !policy(@user).can_manage_next_of_kin? do %> +
    +
    + <%= label_tag "next_of_kin_name", t(".fnok.form.name") %> +
    +
    + <%= text_field_tag "next_of_kin_name", @user.fannish_next_of_kin.try(:kin_name), autocomplete: "off" %> +
    +
    + <%= label_tag "next_of_kin_email", t(".fnok.form.email") %> +
    +
    + <%= text_field_tag "next_of_kin_email", @user.fannish_next_of_kin.try(:kin_email), autocomplete: "off" %> +
    +
    +

    <%= submit_tag t(".fnok.form.submit") %>

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

    <%= t(".status.heading") %>

    + <%= form_tag action: "update_status", controller: "admin/admin_users" do %> + <%= hidden_field_tag "user_login", @user.login %> + <%= field_set_tag t(".status.heading"), disabled: !policy(UserManager).can_manage_users? do %> +
    + <%= t(".status.form.admin_action.legend") %> +

    <%= t(".status.form.admin_action.legend") %>

    +
      +
    • + <%= radio_button_tag "admin_action", "note" %> + <%= label_tag "admin_action_note", t(".status.form.admin_action.note") %> +
    • +
    • + <%= radio_button_tag "admin_action", "warn" %> + <%= label_tag "admin_action_warn", t(".status.form.admin_action.warn") %> +
    • +
    • + <% if @user.suspended? %> + <%= radio_button_tag "admin_action", "unsuspend", false %> + <%= label_tag "admin_action_unsuspend", t(".status.form.admin_action.unsuspend") %> + <% else %> + <%= radio_button_tag "admin_action", "suspend", false, disabled: @user.banned? %> + <%= label_tag "admin_action_suspend", t(".status.form.admin_action.suspend") %> + <%= text_field_tag "suspend_days", "", class: "number", size: 2, disabled: @user.banned? %> + <%= live_validation_for_field("suspend_days", presence: false, numericality: true) %> + <% end %> +
    • +
    • + <% if @user.banned? %> + <%= radio_button_tag "admin_action", "unban", false %> + <%= label_tag "admin_action_unban", t(".status.form.admin_action.unban") %> + <% else %> + <%= radio_button_tag "admin_action", "ban", false %> + <%= label_tag "admin_action_ban", t(".status.form.admin_action.ban") %> + <% end %> +
    • +
    • + <%= radio_button_tag "admin_action", "spamban", false %> + <%= label_tag "admin_action_spamban", t(".status.form.admin_action.spamban") %> +
    • +
    +
    +
    + <%= t(".status.form.notes.legend") %> +

    <%= label_tag "admin_note", t(".status.form.notes.legend") %>

    +

    + <%= t(".status.form.notes.required") %> +

    +

    + <%= text_area_tag "admin_note", nil, class: "observe_textlength" %> + <%= generate_countdown_html("admin_note", ArchiveConfig.LOGNOTE_MAX) %> +

    + <% end %> +

    <%= submit_tag t(".status.form.submit") %>

    +
    + <% end %> + + <%= render "user_history", user: @user %> + +
    diff --git a/app/views/admin/api/_api_key_form.html.erb b/app/views/admin/api/_api_key_form.html.erb new file mode 100755 index 0000000..2c2c03a --- /dev/null +++ b/app/views/admin/api/_api_key_form.html.erb @@ -0,0 +1,39 @@ +<%= form_for @api_key, + url: @api_key.new_record? ? new_admin_api_path(@api_key) : admin_api_path(@api_key), + html: { class: "post" } do |f| %> + <%= error_messages_for @api_key %> + +

    * <%= ts("Required information") %>

    + +
    + <%= ts("API Token") %> +

    <%= ts("API Token") %>

    +
    +
    <%= f.label :name, ts("Name") + "*" %>
    +
    + <%= f.text_field :name %> + <%= live_validation_for_field("api_key_name", + :presence => true, + :maximum_length => Profile::PROFILE_TITLE_MAX) %> +
    +
    <%= f.check_box :banned %>
    +
    + <%= f.label :banned, ts("Banned?") %> +
    +
    + <%= f.label :access_token, ts("Token (automatically generated)") %> +
    +
    + <%= f.text_field :access_token, readonly: true %> +
    +
    +
    +
    + <%= ts("Actions") %> +

    <%= ts("Actions") %>

    + +

    + <%= f.submit @api_key.new_record? ? ts("Create API Token") : ts("Update API Token") %> +

    +
    +<% end %> diff --git a/app/views/admin/api/_navigation.html.erb b/app/views/admin/api/_navigation.html.erb new file mode 100755 index 0000000..8ff75c0 --- /dev/null +++ b/app/views/admin/api/_navigation.html.erb @@ -0,0 +1,4 @@ + diff --git a/app/views/admin/api/edit.html.erb b/app/views/admin/api/edit.html.erb new file mode 100755 index 0000000..e4bad48 --- /dev/null +++ b/app/views/admin/api/edit.html.erb @@ -0,0 +1,13 @@ +
    + +

    <%= ts("Edit API Token") %>

    + + + + <%= render "navigation" %> + + + + <%= render "api_key_form" %> + +
    diff --git a/app/views/admin/api/index.html.erb b/app/views/admin/api/index.html.erb new file mode 100755 index 0000000..3e1f7e6 --- /dev/null +++ b/app/views/admin/api/index.html.erb @@ -0,0 +1,54 @@ +
    +

    <%= t(".page_heading") %>

    + + + <%= render "navigation" %> + + + <%= will_paginate @api_keys %> + + + <%= form_tag url_for(controller: "admin/api", action: "index"), method: :get, class: "search", role: "search" do %> +

    <%= t(".search_by_name") %>

    +
    +
    <%= label_tag "query", t(".search_box.label") %>
    +
    <%= text_field_tag "query", params[:query] %> +
    +
    +

    <%= submit_tag t(".actions.find") %>

    + <% end %> + + "> + + + + + + + + + + + + + <% @api_keys.each do |api_key| %> + + + + + + + + + <% end %> + +
    <%= t(".table.caption") %>
    <%= t(".table.headings.name") %><%= t(".table.headings.token") %><%= t(".table.headings.banned") %><%= t(".table.headings.created") %><%= t(".table.headings.updated") %><%= t(".table.headings.actions") %>
    <%= api_key.name %><%= api_key.access_token %><%= check_box_tag :banned, api_key.banned, api_key.banned, disabled: true %><%= api_key.created_at %><%= api_key.updated_at %> +
      +
    • <%= link_to t(".table.actions.edit"), edit_admin_api_path(api_key) %>
    • +
    +
    + + + <%= will_paginate @api_keys %> + +
    diff --git a/app/views/admin/api/new.html.erb b/app/views/admin/api/new.html.erb new file mode 100755 index 0000000..9e7c6f7 --- /dev/null +++ b/app/views/admin/api/new.html.erb @@ -0,0 +1,13 @@ +
    + +

    <%= ts("New API Token") %>

    + + + + <%= render "navigation" %> + + + + <%= render "api_key_form" %> + +
    diff --git a/app/views/admin/banners/_banner.html.erb b/app/views/admin/banners/_banner.html.erb new file mode 100755 index 0000000..2e74720 --- /dev/null +++ b/app/views/admin/banners/_banner.html.erb @@ -0,0 +1,7 @@ +<% # expects admin_banner %> +<% # don't forget to update layouts/banner! %> +
    +
    + <%= raw sanitize_field(admin_banner, :content, image_safety_mode: true) %> +
    +
    diff --git a/app/views/admin/banners/_banner_form.html.erb b/app/views/admin/banners/_banner_form.html.erb new file mode 100755 index 0000000..2f89868 --- /dev/null +++ b/app/views/admin/banners/_banner_form.html.erb @@ -0,0 +1,55 @@ +<%= form_for @admin_banner, html: { class: 'post' } do |f| %> + <%= error_messages_for @admin_banner %> + +

    <%= ts('* Required information') %>

    + +
    + <%= ts('Admin Banner') %> +

    <%= ts('Admin Banner') %>

    +
    + +
    <%= f.label :content, ts('Banner text') + '*' %>
    +
    +

    <%= allowed_html_instructions %>

    + <%= f.text_area :content %> +
    + +
    <%= ts('Banner type') %>*
    +
    +
      +
    • + <%= f.radio_button :banner_type, '', checked: true %> + <%= f.label :banner_type_, ts('Default') %> +
    • +
    • + <%= f.radio_button :banner_type, 'event' %> + <%= f.label :banner_type_event, ts('Event (For membership drives, celebrations, etc.)') %> +
    • +
    • + <%= f.radio_button :banner_type, 'alert' %> + <%= f.label :banner_type_alert, ts('Alert (For bugs, important changes, expected downtime, etc.)') %> +
    • +
    +
    + +
    <%= f.check_box :active %>
    +
    <%= f.label :active, ts('Active') %>
    + + <% if @admin_banner.active? %> +
    <%= check_box_tag :admin_banner_minor_edit %>
    +
    <%= label_tag :admin_banner_minor_edit, ts('This is a minor update (Do not turn the banner back on for users who have dismissed it)') %>
    + <% end %> + +
    +
    + +
    + <%= ts('Actions') %> +

    <%= ts('Actions') %>

    + +

    + <%= f.submit @admin_banner.new_record? ? ts('Create Banner') : ts('Update Banner') %> +

    +
    + +<% end %> diff --git a/app/views/admin/banners/_navigation.html.erb b/app/views/admin/banners/_navigation.html.erb new file mode 100755 index 0000000..bb70f37 --- /dev/null +++ b/app/views/admin/banners/_navigation.html.erb @@ -0,0 +1,12 @@ + diff --git a/app/views/admin/banners/confirm_delete.html.erb b/app/views/admin/banners/confirm_delete.html.erb new file mode 100755 index 0000000..eac7f69 --- /dev/null +++ b/app/views/admin/banners/confirm_delete.html.erb @@ -0,0 +1,16 @@ +
    + +

    <%= ts('Delete Banner') %>

    + + + + <%= form_for(@admin_banner, html: {method: :delete, class: 'simple destroy'}) do |f| %> +

    + <%= ts('Are you sure you want to delete this banner?').html_safe %> +

    +

    + <%= f.submit ts('Yes, Delete Banner') %> +

    + <% end %> + +
    diff --git a/app/views/admin/banners/edit.html.erb b/app/views/admin/banners/edit.html.erb new file mode 100755 index 0000000..faacc8e --- /dev/null +++ b/app/views/admin/banners/edit.html.erb @@ -0,0 +1,13 @@ +
    + +

    <%= ts('Edit Banner') %>

    + + + + <%= render 'navigation' %> + + + + <%= render 'banner_form' %> + +
    diff --git a/app/views/admin/banners/index.html.erb b/app/views/admin/banners/index.html.erb new file mode 100755 index 0000000..c36cd46 --- /dev/null +++ b/app/views/admin/banners/index.html.erb @@ -0,0 +1,40 @@ +
    + +

    <%= t(".page_heading") %>

    + + + + <%= render 'navigation' %> + + + <%= will_paginate @admin_banners %> + + +
      + <% for admin_banner in @admin_banners %> +
    • + <%= render "banner", admin_banner: admin_banner %> +
        + <% if admin_banner.active? %> +
      • + <%= t(".actions.active") %> +
      • + <% end %> + +
      • + <%= link_to t(".actions.edit"), edit_admin_banner_path(admin_banner) %> +
      • + <% if policy(AdminBanner).destroy? %> +
      • + <%= link_to t(".actions.delete"), confirm_delete_admin_banner_path(admin_banner), data: { confirm: t(".actions.confirm_delete") } %> +
      • + <% end %> +
      +
    • + <% end %> +
    + + + <%= will_paginate @admin_banners %> + +
    diff --git a/app/views/admin/banners/new.html.erb b/app/views/admin/banners/new.html.erb new file mode 100755 index 0000000..7e9288d --- /dev/null +++ b/app/views/admin/banners/new.html.erb @@ -0,0 +1,13 @@ +
    + +

    <%= ts('New Banner') %>

    + + + + <%= render 'navigation' %> + + + + <%= render 'banner_form' %> + +
    diff --git a/app/views/admin/banners/show.html.erb b/app/views/admin/banners/show.html.erb new file mode 100755 index 0000000..e70a268 --- /dev/null +++ b/app/views/admin/banners/show.html.erb @@ -0,0 +1,13 @@ +
    + +

    <%= ts('Banner') %>

    + + + + <%= render 'navigation' %> + + + + <%= render 'banner', admin_banner: @admin_banner %> + +
    diff --git a/app/views/admin/blacklisted_emails/index.html.erb b/app/views/admin/blacklisted_emails/index.html.erb new file mode 100755 index 0000000..64f3dfd --- /dev/null +++ b/app/views/admin/blacklisted_emails/index.html.erb @@ -0,0 +1,62 @@ +
    + +

    <%= t(".page_heading") %>

    + +
      +
    • <%= t(".notes.guest_comments") %>
    • +
    • <%= t(".notes.unaffected_users") %>
    • +
    • <%= t(".notes.canonical_format") %>
    • +
    + + + +

    <%= t(".heading.new") %>

    + + <%= form_for(@admin_blacklisted_email, html: { class: "simple post" }) do |f| %> + <%= error_messages_for @admin_blacklisted_email %> +
    +

    + <%= f.label :email, t(".form.new.label") %> + <%= f.text_field :email %> + <%= f.submit t(".form.new.submit") %> +

    +
    + <% end %> + +

    <%= t(".heading.search")%>

    + + + <%= form_tag url_for(controller: "admin/blacklisted_emails", action: "index"), + method: :get, class: "simple search", role: "search" do %> +
    +

    + <%= label_tag "query", ts("Email to find") %> + <%= text_field_tag "query", params[:query] %> + <%= submit_tag t(".form.search.submit") %> +

    +
    + <% end %> + + + <% if @admin_blacklisted_emails %> +
    +

    + <%= t("admin.blacklist.emails_found", count: @admin_blacklisted_emails.count) %> +

    + <% if @admin_blacklisted_emails.count > 0 %> +
      + <% @admin_blacklisted_emails.each do |blacklisted_email| %> +
    1. + <%= link_to ts("Remove %{email}", email: blacklisted_email.email), + blacklisted_email, + method: :delete, + data: { confirm: t(".confirm_remove", email: blacklisted_email.email) } %> +
    2. + <% end %> + + <%= will_paginate @admin_blacklisted_emails %> + <% end %> +
    + <% end %> + +
    diff --git a/app/views/admin/mailer/password_change.html.erb b/app/views/admin/mailer/password_change.html.erb new file mode 100755 index 0000000..15ac5c8 --- /dev/null +++ b/app/views/admin/mailer/password_change.html.erb @@ -0,0 +1,13 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@resource.login)) %>

    + +

    <%= t(".changed", date: l(Time.current), app_name: ArchiveConfig.APP_SHORT_NAME) %>

    + +

    <%= t(".made_change.html", + login_link: style_link(t(".made_change.login"), new_admin_session_url), + reset_password_link: style_link(t(".made_change.reset_password"), new_admin_password_url)) %>

    + +

    <%= t(".did_not_make_change", app_name: ArchiveConfig.APP_SHORT_NAME) %>

    + +

    <%= t(".secure_again.html", reset_password_link: style_link(t(".secure_again.reset_password"), new_admin_password_url)) %>

    +<% end %> diff --git a/app/views/admin/mailer/password_change.text.erb b/app/views/admin/mailer/password_change.text.erb new file mode 100755 index 0000000..cd20bad --- /dev/null +++ b/app/views/admin/mailer/password_change.text.erb @@ -0,0 +1,13 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @resource.login) %> + +<%= t(".changed", date: l(Time.current), app_name: ArchiveConfig.APP_SHORT_NAME) %> + +<%= t(".made_change.text", + login_url: new_admin_session_url, + reset_password_url: new_admin_password_url) %> + +<%= t(".did_not_make_change", app_name: ArchiveConfig.APP_SHORT_NAME) %> + +<%= t(".secure_again.text", reset_password_url: new_admin_password_url) %> +<% end %> diff --git a/app/views/admin/mailer/reset_password_instructions.html.erb b/app/views/admin/mailer/reset_password_instructions.html.erb new file mode 100755 index 0000000..289b10f --- /dev/null +++ b/app/views/admin/mailer/reset_password_instructions.html.erb @@ -0,0 +1,7 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@resource.login)) %>

    +

    <%= t(".intro") %>

    +

    <%= style_link t(".link_title_html"), edit_admin_password_url(reset_password_token: @token) %>

    +

    <%= t(".expiration", count: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES) %>

    +

    <%= t(".unrequested") %>

    +<% end %> diff --git a/app/views/admin/mailer/reset_password_instructions.text.erb b/app/views/admin/mailer/reset_password_instructions.text.erb new file mode 100755 index 0000000..7e1f1ad --- /dev/null +++ b/app/views/admin/mailer/reset_password_instructions.text.erb @@ -0,0 +1,12 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @resource.login) %> + +<%= t(".intro") %> + +<%= edit_admin_password_url(reset_password_token: @token) %> + +<%= t(".expiration", count: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES) %> + +<%= t(".unrequested") %> + +<% end %> diff --git a/app/views/admin/passwords/edit.html.erb b/app/views/admin/passwords/edit.html.erb new file mode 100755 index 0000000..d068b7f --- /dev/null +++ b/app/views/admin/passwords/edit.html.erb @@ -0,0 +1,26 @@ + +

    <%= t(".page_heading") %>

    +<%= error_messages_for resource %> + + + +<%= form_for resource, url: admin_password_reset_path, html: { method: :put, class: "reset password post" } do |f| %> + <%= f.hidden_field :reset_password_token %> +
    +
    <%= label_tag :edit_password, t(".label.password") %>
    +
    + <%= f.password_field(:password, id: :edit_password, + "aria-describedby" => "password-field-description") %> +

    + <%= t(".describedby.password_length", + minimum: ArchiveConfig.ADMIN_PASSWORD_LENGTH_MIN, + maximum: ArchiveConfig.ADMIN_PASSWORD_LENGTH_MAX) %> +

    +
    +
    <%= label_tag :edit_password_confirmation, t(".label.confirmation") %>
    +
    <%= f.password_field :password_confirmation, id: :edit_password_confirmation %>
    +
    <%= t(".landmark.submit") %>
    +
    <%= f.submit t(".submit") %>
    +
    +<% end %> + diff --git a/app/views/admin/passwords/new.html.erb b/app/views/admin/passwords/new.html.erb new file mode 100755 index 0000000..6236923 --- /dev/null +++ b/app/views/admin/passwords/new.html.erb @@ -0,0 +1,15 @@ + +

    <%= t(".page_heading") %>

    +

    <%= t(".instructions") %>

    + + + +<%= form_for resource, url: admin_password_path, html: { method: :post, class: "reset password simple post" } do |f| %> + <%= error_messages_for resource %> +

    + <%= label_tag :reset_login, t(".reset_login_html") %> + <%= f.text_field :login, id: :reset_login %> + <%= f.submit t(".submit") %> +

    +<% end %> + diff --git a/app/views/admin/sessions/confirm_logout.html.erb b/app/views/admin/sessions/confirm_logout.html.erb new file mode 100755 index 0000000..04875c7 --- /dev/null +++ b/app/views/admin/sessions/confirm_logout.html.erb @@ -0,0 +1,8 @@ +

    <%= ts("Log Out as Admin") %>

    + +<%= form_tag destroy_admin_session_path, method: :delete, class: "simple destroy" do %> +

    <%= ts("Are you sure you want to log out?") %>

    +

    + <%= submit_tag ts("Yes, Log Out") %> +

    +<% end %> diff --git a/app/views/admin/sessions/new.html.erb b/app/views/admin/sessions/new.html.erb new file mode 100755 index 0000000..2b07ee5 --- /dev/null +++ b/app/views/admin/sessions/new.html.erb @@ -0,0 +1,17 @@ + +

    <%= t(".page_heading") %>

    + + + +<%= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: "login post" } ) do |form| %> +
    +
    <%= form.label :login, t(".label.login") %>
    +
    <%= form.text_field :login %>
    +
    <%= form.label :password, t(".label.password") %>
    +
    <%= form.password_field :password %>
    +
    <%= t(".landmark.reset") %> +

    <%= link_to t(".reset_link"), new_admin_password_path %>

    +
    +

    <%= form.submit t(".submit") %>

    +<% end %> + diff --git a/app/views/admin/settings/index.html.erb b/app/views/admin/settings/index.html.erb new file mode 100755 index 0000000..c48dd3c --- /dev/null +++ b/app/views/admin/settings/index.html.erb @@ -0,0 +1,107 @@ + +

    <%= t(".heading") %>

    + + + +<%= form_for @admin_setting, html: { class: "verbose manage" } do |f| %> + <%= error_messages_for @admin_setting %> +
    + <%= t(".legend.account_and_invitations") %> +
    +
    <%= admin_setting_checkbox(f, :account_creation_enabled) %>
    +
    <%= f.label :account_creation_enabled, t(".fields.account_creation_enabled") %>
    + +
    <%= admin_setting_checkbox(f, :creation_requires_invite) %>
    +
    <%= f.label :creation_requires_invite, t(".fields.creation_requires_invite") %>
    + +
    <%= admin_setting_checkbox(f, :request_invite_enabled) %>
    +
    <%= f.label :request_invite_enabled, t(".fields.request_invite_enabled") %>
    + +
    <%= admin_setting_checkbox(f, :invite_from_queue_enabled) %>
    +
    <%= f.label :invite_from_queue_enabled, t(".fields.invite_from_queue_enabled") %>
    + +
    <%= f.label :invite_from_queue_number, t(".fields.invite_from_queue_number") %>
    +
    <%= admin_setting_text_field(f, :invite_from_queue_number, size: "3") %>
    + +
    <%= f.label :invite_from_queue_frequency, t(".fields.invite_from_queue_frequency") %>
    +
    <%= admin_setting_text_field(f, :invite_from_queue_frequency, size: "3") %>
    + +
    <%= f.label :days_to_purge_unactivated, t(".fields.days_to_purge_unactivated") %>
    +
    <%= admin_setting_text_field(f, :days_to_purge_unactivated, size: "3") %>
    +
    +
    + +
    + <%= t(".legend.disable_support_form") %> +
    +
    <%= admin_setting_checkbox(f, :disable_support_form) %>
    +
    + <%= f.label :disable_support_form, t(".fields.disable_support_form") %> +
    + <%= f.label :disabled_support_form_text, t(".fields.disabled_support_form_text") %> +

    <%= allowed_html_instructions %>

    + <%= f.text_area :disabled_support_form_text, + disabled: admin_setting_disabled?(:disabled_support_form_text) %> +
    +
    +
    +
    + +
    + <%= t(".legend.performance_and_misc") %> +
    +
    <%= admin_setting_checkbox(f, :suspend_filter_counts) %>
    +
    <%= f.label :suspend_filter_counts, t(".fields.suspend_filter_counts") %>
    + +
    <%= admin_setting_checkbox(f, :tag_wrangling_off) %>
    +
    <%= f.label :tag_wrangling_off, t(".fields.tag_wrangling_off") %>
    + +
    <%= admin_setting_checkbox(f, :downloads_enabled) %>
    +
    <%= f.label :downloads_enabled, t(".fields.downloads_enabled") %>
    + +
    <%= admin_setting_checkbox(f, :enable_test_caching) %>
    +
    <%= f.label :enable_test_caching, t(".fields.enable_test_caching") %>
    + +
    <%= f.label :cache_expiration, t(".fields.cache_expiration") %>
    +
    <%= admin_setting_text_field(f, :cache_expiration, size: "3") %>
    +
    +
    + +
    + <%= t(".legend.content") %> +
    +
    <%= admin_setting_checkbox(f, :hide_spam) %>
    +
    <%= f.label :hide_spam, t(".fields.hide_spam") %>
    + +
    <%= admin_setting_checkbox(f, :guest_comments_off) %>
    +
    <%= f.label :guest_comments_off, t(".fields.guest_comments_off") %>
    + +
    <%= f.label :account_age_threshold_for_comment_spam_check, t(".fields.account_age_threshold_for_comment_spam_check") %>
    +
    + <%= admin_setting_text_field(f, :account_age_threshold_for_comment_spam_check, size: "3", "aria-describedby": "account-age-threshold-for-comment-spam-check-note") %> +

    <%= t(".fields.account_age_threshold_for_comment_spam_check_note") %>

    +
    +
    +
    + +
    + <%= t(".legend.actions") %> +

    <%= f.submit t(".update") %>

    +
    +<% end %> + +<% if @admin_setting.invite_from_queue_enabled? %> +

    + <%= t(".queue_status", + count: @admin_setting.invite_from_queue_number, + time: l(@admin_setting.invite_from_queue_at, format: :long)) %> + <%= t(".queue_status_help") %> +

    +<% end %> + +

    + <%= t(".last_updated_by_admin", + updated_at: @admin_setting.updated_at, + admin_name: @admin_setting.last_updated ? @admin_setting.last_updated.login : "---") %> +

    + diff --git a/app/views/admin/skins/_navigation.html.erb b/app/views/admin/skins/_navigation.html.erb new file mode 100755 index 0000000..0ff09dd --- /dev/null +++ b/app/views/admin/skins/_navigation.html.erb @@ -0,0 +1,6 @@ +

    Navigation

    + \ No newline at end of file diff --git a/app/views/admin/skins/index.html.erb b/app/views/admin/skins/index.html.erb new file mode 100755 index 0000000..26abe59 --- /dev/null +++ b/app/views/admin/skins/index.html.erb @@ -0,0 +1,71 @@ +
    + +

    <%= ts('Skin Approval Queue') %>

    + + + +<%= render :partial => 'admin/skins/navigation' %> + + + +

    <%= ts('Manage Skins') %>

    + +<%= form_tag update_admin_skin_path, {:method => :put} do %> + + +
    + <%= ts('Approval Queue') %> +

    <%= ts('Approval Queue') %>

    + +
    + + + + + + + + + + + + + + + + <% @unapproved_skins.each_with_index do |skin, i| %> + <% disabled = !policy(skin).update? %> + + + + + + + + + + + <% end %> + +
    <%= ts('Approval Queue for Skins') %>
    <%= ts('Skin') %><%= ts('Type') %><%= ts('Creator') %><%= ts('Preview') %><%= ts('Description') %><%= ts('Admin Note') %><%= ts('Approve') %><%= ts('Reject') %>
    + <% skin_name = skin.title.downcase.gsub(/ +/, '_') %> + <%= label_tag "make_official_#{skin_name}", (link_to skin.title, skin_path(skin)) %> + <%= skin.type == 'WorkSkin' ? 'Work Skin' : 'Site Skin' %><%= skin_author_link(skin) %><%= skin_preview_display(skin) %> + <%= skin.description.blank? ? ts("(No Description Provided)") : raw(strip_images(sanitize_field(skin, :description))) %> + <%= text_field_tag "skin_admin_note[#{skin.id}]", h(skin.admin_note), disabled: disabled %> + <%= check_box_tag "make_official[]", skin.id, false, id: "make_official_#{skin_name}", disabled: disabled %> + + <%= check_box_tag "make_rejected[]", skin.id, false, id: "make_rejected_#{skin_name}", disabled: disabled %> +
    +
    +
    + +

    <%= submit_tag ts('Update') %>

    + +<% end %> + + + + + +
    diff --git a/app/views/admin/skins/index_approved.html.erb b/app/views/admin/skins/index_approved.html.erb new file mode 100755 index 0000000..84632f9 --- /dev/null +++ b/app/views/admin/skins/index_approved.html.erb @@ -0,0 +1,100 @@ +
    + +

    <%= ts('Manage Approved Skins') %>

    + + + +<%= render :partial => 'admin/skins/navigation' %> + + + +<%= form_tag update_admin_skin_path, {:method => :put} do %> + + +
    + <%= ts('Approved Skins') %> +

    <%= ts('Approved Skins') %>

    + + + + + + + + + + + + + + + <% @approved_skins.each_with_index do |skin, i| %> + <% disabled = !policy(skin).update? %> + + + + + + + + + <% end %> + +
    <%= ts('Approved Skins') %>
    <%= ts('Skin') %><%= ts('Type') %><%= ts('Creator') %><%= ts('Users') %><%= ts('Admin Note') %><%= ts('Actions') %>
    <%= link_to skin.title, skin_path(skin) %><%= skin.type == 'WorkSkin' ? 'Work Skin' : 'Site Skin' %><%= skin_author_link(skin) %><%= skin.preferences.count %><%= skin.admin_note %> + <% skin_name = skin.title.downcase.gsub(/ +/, '_') %> + <%= label_tag "make_unofficial_#{skin_name}", class: ["action", disabled ? "disabled" : ""] do %> + <%= ts("Unapprove") %> + <%= check_box_tag "make_unofficial[]", skin.id, false, id: "make_unofficial_#{skin_name}", disabled: disabled %> + <% end %> + + <% %w(cached featured in_chooser).each do |type| %> + <% if skin.send("#{type}?") %> + <%= label_tag "make_un#{type}_#{skin_name}", class: ["action", disabled ? "disabled" : ""] do %> + <%= + case type + when "cached" + ts("Uncache") + when "featured" + ts("Unfeature") + when "in_chooser" + ts("Not In Chooser") + end + %> + <%= check_box_tag "make_un#{type}[]", skin.id, false, id: "make_un#{type}_#{skin_name}", disabled: disabled %> + <% end %> + <% else %> + <%= label_tag "make_#{type}_#{skin_name}", class: ["action", disabled ? "disabled" : ""] do %> + <%= + case type + when "cached" + ts("Cache") + when "featured" + ts("Feature") + when "in_chooser" + ts("Chooser") + end + %> + <%= check_box_tag "make_#{type}[]", skin.id, false, id: "make_#{type}_#{skin_name}", disabled: disabled %> + <% end %> + <% end %> + <% end %> +
    +
    + + <% if policy(Skin).set_default? %> +
    + <%= ts("Set Default Archive Skin") %> +

    <%= ts("Set Default Archive Skin") %>

    +

    <%= ts("This will change the default skin FOR ALL USERS! Don't use unless you are REALLY SURE.") %>

    +

    + <%= label_tag "set_default", ts("Default Skin Title: ") %> + <%= text_field_tag "set_default", AdminSetting.default_skin.try(:title), autocomplete_options("site_skins", data: { autocomplete_token_limit: 1 }) %> + <%= hidden_field_tag :last_updated_by, current_admin.id %> +

    +
    + <% end %> + +

    <%= submit_tag ts("Update") %>

    + +<% end %> +
    diff --git a/app/views/admin/skins/index_rejected.html.erb b/app/views/admin/skins/index_rejected.html.erb new file mode 100755 index 0000000..0385cee --- /dev/null +++ b/app/views/admin/skins/index_rejected.html.erb @@ -0,0 +1,51 @@ +
    + +

    <%= ts('Manage Rejected Skins') %>

    + + + +<%= render :partial => 'admin/skins/navigation' %> + + + +<%= form_tag update_admin_skin_path, {:method => :put} do %> + +
    + <%= ts('Rejected Skins') %> +

    <%= ts('Rejected Skins') %>

    + + + + + + + + + + + + + <% @rejected_skins.each_with_index do |skin, i| %> + <% disabled = !policy(skin).update? %> + + + + + <% skin_name = skin.title.downcase.gsub(/ +/, '_') %> + + + <% end %> + +
    <%= ts('Rejected Skins') %>
    <%= ts('Skin') %><%= ts('Type') %><%= ts('Creator') %><%= ts('Admin Note') %><%= ts('Unreject') %>
    <%= link_to skin.title, skin_path(skin) %> + <%= skin.type == 'WorkSkin' ? 'Work Skin' : 'Site Skin' %><%= skin_author_link(skin) %><%=h skin.admin_note %><%= check_box_tag "make_unrejected[]", skin.id, false, id: "make_unrejected_#{skin_name}", disabled: disabled %>
    +
    + +

    <%= submit_tag ts('Update') %>

    + +<% end %> + + + + + +
    diff --git a/app/views/admin/spam/index.html.erb b/app/views/admin/spam/index.html.erb new file mode 100755 index 0000000..30e1c1d --- /dev/null +++ b/app/views/admin/spam/index.html.erb @@ -0,0 +1,88 @@ + +

    <%= ts("Manage Potential Spam") %>

    + + + + + + + +<%= form_tag "/admin/spam/bulk_update", method: :post do %> + "> + + + + + + + + + + + + <% @works.each do |work| %> + + + + + + + + <% end %> + +
    <%= ts("Works Marked as Spam") %>
    <%= ts("Title") %><%= ts("Creator") %><%= ts("Revised At") %> + <%= ts("Confirm As Spam") %> +
      +
    • + +
    • +
    • + +
    • +
    +
    + <%= ts("Mark As Not Spam") %> +
      +
    • + +
    • +
    • + +
    • +
    +
    + <%= link_to work.title, work_path(id: work.work_id) %> + <%= work.admin_user_links %><%= work.revised_at %> + <%= check_box_tag 'spam[]', work.id, nil, id: "spam_#{work.id}" %> + <%= label_tag "spam_#{work.id}", "Spam" %> + + <%= check_box_tag 'ham[]', work.id, nil, id: "ham_#{work.id}" %> + <%= label_tag "ham_#{work.id}", "Not Spam" %> +
    + <%= submit_button nil, ts("Update Works") %> +<% end %> + +<%= will_paginate @works %> + + +<% content_for :footer_js do %> + <%= javascript_include_tag "select_all", skip_pipeline: true %> +<% end %> diff --git a/app/views/admin/user_creations/confirm_remove_pseud.html.erb b/app/views/admin/user_creations/confirm_remove_pseud.html.erb new file mode 100755 index 0000000..b2fcf6e --- /dev/null +++ b/app/views/admin/user_creations/confirm_remove_pseud.html.erb @@ -0,0 +1,30 @@ + +

    <%= t(".page_heading") %>

    + + +<%= form_with url: remove_pseud_admin_user_creation_path(@work), method: :put, class: "simple destroy" do |f| %> + <% if @orphan_pseuds.length > 1 %> +

    + <%= t(".choose") %> +

    +
      + <%= f.collection_check_boxes :pseuds, @orphan_pseuds, :id, :byline, { include_hidden: false } do |builder| %> +
    • + <%= builder.check_box %> + <%= builder.label %> +
    • + <% end %> +
    +

    + <%= f.submit t(".submit_multiple") %> +

    + <% else %> +

    + <%= t(".caution") %> +

    +

    + <%= f.submit t(".submit_one") %> +

    + <% end %> +<% end %> + diff --git a/app/views/admin_mailer/send_spam_alert.html.erb b/app/views/admin_mailer/send_spam_alert.html.erb new file mode 100755 index 0000000..7bf03af --- /dev/null +++ b/app/views/admin_mailer/send_spam_alert.html.erb @@ -0,0 +1,20 @@ +<% content_for :message do %> + +

    The following accounts have a suspicious level of traffic:

    + <% @users.each do |user| %> + <% info = @spam[user.id] %> + User <%= style_link(user.login, user_works_url(user)) %> has a score of + <%= info["score"] %> +
      + <% Work.where(id: info["work_ids"]).each do |work| %> +
    • + <%= style_link(work.title, work_url(work)) %> + <% if work.spam? %> + (<%= ts('Flagged as spam') %>) + <% end %> +
    • + <% end %> +
    + <% end %> + +<% end %> diff --git a/app/views/admin_mailer/send_spam_alert.text.erb b/app/views/admin_mailer/send_spam_alert.text.erb new file mode 100755 index 0000000..85cba84 --- /dev/null +++ b/app/views/admin_mailer/send_spam_alert.text.erb @@ -0,0 +1,14 @@ +<% content_for :message do %> + + The following accounts have a suspicious level of traffic: + + <% @users.each do |user| %> + <% info = @spam[user.id] %> + User <%= user.login %> (<%= user_works_url(user) %>) has a score of <%= info["score"] %> + + <% Work.where(id: info["work_ids"]).each do |work| %> + * <%= work.title %> (<%= work_url(work) %>) <% if work.spam? %>(<%= ts('Flagged as spam') %>)<% end %> + <% end %> + + <% end %> +<% end %> diff --git a/app/views/admin_mailer/set_password_notification.html.erb b/app/views/admin_mailer/set_password_notification.html.erb new file mode 100755 index 0000000..3c630a4 --- /dev/null +++ b/app/views/admin_mailer/set_password_notification.html.erb @@ -0,0 +1,8 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.informal.addressed_html", name: style_bold(@admin.login)) %>

    +

    <%= t(".created") %>

    +

    <%= style_metadata_label(t(".username")) %><%= @admin.login %>

    +

    <%= style_metadata_label(t(".url")) %><%= style_link(new_admin_session_url, new_admin_session_url) %>

    +

    <%= t(".finish_html", set_password_link: style_link(t(".set_password"), edit_admin_password_url(reset_password_token: @token))) %>

    +

    <%= t(".expiration_html", count: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES, request_reset_link: style_link(t(".request_reset"), new_admin_password_url)) %>

    +<% end %> diff --git a/app/views/admin_mailer/set_password_notification.text.erb b/app/views/admin_mailer/set_password_notification.text.erb new file mode 100755 index 0000000..674fc3b --- /dev/null +++ b/app/views/admin_mailer/set_password_notification.text.erb @@ -0,0 +1,12 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.informal.addressed_html", name: @admin.login) %> + +<%= t(".created") %> + +<%= metadata_label(t(".username")) %><%= @admin.login %> +<%= metadata_label(t(".url")) %><%= new_admin_session_url %> + +<%= t(".finish", set_password_url: edit_admin_password_url(reset_password_token: @token)) %> + +<%= t(".expiration", count: ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES, request_reset_url: new_admin_password_url) %> +<% end %> diff --git a/app/views/admin_posts/_admin_index.html.erb b/app/views/admin_posts/_admin_index.html.erb new file mode 100755 index 0000000..8a386a1 --- /dev/null +++ b/app/views/admin_posts/_admin_index.html.erb @@ -0,0 +1,27 @@ + +

    <%= ts("AO3 News (includes Release Notes)") %>

    + + +<%= render 'filters' %> +<%= render :partial => 'admin/admin_nav' %> + + + +

    <%= ts("Manage News Postings") %>

    +
    + <% @admin_posts.each do |admin_post| %> +
    <%= link_to admin_post.title.html_safe, admin_post %>
    +
    +

    <%= ts("Created at %{created_date} and updated at %{updated_date}", :created_date => admin_post.created_at, :updated_date => admin_post.updated_at) %>

    +
      +
    • <%= link_to ts("Show"), admin_post %>
    • +
    • <%= link_to ts("Edit"), edit_admin_post_path(admin_post) %>
    • +
    • <%= link_to ts("Delete"), admin_post, data: {confirm: 'Are you sure?'}, :method => :delete %>
    • +
    +
    + <% end %> +
    + + + <%= will_paginate @admin_posts %> + diff --git a/app/views/admin_posts/_admin_post.html.erb b/app/views/admin_posts/_admin_post.html.erb new file mode 100755 index 0000000..dc4d6cc --- /dev/null +++ b/app/views/admin_posts/_admin_post.html.erb @@ -0,0 +1,39 @@ +<% # expects "admin_post" %> +
    dir="rtl"<% end %> class="header"> +

    + <%= link_to admin_post.title.html_safe, admin_post %> +

    +
    +

    <%= ts("Post Header") %>

    +
    +
    +
    <%= ts("Published:") %>
    +
    <%= admin_post.created_at %>
    + <% if admin_post.translated_post %> +
    <%= ts("Original:") %>
    +
    <%= link_to admin_post.translated_post.title, admin_post.translated_post %>
    + <% elsif !admin_post.translations.empty? %> +
    <%= ts("Translations:") %>
    +
    +
      + <% for translation in sorted_translations(admin_post) %> +
    • <%= link_to translation.language.name, translation, lang: translation.language.short %>
    • + <% end %> +
    +
    + <% end %> + <% if admin_post.tags.length > 0 %> +
    <%= ts("Tags:") %>
    +
    +
      + <% for tag in admin_post.tags %> +
    • <%= link_to tag.name, admin_posts_path(tag: tag.id), class: "tag" %>
    • + <% end %> +
    +
    + <% end %> +
    +
    +
    dir="rtl"<% end %> class="userstuff"> + <%= raw sanitize_field(admin_post, :content) %> +
    diff --git a/app/views/admin_posts/_admin_post_form.html.erb b/app/views/admin_posts/_admin_post_form.html.erb new file mode 100755 index 0000000..eac6aca --- /dev/null +++ b/app/views/admin_posts/_admin_post_form.html.erb @@ -0,0 +1,105 @@ +
    + <%= form_for(@admin_post) do |f| %> +

    <%= ts("All news posts need a title and some content.") %>

    + <%= error_messages_for @admin_post %> +
    + <%= ts("Post News") %> +

    + <%= f.text_field :title, :title =>"title" %>

    + + +

    + <%= allowed_html_instructions %> + +

    + <% use_tinymce %> +
    +

    <%= f.text_area :content, :class => "mce-editor observe_textlength", :id => "content", :title =>"content" %>

    + <%= live_validation_for_field('content', + :maximum_length => ArchiveConfig.CONTENT_MAX, :minimum_length => ArchiveConfig.CONTENT_MIN, + :tooLongMessage => ts("We salute your ambition! But sadly the content must be less than %{max} letters long.", :max => ArchiveConfig.CONTENT_MAX.to_s), + :tooShortMessage => ts("Brevity is the soul of wit, but your content does have to be at least %{min} letters long.", :min => ArchiveConfig.CONTENT_MIN.to_s), + :failureMessage => ts("You need to post some content here.")) + %> + <%= generate_countdown_html("content", ArchiveConfig.CONTENT_MAX) %> +
    +
    +
    + <%= ts("Set Preferences") %> +

    <%= ts("Set Preferences") %>

    +
    +
    <%= f.label :tag_list, t(".tags.label") %>
    +
    + <% if @admin_post.translated_post %> +
      + <% for tag in @admin_post.tags %> +
    • <%= link_to tag.name, admin_posts_path(tag: tag.id), class: "tag" %>
    • + <% end %> +
    + <% else %> + <%= f.text_field :tag_list, autocomplete_options("admin_post_tags") %> +

    + <%= ts("Comma separated, %{max} characters per tag", max: ArchiveConfig.TAG_MAX) %> +

    + <% end %> +
    +
    + <%= f.label :language_id, t(".language.label") %> +
    +
    + +
    +
    + <%= f.label :translated_post_id, t(".translated_post.label") %> +
    +
    + <%= f.text_field :translated_post_id, + autocomplete_options('admin_posts', + title: ts('translation of'), + data: { autocomplete_token_limit: 1 }) %> + <% unless @admin_post.translated_post %> +

    <%= t(".translated_post.footnote_comment_permissions") %>

    +

    <%= t(".translated_post.footnote_tags") %>

    + <% end %> +
    +
    + <%= f.check_box :moderated_commenting_enabled %> +
    +
    + <%= f.label :moderated_commenting_enabled, t("comments.commentable.permissions.moderated_commenting.enable") %> +
    +
    + <%= t(".comment_permissions.label") %> +
    +
    + <% if @admin_post.translated_post %> +

    <%= t("comments.commentable.permissions.options.#{@admin_post.comment_permissions}") %>

    + <% else %> +
    + <%= + radio_button_list(f, :comment_permissions, [ + [:enable_all, t("comments.commentable.permissions.options.enable_all")], + [:disable_anon, t("comments.commentable.permissions.options.disable_anon")], + [:disable_all, t("comments.commentable.permissions.options.disable_all")] + ]) + %> +
    + <% end %> +
    +
    +
    + +
    + <%= ts('Post') %> +

    <%= ts("Post") %>

    +

    + <%= submit_tag ts('Post'), :name => 'post_button' %> +

    +
    + <% end %> +
    diff --git a/app/views/admin_posts/_filters.html.erb b/app/views/admin_posts/_filters.html.erb new file mode 100755 index 0000000..f5c161a --- /dev/null +++ b/app/views/admin_posts/_filters.html.erb @@ -0,0 +1,8 @@ +

    <%= ts("Filters") %>

    +<%= form_tag admin_posts_path, :method => :get do %> +

    <%= label_tag :tag, ts("Tag:") %> + <%= select_tag :tag, ('' + options_from_collection_for_select(@tags, :id, :name, params[:tag])).html_safe %> + <%= label_tag :language_id, ts("Language:") %> + <%= select_tag :language_id, options_for_select(language_options_for_select(@news_languages, "short"), params[:language_id] || Language.default.short) %> + <%= submit_tag ts('Go') %>

    +<% end %> diff --git a/app/views/admin_posts/_sidebar.html.erb b/app/views/admin_posts/_sidebar.html.erb new file mode 100755 index 0000000..0ff7f2b --- /dev/null +++ b/app/views/admin_posts/_sidebar.html.erb @@ -0,0 +1,8 @@ + diff --git a/app/views/admin_posts/edit.html.erb b/app/views/admin_posts/edit.html.erb new file mode 100755 index 0000000..2fa716f --- /dev/null +++ b/app/views/admin_posts/edit.html.erb @@ -0,0 +1,11 @@ + +

    <%=h 'Edit AO3 News Post' %>

    + + + +<%= render :partial => 'admin/admin_nav' %> + + + +<%= render :partial => 'admin_post_form' %> + diff --git a/app/views/admin_posts/index.html.erb b/app/views/admin_posts/index.html.erb new file mode 100755 index 0000000..c5a5448 --- /dev/null +++ b/app/views/admin_posts/index.html.erb @@ -0,0 +1,43 @@ +
    + <% if policy(@admin_posts).can_post? %> + <%= render "admin_index" %> + <% else %> +
    + +

    <%= link_to ts("AO3 News"), admin_posts_path %>

    +
    + + + + + +
    + + <% @admin_posts.each do |admin_post| %> + +
    + <%= render "admin_post", admin_post: admin_post %> + +

    <%= ts("Comment") %>

    + + +
    + <% end %> + +
    + + + <%= will_paginate @admin_posts %> + + <% end %> +
    diff --git a/app/views/admin_posts/index.rss.builder b/app/views/admin_posts/index.rss.builder new file mode 100755 index 0000000..c269496 --- /dev/null +++ b/app/views/admin_posts/index.rss.builder @@ -0,0 +1,19 @@ +xml.instruct! :xml, :version => "1.0" +xml.rss :version => "2.0" do + xml.channel do + xml.title "Sunset News" + xml.description "Latest updates from sunset.femslash.club" + xml.link admin_posts_url + + @admin_posts.each do |post| + xml.item do + xml.title post.title + xml.description post.content + xml.pubDate post.created_at.to_fs(:rfc822) + xml.link admin_post_url(post) + xml.guid admin_post_url(post) + end + end + end +end + diff --git a/app/views/admin_posts/new.html.erb b/app/views/admin_posts/new.html.erb new file mode 100755 index 0000000..968622e --- /dev/null +++ b/app/views/admin_posts/new.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts("New AO3 News Post") %>

    + + + +<%= render :partial => 'admin/admin_nav' %> + + + +<%= render :partial => 'admin_post_form' %> + \ No newline at end of file diff --git a/app/views/admin_posts/show.html.erb b/app/views/admin_posts/show.html.erb new file mode 100755 index 0000000..3ee21f0 --- /dev/null +++ b/app/views/admin_posts/show.html.erb @@ -0,0 +1,55 @@ +
    +
    + +

    <%= link_to t(".page_heading"), admin_posts_path %>

    +
    + + + + +
    + +
    + <%= render "admin_post", admin_post: @admin_post %> +
    + + + + <%= render "comments/commentable", commentable: @admin_post %> + +
    diff --git a/app/views/admins/index.html.erb b/app/views/admins/index.html.erb new file mode 100755 index 0000000..ea9700b --- /dev/null +++ b/app/views/admins/index.html.erb @@ -0,0 +1,29 @@ + +

    <%= t(".page_title", login: current_admin.login) %>

    + + + + + + +
    +

    <%= t(".confidentiality_reminder") %>

    + +

    <%= t(".responsibility") %>

    + +

    <%= t(".roles.heading") %>

    + <% if current_admin.roles.any? %> +
      + <% current_admin.roles.each do |role| %> +
    • <%= t("activerecord.attributes.admin/role.#{role}") %>
    • + <% end %> +
    + <% else %> +

    <%= t(".roles.none") %>

    + <% end %> + +
    + +

    <%= t(".log_out_reminder") %>

    +
    + diff --git a/app/views/archive_faqs/_admin_index.html.erb b/app/views/archive_faqs/_admin_index.html.erb new file mode 100755 index 0000000..4690932 --- /dev/null +++ b/app/views/archive_faqs/_admin_index.html.erb @@ -0,0 +1,37 @@ +
    + +

    <%= t(".page_heading") %>

    + + + +<%= render "archive_faqs/filters" %> +<%= render "admin/admin_nav" %> + + + + +

    <%= t(".manage_faqs") %>

    +
    + <% @archive_faqs.each do |archive_faq| %> +
    <%= link_to archive_faq.title, archive_faq %>
    +
    +

    <%= t(".created_date", date_created: l(archive_faq.created_at)) %>

    + +
    + <% end %> +
    + +
    diff --git a/app/views/archive_faqs/_archive_faq_form.html.erb b/app/views/archive_faqs/_archive_faq_form.html.erb new file mode 100755 index 0000000..136581f --- /dev/null +++ b/app/views/archive_faqs/_archive_faq_form.html.erb @@ -0,0 +1,61 @@ + + +<%= form_for(@archive_faq, html: { class: "create faq" }) do |form| %> + <%= error_messages_for @archive_faq %> +

    <%= ts("* Required information") %>

    +
    + <%= ts("Set Preferences") %> +

    <%= ts("Set Preferences") %>

    +
    +
    + <%= form.label :title, ts("Category name") + "*" %> +
    +
    + <%= form.text_field :title %> + <%= live_validation_for_field(field_id(form, "title").to_sym, failureMessage: ts("Please enter a category name.")) %> +
    +
    +
    + + <% # TODO: If you have the form set up to create 3 questions and you only fill in 2, you get an error instead of the totally empty section being ignored. This is the same with requests/offers in challenge signups. %> +
    + <%= ts("Questions") %> +

    <%= ts("Questions") %>

    + + <% form.object.questions.each_with_index do |question, index| %> + <%= form.fields_for :questions, question do |question_form| %> + <%= render "question_answer_fields", form: question_form, index: index %> + <% end %> + <% end %> + <% if Globalize.locale.to_s == "en" %> +

    + <%= link_to_add_section("Add Question", form, :questions, "question_answer_fields") %> +

    + <% end %> +
    + +
    + <%= ts("Submit") %> +

    <%= ts("Submit") %>

    +

    + <%= submit_tag ts("Post"), name: "post_button" %> +

    +
    +<% end %> diff --git a/app/views/archive_faqs/_archive_faq_order.html.erb b/app/views/archive_faqs/_archive_faq_order.html.erb new file mode 100755 index 0000000..71912d4 --- /dev/null +++ b/app/views/archive_faqs/_archive_faq_order.html.erb @@ -0,0 +1,33 @@ +
    + <%= form_tag url_for(:action => 'update_positions') do %> +
      + <% for archive_faq in @archive_faqs %> +
    • + <%= text_field_tag "archive_faqs[]", nil, :size => 3, :maxlength => 3, :id => "archive_faqs_#{archive_faq.id}", :class => "number" %> + <%= archive_faq.position %>. +

      <%=h archive_faq.title %>

      +
    • + <% end %> +
    +

    <%= submit_tag "Update Positions" %>

    + <% end %> +
    + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j("#sortable_archive_faq_list").sortable({ + delay: 300, + update: function(event, ui) { + $j(".archive_faq-position-list").each(function(index, li){ + var faqId = $j(li).attr("id").replace("archive_faq_",""); + $j("#position-for-"+faqId).html(index+1); + }); + $j.ajax({ + type: 'post', + data: $j("#sortable_archive_faq_list").sortable("serialize"), + dataType: 'script', + url: "<%= url_for(:action => :update_positions) %>"}) + } + }) + <% end %> +<% end %> diff --git a/app/views/archive_faqs/_archive_faq_questions_order.html.erb b/app/views/archive_faqs/_archive_faq_questions_order.html.erb new file mode 100755 index 0000000..424c80e --- /dev/null +++ b/app/views/archive_faqs/_archive_faq_questions_order.html.erb @@ -0,0 +1,33 @@ +
    + <%= form_tag url_for(:action => 'update_positions') do %> +
      + <% for archive_faq in @archive_faqs %> +
    • + <%= text_field_tag "archive_faqs[]", nil, :size => 3, :maxlength => 3, :id => "archive_faqs_#{archive_faq.id}", :class => "number" %> + <%= archive_faq.position %>. +

      <%=h archive_faq.title %>

      +
    • + <% end %> +
    +

    <%= submit_tag "Update Positions" %>

    + <% end %> +
    + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j("#sortable_archive_faq_list").sortable({ + delay: 300, + update: function(event, ui) { + $j(".archive_faq-position-list").each(function(index, li){ + var faqId = $j(li).attr("id").replace("archive_faq_",""); + $j("#position-for-"+faqId).html(index+1); + }); + $j.ajax({ + type: 'post', + data: $j("#sortable_archive_faq_list").sortable("serialize"), + dataType: 'script', + url: "<%= url_for(:action => :update_positions) %>"}) + } + }) + <% end %> +<% end %> diff --git a/app/views/archive_faqs/_faq_index.html.erb b/app/views/archive_faqs/_faq_index.html.erb new file mode 100755 index 0000000..56f7e23 --- /dev/null +++ b/app/views/archive_faqs/_faq_index.html.erb @@ -0,0 +1,86 @@ + +

    <%= ts("Archive FAQ") %>

    + + + + + + + +

    + <%= ts("The FAQs are currently being updated and translated by our volunteers. This is a work in progress and not all information will be up to date or available in languages other than English at this time. If your language doesn't list all FAQs yet, please consult the English list and check back later for updates.") %> +

    +

    + <%= ts("Some commonly asked questions about the Archive are answered here. + Questions and answers about our Terms of Service can be found in the FAQ Section 2.") %>. + <%= ts("You may also like to check out our") %> <%= link_to ts("Known Issues"), known_issues_path %>. + <%= ts("If you need more help, please ") %> <%= link_to ts("contact Support"), feedbacks_path %>. +

    + +<% if @archive_faqs.blank? %> +

    <%= ts("We're sorry, there are currently no entries in the FAQ System.") %>

    +<% else %> + <% if rtl? %> +
    + <% else %> +
    + <% end %> +

    <%= ts("Available Categories") %> + +

    + +
    + +
    + +
    + + <%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(document).ready(function() { + $j(".category").children("a").click(function(e) { + $j(this).next().toggle(); + e.preventDefault(); + }).next().hide(); + + $j("#expand-categories").find("a").click(function(e) { + $j(".category").children("ul").show(); + e.preventDefault(); + }); + + $j("#collapse-categories").find("a").click(function(e) { + $j(".category").children("ul").hide(); + e.preventDefault(); + }); + }); + <% end %> + <% end %> +<% end %> diff --git a/app/views/archive_faqs/_filters.html.erb b/app/views/archive_faqs/_filters.html.erb new file mode 100755 index 0000000..6767c09 --- /dev/null +++ b/app/views/archive_faqs/_filters.html.erb @@ -0,0 +1,10 @@ +

    <%= ts("Filters") %>

    +<%= form_tag archive_faqs_path, :method => :get do %> +

    <%= label_tag :language_id, ts("Language:") %> + <% if User.current_user.is_a?(Admin) %> + <%= select_tag :language_id, ("" + options_for_select(locale_options_for_select(Locale.default_order, "iso"), params[:language_id])).html_safe %> + <% else %> + <%= select_tag :language_id, ("" + options_for_select(locale_options_for_select(available_faq_locales, "iso"), params[:language_id])).html_safe %> + <% end %> + <%= submit_tag ts('Go') %>

    +<% end %> diff --git a/app/views/archive_faqs/_question_answer_fields.html.erb b/app/views/archive_faqs/_question_answer_fields.html.erb new file mode 100755 index 0000000..c701599 --- /dev/null +++ b/app/views/archive_faqs/_question_answer_fields.html.erb @@ -0,0 +1,67 @@ +
    + <% index ||= 0 %> +
    + <% if index.is_a? String %> + <% question_label = ts("Question #{index}") %> + <% else %> + <% question_label = ts("Question #{(index + 1)}") %> + <% end %> + <%= question_label %> +

    <%= question_label %>

    + +
    +
    + <%= form.label :question, ts("Question") + "*" %> +
    +
    + <%= form.text_field :question %> + <%= live_validation_for_field(field_id(form, "question").to_sym, failureMessage: ts("Please enter a question.")) %> +
    + +
    + <%= form.label :anchor, ts("Anchor name") + "*" %> +
    +
    + <%= form.text_field :anchor, disabled: (I18n.locale != I18n.default_locale) %> + <%= live_validation_for_field(field_id(form, "anchor").to_sym, failureMessage: ts("Please enter an anchor name.")) %> +
    + +
    + <%= form.label :content, ts("Answer") + "*" %> +
    +
    + <%= form.text_area :content %> + <%= live_validation_for_field(field_id(form, "content").to_sym, + minimum_length: ArchiveConfig.CONTENT_MIN, + failureMessage: ts("Please enter an answer that is at least %{min} characters long.", min: ArchiveConfig.CONTENT_MIN.to_s)) %> +
    + +
    + <%= form.label :screencast, ts("Screencast URL") %> +
    +
    + <%= form.text_field :screencast %> +
    + <% if Globalize.locale.to_s != "en" %> +
    <%= form.check_box :is_translated %>
    +
    <%= form.label :is_translated, ts("Question translated") %>
    + <% end %> +
    + <% if Globalize.locale.to_s == "en" %> + <% # TODO: DELETE A QUESTION %> +

    + <% removetext = ts("Remove Question") %> + <%= link_to_remove_section(removetext, form) %> + <% # TODO: DELETE QUESTION WITHOUT JAVASCRIPT %> + +

    + <% end %> + +
    +
    + diff --git a/app/views/archive_faqs/confirm_delete.html.erb b/app/views/archive_faqs/confirm_delete.html.erb new file mode 100755 index 0000000..4350fd2 --- /dev/null +++ b/app/views/archive_faqs/confirm_delete.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts("Delete FAQ Category") %>

    + + +<%= form_for(@archive_faq, :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    <%= ts("Are you sure you want to delete the FAQ Category \"%{category_name}\"?", :category_name => @archive_faq.title).html_safe %>

    +

    + <%= f.submit ts("Yes, Delete FAQ Category") %> +

    +<% end %> + \ No newline at end of file diff --git a/app/views/archive_faqs/edit.html.erb b/app/views/archive_faqs/edit.html.erb new file mode 100755 index 0000000..fa065f3 --- /dev/null +++ b/app/views/archive_faqs/edit.html.erb @@ -0,0 +1,14 @@ +
    + +

    <%= ts("Edit Archive FAQ Category") %>

    + + + + <%= render :partial => 'filters' %> + <%= render :partial => 'admin/admin_nav' %> + + + + <%= render :partial => 'archive_faq_form' %> + +
    diff --git a/app/views/archive_faqs/index.html.erb b/app/views/archive_faqs/index.html.erb new file mode 100755 index 0000000..d59fc41 --- /dev/null +++ b/app/views/archive_faqs/index.html.erb @@ -0,0 +1,5 @@ +<% if policy(ArchiveFaq).translation_access? %> + <%= render "admin_index" %> +<% else %> + <%= render "faq_index" %> +<% end %> \ No newline at end of file diff --git a/app/views/archive_faqs/manage.html.erb b/app/views/archive_faqs/manage.html.erb new file mode 100755 index 0000000..3e774cd --- /dev/null +++ b/app/views/archive_faqs/manage.html.erb @@ -0,0 +1,11 @@ + +

    <%=h 'Manage Archive FAQs' %>

    + + + +<%= render :partial => 'admin/admin_nav' %> + + + +<%= render :partial => 'archive_faq_order' %> + \ No newline at end of file diff --git a/app/views/archive_faqs/new.html.erb b/app/views/archive_faqs/new.html.erb new file mode 100755 index 0000000..a9ad577 --- /dev/null +++ b/app/views/archive_faqs/new.html.erb @@ -0,0 +1,13 @@ +
    + +

    <%= ts("Create New Archive FAQ Category") %>

    + + + + <%= render :partial => 'admin/admin_nav' %> + + + + <%= render :partial => 'archive_faq_form' %> + +
    diff --git a/app/views/archive_faqs/show.html.erb b/app/views/archive_faqs/show.html.erb new file mode 100755 index 0000000..a72d0b1 --- /dev/null +++ b/app/views/archive_faqs/show.html.erb @@ -0,0 +1,58 @@ + +

    <%= link_to t(".page_heading"), archive_faqs_path %> > <%= @archive_faq.title %>

    + + + + + + +<% if @archive_faq.slug == "search-and-browse" %> +

    + <%= t(".elasticsearch_update_notice_html", elasticsearch_news_link: link_to(t(".elasticsearch_news"), admin_post_path(10_575))) %> +

    +<% end %> + +
    + <% if policy(ArchiveFaq).translation_access? %> +
    +

    + <% if Globalize.locale.to_s != "en" || policy(ArchiveFaq).full_access? -%> + <%= link_to t(".edit"), edit_archive_faq_path(@archive_faq) %> + <% end %> +

    +
    + <% end %> + + <% if @archive_faq.questions.blank? %> +

    <%= t(".no_category_entries") %>

    + <% else %> +
    dir="rtl"<% end %> class="userstuff"> + + +
    + <% for q in @questions %> +

    + <%= q.question %> +

    + <% unless q.screencast.to_s == "" %> +

    + <%= t(".screencast") %> <%= link_to q.question, q.screencast.to_s %> +

    + <% end %> + <%= raw sanitize_field(q, :content) %> + <% end %> +
    +
    + <% end %> +
    + diff --git a/app/views/blocked/users/_blocked_user_blurb.html.erb b/app/views/blocked/users/_blocked_user_blurb.html.erb new file mode 100755 index 0000000..be79109 --- /dev/null +++ b/app/views/blocked/users/_blocked_user_blurb.html.erb @@ -0,0 +1,9 @@ +<% pseud = block.blocked.default_pseud %> +
  • + <%= render "pseuds/pseud_module", pseud: pseud, date: block.created_at %> + +
    User Actions
    + +
  • diff --git a/app/views/blocked/users/confirm_block.html.erb b/app/views/blocked/users/confirm_block.html.erb new file mode 100755 index 0000000..03b6045 --- /dev/null +++ b/app/views/blocked/users/confirm_block.html.erb @@ -0,0 +1,31 @@ +

    <%= t(".title", name: @blocked.login) %>

    + +<%= form_tag user_blocked_users_path(@user, blocked_id: @blocked) do %> +
    +

    + <%= t(".sure_html", block: tag.strong(t(".block")), username: @blocked.login) %> + <%= t(".will.intro") %> +

    + +
      +
    • <%= t(".will.commenting") %>
    • +
    • <%= t(".will.replying") %>
    • +
    • <%= t(".will.gifting") %>
    • +
    + +

    <%= t(".will_not.intro") %>

    + +
      +
    • <%= t(".will_not.hide_works") %>
    • +
    • <%= t(".will_not.comments_on_works") %>
    • +
    • <%= t(".will_not.comments_elsewhere") %>
    • +
    + +

    <%= t(".mute_users_instead_html", muted_users_link: link_to(t(".muted_users_link_text"), user_muted_users_path(@user))) %>

    +
    + +

    + <%= link_to t(".cancel"), user_blocked_users_path(@user) %> + <%= submit_tag t(".button") %> +

    +<% end %> diff --git a/app/views/blocked/users/confirm_unblock.html.erb b/app/views/blocked/users/confirm_unblock.html.erb new file mode 100755 index 0000000..7e8b2fc --- /dev/null +++ b/app/views/blocked/users/confirm_unblock.html.erb @@ -0,0 +1,21 @@ +

    <%= t(".title", name: @block.blocked.login) %>

    + +<%= form_tag user_blocked_user_path(@user, @block), method: :delete do %> +
    +

    + <%= t(".sure_html", unblock: tag.strong(t(".unblock")), username: @block.blocked.login) %> + <%= t(".resume.intro") %> +

    + +
      +
    • <%= t(".resume.commenting") %>
    • +
    • <%= t(".resume.replying") %>
    • +
    • <%= t(".resume.gifting") %>
    • +
    +
    + +

    + <%= link_to t(".cancel"), user_blocked_users_path(@user) %> + <%= submit_tag t(".button") %> +

    +<% end %> diff --git a/app/views/blocked/users/index.html.erb b/app/views/blocked/users/index.html.erb new file mode 100755 index 0000000..55389bc --- /dev/null +++ b/app/views/blocked/users/index.html.erb @@ -0,0 +1,52 @@ +

    <%= t(".title") %>

    + + +

    <%= t("a11y.navigation") %>

    + + +
    +

    <%= t(".will.intro", block_limit: number_with_delimiter(ArchiveConfig.MAX_BLOCKED_USERS), count: ArchiveConfig.MAX_BLOCKED_USERS) %>

    + +
      +
    • <%= t(".will.commenting") %>
    • +
    • <%= t(".will.replying") %>
    • +
    • <%= t(".will.gifting") %>
    • +
    + +

    <%= t(".will_not.intro") %>

    + +
      +
    • <%= t(".will_not.hide_works") %>
    • +
    • <%= t(".will_not.comments_on_works") %>
    • +
    • <%= t(".will_not.comments_elsewhere") %>
    • +
    + +

    <%= t(".mute_users_instead_html", muted_users_link: link_to(t(".muted_users_link_text"), user_muted_users_path(@user))) %>

    +
    + +<% # form for blocking users %> + +<%= form_tag confirm_block_user_blocked_users_path(@user), method: :get, class: "single simple post" do %> +
    + <%= t(".legend") %> +

    + <%= label_tag :blocked_id, t(".label"), class: "landmark" %> + <%= text_field_tag :blocked_id, "", autocomplete_options("pseud", data: { autocomplete_token_limit: 1 }) %> + <%= submit_tag t(".button") %> +

    +
    +<% end %> + +

    <%= t(".heading.landmark.blocked_users") %>

    +<% if @blocks.present? %> +
      + <%= render partial: "blocked_user_blurb", collection: @blocks, as: :block %> +
    +<% else %> +

    <%= t(".none") %>

    +<% end %> + +<%= will_paginate @blocks %> diff --git a/app/views/bookmarks/_bookmark_blurb.html.erb b/app/views/bookmarks/_bookmark_blurb.html.erb new file mode 100755 index 0000000..8a35ee3 --- /dev/null +++ b/app/views/bookmarks/_bookmark_blurb.html.erb @@ -0,0 +1,47 @@ +<% # expects "bookmark" %> +<% bookmarkable = bookmark.bookmarkable %> +<% bookmark_form_id = (bookmarkable.blank? ? "#{bookmark.id}" : "#{bookmarkable.id}") %> +
  • + + <% if bookmarkable.blank? %> +

    <%= ts("This has been deleted, sorry!") %>

    + <% # Bookmarks of deleted items need a div because they can still be edited. %> +
    + <% else %> + + <% bookmark_count = bookmarkable.public_bookmark_count %> +

    + <%= get_symbol_for_bookmark(bookmark) %> + <%= get_count_for_bookmark_blurb(bookmarkable) %> +

    + + + <%= render "bookmarks/bookmark_item_module", bookmarkable: bookmarkable %> + + + <% if (bookmark_count > 1 && params[:tag_id]) || (bookmark_count > 1 && (@owner.blank? && @bookmarkable.blank?)) || (logged_in? && !is_author_of?(bookmark)) %> + + <% end %> + + <% # bookmark form loaded here if requested %> +
    + <% end %> + + <%= render "bookmarks/bookmark_user_module", bookmark: bookmark %> + + <% if logged_in_as_admin? && bookmarkable.class == ExternalWork %> + <%= render "admin/admin_options", item: bookmarkable %> + <% end %> + +
  • diff --git a/app/views/bookmarks/_bookmark_blurb_short.html.erb b/app/views/bookmarks/_bookmark_blurb_short.html.erb new file mode 100755 index 0000000..8a4529c --- /dev/null +++ b/app/views/bookmarks/_bookmark_blurb_short.html.erb @@ -0,0 +1,43 @@ +<% # This partial requires local variable 'bookmark' %> +
  • +
    + +

    <%= set_format_for_date(bookmark.created_at) %>

    +

    + <%= get_symbol_for_bookmark(bookmark) %> +

    +
    + + <% unless bookmark.tag_string.blank? %> +
    <%= ts("Bookmark Tags:") %>
    +
      + <% bookmark.tags.each do |tag| %> +
    • <%= link_to tag.name, tag_bookmarks_path(tag), class: "tag" %>
    • + <% end %> +
    + <% end %> + <% unless bookmark.collections.blank? %> +
    <%= ts("Bookmark Collections:") %>
    +
      + <% bookmark.collections.each do |coll| %> +
    • <%= link_to coll.title, collection_path(coll) %>
    • + <% end %> +
    + <% end %> + + <% if bookmark.bookmarker_notes.present? %> +
    <%= ts("Bookmark Notes:") %>
    +
    + <%= raw sanitize_field(bookmark, :bookmarker_notes, image_safety_mode: true) %> +
    + <% end %> + + <% if is_author_of?(bookmark) %> + <%= render "bookmark_owner_navigation", bookmark: bookmark %> + <% elsif logged_in_as_admin? %> + <%= render "admin/admin_options", item: bookmark %> + <% end %> +
  • diff --git a/app/views/bookmarks/_bookmark_form.html.erb b/app/views/bookmarks/_bookmark_form.html.erb new file mode 100755 index 0000000..05e1e9b --- /dev/null +++ b/app/views/bookmarks/_bookmark_form.html.erb @@ -0,0 +1,110 @@ +<% +# This renders the bookmark form based on whatever kind of object we are bookmarking +# we need bookmarkable, action (create or update), and bookmark if it exists +# if in_page is true then we assume that this is embedded within another page (eg the work page) +# if dynamic is true then this has been rendered via ajax +%> +
    +

    <%= ts("Bookmark") %>

    + + <% bookmark ||= Bookmark.new %> + <% bookmarkable ||= bookmark.bookmarkable %> + + <% in_page ||= false %> + <% dynamic ||= false %> + + <% bookmark_form_id = (bookmarkable.blank? ? "#{bookmark.id}" : "#{bookmarkable.id}") %> + <% notes_id = "bookmark_notes" + (dynamic ? "_#{bookmark_form_id}" : "") %> + + <% # Note telling users about our bookmarklet for external links %> + <% if !dynamic && bookmarkable.class == ExternalWork %><%= render "bookmarks/bookmarklet" %><% end %> + + <%= form_for(:bookmark, :url => bookmark_form_path(bookmark, bookmarkable), :html => {:method => bookmark.new_record? ? :post : :put}) do |f| %> + <% if bookmarkable.class == ExternalWork && bookmarkable.new_record? %> +

    * <%= ts('Required information') %>

    + <% end %> +
    + <%= ts("Bookmark") %> + <% if in_page %> +

    + <% if dynamic %> + × + <% else %> + × + <% end %> +

    + <% end %> + +

    + <% if current_user.pseuds.count > 1 %> + <%= select_tag "bookmark[pseud_id]", + options_for_select(current_user.pseuds.map{|pseud| [pseud.name, pseud.id]}, + bookmark.pseud ? bookmark.pseud.id : current_user.default_pseud.id), title: ts("choose pseud") %> + <% else %> + + <% end %> + <%= ts(" save a bookmark!") %> +

    + + <% # What we're bookmarking %> + <% if bookmarkable.class == ExternalWork && bookmarkable.new_record? %> + <%= fields_for :external_work, bookmarkable do |ew_form| %> + <%= render "bookmarks/external_work_fields", ew: ew_form %> + <% end %> + <% end %> + +
    + <%= ts("Write Comments") %> +
    +
    <%= f.label :bookmarker_notes, ts("Notes"), for: notes_id %>
    +
    +

    + <% if bookmarkable.class != ExternalWork %> + <%= ts("The creator's summary is added automatically.") %> + <% end %> + <%= allowed_html_instructions %> +

    + <%= f.text_area :bookmarker_notes, rows: 4, id: notes_id, class: "observe_textlength", + "aria-describedby" => "notes-field-description" %> + <%= generate_countdown_html(notes_id, ArchiveConfig.NOTES_MAX) %> +
    + +
    <%= f.label :tag_string, ts("Your tags") %>
    +
    + <% if bookmarkable.class != ExternalWork %> +

    + <%= ts("The creator's tags are added automatically.") %> +

    + <% end %> + <%= f.text_field :tag_string, autocomplete_options('tag?type=all', size: (in_page ? 60 : 80), "aria-describedby" => "tag-string-description") %> +

    + <%= ts("Comma separated, %{max} characters per tag", max: ArchiveConfig.TAG_MAX) %> +

    +
    + +
    <%= f.label :collection_names, ts("Add to collections") %>
    +
    + <%= f.text_field :collection_names, autocomplete_options('open_collection_names', size: (in_page ? 60 : 80)) %> +
    +
    +
    + +
    + <%= ts("Choose Type and Post") %> +

    + <%= f.check_box :private %> <%= f.label :private, ts("Private bookmark") %> + <%= f.check_box :rec %> <%= f.label :rec, ts("Rec") %> +

    +

    + <%= f.submit(button_name) %> + <% unless in_page %> + <%= link_to ts("My Bookmarks"), user_bookmarks_path(current_user) %> + <% end %> +

    +
    +
    + <% end %> +
    diff --git a/app/views/bookmarks/_bookmark_item_module.html.erb b/app/views/bookmarks/_bookmark_item_module.html.erb new file mode 100755 index 0000000..889692f --- /dev/null +++ b/app/views/bookmarks/_bookmark_item_module.html.erb @@ -0,0 +1,8 @@ +<% # expects "bookmarkable" %> +<% if bookmarkable.is_a?(ExternalWork) %> + <%= render 'external_works/work_module', external_work: bookmarkable, bookmarkable: bookmarkable %> +<% elsif bookmarkable.is_a?(Series) %> + <%= render 'series/series_module', series: bookmarkable %> +<% else %> + <%= render 'works/work_module', work: bookmarkable %> +<% end %> \ No newline at end of file diff --git a/app/views/bookmarks/_bookmark_owner_navigation.html.erb b/app/views/bookmarks/_bookmark_owner_navigation.html.erb new file mode 100755 index 0000000..b3bf21e --- /dev/null +++ b/app/views/bookmarks/_bookmark_owner_navigation.html.erb @@ -0,0 +1,12 @@ +<% # expects "bookmark" %> +<% bookmark_form_id = (bookmark.bookmarkable.blank? ? "#{bookmark.id}" : "#{bookmark.bookmarkable.id}") %> + diff --git a/app/views/bookmarks/_bookmark_user_module.html.erb b/app/views/bookmarks/_bookmark_user_module.html.erb new file mode 100755 index 0000000..bda5ac2 --- /dev/null +++ b/app/views/bookmarks/_bookmark_user_module.html.erb @@ -0,0 +1,60 @@ +<%# expects "bookmark" %> +
    + + <%# If you update the cache key, update flush_bookmark_cache in tag.rb %> + <% blurb_cache_key = (is_author_of?(bookmark) ? "bookmark-owner-blurb-#{bookmark.cache_key}-v3" : "bookmark-blurb-#{bookmark.cache_key}-v3") %> + <% cache(blurb_cache_key, skip_digest: true) do %> +

    <%= set_format_for_date(bookmark.created_at) %>

    + + <%# information added by the bookmark owner %> + <% unless bookmark.tag_string.blank? %> +
    <%= ts('Bookmarker\'s Tags:') %>
    +
      + <% bookmark.tags.each do |tag| %> +
    • <%= link_to(tag.name, tag_bookmarks_path(tag), class: "tag") %>
    • + <% end %> +
    + <% end %> + + <%# When the user views their own bookmark blurb, they are warned about seeing their bookmark in a modded collection %> + <% unless bookmark.collections.blank? %> + <% bookmark.collections.each do |modded| %> + <% if modded.moderated? && !bookmark.approved_collections.include?(modded) && is_author_of?(bookmark) %> +

    <%= ts("The collection %{title} is currently moderated. Your bookmark must be approved by the collection maintainers before being listed there.", title: modded.title) %>

    + <% end %> + <% end %> + <% unless bookmark.approved_collections.empty? && !is_author_of?(bookmark) %> +
    <%= ts('Bookmarker\'s Collections:') %>
    + <% end %> + <% unless bookmark.approved_collections.empty? && !is_author_of?(bookmark) %> +
      + <% if is_author_of?(bookmark) || logged_in_as_admin? %> + <% bookmark.collections.each do |coll| %> +
    • <%= link_to coll.title, collection_path(coll) %>
    • + <% end %> + <% else %> + <% bookmark.approved_collections.each do |coll| %> +
    • <%= link_to coll.title, collection_path(coll) %>
    • + <% end %> + <% end %> +
    + <% end %> + <% end %> + + <% if bookmark.bookmarker_notes.present? %> +
    <%= ts('Bookmarker\'s Notes') %>
    +
    + <%= raw sanitize_field(bookmark, :bookmarker_notes, image_safety_mode: true) %> +
    + <% end %> + <%# end of information added by the bookmark owner %> + <% end %> + + <% if is_author_of?(bookmark) %> + <%= render "bookmarks/bookmark_owner_navigation", bookmark: bookmark %> + <% elsif policy(bookmark).show_admin_options? %> + <%= render "admin/admin_options", item: bookmark %> + <% end %> +
    diff --git a/app/views/bookmarks/_bookmarkable_blurb.html.erb b/app/views/bookmarks/_bookmarkable_blurb.html.erb new file mode 100755 index 0000000..672f57e --- /dev/null +++ b/app/views/bookmarks/_bookmarkable_blurb.html.erb @@ -0,0 +1,54 @@ +<% # expects "bookmarkable" (a BookmarkableDecorator object) %> +<% # Unwrap the bookmarkable to avoid type mis-identification. %> +<% unwrapped = bookmarkable.__getobj__ %> +
  • + + + <% bookmark_count = bookmarkable.public_bookmark_count %> +

    + <%= get_count_for_bookmark_blurb(bookmarkable) %> +

    + + + <%= render "bookmarks/bookmark_item_module", bookmarkable: unwrapped %> + + + + + <% if logged_in_as_admin? && bookmarkable.class == ExternalWork %> + <%= render "admin/admin_options", item: bookmarkable %> + <% end %> + + <% # bookmark form loaded here if requested %> +
    + +
    +
      + <% bookmarkable.matching_bookmarks.each do |bookmark| %> + <%= render "bookmarks/bookmark_blurb_short", bookmark: bookmark %> + <% end %> +
    +
    + + +
  • diff --git a/app/views/bookmarks/_bookmarklet.html.erb b/app/views/bookmarks/_bookmarklet.html.erb new file mode 100755 index 0000000..e2d8689 --- /dev/null +++ b/app/views/bookmarks/_bookmarklet.html.erb @@ -0,0 +1 @@ +

    Bookmark external works with the AO3 External Bookmarklet. This is a simple bookmarklet that should work in any browser, if you have JavaScript enabled. Just right-click and select Bookmark This Link (or Bookmark Link).

    diff --git a/app/views/bookmarks/_bookmarks.html.erb b/app/views/bookmarks/_bookmarks.html.erb new file mode 100755 index 0000000..75f197a --- /dev/null +++ b/app/views/bookmarks/_bookmarks.html.erb @@ -0,0 +1,21 @@ +<% # show blurb for whatever is bookmarked if we're looking at a single bookmarked object %> +<% if params[:work_id] %> + <%= render 'works/work_blurb', :work => @bookmarkable %> +<% elsif params[:external_work_id] %> + <%= render 'external_works/blurb', :external_work => @bookmarkable %> +<% elsif params[:series_id] %> + <%= render 'series/series_blurb', :series => @bookmarkable %> +<% end %> + +<% if @bookmarkable %> + <% # show only partial view for each bookmark since the bookmarked object is already shown above %> + <%= render partial: 'bookmarks/bookmark_blurb_short', collection: @bookmarks, as: :bookmark %> + +<% elsif @bookmarkable_items %> + <% # Display a list of bookmarkables, with several bookmarks under each %> + <%= render partial: 'bookmarks/bookmarkable_blurb', collection: @bookmarkable_items, as: :bookmarkable %> +<% else %> + <% # Standard bookmarks index with full blurb %> + <%= render partial: 'bookmarks/bookmark_blurb', collection: @bookmarks, as: :bookmark %> + +<% end %> diff --git a/app/views/bookmarks/_external_work_fields.html.erb b/app/views/bookmarks/_external_work_fields.html.erb new file mode 100755 index 0000000..2663ec0 --- /dev/null +++ b/app/views/bookmarks/_external_work_fields.html.erb @@ -0,0 +1,119 @@ +
    + <%= ts("External Work") %> +
    +
    <%= ew.label :url, ts("URL") + "*" %>
    +
    + <% if params[:url_from_external].present? %> + <%= ew.text_field :url, autocomplete_options("external_work", data: { autocomplete_token_limit: 1 }, value: params[:url_from_external]) %> + <% else %> + <%= ew.text_field :url, autocomplete_options("external_work", data: { autocomplete_token_limit: 1 }) %> + <% end %> + <%= hidden_field "fetched", "", id: "fetched" %> + <%= content_for :footer_js do %> + <%= javascript_tag do %> + <% if params[:url_from_external].present? %> + // The blur event isn't triggered if we start with a URL from the + // External Bookmarklet, so instead we grab the info on the initial + // page load. This only fires when we're using the bookmarklet, not + // when we're thrown back to the form due to an error -- we don't + // want to override information the user has put in. + $j(document).ready(function() { + loadExternalWorkInfoForBookmark(); + }); + <% else %> + // Fill in the external work information once we have chosen a URL + // from the autocomplete field. + $j("#bookmark-form").on("blur", "#external_work_url_autocomplete", function() { + loadExternalWorkInfoForBookmark(); + }); + <% end %> + function loadExternalWorkInfoForBookmark() { + $j.ajax({ + type: "get", + data: "external_work_url=" + $j("#external_work_url").val(), + dataType: "script", + url: "<%= url_for(controller: "external_works", action: "fetch", only_path: true) %>" + }); + } + <% end %> + <% end %> + +
    +
    <%= ew.label :author, ts("Creator") + "*" %>
    +
    + <%= ew.text_field :author, class: "observe_textlength" %> + <%= generate_countdown_html("external_work_author", ExternalWork::AUTHOR_LENGTH_MAX) %> +
    +
    <%= ew.label :title, ts("Title") + "*" %>
    +
    + <% if params[:url_from_external].present? %> + <%= ew.text_field :title, value: params[:title_from_external], class: "observe_textlength" %> + <% else %> + <%= ew.text_field :title, class: "observe_textlength" %> + <% end %> + <%= generate_countdown_html("external_work_title", ArchiveConfig.TITLE_MAX) %> +
    +
    + <%= ew.label :summary, ts("Creator's Summary") %> + <%= ts("(please copy and paste from original work)") %> +
    +
    + <%= ew.text_area :summary, rows: 5, class: "observe_textlength" %> + <%= generate_countdown_html("external_work_summary", ArchiveConfig.SUMMARY_MAX) %> +
    +
    +
    +
    + <%= ts("Creator's Tags") %> +

    + <%= ts("Creator's Tags (comma separated, %{max} characters per tag). Only a fandom is required. Fandom, relationship, and character tags must not add up to more than %{limit}. Category and rating tags do not count toward this limit.", + limit: ArchiveConfig.USER_DEFINED_TAGS_MAX, + max: ArchiveConfig.TAG_MAX) %> +

    +
    +
    + <%= ew.label :fandom_string, Fandom::NAME.pluralize + "*" %> <%= link_to_help "fandom-help" %> +
    +
    + <%= ew.text_field :fandom_string, autocomplete_options("fandom") %> +
    +
    + <%= ew.label :rating_string, Rating::NAME %> <%= link_to_help "rating-help" %> +
    +
    + <%= ew.collection_select :rating_string, + Rating.defaults_by_severity, + :name, + :name, + selected: ew.object.rating_string.presence || ArchiveConfig.RATING_DEFAULT_TAG_NAME + %> +
    +
    + <%= Category::NAME.pluralize %> <%= link_to_help "categories-help" %> +
    +
    +
      + <%= ew.collection_check_boxes :category_strings, Category.canonical.by_name.sort, :name, :name do |builder| %> +
    • + <%= builder.check_box %> + <%= builder.label %> +
    • + <% end %> +
    +
    +
    + <%= ew.label :relationship_string, Relationship::NAME.pluralize %> <%= link_to_help "relationships-help" %> +
    +
    + <%= ew.text_field :relationship_string, autocomplete_options("relationship_in_fandom", data: { autocomplete_live_params: "fandom=external_work_fandom_string" }) %> +
    +
    + <%= ew.label :character_string, Character::NAME.pluralize %> <%= link_to_help "characters-help" %> +
    +
    + <%= ew.text_field :character_string, autocomplete_options("character_in_fandom", data: { autocomplete_live_params: "fandom=external_work_fandom_string" }) %> +
    +
    +
    diff --git a/app/views/bookmarks/_filters.html.erb b/app/views/bookmarks/_filters.html.erb new file mode 100755 index 0000000..2eeb66c --- /dev/null +++ b/app/views/bookmarks/_filters.html.erb @@ -0,0 +1,154 @@ +<%= form_for @search, as: :bookmark_search, + url: (@collection ? collection_bookmarks_path(@collection) : bookmarks_path), + html: { + method: :get, + class: "narrow-hidden filters", + id: "bookmark-filters" + } do |f| %> +

    <%= ts("Filters") %>

    + <%= field_set_tag ts("Filter results:") do %> +
    +
    <%= ts("Submit") %>
    +
    <%= f.submit ts("Sort and Filter") %>
    +
    + <%= f.label :sort_column, ts("Sort by") %> +
    +
    + <%= f.select :sort_column, options_for_select(@search.sort_options, @search.sort_column) %> +
    + + <% %w(include exclude).each do |filter_action| %> +
    +

    + <%= ts("%{filter_action}", filter_action: filter_action.titleize) %> +

    + <%= link_to_help "bookmark-filters-#{filter_action}-tags" %> +
    +
    +
    + <% %w(rating archive_warning category fandom character relationship freeform tag).each do |tag_type| %> +
    + <% # For accessibility, include filter action (e.g. Include) as landmark text %> + <% # The space needs to be in the landmark to keep the text aligned %> + <%= ts("%{filter_action} %{tag_type}", + filter_action: filter_action.titleize, + tag_type: tag_type_label_name(tag_type).pluralize + ).html_safe %> +
    + + <% end %> + <% field_name = filter_action == "include" ? "other_tag_names" : "excluded_tag_names" %> + + + <% field_name = filter_action == "include" ? "other_bookmark_tag_names" : "excluded_bookmark_tag_names" %> + + +
    +
    + <% end %> + +
    +

    <%= ts("More Options") %>

    +
    +
    +
    + + + + + + +
    + <%= f.label :language_id, ts("Work language") %> +
    +
    + <%= f.select(:language_id, language_options_for_select(Language.default_order, "short"), include_blank: true) %> +
    + +
    <%= ts("Bookmark types") %>
    +
    +
      +
    • + <%= f.label :rec do %> + <%= f.check_box :rec %> + <%= label_indicator_and_text(ts("Recs only")) %> + <% end %> +
    • +
    • + <%= f.label :with_notes do %> + <%= f.check_box :with_notes %> + <%= label_indicator_and_text(ts("Only bookmarks with notes")) %> + <% end %> +
    • +
    +
    +
    +
    +
    <%= ts("Submit") %>
    +
    <%= f.submit ts("Sort and Filter") %>
    +
    + + <% if @owner %> +

    + <%= link_to ts("Clear Filters"), bookmarks_original_path %> +

    + <% end %> + +
    + <%= hidden_field_tag("collection_id", @collection.id) if @collection %> + <%= hidden_field_tag("tag_id", @tag.to_param) if @tag %> + <%= hidden_field_tag("fandom_id", @fandom.id) if @fandom %> + <%= hidden_field_tag("pseud_id", @pseud.name) if @pseud %> + <%= hidden_field_tag("user_id", @user.login) if @user %> +
    + <% end %> + <% # On narrow screens, link jumps to top of index when JavaScript is disabled and closes filters when JavaScript is enabled %> + +<% end %> diff --git a/app/views/bookmarks/_search_form.html.erb b/app/views/bookmarks/_search_form.html.erb new file mode 100755 index 0000000..b14a480 --- /dev/null +++ b/app/views/bookmarks/_search_form.html.erb @@ -0,0 +1,121 @@ +<%= form_for @search, as: :bookmark_search, url: search_bookmarks_path, + html: { class: "search", method: :get } do |f| %> +
    + <%= ts("Bookmarked Item") %> +

    <%= ts("Bookmarked Item") %>

    +
    +
    + <%= f.label :bookmarkable_query, ts("Any field on work") %> + <%= link_to_help "bookmark-search-text-help" %> +
    +
    + <%= f.text_field :bookmarkable_query %> +
    +
    + <%= f.label :other_tag_names, ts("Work tags") %> + <%= link_to_help "bookmark-search-work-tag" %> +
    +
    + <%= f.text_field :other_tag_names, autocomplete_options("tag") %> +
    +
    + <%= f.label :bookmarkable_type, ts("Type") %> + <%= link_to_help "bookmark-search-type-help" %> +
    +
    + <%= f.select :bookmarkable_type, + options_for_select(["", "Work", "Series", "External Work"], + @search.bookmarkable_type) %> +
    +
    + <%= f.label :language_id, ts("Work language") %> +
    +
    + <%= f.select(:language_id, language_options_for_select(@languages, "short"), include_blank: true) %> +
    +
    + <%= f.label :bookmarkable_date, ts("Date updated") %> + <%= link_to_help "bookmark-search-date-updated-help" %> +
    +
    + <%= f.text_field :bookmarkable_date %> +
    +
    +
    + +
    + <%= ts("Bookmark") %> +

    <%= ts("Bookmark") %>

    +
    +
    + <%= f.label :bookmark_query, ts("Any field on bookmark") %> + <%= link_to_help "bookmark-search-text-help" %> +
    +
    + <%= f.text_field :bookmark_query %> +
    +
    + <%= f.label :other_bookmark_tag_names, ts("Bookmarker's tags") %> + <%= link_to_help "bookmark-search-bookmarker-tag" %> +
    +
    + <%= f.text_field :other_bookmark_tag_names, autocomplete_options("tag") %> +
    +
    + <%= f.label :bookmarker, ts("Bookmarker") %> + <%= link_to_help "bookmark-search-text-help" %> +
    +
    + <%= f.text_field :bookmarker %> +
    +
    + <%= f.label :bookmark_notes, ts("Notes") %> + <%= link_to_help "bookmark-search-text-help" %> +
    +
    + <%= f.text_field :bookmark_notes %> +
    +
    + <%= ts("Bookmark type") %> +
    +
    +
      +
    • + <%= f.check_box :rec %> + <%= f.label :rec, ts("Rec") %> + <%= link_to_help "bookmark-search-rec-help" %> +
    • +
    • + <%= f.check_box :with_notes %> + <%= f.label :with_notes, ts("With notes") %> + <%= link_to_help "bookmark-search-notes-help" %> +
    • +
    +
    +
    + <%= f.label :date, ts("Date bookmarked") %> + <%= link_to_help "bookmark-search-date-bookmarked-help" %> +
    +
    + <%= f.text_field :date %> +
    +
    +
    + +
    + <%= ts("Search") %> +

    <%= ts("Search") %>

    +
    +
    + <%= f.label :sort_column, ts("Sort by") %> +
    +
    + <%= f.select :sort_column, + options_for_select(@search.sort_options, + @search.sort_column), + { include_blank: ts("Best Match") } %> +
    +
    +

    <%= f.submit ts("Search Bookmarks") %>

    +
    +<% end %> diff --git a/app/views/bookmarks/bookmark_form_dynamic.js.erb b/app/views/bookmarks/bookmark_form_dynamic.js.erb new file mode 100755 index 0000000..c969550 --- /dev/null +++ b/app/views/bookmarks/bookmark_form_dynamic.js.erb @@ -0,0 +1,22 @@ +<% # Use the bookmarkable item's id unless we're dealing with a bookmark of a deleted item %> +<% bookmark_form_id = (@bookmarkable.blank? ? "#{@bookmark.id}" : "#{@bookmarkable.id}") %> + +var bookmark_div = $j('#bookmark_form_placement_for_<%= bookmark_form_id %>'); +var bookmark_close = $j('#bookmark_form_close_for_<%= bookmark_form_id %>'); +var bookmark_open = $j('#bookmark_form_trigger_for_<%= bookmark_form_id %>'); + +bookmark_div.html("<%= escape_javascript(render "bookmarks/bookmark_form", :bookmarkable => @bookmarkable, :bookmark => @bookmark, :button_name => @button_name, :action => @action, :in_page => true, :dynamic => true) %>"); +bookmark_open.hide(); + +$j('#bookmark_form_close_for_<%= bookmark_form_id %>').click(function(){ + bookmark_div.hide(); + bookmark_open.show(); +}); + +// if canceled we don't want to generate the form a second time, just reopen it +bookmark_open.attr('href', '#'); +$j("#bookmark_form_trigger_for_<%= bookmark_form_id %>").click(function(event){ + bookmark_div.show(); + bookmark_open.hide(); + event.preventDefault(); +}); diff --git a/app/views/bookmarks/confirm_delete.html.erb b/app/views/bookmarks/confirm_delete.html.erb new file mode 100755 index 0000000..312564a --- /dev/null +++ b/app/views/bookmarks/confirm_delete.html.erb @@ -0,0 +1,17 @@ + +

    <%= ts("Delete Bookmark") %>

    + + +<%= form_for(@bookmark, :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    + <% if @bookmark.bookmarkable.nil? %> + <%= ts('Are you sure you want to delete your bookmark of this deleted work?').html_safe %> + <% else %> + <%= ts('Are you sure you want to delete your bookmark of "%{bookmarkable}"?', :bookmarkable => @bookmark.bookmarkable.title).html_safe %> + <% end %> +

    +

    + <%= f.submit ts("Yes, Delete Bookmark") %> +

    +<% end %> + diff --git a/app/views/bookmarks/edit.html.erb b/app/views/bookmarks/edit.html.erb new file mode 100755 index 0000000..0dd9e4e --- /dev/null +++ b/app/views/bookmarks/edit.html.erb @@ -0,0 +1,22 @@ + +

    + <% if @bookmarkable %> + <%= (ts("Editing bookmark for ") + link_to(@bookmarkable.title, @bookmarkable)).html_safe %> + <% else %> + <%= ts("Editing bookmark") %> + <% end %> +

    + +<%= error_messages_for :bookmark %> + + + + + + + +<%= render 'bookmark_form', :button_name => ts('Update'), :action => 'update', :bookmark => @bookmark, :bookmarkable => @bookmarkable %> + diff --git a/app/views/bookmarks/index.html.erb b/app/views/bookmarks/index.html.erb new file mode 100755 index 0000000..baeb832 --- /dev/null +++ b/app/views/bookmarks/index.html.erb @@ -0,0 +1,71 @@ + +<%= render "muted/muted_items_notice" %> + +

    + <% if @bookmarkable_items %> + <%= search_header @bookmarkable_items, @search, "Bookmarked Item", @owner %> + <% else %> + <%= search_header @bookmarks, @search, "Bookmark", @owner %> + <% end %> +

    + + + +<% if current_user.is_a?(User) || @tag || @facets.present? %> + +<% end %> + + +<% if params[:work_id] || params[:series_id] || params[:external_work_id] %> + <% # bookmark form loaded here if requested %> +
    +<% end %> + +<% unless @owner.present? || @bookmarkable.present? %> +

    <%= t(".recent_bookmarks_html", choose_fandom_link: link_to(t(".choose_fandom"), media_index_path), advanced_search_link: link_to(t(".advanced_search"), search_bookmarks_path)) %> +<% end %> + +<%== pagy_nav @pagy %> + + +

    <%= ts("List of Bookmarks") %>

    +
      + <%= render "bookmarks/bookmarks" %> +
    + + + +<% if @facets.present? %> + <%= render "filters" %> +<% end %> + + + + + +<%== pagy_nav @pagy %> + diff --git a/app/views/bookmarks/new.html.erb b/app/views/bookmarks/new.html.erb new file mode 100755 index 0000000..3184a06 --- /dev/null +++ b/app/views/bookmarks/new.html.erb @@ -0,0 +1,9 @@ + +

    <%= (ts("New bookmark for ") + link_to(@bookmarkable.title, @bookmarkable)).html_safe %>

    + +<%= error_messages_for :bookmark %> + + + +<%= render :partial => 'bookmark_form', :locals => { :bookmark => @bookmark, :bookmarkable => @bookmarkable, :button_name => ts("Create"), :action => 'create' }%> + diff --git a/app/views/bookmarks/search.html.erb b/app/views/bookmarks/search.html.erb new file mode 100755 index 0000000..765d461 --- /dev/null +++ b/app/views/bookmarks/search.html.erb @@ -0,0 +1,12 @@ + + +

    <%= ts("Bookmark Search") %>

    + + + +<%= render 'shared/search_nav' %> + + + +<%= render "bookmarks/search_form" %> + diff --git a/app/views/bookmarks/search_results.html.erb b/app/views/bookmarks/search_results.html.erb new file mode 100755 index 0000000..70032e4 --- /dev/null +++ b/app/views/bookmarks/search_results.html.erb @@ -0,0 +1,35 @@ + +<%= render "muted/muted_items_notice" %> + +

    <%= ts('Search Results') %>

    + +

    + <%= ts("You searched for:") %> + <%= (sanitize @search.summary, tags: %w[span], attributes: %w[lang]).html_safe %> +

    + + + + + + + +<% if @bookmarks.blank? %> +

    <%= ts("No results found. You may want to edit your search to make it less specific.") %>

    +<% else %> +

    <%= search_results_found(@bookmarks) %> <%= link_to_help "bookmark-search-results-help" %>

    + +

    Bookmarks List

    +
      + <% @bookmarks.each do |bookmark| %> + <% unless bookmark.nil? %> + <%= render 'bookmarks/bookmark_blurb', :bookmark => bookmark %> + <% end %> + <% end %> +
    + + <%= will_paginate @bookmarks %> +<% end %> + diff --git a/app/views/bookmarks/share.html.erb b/app/views/bookmarks/share.html.erb new file mode 100755 index 0000000..64f2915 --- /dev/null +++ b/app/views/bookmarks/share.html.erb @@ -0,0 +1 @@ +<%= render 'share/share', shareable: @bookmark %> diff --git a/app/views/bookmarks/show.html.erb b/app/views/bookmarks/show.html.erb new file mode 100755 index 0000000..100ffbd --- /dev/null +++ b/app/views/bookmarks/show.html.erb @@ -0,0 +1,23 @@ + +

    + <%= ts("Bookmark") %> +

    + + + + + + + +
      + <%= render 'bookmark_blurb', :bookmark => @bookmark %> +
    + diff --git a/app/views/challenge/gift_exchange/_challenge_main.html.erb b/app/views/challenge/gift_exchange/_challenge_main.html.erb new file mode 100755 index 0000000..10056b2 --- /dev/null +++ b/app/views/challenge/gift_exchange/_challenge_main.html.erb @@ -0,0 +1 @@ + diff --git a/app/views/challenge/gift_exchange/_challenge_meta.html.erb b/app/views/challenge/gift_exchange/_challenge_meta.html.erb new file mode 100755 index 0000000..d394f2c --- /dev/null +++ b/app/views/challenge/gift_exchange/_challenge_meta.html.erb @@ -0,0 +1 @@ +<%= render "challenge/shared/challenge_meta" %> diff --git a/app/views/challenge/gift_exchange/_challenge_navigation_maintainer.html.erb b/app/views/challenge/gift_exchange/_challenge_navigation_maintainer.html.erb new file mode 100755 index 0000000..331129c --- /dev/null +++ b/app/views/challenge/gift_exchange/_challenge_navigation_maintainer.html.erb @@ -0,0 +1,6 @@ +<% if @collection.challenge.user_allowed_to_see_signups?(current_user) %> +
  • <%= link_to ts("Sign-ups"), collection_signups_path(@collection) %>
  • +<% end %> +<% if @collection.user_is_owner?(current_user) %> +
  • <%= link_to ts("Challenge Settings"), edit_collection_gift_exchange_path(@collection) %>
  • +<% end %> diff --git a/app/views/challenge/gift_exchange/_challenge_navigation_user.html.erb b/app/views/challenge/gift_exchange/_challenge_navigation_user.html.erb new file mode 100755 index 0000000..23ee157 --- /dev/null +++ b/app/views/challenge/gift_exchange/_challenge_navigation_user.html.erb @@ -0,0 +1 @@ +<%= render "challenge/shared/challenge_navigation_user", :collection => (collection ||= @collection) %> \ No newline at end of file diff --git a/app/views/challenge/gift_exchange/_challenge_requests.html.erb b/app/views/challenge/gift_exchange/_challenge_requests.html.erb new file mode 100755 index 0000000..ef85178 --- /dev/null +++ b/app/views/challenge/gift_exchange/_challenge_requests.html.erb @@ -0,0 +1 @@ +<%= render "challenge/shared/challenge_requests" %> diff --git a/app/views/challenge/gift_exchange/_challenge_sidebar.html.erb b/app/views/challenge/gift_exchange/_challenge_sidebar.html.erb new file mode 100755 index 0000000..337a286 --- /dev/null +++ b/app/views/challenge/gift_exchange/_challenge_sidebar.html.erb @@ -0,0 +1,46 @@ +<% if logged_in? %> +

    <%= ts("Gift Exchange") %>

    + +<% end %> diff --git a/app/views/challenge/gift_exchange/_challenge_signups.html.erb b/app/views/challenge/gift_exchange/_challenge_signups.html.erb new file mode 100755 index 0000000..f6e6486 --- /dev/null +++ b/app/views/challenge/gift_exchange/_challenge_signups.html.erb @@ -0,0 +1,64 @@ + +

    + <% if @query %> + <%= search_header @challenge_signups, nil, t(".heading.for_search") %> + <% else %> + <%= t(".heading.for_collection", collection: @collection.title) %> + <% end %> +

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

    <%= t(".no_sign_ups_yet") %>

    +<% else %> + <%= will_paginate(@challenge_signups) %> + +
    + <% @challenge_signups.each do |signup| %> +
    + <%= link_to signup.pseud.byline, collection_signup_path(@collection, signup) %> + <%= mailto_link signup.pseud.user, subject: "[#{h(@collection.title)}] Message from Collection Maintainer" %> +
    +
    + <%= render "challenge_signups/signup_controls", challenge_signup: signup, subnav: false %> +
      +
    • + <%= link_to t(".requests_html"), "#", class: "requests_#{signup.id}_open" %> + <%= link_to t(".close_requests_html"), "#", class: "requests_#{signup.id}_close" %> +
    • +
    • + <%= link_to t(".offers_html"), "#", class: "offers_#{signup.id}_open" %> + <%= link_to t(".close_offers_html"), "#", class: "offers_#{signup.id}_close" %> +
    • +
    +
    "> + <%= render "challenge_signups/show_requests", challenge_signup: signup %> +
    +
    "> + <%= render "challenge_signups/show_offers", challenge_signup: signup %> +
    +
    + <% end %> +
    + + <%= will_paginate(@challenge_signups) %> +<% end %> + diff --git a/app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb b/app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb new file mode 100755 index 0000000..2681e29 --- /dev/null +++ b/app/views/challenge/gift_exchange/_challenge_signups_summary.html.erb @@ -0,0 +1,42 @@ +<% # display a summary version of what users have requested and offered %> +<% # requires locals :challenge_collection :tag_type :summary_tags :generated_live %> +

    <%= ts("Sign-up Summary for %{challenge_collection}", :challenge_collection => challenge_collection.title) %>

    + +<% unless generated_live %> +

    + <%= ts("Last generated at:") %> <%= time_in_zone(Time.now, (challenge_collection.challenge.time_zone || Time.zone.name)) %> + <%= ts("(Generated hourly on request while sign-ups are open.)") %> +

    +<% end %> + +<% if summary_tags.empty? %> +

    <%= ts("Tags were not used in this Challenge, so there is no summary to display here.") %>

    +<% else %> +

    <%= ts("Requested %{tag_type}", tag_type: tag_type_label_name(tag_type).pluralize) %>

    +

    + <%= ts('Listed by fewest offers and most requests.') %> +

    + "> + + + + + + + + + + <% summary_tags.each do |tag| %> + + + + + + <% end %> + +
    <%=ts("Requests and Offers for Requested %{tag_type}", tag_type: tag_type_label_name(tag_type)) %>
    <%= tag_type_label_name(tag_type) %><%= ts('Requests') %><%= ts('Offers') %>
    + + <%= tag.name %> + + <%= tag.requests.to_i %><%= tag.offers.to_i %>
    +<% end %> diff --git a/app/views/challenge/gift_exchange/_gift_exchange_form.html.erb b/app/views/challenge/gift_exchange/_gift_exchange_form.html.erb new file mode 100755 index 0000000..5b80e8e --- /dev/null +++ b/app/views/challenge/gift_exchange/_gift_exchange_form.html.erb @@ -0,0 +1,57 @@ + +

    <%= ts("Setting Up the %{title} Gift Exchange", :title => @collection.title) %>

    + + + +<% if @collection.challenge %> + +<% end %> + + + +

    <%= ts('Notes') %>

    +
      +
    • <%= ts("The more options you allow here, the more complicated your sign-up form will be.") %>
    • +
    • <%= ts("If you keep to one request and one offer, automated matching will be easier! A single request can include multiple fandoms. Unless you want to do fairly complicated requests, you probably don't need more than one request/offer.") %>
    • +
    • <%= ts('You only need to set the "Allowed" number if you want more allowed than required.') %>
    • +
    + +

    <%= ts("Gift Exchange Settings") %>

    +<%= form_for([@collection, @challenge], :url => collection_gift_exchange_path(@collection), :html => {:class => "verbose create challenge"}) do |f| %> + <%= error_messages_for @challenge %> + <%= render "challenge/shared/challenge_form_schedule", :f => f %> + +
    + <%= ts("Requests and Offers") %> +

    <%= ts("Requests and Offers") %>

    +
    +
    <%= f.label :requests_summary_visible, ts("Requests visible?") %> <%= link_to_help "challenge-requests-summary" %>
    +
    <%= f.check_box :requests_summary_visible %>
    + +
    <%= f.label :requests_num_required, ts("Number of requests per sign-up:") %>
    + <%= required_and_allowed(f, "requests", @collection.prompts.empty?, false) %> + +
    <%= f.label :offers_num_required, ts("Number of offers per sign-up:") %>
    + <%= required_and_allowed(f, "offers", @collection.prompts.empty?, false) %> +
    +
    + + + <%= render "prompt_restrictions/prompt_restriction_form", :challenge_form => f, :is_offer => false, :show_tag_options => false, :type => "gift_exchange" %> + + + <%= render "prompt_restrictions/prompt_restriction_form", :challenge_form => f, :is_offer => true, :show_tag_options => true, :type => "gift_exchange" %> + + + <%= render "potential_match_settings/potential_match_settings_form", :challenge_form => f %> + + + <%= render "challenge/shared/challenge_form_instructions", :f => f %> + + <%= submit_fieldset f %> + +<% end %> + + diff --git a/app/views/challenge/gift_exchange/confirm_delete.html.erb b/app/views/challenge/gift_exchange/confirm_delete.html.erb new file mode 100755 index 0000000..dde3cf9 --- /dev/null +++ b/app/views/challenge/gift_exchange/confirm_delete.html.erb @@ -0,0 +1,6 @@ + +

    <%= ts("Delete Gift Exchange") %>

    + + +<%= render "challenge/shared/challenge_form_confirm_delete" %> + diff --git a/app/views/challenge/gift_exchange/edit.html.erb b/app/views/challenge/gift_exchange/edit.html.erb new file mode 100755 index 0000000..eeb120a --- /dev/null +++ b/app/views/challenge/gift_exchange/edit.html.erb @@ -0,0 +1,2 @@ +<%= render :partial => "gift_exchange_form" %> + diff --git a/app/views/challenge/gift_exchange/new.html.erb b/app/views/challenge/gift_exchange/new.html.erb new file mode 100755 index 0000000..1c201ae --- /dev/null +++ b/app/views/challenge/gift_exchange/new.html.erb @@ -0,0 +1 @@ +<%= render :partial => "gift_exchange_form" %> \ No newline at end of file diff --git a/app/views/challenge/prompt_meme/_challenge_main.html.erb b/app/views/challenge/prompt_meme/_challenge_main.html.erb new file mode 100755 index 0000000..10056b2 --- /dev/null +++ b/app/views/challenge/prompt_meme/_challenge_main.html.erb @@ -0,0 +1 @@ + diff --git a/app/views/challenge/prompt_meme/_challenge_meta.html.erb b/app/views/challenge/prompt_meme/_challenge_meta.html.erb new file mode 100755 index 0000000..602ce63 --- /dev/null +++ b/app/views/challenge/prompt_meme/_challenge_meta.html.erb @@ -0,0 +1,4 @@ +<%= render "challenge/shared/challenge_meta" %> + +
    <%= ts("Prompts") %>:
    +
    <%= @collection.prompts.count.to_s %>
    diff --git a/app/views/challenge/prompt_meme/_challenge_navigation_maintainer.html.erb b/app/views/challenge/prompt_meme/_challenge_navigation_maintainer.html.erb new file mode 100755 index 0000000..caa267f --- /dev/null +++ b/app/views/challenge/prompt_meme/_challenge_navigation_maintainer.html.erb @@ -0,0 +1,6 @@ +<% if @collection.challenge.user_allowed_to_see_signups?(current_user) %> +
  • <%= link_to ts("Sign-ups"), collection_signups_path(@collection) %>
  • +<% end %> +<% if @collection.user_is_owner?(current_user) %> +
  • <%= link_to ts("Challenge Settings"), edit_collection_prompt_meme_path(@collection) %>
  • +<% end %> diff --git a/app/views/challenge/prompt_meme/_challenge_navigation_user.html.erb b/app/views/challenge/prompt_meme/_challenge_navigation_user.html.erb new file mode 100755 index 0000000..23ee157 --- /dev/null +++ b/app/views/challenge/prompt_meme/_challenge_navigation_user.html.erb @@ -0,0 +1 @@ +<%= render "challenge/shared/challenge_navigation_user", :collection => (collection ||= @collection) %> \ No newline at end of file diff --git a/app/views/challenge/prompt_meme/_challenge_requests.html.erb b/app/views/challenge/prompt_meme/_challenge_requests.html.erb new file mode 100755 index 0000000..3db34bb --- /dev/null +++ b/app/views/challenge/prompt_meme/_challenge_requests.html.erb @@ -0,0 +1 @@ +<%= render "challenge/shared/challenge_requests" %> \ No newline at end of file diff --git a/app/views/challenge/prompt_meme/_challenge_sidebar.html.erb b/app/views/challenge/prompt_meme/_challenge_sidebar.html.erb new file mode 100755 index 0000000..60b2258 --- /dev/null +++ b/app/views/challenge/prompt_meme/_challenge_sidebar.html.erb @@ -0,0 +1,28 @@ +

    <%= ts("Prompt Meme") %>

    + diff --git a/app/views/challenge/prompt_meme/_challenge_signups.html.erb b/app/views/challenge/prompt_meme/_challenge_signups.html.erb new file mode 100755 index 0000000..cdbb282 --- /dev/null +++ b/app/views/challenge/prompt_meme/_challenge_signups.html.erb @@ -0,0 +1,11 @@ +

    <%= ts("Sign-ups for %{collection}", :collection => @collection.title) %>

    + +<% @challenge ||= @collection.challenge -%> + diff --git a/app/views/challenge/prompt_meme/_prompt_meme_form.html.erb b/app/views/challenge/prompt_meme/_prompt_meme_form.html.erb new file mode 100755 index 0000000..9c12780 --- /dev/null +++ b/app/views/challenge/prompt_meme/_prompt_meme_form.html.erb @@ -0,0 +1,52 @@ + +

    <%= ts("Setting Up the %{title} Prompt Meme", :title => @collection.title) -%>

    + + + +<% if @collection.challenge %> + +<% end %> + + + + +

    <%= ts("Notes") %>

    +
      +
    • <%= ts("The more options you allow here, the more complicated your sign-up form will be.") %>
    • +
    • <%= ts('If you set the "Required" value higher than the corresponding "Allowed" value, we will + automatically assume that you want the allowed value to be the same as the required value. You only need to manually + set the "Allowed" number if you want more allowed than required.') %>
    • +
    + +

    <%= ts("Prompt Meme Settings") %>

    + +<%= form_for([@collection, @challenge], :url => collection_prompt_meme_path(@collection), :html => {:class => "verbose create challenge"}) do |f| %> + <%= error_messages_for @challenge %> + <%= render "challenge/shared/challenge_form_schedule", :f => f %> + +
    + <%= ts("Prompts") %> +

    <%= ts("Prompts") %>

    +
    +
    <%= f.label :anonymous, ts("Prompts anonymous by default?") %>
    +
    <%= f.check_box :anonymous %> +

    (Participants can override)

    +
    +
    <%= f.label :requests_num_required, ts("Number of prompts per sign-up:") %>
    + <%= required_and_allowed(f, "requests", @collection.prompts.empty?, false) %> + +
    +
    + + + <%= render "prompt_restrictions/prompt_restriction_form", :challenge_form => f, :is_offer => false, :show_tag_options => true, :type => "prompt_meme" -%> + + <%= render "challenge/shared/challenge_form_instructions", :f => f %> + + <%= submit_fieldset f %> + +<% end %> + + diff --git a/app/views/challenge/prompt_meme/confirm_delete.html.erb b/app/views/challenge/prompt_meme/confirm_delete.html.erb new file mode 100755 index 0000000..bdfeeb3 --- /dev/null +++ b/app/views/challenge/prompt_meme/confirm_delete.html.erb @@ -0,0 +1,6 @@ + +

    <%= ts("Delete Prompt Meme") %>

    + + +<%= render "challenge/shared/challenge_form_confirm_delete" %> + diff --git a/app/views/challenge/prompt_meme/edit.html.erb b/app/views/challenge/prompt_meme/edit.html.erb new file mode 100755 index 0000000..abfcba8 --- /dev/null +++ b/app/views/challenge/prompt_meme/edit.html.erb @@ -0,0 +1 @@ +<%= render :partial => "prompt_meme_form" %> diff --git a/app/views/challenge/prompt_meme/manage.html.erb b/app/views/challenge/prompt_meme/manage.html.erb new file mode 100755 index 0000000..e69de29 diff --git a/app/views/challenge/prompt_meme/new.html.erb b/app/views/challenge/prompt_meme/new.html.erb new file mode 100755 index 0000000..abfcba8 --- /dev/null +++ b/app/views/challenge/prompt_meme/new.html.erb @@ -0,0 +1 @@ +<%= render :partial => "prompt_meme_form" %> diff --git a/app/views/challenge/prompt_meme/show.html.erb b/app/views/challenge/prompt_meme/show.html.erb new file mode 100755 index 0000000..e69de29 diff --git a/app/views/challenge/shared/_challenge_form_confirm_delete.html.erb b/app/views/challenge/shared/_challenge_form_confirm_delete.html.erb new file mode 100755 index 0000000..96e8ca4 --- /dev/null +++ b/app/views/challenge/shared/_challenge_form_confirm_delete.html.erb @@ -0,0 +1,14 @@ +<%= form_for(@collection, :url => + if @collection.prompt_meme? + collection_prompt_meme_path(@collection) + else + collection_gift_exchange_path(@collection) + end, + :html => { :method => :delete }) do |f| %> +

    + <%= ts("Are you sure you want to delete the challenge from the collection %{title}? All sign-ups, assignments, and settings will be lost. (Works and bookmarks will remain in the collection.)", title: @collection.title).html_safe %> +

    +

    + <%= f.submit ts("Yes, Delete Challenge") %> +

    +<% end %> diff --git a/app/views/challenge/shared/_challenge_form_delete.html.erb b/app/views/challenge/shared/_challenge_form_delete.html.erb new file mode 100755 index 0000000..2f2b697 --- /dev/null +++ b/app/views/challenge/shared/_challenge_form_delete.html.erb @@ -0,0 +1,8 @@ +<%= link_to ts("Delete Challenge"), + if @collection.prompt_meme? + confirm_delete_collection_prompt_meme_path(@collection) + else + confirm_delete_collection_gift_exchange_path(@collection) + end, + data: { confirm: ts("Are you sure you want to delete the challenge from this collection? All sign-ups, assignments, and settings will be lost. (Works and bookmarks will remain in the collection.)") } +%> diff --git a/app/views/challenge/shared/_challenge_form_instructions.html.erb b/app/views/challenge/shared/_challenge_form_instructions.html.erb new file mode 100755 index 0000000..57afc8e --- /dev/null +++ b/app/views/challenge/shared/_challenge_form_instructions.html.erb @@ -0,0 +1,44 @@ +
    + <%= ts("Sign-up Instructions") %> +

    <%= ts("Sign-up Instructions") %>

    +

    + <%= ts("Explain to your members how you want them to sign up.") %> <%= allowed_html_instructions %> +

    +
    +
    <%= f.label :signup_instructions_general, ts("General Sign-up Instructions:") %>
    +
    + <%= f.text_area :signup_instructions_general, :id => field_id(f, "signup_instructions_general").to_sym, :rows => 6, :cols => 60, :class => "observe_textlength" %> + <%= live_validation_for_field(field_id(f, "signup_instructions_general").to_sym, :presence => false, :maximum_length => ArchiveConfig.INFO_MAX) -%> + <%= generate_countdown_html(field_id(f, "signup_instructions_general").to_sym, ArchiveConfig.INFO_MAX) -%> +
    + + <% f.object.class::PROMPT_TYPES.each do |prompt_type| %> +
    <%= f.label "signup_instructions_#{prompt_type}".to_sym, ts("#{prompt_type.singularize.capitalize} Instructions: ") %>
    +
    + <%= f.text_area "signup_instructions_#{prompt_type}".to_sym, :id => field_id(f, "signup_instructions_#{prompt_type}").to_sym, :rows => 6, :cols => 60, :class => "observe_textlength" %> + <%= live_validation_for_field(field_id(f, "signup_instructions_#{prompt_type}").to_sym, :presence => false, :maximum_length => ArchiveConfig.INFO_MAX) -%> + <%= generate_countdown_html(field_id(f, "signup_instructions_#{prompt_type}").to_sym, ArchiveConfig.INFO_MAX) -%> +
    + <% end %> +
    + +

    <%= ts("Change the Labels") %>

    +

    <%= ts("You can change these form fields to something more useful for your own challenge.") %>

    +
    + <% f.object.class::PROMPT_TYPES.each do |prompt_types| %> + <% prompt_type = prompt_types.singularize %> +
    <%= ts("In #{prompt_types.capitalize} change:") %>
    +
    +
    +
    +
    <%= f.label "#{prompt_type}_url_label".to_sym, ts("\"Prompt URL\" to:") %>
    +
    <%= f.text_field "#{prompt_type}_url_label".to_sym %>
    + +
    <%= f.label "#{prompt_type}_description_label".to_sym, ts("\"Description\" to:") %>
    +
    <%= f.text_field "#{prompt_type}_description_label".to_sym %>
    +
    +
    +
    + <% end %> +
    +
    \ No newline at end of file diff --git a/app/views/challenge/shared/_challenge_form_schedule.html.erb b/app/views/challenge/shared/_challenge_form_schedule.html.erb new file mode 100755 index 0000000..3b20046 --- /dev/null +++ b/app/views/challenge/shared/_challenge_form_schedule.html.erb @@ -0,0 +1,50 @@ +
    + <%= ts("Schedule") %> +

    <%= ts("Schedule") %>

    +
      +
    • + <%= ts("Collection maintainers can sign up while sign-up is closed. Nobody else will + see the sign-up links until you mark your collection open. In this way you can go through the steps and make sure your sign-up form looks just as you want before you launch.") %> +
    • +
    • <%= ts("Dates don't do anything right now; you need to manually open and close sign-up.") %>
    • +
    +
    +
    <%= f.label :signup_open, ts("Sign-up open?") %>
    +
    <%= f.check_box :signup_open %>
    + +
    <%= f.label :time_zone, ts("Time zone:") %>
    +
    <%= f.time_zone_select :time_zone, nil, :default => Time.zone.name %>
    + +
    <%= f.label :signups_open_at_string, ts("Sign-up opens:")%>
    +
    <%= f.text_field :signups_open_at_string, :class => 'timepicker' %>
    + +
    <%= f.label :signups_close_at_string, ts("Sign-up closes:")%>
    +
    <%= f.text_field :signups_close_at_string, :class => 'timepicker' %>
    + +
    <%= f.label :assignments_due_at_string, ts("Assignments due:")%>
    +
    <%= f.text_field :assignments_due_at_string, :class => 'timepicker' %>
    + + <% if @collection.unrevealed? %> +
    <%= f.label :works_reveal_at_string, ts("Works revealed:")%>
    +
    <%= f.text_field :works_reveal_at_string, :class => 'timepicker' %>
    + <% end %> + + <% if @collection.anonymous? %> +
    <%= f.label :authors_reveal_at_string, ts("Creators revealed:")%>
    +
    <%= f.text_field :authors_reveal_at_string , :class => 'timepicker' %>
    + <% end %> +
    +
    + +<%= content_for :footer_js do %> + + <%= javascript_tag do %> + $j('.timepicker').datetimepicker({ + ampm: true, + dateFormat: 'yy-mm-dd', + timeFormat: 'hh:mmTT', + hourGrid: 5, + minuteGrid: 10 + }); + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/challenge/shared/_challenge_meta.html.erb b/app/views/challenge/shared/_challenge_meta.html.erb new file mode 100755 index 0000000..6955d19 --- /dev/null +++ b/app/views/challenge/shared/_challenge_meta.html.erb @@ -0,0 +1,74 @@ + +<% challenge = @collection.challenge %> +<% zone = (challenge.time_zone || Time.zone.name) %> +<% if challenge.signup_open %> +
    <%= ts("Sign-up:")%>
    +
    <%= link_to ts("Open"), new_collection_signup_path(@collection) %>
    + +
    <%= ts("Sign-up Closes:")%>
    +
    <%= time_in_zone(challenge.signups_close_at, zone) %>
    + +<% elsif Time.now < (challenge.signups_open_at || 1.day.ago) %> + +
    <%= ts("Sign-up Opens:")%>
    +
    <%= time_in_zone(challenge.signups_open_at, zone) %>
    + +
    <%= ts("Sign-up Closes:")%>
    +
    <%= time_in_zone(challenge.signups_close_at, zone) %>
    + +<% elsif Time.now < (challenge.signups_close_at || 1.day.ago) %> +
    <%= ts("Sign-up:")%>
    +
    <%= ts("Closed")%>
    +<% end %> + +
    <%= ts("Assignments Due:")%>
    +
    <%= time_in_zone(challenge.assignments_due_at, zone) %>
    + +<% if @collection.unrevealed? %> +
    <%= ts("Works Revealed:")%>
    +
    <%= time_in_zone(challenge.works_reveal_at, zone) %>
    +<% end %> + +<% if @collection.anonymous? %> +
    <%= ts("Creators Revealed:")%>
    +
    <%= time_in_zone(challenge.authors_reveal_at, zone) %>
    +<% end %> + +
    <%= ts("Signed up:") %>
    +
    + <%= signup_count = @collection.signups.count %> + <% if signup_count < 6 %> + <%= ts("Too few sign-ups to display names") %> + <% else %> + <% num_to_show = 20 # arbitrary number for how many names to list %> +
      + <% @collection.signups.includes(:pseud => :user).collect(&:pseud).compact.each_with_index do |pseud, index| %> + <% if index == num_to_show %> +
    + +
      + <% end %> +
    • <%= "#{pseud.byline}" + (index != (num_to_show-1) && index != (signup_count-1) ? "," : "") %>
    • + <% end %> +
    + <% if signup_count > num_to_show %> + + <%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(document).ready(function(){ + $j('#show_signups').click(function() { + $j('#more_signups').show(); + $j('#hide_signups').show(); + $j(this).hide(); + }); + $j('#hide_signups').click(function() { + $j('#more_signups').hide(); + $j('#show_signups').show(); + $j(this).hide(); + }); + }) + <% end %> + <% end %> + <% end %> + <% end %> +
    diff --git a/app/views/challenge/shared/_challenge_navigation_user.html.erb b/app/views/challenge/shared/_challenge_navigation_user.html.erb new file mode 100755 index 0000000..b282d1a --- /dev/null +++ b/app/views/challenge/shared/_challenge_navigation_user.html.erb @@ -0,0 +1,40 @@ +<% # added to the navigation controls for the collection. enclose items in list elements. @collection is defined here but @challenge may not be. %> +<% collection ||= @collection %> + +<% # Start logged-in challenge logic %> +<% if logged_in? && collection.challenge %> + + <% # Start open sign-ups logic %> + <% if collection.challenge.signup_open %> + <% # Start user's sign-up options logic %> + <% if (@challenge_signup = ChallengeSignup.in_collection(collection).by_user(current_user).first) %> +
  • <%= link_to ts("Edit Sign-up"), edit_collection_signup_path(collection, @challenge_signup) %>
  • +
  • + <%= link_to ts("Cancel Sign-up"), + collection_signup_path(collection, @challenge_signup), + data: {confirm: ts("Are you sure you want to cancel your sign-up? All sign-up information will be lost.")}, + :method => :delete %> +
  • + <% else %> +
  • <%= link_to ts("Sign Up"), new_collection_signup_path(collection) %>
  • + <% end %> + <% # End user's sign-up options logic %> + <% end %> + <% # End open sign-ups logic %> + + <% # Start membership logic %> + <% if !collection.user_is_owner?(current_user) && collection.moderated? %> +
  • + <% if (@participant ||= collection.get_participants_for_user(current_user).first) %> + <%= link_to ts("Leave"), collection_participant_path(collection, @participant), + data: {confirm: ts('Are you certain you want to leave this collection?')}, + :method => :delete %>
  • + <% else %> + <%= button_to ts("Join"), join_collection_participants_path(collection), method: :post %> + <% end %> + + <% end %> + <% # End membership logic %> + +<% end %> +<% # End logged-in challenge logic %> diff --git a/app/views/challenge/shared/_challenge_requests.html.erb b/app/views/challenge/shared/_challenge_requests.html.erb new file mode 100755 index 0000000..d79e1fe --- /dev/null +++ b/app/views/challenge/shared/_challenge_requests.html.erb @@ -0,0 +1,40 @@ + +

    <%= ts("Prompts for %{collection}", :collection => @collection.title) %>

    + + + + + + +<%= will_paginate @requests %> + + +
      + <% @requests.each do |request| %> + <% # here we render each prompt as a blurb %> + <%= render "prompts/prompt_blurb", :prompt => request %> + <% end %> +
    + + +<%= will_paginate @requests %> diff --git a/app/views/challenge/shared/_challenge_signups.html.erb b/app/views/challenge/shared/_challenge_signups.html.erb new file mode 100755 index 0000000..ef3a13d --- /dev/null +++ b/app/views/challenge/shared/_challenge_signups.html.erb @@ -0,0 +1,31 @@ +<% + # The purpose of this page is to display challenge signups for review by the moderator + # It should not be user-facing for most challenges +%> + +

    <%= ts("Sign-ups for %{collection}", :collection => @collection.title) %>

    +<% @challenge ||= @collection.challenge %> + + + + +<% @challenge_signups.each do |challenge_signup| %> + + <% # the person who signed up, linking to their full individual signup, and a way to email them %> + <%= link_to challenge_signup.pseud.name, collection_signup_path(@collection, challenge_signup) %> + <%= mailto_link challenge_signup.pseud.user, :subject => "[#{h(@collection.title)}] Message from Collection Maintainer" %> + + <% # %> + + <% # %> + + <% # %> + + + <% # %> + \ No newline at end of file diff --git a/app/views/challenge_assignments/_assignment_blurb.html.erb b/app/views/challenge_assignments/_assignment_blurb.html.erb new file mode 100755 index 0000000..e4d9772 --- /dev/null +++ b/app/views/challenge_assignments/_assignment_blurb.html.erb @@ -0,0 +1,70 @@ +<% # expects "assignment" %> +
    + <% if @collection && @collection.user_is_maintainer?(current_user) %> + <% # we're listing assignments for a mod by the assigned writer %> + <%= challenge_assignment_byline(assignment) %> <%= challenge_assignment_email(assignment) %> + <% else %> + <% # we're listing assignments for a user by the recipient %> + <%= link_to assignment.collection.title, collection_assignment_path(assignment.collection, assignment) %> + <%= ts("for") %> <%= link_to assignment.request_byline, collection_assignment_path(assignment.collection, assignment) %> + <% end %> +
    +
    + <% # link to the work %> + <% if assignment.creation %> + <%= link_to (assignment.creation.try(:title) || assignment.creation.class.name), assignment.creation, :class => "work" %> + <% end %> + + <% if @collection && @collection.user_is_maintainer?(current_user) %> + <% # for a mod: list recipient (and check in case there are some people without recipients) %> + <% if assignment.request_signup %> + <%= ts("for") %> <%= link_to assignment.request_byline, collection_assignment_path(@collection, assignment) %> + <% else %> + <%= ts("No Recipient") %> + <% end %> + <% end %> + + +
    +
    <%= ts("Status:") %>
    +
    + <% # status can be: unposted (no creation), unapproved (creation but it hasn't been approved), complete %> + <% if !assignment.posted? %> + <%= ts("Unposted") %> + <% elsif !assignment.fulfilled? %> + <%= ts("Unapproved") %> + <% else %> + <%= ts("Complete!") %> + <% end %> +
    + + <% if assignment.creation %> +
    <%= ts("Posted:") %>
    +
    <%= assignment.creation.published_at %>
    + + <% if assignment.creation.respond_to?(:word_count) %> +
    <%= ts("Words:") %>
    +
    <%= ts("%{count}", :count => assignment.creation.word_count) %>
    + <% end %> + <% end %> +
    + + <% unless assignment.fulfilled? %> + + <% end %> + +
    diff --git a/app/views/challenge_assignments/_maintainer_index.html.erb b/app/views/challenge_assignments/_maintainer_index.html.erb new file mode 100755 index 0000000..cf05d20 --- /dev/null +++ b/app/views/challenge_assignments/_maintainer_index.html.erb @@ -0,0 +1,82 @@ + +

    + <%= ts("Assignments for %{collection_title}", collection_title: @collection.title) %> + <%= link_to_help "challenge-assignments" %> +

    + + + + + + +<% if @assignments.count < 1 %> + +

    <%= ts("No assignments to review!") %>

    + +<% else %> + + <%= will_paginate @assignments %> + + + <% if params[:fulfilled] %> + <%= render "maintainer_index_fulfilled" %> + <% else %> + <%= form_tag update_multiple_collection_assignments_path(@collection), method: :put do %> +
    + + <% if !(params[:pinch_hit] || params[:unfulfilled] || params[:fulfilled]) %> + <%= render "maintainer_index_defaulted" %> + <% elsif params[:pinch_hit] %> + <%= ts("Pinch Hit Assignments") %> +

    <%=ts("Pinch Hit Assignments") %>

    + <%= render "maintainer_index_unfulfilled" %> + <% elsif params[:unfulfilled] %> + <%= ts("Open Assignments") %> +

    <%=ts("Open Assignments") %>

    + <%= render "maintainer_index_unfulfilled" %> + <% end %> + +
    + <%= submit_fieldset %> + <% end %> + <% end %> + + + <%= will_paginate @assignments %> +<% end %> + diff --git a/app/views/challenge_assignments/_maintainer_index_defaulted.html.erb b/app/views/challenge_assignments/_maintainer_index_defaulted.html.erb new file mode 100755 index 0000000..4a1a86d --- /dev/null +++ b/app/views/challenge_assignments/_maintainer_index_defaulted.html.erb @@ -0,0 +1,22 @@ +<% # list assignments which were defaulted-on and which need or have a pinch hitter assigned %> +<%= ts("Defaulted Assignments") %> +

    <%=ts("Defaulted Assignments") %>

    +
    + <% @assignments.each do |assignment| %> +
    + + <%= link_to assignment.request_byline, collection_signup_path(@collection, assignment.request_signup) %> + <% assignments = ChallengeAssignment.in_collection(@collection).by_offering_user(assignment.request_signup.pseud.user) %> + <% if (defaulted = assignments.defaulted) && assignments && defaulted.size == assignments.size %> + <%= ts("(Also defaulted)") %> + <% end %> +
    +
    + <%= label_tag "undefault_#{assignment.id}", :class => 'action' do %> + <%= ts("Undefault") %> <%= assignment.offer_byline %> <%= check_box_tag "undefault_#{assignment.id}" %> + <% end %> + +
    + + <% end %> +
    diff --git a/app/views/challenge_assignments/_maintainer_index_fulfilled.html.erb b/app/views/challenge_assignments/_maintainer_index_fulfilled.html.erb new file mode 100755 index 0000000..44a1768 --- /dev/null +++ b/app/views/challenge_assignments/_maintainer_index_fulfilled.html.erb @@ -0,0 +1,6 @@ +<% # this just shows completed and approved assignments %> +
    + <% @assignments.each do |assignment| %> + <%= render "assignment_blurb", :assignment => assignment %> + <% end %> +
    diff --git a/app/views/challenge_assignments/_maintainer_index_unfulfilled.html.erb b/app/views/challenge_assignments/_maintainer_index_unfulfilled.html.erb new file mode 100755 index 0000000..41ec991 --- /dev/null +++ b/app/views/challenge_assignments/_maintainer_index_unfulfilled.html.erb @@ -0,0 +1,47 @@ +<% # list assignments which have not yet been fulfilled %> +
    + <% @assignments.each do |assignment| %> +
    + + <%= challenge_assignment_byline(assignment) %> <%= challenge_assignment_email(assignment) %> + + <%= ts("for") %> + <% if assignment.request_signup.nil? %> + <%= ts("No Recipient!")%> + <% else %> + <%= link_to assignment.request_byline, collection_signup_path(@collection, assignment.request_signup) %> + <% end %> + +
    +
    + <% if @collection.moderated? %> + <% # we might have works posted that haven't yet been approved %> + <% if assignment.posted? %> + <%= link_to ts("Gift posted on %{published_at}", :published_at => assignment.creation.published_at), assignment.creation %> + <% if assignment.creation.respond_to?(:word_count) %> + <%= ts("(%{count} words)", :count => assignment.creation.word_count) %> + <% end %> + <% else %> + <%= ts("Not yet posted") %> + <% end %> + <% end %> + +
      + <% if assignment.posted? %> +
    • + <%= label_tag "approve_#{assignment.id}" do %> + <%= ts("Approve") %> + <%= check_box_tag "approve_#{assignment.id}" %> + <% end %> +
    • + <% end %> +
    • + <%= label_tag "default_#{assignment.id}" do %> + <%= ts("Default") %> + <%= check_box_tag "default_#{assignment.id}" %> + <% end %> +
    • +
    +
    + <% end %> +
    diff --git a/app/views/challenge_assignments/_user_index.html.erb b/app/views/challenge_assignments/_user_index.html.erb new file mode 100755 index 0000000..9454149 --- /dev/null +++ b/app/views/challenge_assignments/_user_index.html.erb @@ -0,0 +1,20 @@ + +

    <%= ts("My Assignments") %> <%= @collection ? ts("in %{collection_link}", :collection_link => link_to(@collection.title, @collection)).html_safe : "" %>

    + + + + + + +<% unless @collection %> +

    <%= ts('Looking for prompts you claimed in a prompt meme? Try') %> <%= link_to ts("My Claims"), user_claims_path(@user) %>

    +<% end %> + +
    + + <% @challenge_assignments.each do |assignment| %> + <%= render "assignment_blurb", :assignment => assignment %> + <% end %> + +
    + diff --git a/app/views/challenge_assignments/confirm_purge.html.erb b/app/views/challenge_assignments/confirm_purge.html.erb new file mode 100755 index 0000000..9aec476 --- /dev/null +++ b/app/views/challenge_assignments/confirm_purge.html.erb @@ -0,0 +1,19 @@ + +

    + <%= ts("Purge Assignments for %{collection_title}", + collection_title: @collection.title) %> +

    + + +<%= form_tag purge_collection_assignments_path(@collection), class: "simple destroy" do %> +

    + <%= ts("Are you sure you want to purge all assignments for + %{collection_title}? This cannot be undone. Please only do + this if you absolutely must!", + collection_title: @collection.title).html_safe %> +

    +

    + <%= submit_tag ts("Yes, Purge Assignments") %> +

    +<% end %> + diff --git a/app/views/challenge_assignments/index.html.erb b/app/views/challenge_assignments/index.html.erb new file mode 100755 index 0000000..8d25664 --- /dev/null +++ b/app/views/challenge_assignments/index.html.erb @@ -0,0 +1,5 @@ +<% if @user %> + <%= render "user_index" %> +<% elsif @challenge && @challenge.user_allowed_to_see_assignments?(current_user) %> + <%= render "maintainer_index" %> +<% end %> \ No newline at end of file diff --git a/app/views/challenge_assignments/show.html.erb b/app/views/challenge_assignments/show.html.erb new file mode 100755 index 0000000..87f7b53 --- /dev/null +++ b/app/views/challenge_assignments/show.html.erb @@ -0,0 +1,46 @@ +<% # accessed through My Assignment on challenge dashboard %> + +

    <%= ts("Assignment for") %> <%= @challenge_assignment.offer_byline %> <% if @challenge_assignment.collection.challenge.user_allowed_to_see_assignments?(current_user) %><%= challenge_assignment_email(@challenge_assignment) %><% end %>

    + + + +<% if !@challenge_assignment.fulfilled? && @challenge_assignment.try(:offering_pseud).try(:user) == current_user %> + +<% end %> + + + + +<% if @challenge_assignment.request_signup %> + <%= render "challenge_signups/show_requests", challenge_signup: @challenge_assignment.request_signup %> +<% else %> +

    <%= ts("No request!") %>

    +

    <%= ts("Contact challenge moderators for help.") %>

    +<% end %> + +<% if @challenge_assignment.offer_signup %> + <%= render "challenge_signups/show_offers", :challenge_signup => @challenge_assignment.offer_signup %> +<% elsif @challenge_assignment.pinch_hitter %> +

    <%= ts("Pinch Hitter") %>

    +<% else %> +

    <%= ts("No assigned giver!") %>

    +

    <%= ts("Contact challenge moderators for help.") %>

    +<% end %> + diff --git a/app/views/challenge_claims/_maintainer_index.html.erb b/app/views/challenge_claims/_maintainer_index.html.erb new file mode 100755 index 0000000..21c4824 --- /dev/null +++ b/app/views/challenge_claims/_maintainer_index.html.erb @@ -0,0 +1,36 @@ + +

    <%= ts("Unposted Claims for") %> <%= @collection.title %>

    + + + + + + +<% # we just briefly list all the unposted claims so a mod can clean them up if there are a ton of old ones %> + +<% if @claims.empty? %> + +

    <%= ts("No claims to review!") %>

    + +<% else %> + + <%= will_paginate @claims %> + + + <% # this used to be a listbox, but if we ever decide to display posted claims as well we should model it after challenge_assignments/_maintainer_index instead %> +
      + <% @claims.each do |claim| %> + <%= render "challenge_claims/unposted_claim_blurb", :claim => claim %> + <% end %> +
    + + <%= will_paginate @claims %> + +<% end %> diff --git a/app/views/challenge_claims/_unposted_claim_blurb.html.erb b/app/views/challenge_claims/_unposted_claim_blurb.html.erb new file mode 100755 index 0000000..0d8ea6c --- /dev/null +++ b/app/views/challenge_claims/_unposted_claim_blurb.html.erb @@ -0,0 +1,59 @@ +<% # expects "claim" %> + +<% prompt = claim.request_prompt %> +<% collection = claim.collection %> +<% challenge = claim.collection.challenge %> +
  • +
    +

    + <%= prompt.title || ts("Request") %> +

    + + +
    + <%= ts("by") %> + + <%= ts("claimed by") %> + +
    + + +

    + <%= ts("Claimed") %> <%= set_format_for_date(claim.created_at) %> + <% if @challenge.try(:assignments_due_at).present? %> + + <%= ts("Due") %> <%= time_in_zone(@challenge.assignments_due_at, (@challenge.time_zone || Time.zone.name)) %> + <% end %> +

    + +
    + <%= collection_icon_display(claim.collection) %> +
    +
    + + + <%= prompt_tags(prompt) %> + + + <% unless prompt.description.blank? %> +
    <%= ts("Summary") %>
    +
    + <%=raw sanitize_field(prompt, :description) %> +
    + <% end %> + + + <% if @collection.user_is_maintainer?(current_user) %> + + <% end %> +
  • diff --git a/app/views/challenge_claims/_user_index.html.erb b/app/views/challenge_claims/_user_index.html.erb new file mode 100755 index 0000000..a7f628f --- /dev/null +++ b/app/views/challenge_claims/_user_index.html.erb @@ -0,0 +1,34 @@ + +

    <%= ts("My Claims") %> <% if @collection %><%= ts("in") %> <%= link_to(@collection.title, @collection) %><% end %>

    + + + +<% unless params[:for_user] %> + +<% end %> + + +<%= will_paginate @claims %> + + +<% unless @collection %> +

    <%= ts('Looking for assignments you were given for a gift exchange? Try') %> <%= link_to ts("My Assignments"), user_assignments_path(@user) %>

    +<% end %> + +
      + + <% @claims.each do |claim| %> + <%= render "prompts/prompt_blurb", :prompt => claim.request_prompt, :claim => claim, :suppress_claims => !params[:posted] %> + <% end %> + +
    + + +<%= will_paginate @claims %> \ No newline at end of file diff --git a/app/views/challenge_claims/index.html.erb b/app/views/challenge_claims/index.html.erb new file mode 100755 index 0000000..2a53685 --- /dev/null +++ b/app/views/challenge_claims/index.html.erb @@ -0,0 +1,5 @@ +<% if @user || params[:for_user] || (@challenge && !@challenge.user_allowed_to_see_claims?(current_user)) %> + <%= render "user_index" %> +<% elsif @challenge && @challenge.user_allowed_to_see_claims?(current_user) %> + <%= render "maintainer_index" %> +<% end %> diff --git a/app/views/challenge_requests/index.html.erb b/app/views/challenge_requests/index.html.erb new file mode 100755 index 0000000..403c6b5 --- /dev/null +++ b/app/views/challenge_requests/index.html.erb @@ -0,0 +1,5 @@ +<% @challenge ||= @collection.challenge %> + + <% # render differently based on the challenge %> + <%= render "challenge/#{challenge_class_name(@collection)}/challenge_requests" %> + diff --git a/app/views/challenge_signups/_show_offers.html.erb b/app/views/challenge_signups/_show_offers.html.erb new file mode 100755 index 0000000..0f8e965 --- /dev/null +++ b/app/views/challenge_signups/_show_offers.html.erb @@ -0,0 +1,24 @@ +<% unless challenge_signup.offers.empty? %> + + +
    +

    + <%= ts("Offers") %> + + <% if @challenge_assignment %> + <%= ts("by %{offerer}", :offerer => @challenge_assignment.offer_byline) %> + <% user = @challenge_assignment.try(:offer_signup).try(:pseud).try(:user) %> + <% if user && @challenge.user_allowed_to_see_assignments?(current_user) %> + <%= mailto_link user, :subject => "[#{h(@collection.title)}] Message from Collection Maintainer" %> + <% end %> + <% end %> +

    + +
      + <% challenge_signup.offers.each_with_index do |offer, index| %> + <%= render "prompts/prompt_blurb", :prompt => offer, :index => index %> + <% end %> +
    +
    + +<% end %> diff --git a/app/views/challenge_signups/_show_requests.html.erb b/app/views/challenge_signups/_show_requests.html.erb new file mode 100755 index 0000000..f7dcfb2 --- /dev/null +++ b/app/views/challenge_signups/_show_requests.html.erb @@ -0,0 +1,24 @@ +<% unless challenge_signup.requests.empty? %> + + +
    +

    + <%= ts("Requests") %> + + <% if @challenge_assignment %> + <%= ts("by %{requester}", :requester => @challenge_assignment.request_byline) %> + <% user = @challenge_assignment.try(:request_signup).try(:pseud).try(:user) %> + <% if user && @challenge.user_allowed_to_see_assignments?(current_user) %> + <%= mailto_link user, :subject => "[#{h(@collection.title)}] Message from Collection Maintainer" %> + <% end %> + <% end %> +

    + +
      + <% challenge_signup.requests.each_with_index do |request, index| %> + <%= render "prompts/prompt_blurb", :prompt => request, :index => index %> + <% end %> +
    +
    + +<% end %> diff --git a/app/views/challenge_signups/_signup_controls.html.erb b/app/views/challenge_signups/_signup_controls.html.erb new file mode 100755 index 0000000..4f7f282 --- /dev/null +++ b/app/views/challenge_signups/_signup_controls.html.erb @@ -0,0 +1,48 @@ +<% # requires 'challenge_signup' local %> +<% # to make the code more readable: %> +<% collection = challenge_signup.collection %> +<% challenge = collection.challenge %> +<% user = challenge_signup.pseud.user %> + +<% if challenge.signup_open || (!challenge.signup_open && collection.user_is_maintainer?(current_user)) || collection.challenge_type == "PromptMeme" %> + +<% end %> diff --git a/app/views/challenge_signups/_signup_form.html.erb b/app/views/challenge_signups/_signup_form.html.erb new file mode 100755 index 0000000..616c55a --- /dev/null +++ b/app/views/challenge_signups/_signup_form.html.erb @@ -0,0 +1,83 @@ +<% types = @challenge.class::PROMPT_TYPES.select {|t| @challenge.allowed(t) > @challenge.required(t)} %> +<% unless types.empty? %> + +<% end %> + +<%= form_for([@collection, @challenge_signup], :url => (@challenge_signup.new_record? ? collection_signups_path(@collection) : collection_signup_path(@collection))) do |signup_form| %> + <% if !@current_user&.preference&.allow_gifts? %> +

    + <%= t(".notice.preference.#{@collection.challenge_type.underscore}", + preferences_link: link_to( + t(".notice.preference.preferences_link_text"), + user_preferences_path(@current_user)), + refuse_link: link_to( + t(".notice.preference.refuse_link_text"), + archive_faq_path("your-account", anchor: "refusegift")) + ).html_safe %> +

    + <% end %> + <% if @collection.challenge_type == "GiftExchange" %> +

    <%= ts("Challenge maintainers will have access to the email address associated with your AO3 account for the purpose of communicating with you about the challenge.") %>

    + <% end %> +

    <%= ts("* Required information") %>

    + <% unless @challenge_signup.errors.empty? %> +
    +

    <%= ts("There were some problems with this submission. Please correct the mistakes below.") %>

    +
    + <% end %> + + <%= error_messages_for @challenge_signup %> + + <%= render "signup_form_general_information", :form => signup_form %> + + <% # requests and offers section %> + <% @challenge.class::PROMPT_TYPES.each do |prompt_type| %> +
    + <%= prompt_type.capitalize %> +

    + <%= prompt_type.capitalize %> (<%= @challenge.allowed_range_string(prompt_type) %>) +

    + <% unless sanitize_field(@challenge, "signup_instructions_#{prompt_type}".to_sym).blank? %> +
    + <%=raw sanitize_field(@challenge, "signup_instructions_#{prompt_type}".to_sym) %> +
    + <% end %> + + <% @challenge_signup.send("#{prompt_type}").each_with_index do |prompt, index| %> + <%= error_messages_for(prompt).html_safe unless !prompt.errors.present? %> + <%= signup_form.fields_for prompt_type.to_sym, prompt do |prompt_form| %> + <%= render "prompts/prompt_form", :form => prompt_form, :index => index, :required => (index < @challenge.required(prompt_type)) %> + <% end %> + <% end %> + + <% if @challenge.allowed(prompt_type) > @challenge.required(prompt_type) %> +

    + <% linktext = ts("Add another %{type}? (Up to %{allowed} allowed.)", :type => prompt_type.singularize, :allowed => @challenge.allowed(prompt_type)) %> + <%= link_to_add_section(linktext, signup_form, prompt_type.to_sym, "prompts/prompt_form", :required => false) %> +

    + <% end %> + +
    + <% end # requests & offers section %> + + <%= submit_fieldset signup_form %> + +<% end %> diff --git a/app/views/challenge_signups/_signup_form_general_information.html.erb b/app/views/challenge_signups/_signup_form_general_information.html.erb new file mode 100755 index 0000000..42897cb --- /dev/null +++ b/app/views/challenge_signups/_signup_form_general_information.html.erb @@ -0,0 +1,21 @@ +

    <%= ts("Sign Up as") %> + <% if (form.object.new_record? || @challenge.allow_name_change?) && current_user.pseuds.size > 1 %> + <%= form.select :pseud_id, options_from_collection_for_select(current_user.pseuds, :id, :name, current_user.default_pseud.id) %> + <% else %> + <% pseud = form.object.new_record? ? current_user.default_pseud : form.object.pseud %> + + <%= form.hidden_field :pseud_id, :value => pseud.id %> + <% end %> +

    + +<% if @challenge.signup_instructions_general.present? %> +
    +

    <%= ts("General Sign Up Instructions") %>

    + <% if @challenge.signup_instructions_general %> +
    + <%=raw sanitize_field(@challenge, :signup_instructions_general) %> +
    + <% end %> +
    +<% end %> + diff --git a/app/views/challenge_signups/confirm_delete.html.erb b/app/views/challenge_signups/confirm_delete.html.erb new file mode 100755 index 0000000..37b5b60 --- /dev/null +++ b/app/views/challenge_signups/confirm_delete.html.erb @@ -0,0 +1,17 @@ + +

    <%= ts("Delete Sign-up") %>

    + + +<%= form_for(@challenge_signup, :url => collection_signup_path(@collection, @challenge_signup), :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    <%= ts("Are you sure you want to delete the sign-up for %{person}?", :person => @challenge_signup.pseud.byline).html_safe %> + <% if @collection.potential_matches.count == 0 %> + <%= ts("All prompts in this sign-up will be lost.") %> + <% else %> + <%= ts("Potential matches will need to be regenerated afterwards.") %> + <% end %> +

    +

    + <%= f.submit ts("Yes, Delete Sign-up") %> +

    +<% end %> + diff --git a/app/views/challenge_signups/edit.html.erb b/app/views/challenge_signups/edit.html.erb new file mode 100755 index 0000000..accd35e --- /dev/null +++ b/app/views/challenge_signups/edit.html.erb @@ -0,0 +1,10 @@ + +

    <%= ts("Edit Sign-up for %{title}", :title => @collection.title) %>

    + + + + + + +<%= render "signup_form" %> + diff --git a/app/views/challenge_signups/index.html.erb b/app/views/challenge_signups/index.html.erb new file mode 100755 index 0000000..24326e5 --- /dev/null +++ b/app/views/challenge_signups/index.html.erb @@ -0,0 +1,30 @@ +<% if @collection && @collection.challenge %> + <% # signups for a given challenge %> + + <% # render differently based on the challenge %> + <%= render "challenge/#{challenge_class_name(@collection)}/challenge_signups" %> + +<% elsif @user %> + <% # view in user dashboard %> + + +

    <%= ts("Challenge Sign-ups for %{user}", :user => @user.login) %>

    + + + + + + + + +<% end %> diff --git a/app/views/challenge_signups/index.xls.erb b/app/views/challenge_signups/index.xls.erb new file mode 100755 index 0000000..baadc3e --- /dev/null +++ b/app/views/challenge_signups/index.xls.erb @@ -0,0 +1,7 @@ + +<% if @collection && @collection.challenge %> + <% @template_format = 'html' %> + <%= render :partial => "challenge/#{challenge_class_name(@collection)}/challenge_signups" %> +<% end %> \ No newline at end of file diff --git a/app/views/challenge_signups/new.html.erb b/app/views/challenge_signups/new.html.erb new file mode 100755 index 0000000..24ccf03 --- /dev/null +++ b/app/views/challenge_signups/new.html.erb @@ -0,0 +1,10 @@ + +

    <%= ts("Sign Up for %{title}", :title => @collection.title) %>

    + + + + + + +<%= render "signup_form" %> + diff --git a/app/views/challenge_signups/show.html.erb b/app/views/challenge_signups/show.html.erb new file mode 100755 index 0000000..c2bc778 --- /dev/null +++ b/app/views/challenge_signups/show.html.erb @@ -0,0 +1,13 @@ +<% # Only gift exchanges link to this page, but you can manually enter collections/name/signups/# to view for prompt memes %> + +

    <%= ts("Sign-up for %{person}", :person => @challenge_signup.pseud.byline) %>

    + + + +<%= render "signup_controls", :challenge_signup => @challenge_signup, :subnav => true %> + + + +<%= render "show_requests", :challenge_signup => @challenge_signup %> +<%= render "show_offers", :challenge_signup => @challenge_signup %> + diff --git a/app/views/challenge_signups/summary.html.erb b/app/views/challenge_signups/summary.html.erb new file mode 100755 index 0000000..1c7c313 --- /dev/null +++ b/app/views/challenge_signups/summary.html.erb @@ -0,0 +1,13 @@ +<% if @generated_live %> + <% # render differently based on the challenge %> + <%= render :partial => "challenge/#{challenge_class_name(@collection)}/challenge_signups_summary", + :locals => {:challenge_collection => @collection, :tag_type => @tag_type, :summary_tags => @summary_tags, :generated_live => @generated_live} %> +<% elsif (cached_summary = @summary.cached_contents).present? %> + <%=raw cached_summary %> +<% else %> +

    <%= ts("Sign-up Summary for %{collection}", :collection => @collection.title) %>

    + +

    + <%= ts('The summary is being generated. Please try again in a few minutes.') %> +

    +<% end %> diff --git a/app/views/chapters/_chapter.html.erb b/app/views/chapters/_chapter.html.erb new file mode 100755 index 0000000..f4f31e3 --- /dev/null +++ b/app/views/chapters/_chapter.html.erb @@ -0,0 +1,85 @@ + +<% chapter_id = "chapter-#{chapter.position.to_s}" %> +
    + <% unless chapter.posted? || @preview_mode %> +

    + <%= ts("This chapter is a draft and hasn't been posted yet!") %> +

    + <% end %> + <% if chapter.user_has_creator_invite?(current_user) %> +

    + <%= ts("You've been invited to become a co-creator of this chapter. To accept or reject the request, visit your %{creator_requests_page}.", + creator_requests_page: link_to(ts("Co-Creator Requests page"), user_creatorships_path(current_user))).html_safe %> +

    + <% end %> + + <% if logged_in? && is_author_of?(@work) && !@preview_mode%> + <%= render "chapters/chapter_management", chapter: chapter, work: @work %> + <% end %> + +<%# Both Entire Work and Chapter by Chapter mode write to and read from this cache. Only content needed for both modes should be included here. %> +<% cache_if(!@preview_mode, "#{@work.cache_key}/#{chapter.cache_key}-show-v7", skip_digest: true) do %> + +
    +

    + <%= link_to chapter.chapter_header, [chapter.work, chapter] %><% unless chapter.title.blank? %>: <%= chapter.title.html_safe %><% end %> +

    + + + <% if (!chapter.pseuds.blank? && (chapter.pseuds.sort != @work.pseuds.sort) && (!@work.anonymous?)) || @preview_mode %> + + <% end %> + + <% if (@work.number_of_posted_chapters > 1) || @work.chaptered? %> + <% unless chapter.summary.blank? %> +
    +

    <%= ts('Summary:') %>

    +
    + <%=raw sanitize_field(chapter, :summary) %> +
    +
    + <% end %> + + <% unless chapter.notes.blank? && chapter.endnotes.blank? %> +
    +

    <%=h ts('Notes:') %>

    + <% if chapter.notes.blank? %> +

    + (<%= ts("See the end of the chapter for ") %> <%= link_to(h(ts("notes")), "#chapter_#{chapter.position.to_s}_endnotes") %>.) +

    + <% else %> +
    <%=raw sanitize_field(chapter, :notes) %>
    + <% unless chapter.endnotes.blank? %> +

    + (<%= ts("See the end of the chapter for ") %> <%= link_to(h(ts("more notes")), "#chapter_#{chapter.position.to_s}_endnotes") %>.) +

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

    <%= ts("Chapter Text") %>

    + <%=raw sanitize_field(chapter, :content) %> +
    + + + <% unless chapter.endnotes.blank? %> +
    +
    +

    <%=h ts('Notes:') %>

    +
    + <%=raw sanitize_field(chapter, :endnotes) %> +
    +
    +
    + <% end %> + +
    + +<% end %> diff --git a/app/views/chapters/_chapter_form.html.erb b/app/views/chapters/_chapter_form.html.erb new file mode 100755 index 0000000..06167ad --- /dev/null +++ b/app/views/chapters/_chapter_form.html.erb @@ -0,0 +1,101 @@ +
    + <%= form_for([@work, chapter]) do |f| %> +

    <%= ts("* Required information") %>

    +
    + <%= ts("Name, Order and Date") %> +

    <%= ts("Name, Order and Date") %>

    +
    +
    <%= f.label :title, ts("Chapter Title") %> <%= link_to_help "chapter-title" %>
    +
    + <%= f.text_field :title, class: "observe_textlength" %> + <%= live_validation_for_field("chapter_title", presence: false, maximum_length: ArchiveConfig.TITLE_MAX) %> + <%= generate_countdown_html("chapter_title", ArchiveConfig.TITLE_MAX) %> +
    + +
    <%= f.label :position, ts("Chapter Number") %>
    +
    +

    + <%= f.text_field :position, class: "number" %> + <%= f.label :wip_length, ts("of"), title: ts("of total chapters") %> + <%= f.text_field :wip_length, class: "number" %> +

    +
    +
    <%= f.label :published_at, ts("Chapter Publication Date") %> <%= link_to_help "backdating-help" %>
    +
    <%= f.date_select "published_at", start_year: Date.current.year, end_year: 1950, default: @work.default_date, order: [:day, :month, :year] %>
    +
    +
    + +
    + <%= ts("Chapter Preface") %> +

    <%= ts("Chapter Preface") %>

    +
    + <%= render "pseuds/byline", form: f, object: @chapter %> + +
    <%= f.label :summary, ts("Chapter Summary") %>
    +
    + <%= f.text_area :summary, rows: 4, cols: 60, class: "observe_textlength" %> + <%= live_validation_for_field("chapter_summary", presence: false, maximum_length: ArchiveConfig.SUMMARY_MAX) %> + <%= generate_countdown_html("chapter_summary", ArchiveConfig.SUMMARY_MAX) %> +
    + + <%= render "works/notes_form", f: f, type: "chapter" %> + +
    +
    + +
    + <%= ts("Chapter Text") + "*" %> +

    <%= ts("Chapter Text") %>

    + +

    + <%= allowed_html_instructions %> + +

    +
    + <%= f.text_area :content, id: "content", class: "mce-editor observe_textlength large" %> + <%= live_validation_for_field("content", + maximum_length: ArchiveConfig.CONTENT_MAX_DISPLAYED, + minimum_length: ArchiveConfig.CONTENT_MIN, + tooLongMessage: ts("We salute your ambition! But sadly each chapter of a work must be less than %{max} characters long.", max: ArchiveConfig.CONTENT_MAX_DISPLAYED.to_s), + tooShortMessage: ts("Brevity is the soul of wit, but your content does have to be at least %{min} characters long.", min: ArchiveConfig.CONTENT_MIN.to_s), + failureMessage: ts("Brevity is the soul of wit, but your content does have to be at least %{min} characters long.", min: ArchiveConfig.CONTENT_MIN.to_s)) + %> + <%= generate_countdown_html("content", ArchiveConfig.CONTENT_MAX_DISPLAYED) %> +
    +
    + +
    + <%= ts("Post Chapter") %> +

    + <%= t(".post_notice_html", + content_policy_link: link_to(t(".content_policy"), content_path), + tos_faq_link: link_to(t(".tos_faq"), tos_faq_path(anchor: "content_faq"))) %> +

    +
      + <% unless @chapter.new_record? || @chapter.posted? %> +
    • <%= submit_tag ts("Save As Draft"), name: "save_button" %>
    • + <% end %> +
    • <%= submit_tag ts("Preview"), name: "preview_button" %>
    • +
    • <%= submit_tag ts("Post"), name: "post_without_preview_button", data: { disable_with: ts("Please wait...") } %>
    • +
    • <%= submit_tag ts("Cancel"), name: "cancel_button" %>
    • +
    +
    + + <% end # form_for %> +
    + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(document).ready(function(){ + $j(".toggle_formfield").click(function() { + var targetId = $j(this).attr("id").replace("-show", ""); + toggleFormField(targetId); + }); + }) + <% end %> + + <% use_tinymce %> +<% end %> diff --git a/app/views/chapters/_chapter_management.html.erb b/app/views/chapters/_chapter_management.html.erb new file mode 100755 index 0000000..323e78c --- /dev/null +++ b/app/views/chapters/_chapter_management.html.erb @@ -0,0 +1,11 @@ +

    <%= ts("Chapter Management") %>

    + diff --git a/app/views/chapters/_hidden_fields.html.erb b/app/views/chapters/_hidden_fields.html.erb new file mode 100755 index 0000000..ff47fb4 --- /dev/null +++ b/app/views/chapters/_hidden_fields.html.erb @@ -0,0 +1,24 @@ + + + +<%= form.fields_for :author_attributes do |creator_form| %> + <% (@chapter.current_user_pseuds || []).each do |pseud| %> + <%= creator_form.hidden_field :ids, value: pseud.id, multiple: true %> + <% end %> + + <% @chapter.creatorships.each do |creatorship| %> + <% if creatorship.new_record? %> + <%= creator_form.hidden_field :coauthors, value: creatorship.pseud_id, multiple: true %> + <% end %> + <% end %> +<% end %> + +<%= form.hidden_field :title, :value => "#{@chapter.title}" %> +<%= form.hidden_field :summary, :value => "#{@chapter.summary}" %> +<%= form.hidden_field :notes, :value => "#{@chapter.notes}" %> +<%= form.hidden_field :endnotes, :value => "#{@chapter.endnotes}" %> +<%= form.hidden_field :content, :value => "#{@chapter.content}" %> + +<%= form.hidden_field :wip_length, :value => "#{@chapter.wip_length}" %> +<%= form.hidden_field :position, :value => "#{@chapter.position}" %> +<%= form.hidden_field :published_at, :value => "#{@chapter.published_at}" %>

    diff --git a/app/views/chapters/confirm_delete.html.erb b/app/views/chapters/confirm_delete.html.erb new file mode 100755 index 0000000..df49148 --- /dev/null +++ b/app/views/chapters/confirm_delete.html.erb @@ -0,0 +1,12 @@ + +

    <%= ts("Delete Chapter") %>

    + + +<%= form_for(@chapter, :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    <%= ts("Are you sure you want to delete %{chapter_number} of %{work_title}? This will delete all comments on the chapter as well and cannot be undone!", :chapter_number => @chapter.chapter_header, :work_title => @work.title).html_safe %> +

    +

    + <%= f.submit ts("Yes, Delete Chapter") %> +

    +<% end %> + diff --git a/app/views/chapters/edit.html.erb b/app/views/chapters/edit.html.erb new file mode 100755 index 0000000..7c4850c --- /dev/null +++ b/app/views/chapters/edit.html.erb @@ -0,0 +1,28 @@ + + +

    <%= ts("Edit Chapter") %>

    + +<%= error_messages_for :chapter %> + + + + + + + + +<%= render 'chapter_form', chapter: @chapter %> + diff --git a/app/views/chapters/manage.html.erb b/app/views/chapters/manage.html.erb new file mode 100755 index 0000000..aa8a4f9 --- /dev/null +++ b/app/views/chapters/manage.html.erb @@ -0,0 +1,78 @@ + +

    <%= ts('Manage Chapters') %>

    + + + + + + +
    + +

    <%= ts("Drag chapters to change their order.") %>

    +

    <%= ts("Enter new chapter numbers.") %>

    + + <%= form_tag url_for(action: 'update_positions') do %> + +

      + <% for chapter in @chapters %> +
    • + + <%= text_field_tag 'chapters[]', nil, + size: 3, + maxlength: 3, + class: "number chapter-position-field", + id: "chapters_" + chapter.position.to_s %> + <%= chapter.position %>. + <%= chapter.chapter_title.html_safe %> + <% if !chapter.posted %>(Draft)<% end %> + +
        +
      • <%= link_to ts("Edit"), [:edit, @work, chapter] %>
      • + <% if @work.chapters.count > 1 %> +
      • + <%= link_to ts("Delete"), [@work, chapter], + data: { confirm: ts("Are you sure?") }, + method: :delete %> +
      • + <% if @work.pseuds.size > 1 && chapter.pseuds.size > 1 && current_user.is_author_of?(chapter) %> +
      • + <%= link_to ts("Remove Me As Chapter Co-Creator"), + remove_user_creatorship_chapter_path(chapter), + data: { confirm: ts("Are you sure you want to remove yourself as a co-creator of this chapter?") }, + method: :patch %> +
      • + <% end %> + <% end %> +
      + +
    • + <% end %> +
    + +

    + <%= submit_tag ts("Update Positions") %> + <%= link_to ts("Back"), url_for(@work) %> +

    + + <% end %> +
    + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j("#sortable_chapter_list").sortable({ + delay: 300, + update: function(event, ui) { + $j(".chapter-position-list").each(function(index, li){ + var chapterId = $j(li).attr("id").replace("chapter_",""); + $j("#position-for-"+chapterId).html(index+1); + }); + $j.ajax({ + type: 'post', + data: $j("#sortable_chapter_list").sortable("serialize") + "&work_id=<%= @work.id %>", + dataType: 'script', + url: "<%= url_for(:action => :update_positions) %>"}) + } + }) + <% end %> +<% end %> + diff --git a/app/views/chapters/new.html.erb b/app/views/chapters/new.html.erb new file mode 100755 index 0000000..3376025 --- /dev/null +++ b/app/views/chapters/new.html.erb @@ -0,0 +1,14 @@ + +

    <%= ts('Post New Chapter') %>

    +

    <%= @work.title %>

    + +<%= error_messages_for :chapter %> + + + + + + +<%= render 'chapter_form', :chapter => @chapter %> + + diff --git a/app/views/chapters/preview.html.erb b/app/views/chapters/preview.html.erb new file mode 100755 index 0000000..5f00278 --- /dev/null +++ b/app/views/chapters/preview.html.erb @@ -0,0 +1,47 @@ + +

    <%= ts("Preview") %>

    +<%= error_messages_for :chapter %> + + +<% if @work.work_skin && !Preference.disable_work_skin?(params[:style]) %> + <% cache("#{@work.work_skin.id}-#{@work.work_skin.updated_at}-work-skin", skip_digest: true) do %> + <%= render "skins/skin_style_block", skin: @work.work_skin %> + <% end %> +<% end %> + +
    +
    + <%= render @chapter %> +
    +
    + +<%= form_for([@work, @chapter]) do |f| %> + + <%= render "hidden_fields", form: f %> + +
    + <%= ts("Post Chapter") %> +

    + <%= t(".post_notice_html", + content_policy_link: link_to(t(".content_policy"), content_path), + tos_faq_link: link_to(t(".tos_faq"), tos_faq_path(anchor: "content_faq"))) %> +

    +
      + <% if @chapter.posted? %> +
    • <%= submit_tag ts("Update"), name: "update_button" %>
    • + <% else %> +
    • + <%= submit_tag ts("Post"), + name: "post_button", + data: { disable_with: ts("Please wait...") } %> +
    • +
    • + <%= submit_tag ts("Save As Draft"), name: "save_button" %> +
    • + <% end %> +
    • <%= submit_tag ts("Edit"), name: "edit_button" %>
    • +
    • <%= submit_tag ts("Cancel"), name: "cancel_button" %>
    • +
    +
    + +<% end %> diff --git a/app/views/chapters/show.html.erb b/app/views/chapters/show.html.erb new file mode 100755 index 0000000..3bdbc74 --- /dev/null +++ b/app/views/chapters/show.html.erb @@ -0,0 +1,69 @@ + +<% if @work.unrevealed? %> + <%= render "works/work_unrevealed_notice" %> +<% end %> +<% if @work.user_has_creator_invite?(current_user) %> +

    + <%= ts("You've been invited to become a co-creator of this work. To accept or reject the request, visit your %{creator_requests_page}.", + creator_requests_page: link_to(ts("Co-Creator Requests page"), user_creatorships_path(current_user))).html_safe %> +

    +<% end %> + + + +<% if policy(@work).show_admin_options? %> + <%= render "admin/admin_options", item: @work %> +<% end %> + + +<% if !@work.unrevealed? || logged_in_as_admin? || can_access_unrevealed_work(@work, current_user) %> + +

     

    + <%= render :partial => 'works/work_header' %> + +
    + <%= render :partial => 'chapters/chapter', :locals => { :chapter => @chapter } %> +
    + + <% inspired_by = get_inspired_by(@work) %> + <% last_chapter = @work.posted? ? @work.last_posted_chapter : @work.last_chapter %> + <% if @chapter == last_chapter && (@work.endnotes.present? || @work.series.present? || inspired_by.present?) %> + +
    + <% if !@work.endnotes.blank? %> + <%= render :partial => 'works/work_endnotes' %> + <% end %> + <% unless @preview_mode || @work.series.blank? %> + <%= render :partial => 'works/work_series_links' %> + <% end %> + <% unless inspired_by.empty? %> + <%= render :partial => 'works/work_approved_children', :locals => {:inspired_by => inspired_by} %> + <% end %> +
    + + <% end %> + +
    + + + + + + <%= render :partial => 'comments/commentable', :locals => {:commentable => @chapter} %> + + + <% if @next_chapter %> + + <% end %> +<% end %> + +<%= render "hit_count/include" %> diff --git a/app/views/collectibles/_collectible_form.html.erb b/app/views/collectibles/_collectible_form.html.erb new file mode 100755 index 0000000..075850a --- /dev/null +++ b/app/views/collectibles/_collectible_form.html.erb @@ -0,0 +1,17 @@ +<% # expects 'form' and any of 'collectibles', 'collectible' or '@collectible which can be 1 or more collectibles %> + +<% collectibles = [collectible] if (!collectibles && collectible) %> +<% collectibles = [@collectible] if (!collectibles && @collectible) %> + +<% unless (collections = collectibles.collect(&:collections).flatten.uniq).empty? %> +
    <%= form.label :collections_to_remove, ts("Current Collections") %>
    +
    +

    <%= ts("Check to remove") %>

    + <%= checkbox_section(form, :collections_to_remove, collections, :name_method => "title") %> +
    +<% end %> + +
    <%= form.label :collections_to_add, ts("Add to collections") %> <%= link_to_help "add-collectible-to-collection" %>
    +
    + <%= form.text_field :collections_to_add, autocomplete_options("open_collection_names") %> +
    diff --git a/app/views/collection_items/_collection_item_controls.html.erb b/app/views/collection_items/_collection_item_controls.html.erb new file mode 100755 index 0000000..856ca98 --- /dev/null +++ b/app/views/collection_items/_collection_item_controls.html.erb @@ -0,0 +1,75 @@ +<% # expects collection_item, form %> +
      + <% if collection_item.item %> +
    • + <% # TODO: AO3-6508 Revamp this so we don't have two useless links showing when JavaScript is disabled. %> + <% id = "blurb_#{collection_item.item_type}_#{collection_item.item_id}_#{collection_item.collection.name}" %> + <%= link_to h(ts("Details")) + ' ↓'.html_safe, "#", :class => "#{id}_open" %> + <%= link_to h(ts("Close Details")) + ' ↑'.html_safe, "#", :class => "#{id}_close" %> +
    • + <% end %> + +
    • + <%= form.label(:user_approval_status, + options = {}, + html_options = { class: @collection ? "disabled" : nil }) do %> + <%= collection_item_approval_options_label( + actor: "user", + item_type: collection_item.item_type) %> + <%= form.select(:user_approval_status, + collection_item_approval_options( + actor: "user", + item_type: collection_item.item_type), + options = {}, + html_options = { disabled: @collection ? true : nil }) %> + <% end %> +
    • + +
    • + <%= form.label(:collection_approval_status, + options = {}, + html_options = { class: @user ? "disabled" : nil }) do %> + <%= collection_item_approval_options_label( + actor: "collection", + item_type: collection_item.item_type) %> + <%= form.select(:collection_approval_status, + collection_item_approval_options( + actor: "collection", + item_type: collection_item.item_type), + options = {}, + html_options = { disabled: @user ? true : nil }) %> + <% end %> +
    • + + <% if collection_item.collection.unrevealed? %> +
    • + <%= form.label(:unrevealed, + options = {}, + html_options = { class: @user ? "disabled" : nil }) do %> + <%= form.check_box :unrevealed, disabled: @user %> + <%= ts("Unrevealed") %> + <% end %> +
    • + <% end %> + + <% if collection_item.collection.anonymous? %> +
    • + <%= form.label(:anonymous, + options = {}, + html_options = { class: @user ? "disabled" : nil }) do %> + <%= form.check_box :anonymous, disabled: @user %> + <%= ts("Anonymous") %> + <% end %> +
    • + <% end %> + +
    • + <% disable_destroy = !collection_item.user_allowed_to_destroy?(@current_user) %> + <%= form.label(:remove, + options = {}, + html_options = { class: disable_destroy ? "disabled" : nil }) do %> + <%= form.check_box :remove, disabled: disable_destroy %> + <%= ts("Remove") %> + <% end %> +
    • +
    diff --git a/app/views/collection_items/_collection_item_form.html.erb b/app/views/collection_items/_collection_item_form.html.erb new file mode 100755 index 0000000..b8bd75e --- /dev/null +++ b/app/views/collection_items/_collection_item_form.html.erb @@ -0,0 +1,42 @@ +<% item ||= @item %> +<% @collection_item ||= CollectionItem.new %> +<% in_page ||= false %> +
    + <% if item.is_a?(Work) %> +

    + <% if current_user.archivist %> + <%= t(".add_work_header_html", title: item.title) %> + <% else %> + <%= t(".invite_header_html", title: item.title) %> + <% end %> +

    + <% else %> +

    <%= t(".add_bookmark_header") %>

    + <% end %> + <% + # when in the works controller, such as for a non-multi-chapter work, form_for does not set work_id + # so the create action of the collection_items controller fails to find the targetted work + # hence the klutzy workaround with setting the _id manually in the url, below + %> + <%= form_for([item, @collection_item], :url => { (item.class.name.foreign_key).to_sym => item.id, :controller => 'collection_items', :action => :create}) do |form| %> +
    +
    <%= label_tag :collection_names, ts("Collection name(s): ") %>
    +
    + <%= text_field_tag :collection_names, nil, autocomplete_options("open_collection_names", :size => 40) %> +
    +
    <%= ts("Submit") %>
    +
    + <% if item.is_a?(Work) && !current_user.archivist %> + <%= form.submit(t(".invite")) %> + <% else %> + <%= form.submit(t(".add")) %> + <% end %> + <% if in_page %> + <%= ts("Cancel") %> + <% else %> + <%= link_to ts("Back"), polymorphic_path(item) %> + <% end %> +
    +
    + <% end %> +
    diff --git a/app/views/collection_items/_item_fields.html.erb b/app/views/collection_items/_item_fields.html.erb new file mode 100755 index 0000000..2868382 --- /dev/null +++ b/app/views/collection_items/_item_fields.html.erb @@ -0,0 +1,62 @@ +
  • + <%= fields_for("collection_items[]", collection_item) do |form| %> +
    + +

    + <%= error_messages_for collection_item %> + <%= link_to collection_item_display_title(collection_item), collection_item.item %> +

    + +
    + <% if @user %> + <% # user version %> + <%= ts("in") %> <%= link_to collection_item.collection.title, collection_path(collection_item.collection) %> + <% if collection_item.collection.user_is_posting_participant?(@user) %> + <%= ts("(Member)") %> + <% end %> + <% else %> + <% # mod version %> + <% collection_item.item_creator_pseuds.each do |pseud| %> + <%= pseud.byline %> + <% if collection_item.collection.user_is_posting_participant?(pseud.user) %> + <%= ts("(Member)")%> + <% end %> + <% end %> + <% # TODO: Make recipients and bylines links, separate recipients with space (currently "snow,astolat") %> + <% unless collection_item.recipients.blank? %> + <%= ts("for") %> <%= collection_item.recipients %> + <% end %> + <% end %> +
    + + <% if collection_item.item %> +

    <%= collection_item.item_date.to_date %>

    + <% end %> +
    + <%= collection_icon_display(collection_item.collection) %> +
    +
    + + <% if collection_item.item %> + <% # An item can be in multiple collections. Including the collection name in the id prevents multiple items from having the same id. %> + <% id = "blurb_#{collection_item.item_type}_#{collection_item.item_id}_#{collection_item.collection.name}" %> +
    + <% if collection_item.item_type == 'Work' %> + <%= render "works/work_module", work: collection_item.item, is_unrevealed: false %> + <% elsif collection_item.item_type == 'Bookmark' %> + <% bookmark = collection_item.item %> + <% bookmarkable = bookmark.bookmarkable %> + <% if bookmarkable.blank? %> +

    <%= ts("This has been deleted, sorry!") %>

    + <% else %> + <%= render 'bookmarks/bookmark_item_module', bookmarkable: bookmarkable %> + <% end %> + <%= render 'bookmarks/bookmark_user_module', bookmark: bookmark %> + <% end %> +
    + <% end %> + + + <%= render 'collection_item_controls', collection_item: collection_item, form: form %> + <% end %> +
  • diff --git a/app/views/collection_items/index.html.erb b/app/views/collection_items/index.html.erb new file mode 100755 index 0000000..8118603 --- /dev/null +++ b/app/views/collection_items/index.html.erb @@ -0,0 +1,50 @@ + +

    + <% if @user %> + <%= t(".user.page_heading", username: @user.login) %> + <% else %> + <%= t(".collection.page_heading_html", collection_link: link_to(@collection.title, @collection)) %> + <% end %> +

    + + + + + +<% if @collection && params[:status] == "unreviewed_by_user" %> +

    <%= t(".collection.notice.unreviewed_by_user") %>

    +<% end %> +<% if @user && params[:status] == "unreviewed_by_collection" %> +

    <%= t(".user.notice.unreviewed_by_collection") %>

    +<% end %> +<% if @collection_items.count < 1 %> +

    <%= t(".no_items") %>

    +<% else %> + <%= form_tag (@user ? update_multiple_user_collection_items_path(@user) : update_multiple_collection_items_path(@collection)), method: :patch do %> +
      + <% @collection_items.each do |collection_item| %> + <%= render "item_fields", collection_item: collection_item %> + <% end %> +
    + <%= submit_fieldset %> + <% end %> + + <%= will_paginate @collection_items %> +<% end %> + diff --git a/app/views/collection_items/new.html.erb b/app/views/collection_items/new.html.erb new file mode 100755 index 0000000..ece1d4a --- /dev/null +++ b/app/views/collection_items/new.html.erb @@ -0,0 +1,12 @@ + +

    <%= ts("Add To Collection") %>

    + +<%= error_messages_for :collection_item %> + + + + + + +<%= render 'collection_item_form', :item => @item %> + diff --git a/app/views/collection_mailer/item_added_notification.html.erb b/app/views/collection_mailer/item_added_notification.html.erb new file mode 100755 index 0000000..749e9e7 --- /dev/null +++ b/app/views/collection_mailer/item_added_notification.html.erb @@ -0,0 +1,21 @@ +<% content_for :message do %> + + <% pseuds = @creation.is_a?(Work) ? @creation.pseuds.map{|p| style_pseud_link(p)}.to_sentence.html_safe : @creation.pseud.name %> + + <%= @creation.is_a?(Work) ? @creation.pseuds.length > 0 ? pseuds : style_bold(@creation.authors_to_sort_on) : pseuds %> posted a + <%= @creation.is_a?(Work) ? @creation.backdate ? "backdated " : "new " : "new " %> <%= @creation.is_a?(Work) ? "work" : "bookmark" %> to your collection, + <%= style_link(@collection.name, collection_url(@collection)) %>: + +
    + <% if @creation.is_a?(Work) %> + <%= style_link(@creation.title.html_safe, work_url(@creation)) %> + <% else %> + <%= style_link("A bookmark of: " + @creation.bookmarkable.title.html_safe, bookmark_url(@creation)) %> + <% end %> + + +<% end %> + +<% content_for :footer_note do %> + You're receiving this email because you've chosen to be notified when new items are added to your collection <%= style_footer_link(@collection.name, collection_url(@collection)) %>. Follow the link to change settings if you no longer wish to receive updates. +<% end %> \ No newline at end of file diff --git a/app/views/collection_mailer/item_added_notification.text.erb b/app/views/collection_mailer/item_added_notification.text.erb new file mode 100755 index 0000000..cc8b5fb --- /dev/null +++ b/app/views/collection_mailer/item_added_notification.text.erb @@ -0,0 +1,18 @@ +<% content_for :message do %> +<% pseuds = @creation.is_a?(Work) ? @creation.pseuds.map{|p| text_pseud(p)}.to_sentence.html_safe : @creation.pseud.name %> + + +<%= @creation.is_a?(Work) ? @creation.pseuds.length > 0 ? pseuds : @creation.authors_to_sort_on : pseuds %> posted a <%= @creation.is_a?(Work) ? @creation.backdate ? "backdated " : "new " : "new " %> <%= @creation.is_a?(Work) ? "work" : "bookmark" %> to your collection, "<%= @collection.name %>" (<%= collection_url(@collection) %>: + +<% if @creation.is_a?(Work) %> +"<%= @creation.title.html_safe %>" +<%= work_url(@creation) %> +<% else %> +<%= "A bookmark of: " + @creation.bookmarkable.title.html_safe %> +<%= bookmark_url(@creation) %> +<% end %> +<% end %> + +<% content_for :footer_note do %> +You're receiving this email because you've chosen to be notified when new items are added to your collection "<%= @collection.name %>" (<%= collection_url(@collection) %>). Follow the link to change settings if you no longer wish to receive updates. +<% end %> \ No newline at end of file diff --git a/app/views/collection_participants/_add_participants_form.html.erb b/app/views/collection_participants/_add_participants_form.html.erb new file mode 100755 index 0000000..e2a6547 --- /dev/null +++ b/app/views/collection_participants/_add_participants_form.html.erb @@ -0,0 +1,10 @@ +<%= form_tag add_collection_participants_path(@collection), class: "single simple post", method: :post do %> +
    + Add new members +

    + <%= label_tag :participants_to_invite, ts("Add new members"), class: "landmark" %> + <%= text_field_tag :participants_to_invite, nil, autocomplete_options("pseud") %> + <%= submit_tag ts("Submit") %> +

    +
    +<% end %> diff --git a/app/views/collection_participants/_participant_form.html.erb b/app/views/collection_participants/_participant_form.html.erb new file mode 100755 index 0000000..3d9a551 --- /dev/null +++ b/app/views/collection_participants/_participant_form.html.erb @@ -0,0 +1,19 @@ + + +<% if participant %> +
  • + <%= form_for(participant, url: collection_participant_path(@collection, participant), as: :collection_participant) do |form| %> + + + +
  • +<% end %> diff --git a/app/views/collection_participants/index.html.erb b/app/views/collection_participants/index.html.erb new file mode 100755 index 0000000..4fb615c --- /dev/null +++ b/app/views/collection_participants/index.html.erb @@ -0,0 +1,10 @@ + +

    <%= ts("Members of %{title}", title: @collection.title) %>

    + + +<%= render partial: "add_participants_form" %> + +

    <%= ts("Listing Collection Members") %>

    +
      + <%= render partial: "participant_form", collection: @collection_participants, as: :participant %> +
    diff --git a/app/views/collection_profile/_navigation.html.erb b/app/views/collection_profile/_navigation.html.erb new file mode 100755 index 0000000..8085d1c --- /dev/null +++ b/app/views/collection_profile/_navigation.html.erb @@ -0,0 +1,14 @@ +

    <%= ts("Navigation") %>

    +<% if show_collection_profile_navigation(@collection, section) %> + +<% end %> \ No newline at end of file diff --git a/app/views/collection_profile/show.html.erb b/app/views/collection_profile/show.html.erb new file mode 100755 index 0000000..730805a --- /dev/null +++ b/app/views/collection_profile/show.html.erb @@ -0,0 +1,112 @@ +
    + <%= render 'collections/header', :collection => @collection %> + +

    + <%= ts('About') %> + <%= @collection.title %> + <% if @collection.title != @collection.name %> + + (<%= @collection.name %>) + + <% end %> +

    +
    +
    +
    <%= ts('Active since:') %> +
    <%= l(@collection.created_at.to_date) %> +
    <%= ts('Maintainers:') %>
    +
    +
      + <%= (@collection.all_owners + @collection.all_moderators).map {|owner| content_tag(:li, link_to(owner.byline, owner.user))}.join("\n").html_safe %> +
    +
    + <% unless @collection.email.blank? %> +
    <%= ts('Contact:') %>
    +
    <%= @collection.email %>
    + <% end %> + <% if @collection.challenge.present? %> + <% tag_sets_counted = tag_set_count(@collection) %> + <% if tag_sets_counted.present? %> +
    <%= tag_sets_counted > 1 ? ts('Tag Sets:') : ts('Tag Set:') %>
    +
    +
      + <%= (@collection.challenge_type == "GiftExchange" ? @collection.challenge.offer_restriction.owned_tag_sets : @collection.challenge.request_restriction.owned_tag_sets).map {|tag_set| content_tag(:li, link_to(tag_set.title, tag_set_path(tag_set)))}.join("\n").html_safe %> +
    +
    + <% end %> + <% end %> + <% if @collection.challenge %> + + <%= render "challenge/#{challenge_class_name(@collection)}/challenge_meta" %> + + <% end %> +
    +
    + + + <% cache("collection-profile-#{@collection.id}", skip_digest: true) do %> + + + + <% if show_collection_preface(@collection) %> +
    + <% if show_collection_section(@collection, "intro") %> +
    + <%= render 'navigation', :section => 'intro' %> +

    <%= ts('Intro:') %>

    +
    + <%=raw sanitize_field(@collection.collection_profile.intro.blank? ? @collection.parent.collection_profile : @collection.collection_profile, :intro) %> +
    +
    + <% end %> + + <% if show_collection_section(@collection, "faq") %> +
    + <%= render 'navigation', :section => 'faq' %> +

    <%= ts('FAQ:') %>

    +
    + <%=raw sanitize_field(@collection.collection_profile.faq.blank? ? @collection.parent.collection_profile : @collection.collection_profile, :faq) %> +
    +
    + <% end %> + + <% if show_collection_section(@collection, "rules") %> +
    + <%= render 'navigation', :section => 'rules' %> +

    <%= ts('Rules:') %>

    +
    + <%=raw sanitize_field(@collection.collection_profile.rules.blank? ? @collection.parent.collection_profile : @collection.collection_profile, :rules) %> +
    +
    + <% end %> +
    + <% end %> + + <% end %> + + + <% if @collection.user_is_owner?(current_user) || @collection.user_is_maintainer?(current_user) %> +

    <%= ts('Actions') %>

    + + <% end %> + + +
    diff --git a/app/views/collections/_bookmarks_module.html.erb b/app/views/collections/_bookmarks_module.html.erb new file mode 100755 index 0000000..c85c52f --- /dev/null +++ b/app/views/collections/_bookmarks_module.html.erb @@ -0,0 +1,17 @@ +
    +

    + <% if collection.collection_preference.show_random || params[:show_random] %> + <%= ts("Random bookmarks") %> + <% else %> + <%= ts("Recent bookmarks") %> + <% end %> +

    +
      + <% for bookmark in bookmarks %> + <%= render 'bookmarks/bookmark_blurb', :bookmark => bookmark %> + <% end %> +
    + <% if bookmarks.total_entries > ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD %> + + <% end %> +
    diff --git a/app/views/collections/_challenge_collections.html.erb b/app/views/collections/_challenge_collections.html.erb new file mode 100755 index 0000000..830fd98 --- /dev/null +++ b/app/views/collections/_challenge_collections.html.erb @@ -0,0 +1,12 @@ +<% if @challenge_collections.blank? %> +

    <%= ts("There are no challenges currently open for sign-ups in the archive.") %>

    +<% else %> +

    <%= ts("The following challenges are currently open for sign-ups! Those closing soonest are at the top.") %>

    + +

    <%= ts("List of Collections") %>

    +
      + <% @challenge_collections.each do |collection| %> + <%= render :partial => "collection_blurb", :locals => {:collection => collection} %> + <% end %> +
    +<% end %> \ No newline at end of file diff --git a/app/views/collections/_challenge_list_top_navigation.html.erb b/app/views/collections/_challenge_list_top_navigation.html.erb new file mode 100755 index 0000000..5e499ce --- /dev/null +++ b/app/views/collections/_challenge_list_top_navigation.html.erb @@ -0,0 +1,7 @@ +

    <%= ts("Navigation") %>

    + \ No newline at end of file diff --git a/app/views/collections/_collection_blurb.html.erb b/app/views/collections/_collection_blurb.html.erb new file mode 100755 index 0000000..4895305 --- /dev/null +++ b/app/views/collections/_collection_blurb.html.erb @@ -0,0 +1,87 @@ + +
  • + <% logged_in = (logged_in_as_admin? || logged_in?) ? "logged-in" : "logged-out" %> + <% # remember to update collection_sweeper if you change this key %> + <% cache("collection-blurb-#{logged_in}-#{collection.id}-v4", expires_in: ArchiveConfig.MINUTES_UNTIL_COLLECTION_BLURBS_EXPIRE.minutes, skip_digest: true) do %> +
    +

    + <%= link_to collection.title, collection_path(collection) %> + (<%= collection.name %>) + <%= ts('by') %> + <%= collection.all_owners.map {|owner| link_to(owner.byline, owner.user)}.join(", ").html_safe %> +

    + +
    + <%= collection_icon_display(collection) %> +
    +

    <%= set_format_for_date(collection.updated_at) %>

    + <% if collection.all_moderators.length > 0%> +
    <%= ts("Mods") %>
    +
      + <%= collection.all_moderators.map {|mod| content_tag(:li, link_to(mod.byline, mod.user))}.join("\n").html_safe %> +
    + <% end %> +
    + + +
    <%= ts("Summary") %>
    +
    + <%=raw strip_images(sanitize_field(collection, :description)) || " ".html_safe %> + + <% if collection.challenge && collection.challenge.signup_open %> +

    <%= ts("Sign-ups close at:") %> <%= time_in_zone(collection.challenge.signups_close_at, (collection.challenge.time_zone || Time.zone.name)) %>

    + <% end %> +
    + +

    + (<%= collection.closed? ? ts("Closed") : ts("Open") %>, <%= collection.moderated? ? ts("Moderated") : ts("Unmoderated") %><%= collection.unrevealed? ? ts(", Unrevealed") : "" %><%= collection.anonymous? ? ts(", Anonymous") : "" %><%= collection.gift_exchange? ? ts(", Gift Exchange Challenge") : "" %><%= collection.prompt_meme? ? ts(", Prompt Meme Challenge") : "" %>) +

    + + +
    + <% if (@challenges_count = collection.children.count) > 0 %> +
    <%= ts("Challenges/Subcollections:") %>
    +
    <%= link_to(@challenges_count, collection_collections_path(collection)) %>
    + <% end %> + <% if (@works_count = SearchCounts.work_count_for_collection(collection)) > 0 %> +
    <%= ts("Fandoms:") %>
    +
    <%= link_to(SearchCounts.fandom_count_for_collection(collection), collection_fandoms_path(collection)) %>
    + <% end %> + <% if collection.challenge? && collection.prompt_meme? %> +
    <%= ts("Prompts:") %>
    +
    <%= link_to(collection.prompts.count.to_s, collection_requests_path(collection)) %>
    + <% end %> +
    <%= ts("Works:") %>
    +
    <%= link_to(@works_count, collection_works_path(collection)) %>
    + <% if (@bookmarks_count = SearchCounts.bookmarkable_count_for_collection(collection)) > 0 %> +
    <%= ts("Bookmarked Items:") %>
    +
    <%= link_to(@bookmarks_count, collection_bookmarks_path(collection)) %>
    + <% end %> +
    + + <% end %> + + <% if collection.user_is_owner?(current_user) || (collection.challenge && collection.challenge.signup_open && logged_in?) || (collection.moderated? && logged_in?) %> +
    <%= ts("User Actions") %>
    + + <% end %> +
  • + diff --git a/app/views/collections/_collection_form_delete.html.erb b/app/views/collections/_collection_form_delete.html.erb new file mode 100755 index 0000000..eb9c2b8 --- /dev/null +++ b/app/views/collections/_collection_form_delete.html.erb @@ -0,0 +1,6 @@ + diff --git a/app/views/collections/_collection_profile_navigation.html.erb b/app/views/collections/_collection_profile_navigation.html.erb new file mode 100755 index 0000000..8beca1b --- /dev/null +++ b/app/views/collections/_collection_profile_navigation.html.erb @@ -0,0 +1,14 @@ +

    <%= ts("Navigation") %>

    +<% if show_collection_profile_navigation(@collection, section) %> + +<% end %> \ No newline at end of file diff --git a/app/views/collections/_filters.html.erb b/app/views/collections/_filters.html.erb new file mode 100755 index 0000000..5e3c226 --- /dev/null +++ b/app/views/collections/_filters.html.erb @@ -0,0 +1,151 @@ +<%= form_tag collections_path, method: :get, class: "narrow-hidden filters", + id: "collection-filters" do %> +

    <%= ts("Filters") %>

    + <%= field_set_tag ts("Filter collections:") do %> +
    +
    <%= ts("Sort and Filter") %>
    +
    <%= submit_tag ts("Sort and Filter") %>
    +
    + <%= label_tag :sort_column, ts("Sort by") %> +
    +
    + <%= select_tag :sort_column, + options_for_select({ + ts("Title") => "collections.title", + ts("Date Created") => "collections.created_at" }, + params[:sort_column]) %> +
    +
    + <%= label_tag :sort_direction, ts("Sort direction") %> +
    +
    + <%= select_tag :sort_direction, + options_for_select({ + ts("Ascending") => "ASC", + ts("Descending") => "DESC" }, + params[:sort_direction]) %> +
    + + + + + +
    <%= ts("Closed") %>
    +
    +
      +
    • + <%= label_tag "collection_filters_closed_true" do %> + <%= radio_button_tag "collection_filters[closed]", true, + params[:collection_filters][:closed] == "true" %> + <%= label_indicator_and_text(ts("Yes")) %> + <% end %> +
    • +
    • + <%= label_tag "collection_filters_closed_false" do %> + <%= radio_button_tag "collection_filters[closed]", false, + params[:collection_filters][:closed] == "false" %> + <%= label_indicator_and_text(ts("No")) %> + <% end %> +
    • +
    • + <%= label_tag "collection_filters_closed_" do %> + <%= radio_button_tag "collection_filters[closed]", "", + params[:collection_filters][:closed] == "" %> + <%= label_indicator_and_text(ts("Either")) %> + <% end %> +
    • +
    +
    +
    <%= ts("Moderated") %>
    +
    +
      +
    • + <%= label_tag "collection_filters_moderated_true" do %> + <%= radio_button_tag "collection_filters[moderated]", true, + params[:collection_filters][:moderated] == "true" %> + <%= label_indicator_and_text(ts("Yes")) %> + <% end %> +
    • +
    • + <%= label_tag "collection_filters_moderated_false" do %> + <%= radio_button_tag "collection_filters[moderated]", false, + params[:collection_filters][:moderated] == "false" %> + <%= label_indicator_and_text(ts("No")) %> + <% end %> +
    • +
    • + <%= label_tag "collection_filters_moderated_" do %> + <%= radio_button_tag "collection_filters[moderated]", "", + params[:collection_filters][:moderated] == "" %> + <%= label_indicator_and_text(ts("Either")) %> + <% end %> +
    • +
    +
    +
    <%= ts("Collection Type") %>
    +
    +
      +
    • + <%= label_tag "collection_filters_challenge_type_gift_exchange" do %> + <%= radio_button_tag "collection_filters[challenge_type]", + "gift_exchange", + params[:collection_filters][:challenge_type] == "gift_exchange" + %> + <%= label_indicator_and_text(ts("Gift Exchange Challenge")) %> + <% end %> +
    • +
    • + <%= label_tag "collection_filters_challenge_type_prompt_meme" do %> + <%= radio_button_tag "collection_filters[challenge_type]", + "prompt_meme", + params[:collection_filters][:challenge_type] == "prompt_meme" + %> + <%= label_indicator_and_text(ts("Prompt Meme Challenge")) %> + <% end %> +
    • +
    • + <%= label_tag "collection_filters_challenge_type_no_challenge" do %> + <%= radio_button_tag "collection_filters[challenge_type]", + "no_challenge", + params[:collection_filters][:challenge_type] == "no_challenge" + %> + <%= label_indicator_and_text(ts("No Challenge")) %> + <% end %> +
    • +
    • + <%= label_tag "collection_filters_challenge_type_" do %> + <%= radio_button_tag "collection_filters[challenge_type]", "", + params[:collection_filters][:challenge_type] == "" %> + <%= label_indicator_and_text(ts("Any")) %> + <% end %> +
    • +
    +
    +
    <%= ts("Submit") %>
    +
    <%= submit_tag ts("Sort and Filter") %>
    +
    +

    + <%= link_to ts("Clear Filters"), collections_path %> +

    + <% end %> + <% # On narrow screens, link jumps to top of index when JavaScript is disabled and closes filters when JavaScript is enabled %> + +<% end %> diff --git a/app/views/collections/_form.html.erb b/app/views/collections/_form.html.erb new file mode 100755 index 0000000..07055c3 --- /dev/null +++ b/app/views/collections/_form.html.erb @@ -0,0 +1,250 @@ +<%= error_messages_for :collection %> +<%= form_for(@collection, html: { multipart: true, class: "verbose post collection" }) do |collection_form| %> +

    * <%= ts('Required information') %>

    +
    + <%= ts("Header") %> +
    + + <% if @collection.new_record? && current_user.pseuds.size > 1 %> +
    + <%= label_tag "owner_pseuds[]", ts("Owner pseud(s)") %> +
    +
    + <%= select_tag "owner_pseuds[]", options_from_collection_for_select(current_user.pseuds, :id, :name, current_user.default_pseud_id), multiple: true %> +
    + <% else %> +

    <%= hidden_field_tag "owner_pseuds[]", [current_user.default_pseud.id] %>

    + <% end %> + +
    + <%= collection_form.label :name, ts("Collection name" + "*") %> + <%= link_to_help "collection-name" %> +
    +
    + <%= collection_form.text_field :name, "aria-describedby" => "name-field-notes" %> +

    + <%= ts("%{minimum} to %{maximum} characters (A-Z, a-z, _, 0-9 only), no spaces, cannot begin or end with underscore (_)", + minimum: ArchiveConfig.TITLE_MIN, + maximum: ArchiveConfig.TITLE_MAX) %> +

    +
    + +
    + <%= collection_form.label :title, ts("Display title") + "*" %> +
    +
    + <%= collection_form.text_field :title, "aria-describedby" => "title-field-notes" %> +

    + <%= ts("(text only)") %> +

    +
    + + <% if @collection.children.empty? %> +
    + <%= collection_form.label :parent_name, ts("Parent collection (that you maintain)") %> +
    +
    + <%= collection_form.text_field :parent_name, autocomplete_options("collection_parent_name", data: { autocomplete_token_limit: 1 }) %> +
    + <% end %> + +
    <%= collection_form.label :email, ts("Collection email") %>
    +
    <%= collection_form.text_field :email, size: 40 %>
    + +
    + <%= collection_form.label :header_image_url, ts("Custom header URL") %> +
    +
    + <%= collection_form.text_field :header_image_url, "aria-describedby" => "header-image-field-description" %> +

    + <%= ts("JPG, GIF, PNG") %> +

    +
    + +
    <%= ts("Icon") %>
    +
    +
      + <% unless @collection.new_record? %> +
    • + <%= collection_icon_display(@collection) %> + <%= ts("This is the collection's icon.") %> +
    • + <% end %> +
    • <%= ts("Each collection can have one icon") %>
    • +
    • <%= ts("Icons can be in png, jpeg or gif form") %>
    • +
    • <%= ts("Icons should be sized 100x100 pixels for best results") %>
    • +
    + <% if @collection.icon.attached? %> + <%= collection_form.check_box :delete_icon, {:checked => false} %> + <%= collection_form.label :delete_icon, t(".icon.delete") %> + <% end %> +
    + +
    <%= collection_form.label :icon, ts("Upload a new icon") %>
    +
    + <%= collection_form.file_field :icon %> +
    + +
    + <%= collection_form.label :icon_alt_text, ts("Icon alt text") %> + <%= link_to_help "icon-alt-text" %> +
    +
    + <%= collection_form.text_field :icon_alt_text, class: "observe_textlength" %> + <%= generate_countdown_html("collection_icon_alt_text", ArchiveConfig.ICON_ALT_MAX) %> +
    + +
    + <%= collection_form.label :icon_comment_text, ts("Icon comment text") %> + <%= link_to_help "pseud-icon-comment" %> +
    +
    + <%= collection_form.text_field :icon_comment_text, class: "observe_textlength" %> + <%= generate_countdown_html("collection_icon_comment_text", ArchiveConfig.ICON_COMMENT_MAX) %> +
    + +
    <%= collection_form.label :description, ts("Brief description") %>
    +
    + <%= collection_form.text_area :description, rows: 4, cols: 60, class: "description-field observe_textlength" %> + <%= live_validation_for_field('collection_description', + presence: false, maximum_length: ArchiveConfig.SUMMARY_MAX) %> + <%= generate_countdown_html("collection_description", ArchiveConfig.SUMMARY_MAX) %> +
    +
    +
    + + <% @collection.build_collection_preference unless @collection.collection_preference %> + <%= collection_form.fields_for :collection_preference do |preference_form| %> +
    + <%= ts("Preferences") %> +

    + <%= ts("You can also individually ") %> + <% if @collection.new_record? %> + <%= ts("Manage Items") %> + <% else %> + <%= link_to ts("Manage Items"), collection_items_path(@collection) %> + <% end %> + <%= ts(" in your collection.") %> +

    +
    +
    <%= preference_form.check_box :moderated %>
    +
    + <%= preference_form.label :moderated, ts("This collection is moderated") %> + <%= link_to_help "collection-moderated" %> +
    + +
    <%= preference_form.check_box :closed %>
    +
    + <%= preference_form.label :closed, ts("This collection is closed") %> + <%= link_to_help "collection-closed" %> +
    + +
    <%= preference_form.check_box :unrevealed %>
    +
    + <%= preference_form.label :unrevealed, ts("This collection is unrevealed") %> +
    + +
    <%= preference_form.check_box :anonymous %>
    +
    + <%= preference_form.label :anonymous, ts("This collection is anonymous") %> +
    + +
    <%= preference_form.check_box :show_random %>
    +
    + <%= preference_form.label :show_random, ts("Show random works on the front page instead of the most recent") %> +
    + +
    <%= preference_form.check_box :email_notify %>
    +
    + <%= preference_form.label :email_notify, ts("Send a message to the collection email when a work is added") %> +
    + +
    <%= label_tag :challenge_type, ts("Type of challenge, if any") %>
    + <% type = @collection.challenge ? @collection.challenge.class.name : @challenge_type %> +
    + <%= select_tag :challenge_type, options_for_select(Collection::CHALLENGE_TYPE_OPTIONS, type) %> +
    +
    <%= ts("Notice to challenge creators") %>
    +
    +
      +
    • <%= ts("As a challenge owner, you may have access to challenge participants' email addresses.") %>
    • +
    • <%= ts("Use of those email addresses for any purpose other than running the challenge will lead to the termination of your account.") %>
    • +
    +
    +
    +
    + <% end %> + + <% @collection.build_collection_profile unless @collection.collection_profile %> + <%= collection_form.fields_for :collection_profile do |profile_form| %> +
    + <%= ts("Profile") %> +

    <%= allowed_html_instructions %>

    +

    + <%= ts("Tip: if this is a subcollection or challenge, you don't need to repeat yourself: fields left blank will copy from your parent collection.") %> +

    + +

    + <%= profile_form.label :intro, ts("Introduction") %> +

    +

    + <%= profile_form.text_area :intro, rows: 10, cols: 80, class: "observe_textlength" %> + <%= live_validation_for_field('collection_collection_profile_attributes_intro', + presence: false, maximum_length: ArchiveConfig.INFO_MAX) %> + <%= generate_countdown_html("collection_collection_profile_attributes_intro", ArchiveConfig.INFO_MAX) %> +

    + +

    + <%= profile_form.label :faq, ts("FAQ"), title: ts("frequently asked questions") %> +

    +

    + <%= profile_form.text_area :faq, rows: 10, cols: 80, class: "observe_textlength" %> + <%= live_validation_for_field('collection_collection_profile_attributes_faq', + presence: false, maximum_length: ArchiveConfig.INFO_MAX) %> + <%= generate_countdown_html("collection_collection_profile_attributes_faq", ArchiveConfig.INFO_MAX) %> +

    + +

    + <%= profile_form.label :rules, ts("Rules") %> +

    +

    <%= profile_form.text_area :rules, rows: 10, cols: 80, class: "observe_textlength" %> + <%= live_validation_for_field('collection_collection_profile_attributes_rules', + presence: false, maximum_length: ArchiveConfig.INFO_MAX) %> + <%= generate_countdown_html("collection_collection_profile_attributes_rules", ArchiveConfig.INFO_MAX) %> +

    + +

    + <%= profile_form.label :assignment_notification, ts("Assignment notification message") %> +

    +

    + <%= ts('This will be sent out with assignments in a gift exchange challenge. Plain text only.') %> +

    +

    + <%= profile_form.text_area :assignment_notification, rows: 8, cols: 80, + class: "observe_textlength", + "aria-describedby" => "assignment-notification-field-description" %> + <%= live_validation_for_field('collection_collection_profile_attributes_assignment_notification', + presence: false, maximum_length: ArchiveConfig.SUMMARY_MAX) %> + <%= generate_countdown_html("collection_collection_profile_attributes_assignment_notification", ArchiveConfig.SUMMARY_MAX) %> +

    + +

    + <%= profile_form.label :gift_notification, ts("Gift notification message") %> +

    +

    + <%= ts('This will be sent out with each work notification when you "reveal" a gift exchange or prompt meme. Plain text only.') %> +

    +

    + <%= profile_form.text_area :gift_notification, rows: 8, cols: 80, + class: "observe_textlength", + "aria-describedby" => "gift-notification-field-description" %> + <%= live_validation_for_field('collection_collection_profile_attributes_gift_notification', + presence: false, maximum_length: ArchiveConfig.SUMMARY_MAX) %> + <%= generate_countdown_html("collection_collection_profile_attributes_gift_notification", ArchiveConfig.SUMMARY_MAX) %> +

    + + <% end %> +
    + +<%= submit_fieldset collection_form %> +<% end %> diff --git a/app/views/collections/_header.html.erb b/app/views/collections/_header.html.erb new file mode 100755 index 0000000..4f74ed1 --- /dev/null +++ b/app/views/collections/_header.html.erb @@ -0,0 +1,45 @@ + +
    +

    <%= link_to_unless_current(@collection.title, @collection) %>

    +
    + <%= collection_icon_display(@collection) %> +
    + + + + + +
    <%=raw sanitize_field(@collection, :description) %>
    +

    + (<%= collection.closed? ? ts("Closed") : ts("Open") %>, <%= collection.moderated? ? ts("Moderated") : ts("Unmoderated") %><%= collection.unrevealed? ? ts(", Unrevealed") : "" %><%= collection.anonymous? ? ts(", Anonymous") : "" %><%= collection.gift_exchange? ? ts(", Gift Exchange Challenge") : "" %><%= collection.prompt_meme? ? ts(", Prompt Meme Challenge") : "" %>) +

    +
    diff --git a/app/views/collections/_sidebar.html.erb b/app/views/collections/_sidebar.html.erb new file mode 100755 index 0000000..76968e2 --- /dev/null +++ b/app/views/collections/_sidebar.html.erb @@ -0,0 +1,54 @@ +
    +

    <%= t(".landmark.dashboard") %>

    + + + + <% if @collection.challenge %> + <%= render partial: "challenge/#{challenge_class_name(@collection)}/challenge_sidebar" %> + <% end %> + +

    <%= t(".landmark.contents") %>

    + + + <% if @collection.user_is_maintainer?(current_user) %> +

    <%= t(".landmark.choices") %>

    + + <% end %> +
    diff --git a/app/views/collections/_works_module.html.erb b/app/views/collections/_works_module.html.erb new file mode 100755 index 0000000..b7d353b --- /dev/null +++ b/app/views/collections/_works_module.html.erb @@ -0,0 +1,17 @@ +
    +

    + <% if collection.collection_preference.show_random || params[:show_random] %> + <%= ts("Random works") %> + <% else %> + <%= ts("Recent works") %> + <% end %> +

    +
      + <% for work in works %> + <%= render 'works/work_blurb', :work => work %> + <% end %> +
    + <% if works.total_entries > ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD %> + + <% end %> +
    diff --git a/app/views/collections/confirm_delete.html.erb b/app/views/collections/confirm_delete.html.erb new file mode 100755 index 0000000..826e510 --- /dev/null +++ b/app/views/collections/confirm_delete.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts("Delete Collection") %>

    + + +<%= form_for(@collection, :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    <%= ts("Are you sure you want to delete the collection %{collection_name}? All collection settings will be lost. (Works will not be deleted.)", :collection_name => @collection.title).html_safe %>

    +

    + <%= f.submit ts("Yes, Delete Collection") %> +

    +<% end %> + diff --git a/app/views/collections/edit.html.erb b/app/views/collections/edit.html.erb new file mode 100755 index 0000000..68b3220 --- /dev/null +++ b/app/views/collections/edit.html.erb @@ -0,0 +1,13 @@ + +

    <%= ts("Edit Collection") %>

    + + + + <%= render "collections/collection_form_delete" %> + + + +

    <%= ts("Edit Collection Form") %>

    +<%= render :partial => 'form' %> + + diff --git a/app/views/collections/index.html.erb b/app/views/collections/index.html.erb new file mode 100755 index 0000000..f332900 --- /dev/null +++ b/app/views/collections/index.html.erb @@ -0,0 +1,71 @@ + +

    + <% if @user %> + <%= t(".page_heading.users_collections", user: @user.login) %> + <% elsif @collection %> + <%= t(".page_heading.challenges_subcollections_in", collection: @collection.title) %> + <% elsif @work %> + <%= t(".page_heading.collections_including", work: @work.title) %> + <% else %> + <%= t(".page_heading.collections_in_the", archive: ArchiveConfig.APP_NAME) %> + <% end %> +

    + +

    + <% if @collections.empty? %> + <%= ts("Sorry, there were no collections found.") %> + <% else %> + <%= search_header @collections, @query, ts("Collection") %> + <% end %> +

    + + + +

    <%= ts("Navigation") %>

    + + +<% unless @collections.blank? %> + + <%= will_paginate @collections %> + + +

    <%= ts("List of Collections") %>

    +
      + <% @collections.each do |collection| %> + <%= render :partial => "collection_blurb", :locals => {:collection => collection} %> + <% end %> +
    +<% end %> + +<% if @sort_and_filter %> + + <%= render 'collections/filters' %> + +<% end %> + +<% unless @collections.blank? %> + <%= will_paginate @collections %> +<% end %> diff --git a/app/views/collections/list_challenges.html.erb b/app/views/collections/list_challenges.html.erb new file mode 100755 index 0000000..0f5c7db --- /dev/null +++ b/app/views/collections/list_challenges.html.erb @@ -0,0 +1,10 @@ +

    <%= ts("Open Challenges") %>

    + + +<%= render :partial => "challenge_list_top_navigation" %> + + + +<%= render :partial => "challenge_collections" %> + + diff --git a/app/views/collections/list_ge_challenges.html.erb b/app/views/collections/list_ge_challenges.html.erb new file mode 100755 index 0000000..f2442d8 --- /dev/null +++ b/app/views/collections/list_ge_challenges.html.erb @@ -0,0 +1,10 @@ +

    <%= ts("Open Gift Exchange Challenges") %>

    + + +<%= render :partial => "challenge_list_top_navigation" %> + + + +<%= render :partial => "challenge_collections" %> + + diff --git a/app/views/collections/list_pm_challenges.html.erb b/app/views/collections/list_pm_challenges.html.erb new file mode 100755 index 0000000..76f03ac --- /dev/null +++ b/app/views/collections/list_pm_challenges.html.erb @@ -0,0 +1,10 @@ +

    <%= ts("Open Prompt Meme Challenges") %>

    + + +<%= render :partial => "challenge_list_top_navigation" %> + + + +<%= render :partial => "challenge_collections" %> + + diff --git a/app/views/collections/new.html.erb b/app/views/collections/new.html.erb new file mode 100755 index 0000000..fdff652 --- /dev/null +++ b/app/views/collections/new.html.erb @@ -0,0 +1,23 @@ + +

    <%= ts("New Collection") %>

    + + + + +

    <%= ts('Suggestions') %>

    +
      +
    • <%= ts("Only registered users can post, so you don't need to worry about spam: you can leave your collection unmoderated. You can always reject works afterwards if there") %> <%= ts("is") %> <%= ts("a mistaken submission.") %>
    • +
    • <%= ts("The best way to set up a regular challenge (e.g., an annual challenge like Yuletide, + or a weekly one like sga_flashfic) is to create a closed parent collection and then add a new, open, subcollection for each challenge.") %> +
    • +
    • + <%= ts("If you limit membership for each challenge (e.g., for a gift exchange), people can sign + up for each subcollection separately. If you just want the whole thing moderated, have people sign up as members of the parent collection; they'll then be able to post in every subcollection.") %> +
    • +
    + + + +

    <%= ts("New Collection Form") %>

    +<%= render :partial => 'form' %> + diff --git a/app/views/collections/show.html.erb b/app/views/collections/show.html.erb new file mode 100755 index 0000000..1f208f2 --- /dev/null +++ b/app/views/collections/show.html.erb @@ -0,0 +1,20 @@ +
    + + <%= render "collections/header", :collection => @collection %> + + + <% # expects @works, @bookmarks %> + <% unless @works.blank? %> + <%= render 'works_module', :collection => @collection, :works => @works %> + <% end %> + + <% unless @bookmarks.blank? %> + <%= render 'bookmarks_module', :collection => @collection, :bookmarks => @bookmarks %> + <% end %> + + <% if @works.blank? && @bookmarks.blank? %> +

    <%= ts("There are no works or bookmarks in this collection yet.") %>

    + <% end %> + + +
    diff --git a/app/views/comment_mailer/_comment_notification_footer.html.erb b/app/views/comment_mailer/_comment_notification_footer.html.erb new file mode 100755 index 0000000..43715a3 --- /dev/null +++ b/app/views/comment_mailer/_comment_notification_footer.html.erb @@ -0,0 +1,12 @@ +

    + <%= ts("Posted") %>: <%= @comment.created_at %> + <% unless @comment.edited_at.blank? %> +
    <%= ts("Last edited") %>: <%= @comment.edited_at %> + <% end %> +

    + +<% if @comment.ultimate_parent.is_a?(Tag) %> + <%= render "comment_mailer/comment_notification_footer_for_tag" %> +<% else %> + <%= render "comment_mailer/comment_notification_footer_for_other" %> +<% end %> diff --git a/app/views/comment_mailer/_comment_notification_footer.text.erb b/app/views/comment_mailer/_comment_notification_footer.text.erb new file mode 100755 index 0000000..2a8cf25 --- /dev/null +++ b/app/views/comment_mailer/_comment_notification_footer.text.erb @@ -0,0 +1,6 @@ +<%= text_divider %> +Posted: <%= @comment.created_at %><% unless @comment.edited_at.blank? %> +Last edited: <%= @comment.edited_at %><% end %> +<% if @comment.ultimate_parent.is_a?(Tag) %> +<%= render 'comment_mailer/comment_notification_footer_for_tag', formats: [:text] %><% else %> +<%= render 'comment_mailer/comment_notification_footer_for_other', formats: [:text] %><% end %> \ No newline at end of file diff --git a/app/views/comment_mailer/_comment_notification_footer_for_other.html.erb b/app/views/comment_mailer/_comment_notification_footer_for_other.html.erb new file mode 100755 index 0000000..f852ac0 --- /dev/null +++ b/app/views/comment_mailer/_comment_notification_footer_for_other.html.erb @@ -0,0 +1,40 @@ +<% if @comment.unreviewed? %> + <% if @owner && @comment.ultimate_parent.is_a?(Work) %> +

    Comments on this work are moderated and will not appear until you approve them.

    + <% elsif @comment.ultimate_parent.is_a?(AdminPost) %> +

    Comments on this news post are moderated and will not appear until approved.

    + <% else %> +

    Comments on this work are moderated and will not appear until approved by the work creator.

    + <% end %> +<% end %> + +<% if @comment.unreviewed? && @owner %> + <%= style_link("Review comments on " + @comment.ultimate_parent.commentable_name + "", + polymorphic_url([:unreviewed, @comment.ultimate_parent, :comments])) %> +
    +<% end %> + +<% unless (@comment.unreviewed? || @noreply) %> + <%= style_link("Reply to this comment", + comment_url(@comment, :add_comment_reply_id => @comment.id, :only_path => false)) %> +
    +<% end %> + +<%= style_link("Go to the thread starting from this comment", + comment_url(@comment, :only_path => false)) %> +
    + +<% unless @comment.id == @comment.thread %> + <%= style_link("Go to the thread to which this comment belongs", + comment_url(:id => @comment.thread, :only_path => false)) %> +
    +<% end %> + +<% if @comment.parent.kind_of?(Chapter) && @comment.ultimate_parent.chaptered? %> + <%= style_link("Read all comments on Chapter #{@comment.parent.position} of #{@comment.ultimate_parent.commentable_name}", + work_chapter_url(@comment.parent.work, @comment.parent, show_comments: true, anchor: :comments)) %> +
    +<% else %> + <%= style_link("Read all comments on #{@comment.ultimate_parent.commentable_name}", + polymorphic_url(@comment.ultimate_parent, view_full_work: true, show_comments: true, anchor: :comments)) %> +<% end %> diff --git a/app/views/comment_mailer/_comment_notification_footer_for_other.text.erb b/app/views/comment_mailer/_comment_notification_footer_for_other.text.erb new file mode 100755 index 0000000..a1f766f --- /dev/null +++ b/app/views/comment_mailer/_comment_notification_footer_for_other.text.erb @@ -0,0 +1,14 @@ +<% if @comment.unreviewed? %><% if @owner && @comment.ultimate_parent.is_a?(Work) %> +Comments on this work are moderated and will not appear until you approve them.<% elsif @comment.ultimate_parent.is_a?(AdminPost) %> +Comments on this news post are moderated and will not appear until approved.<% else %> +Comments on this work are moderated and will not appear until approved by the work creator.<% end %> +<% end %><% if @comment.unreviewed? && @owner %> +Review comments on "<%= @comment.ultimate_parent.commentable_name %>": <%= polymorphic_url([:unreviewed, @comment.ultimate_parent, :comments]) %><% end %><% unless @noreply || @comment.unreviewed? %> +Reply to this comment: <%= comment_url(@comment, :add_comment_reply_id => @comment.id, :only_path => false) %><% end %> +Go to the thread starting from this comment: <%= comment_url(@comment, :only_path => false) %><% unless @comment.id == @comment.thread %> +Go to the thread to which this comment belongs: <%= comment_url(:id => @comment.thread, :only_path => false) %><% end %> +<% if @comment.parent.kind_of?(Chapter) && @comment.parent.work.chaptered? -%> +Read all comments on Chapter <%= @comment.parent.position %> of "<%= @comment.ultimate_parent.commentable_name %>": <%= work_chapter_url(@comment.parent.work, @comment.parent, show_comments: true, anchor: :comments) %> +<%- else -%> +Read all comments on "<%= @comment.ultimate_parent.commentable_name %>": <%= polymorphic_url(@comment.ultimate_parent, view_full_work: true, show_comments: true, anchor: :comments) %> +<%- end %> diff --git a/app/views/comment_mailer/_comment_notification_footer_for_tag.html.erb b/app/views/comment_mailer/_comment_notification_footer_for_tag.html.erb new file mode 100755 index 0000000..76a0516 --- /dev/null +++ b/app/views/comment_mailer/_comment_notification_footer_for_tag.html.erb @@ -0,0 +1,18 @@ +<%= style_link("Read all comments on " + @comment.ultimate_parent.name, + tag_comments_url(@comment.ultimate_parent)) %> +
    + +<% unless @noreply %> + <%= style_link("Reply to this comment", + comment_url(@comment, add_comment_reply_id: @comment.id)) %> +
    +<% end %> + +<%= style_link("Go to the thread starting from this comment", + comment_url(@comment)) %> +
    + +<% unless @comment.id == @comment.thread %> + <%= style_link("Go to the thread to which this comment belongs", + comment_url(@comment.thread)) %> +<% end %> diff --git a/app/views/comment_mailer/_comment_notification_footer_for_tag.text.erb b/app/views/comment_mailer/_comment_notification_footer_for_tag.text.erb new file mode 100755 index 0000000..a9c8525 --- /dev/null +++ b/app/views/comment_mailer/_comment_notification_footer_for_tag.text.erb @@ -0,0 +1,4 @@ +Read all comments on <%= @comment.ultimate_parent.name %>: <%= tag_comments_url(@comment.ultimate_parent) %><% unless @noreply %> +Reply to this comment: <%= comment_url(@comment, add_comment_reply_id: @comment.id) %><% end %> +Go to the thread starting from this comment: <%= comment_url(@comment) %><% unless @comment.id == @comment.thread %> +Go to the thread to which this comment belongs: <%= comment_url(@comment.thread) %><% end %> diff --git a/app/views/comment_mailer/comment_notification.html.erb b/app/views/comment_mailer/comment_notification.html.erb new file mode 100755 index 0000000..0512243 --- /dev/null +++ b/app/views/comment_mailer/comment_notification.html.erb @@ -0,0 +1,13 @@ +<% content_for :message do %> + <%# i18n-tasks-use t("comment_mailer.comment_notification.chapter.titled") %> + <%# i18n-tasks-use t("comment_mailer.comment_notification.chapter.untitled") %> + <%# i18n-tasks-use t("comment_mailer.comment_notification.content.chapter.html") %> + <%# i18n-tasks-use t("comment_mailer.comment_notification.content.other.html") %> + <%# i18n-tasks-use t("comment_mailer.comment_notification.content.tag.html") %> + <%= content_for_commentable_html(@comment) %> + + <%= style_quote(raw(@comment.sanitized_mailer_content)) %> + + <%= render 'comment_notification_footer' %> + +<% end %> diff --git a/app/views/comment_mailer/comment_notification.text.erb b/app/views/comment_mailer/comment_notification.text.erb new file mode 100755 index 0000000..5a8a938 --- /dev/null +++ b/app/views/comment_mailer/comment_notification.text.erb @@ -0,0 +1,11 @@ +<% content_for :message do %> +<%# i18n-tasks-use t("comment_mailer.comment_notification.content.chapter.titled_text") %> +<%# i18n-tasks-use t("comment_mailer.comment_notification.content.chapter.untitled_text") %> +<%# i18n-tasks-use t("comment_mailer.comment_notification.content.other.text") %> +<%# i18n-tasks-use t("comment_mailer.comment_notification.content.tag.text") %> +<%= content_for_commentable_text(@comment) %> +<%= text_divider %> + +<%= to_plain_text(raw(@comment.sanitized_mailer_content))%> + +<%= render 'comment_notification_footer', formats: [:text] %><% end %> diff --git a/app/views/comment_mailer/comment_reply_notification.html.erb b/app/views/comment_mailer/comment_reply_notification.html.erb new file mode 100755 index 0000000..f47a227 --- /dev/null +++ b/app/views/comment_mailer/comment_reply_notification.html.erb @@ -0,0 +1,22 @@ +<% content_for :message do %> + + <%# i18n-tasks-use t("comment_mailer.comment_reply_notification.chapter.titled") %> + <%# i18n-tasks-use t("comment_mailer.comment_reply_notification.chapter.untitled") %> + <%# i18n-tasks-use t("comment_mailer.comment_reply_notification.content.chapter.html") %> + <%# i18n-tasks-use t("comment_mailer.comment_reply_notification.content.other.html") %> + <%# i18n-tasks-use t("comment_mailer.comment_reply_notification.content.tag.html") %> + <%= content_for_commentable_html(@comment) %> + +

    + You wrote: + <%= style_quote(raw(@your_comment.sanitized_mailer_content)) %> +

    + +

    + <%= commenter_pseud_or_name_link(@comment) %> responded: + <%= style_quote(raw(@comment.sanitized_mailer_content)) %> +

    + + <%= render 'comment_notification_footer' %> + +<% end %> diff --git a/app/views/comment_mailer/comment_reply_notification.text.erb b/app/views/comment_mailer/comment_reply_notification.text.erb new file mode 100755 index 0000000..c3f6440 --- /dev/null +++ b/app/views/comment_mailer/comment_reply_notification.text.erb @@ -0,0 +1,20 @@ +<% content_for :message do %> +<%# i18n-tasks-use t("comment_mailer.comment_reply_notification.content.chapter.titled_text") %> +<%# i18n-tasks-use t("comment_mailer.comment_reply_notification.content.chapter.untitled_text") %> +<%# i18n-tasks-use t("comment_mailer.comment_reply_notification.content.other.text") %> +<%# i18n-tasks-use t("comment_mailer.comment_reply_notification.content.tag.text") %> +<%= content_for_commentable_text(@comment) %> + +You wrote: +<%= text_divider %> + +<%= to_plain_text(raw(@your_comment.sanitized_mailer_content)) %> + +<%= text_divider %> + +<%= commenter_pseud_or_name_text(@comment) %> responded: +<%= text_divider %> + +<%= to_plain_text(raw(@comment.sanitized_mailer_content)) %> + +<%= render 'comment_notification_footer', formats: [:text] %><% end %> diff --git a/app/views/comment_mailer/comment_reply_sent_notification.html.erb b/app/views/comment_mailer/comment_reply_sent_notification.html.erb new file mode 100755 index 0000000..6dd04ad --- /dev/null +++ b/app/views/comment_mailer/comment_reply_sent_notification.html.erb @@ -0,0 +1,22 @@ +<% content_for :message do %> + + <%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.chapter.titled") %> + <%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.chapter.untitled") %> + <%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.content.chapter.html") %> + <%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.content.other.html") %> + <%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.content.tag.html") %> + <%= content_for_commentable_html(@comment) %> + +

    + <%= commenter_pseud_or_name_link(@parent_comment) %> wrote: + <%= style_quote(raw(@parent_comment.sanitized_mailer_content)) %> +

    + +

    + You responded: + <%= style_quote(raw(@comment.sanitized_mailer_content)) %> +

    + + <%= render 'comment_notification_footer' %> + +<% end %> diff --git a/app/views/comment_mailer/comment_reply_sent_notification.text.erb b/app/views/comment_mailer/comment_reply_sent_notification.text.erb new file mode 100755 index 0000000..2ff3483 --- /dev/null +++ b/app/views/comment_mailer/comment_reply_sent_notification.text.erb @@ -0,0 +1,20 @@ +<% content_for :message do %> +<%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.content.chapter.titled_text") %> +<%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.content.chapter.untitled_text") %> +<%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.content.other.text") %> +<%# i18n-tasks-use t("comment_mailer.comment_reply_sent_notification.content.tag.text") %> +<%= content_for_commentable_text(@comment) %> + +<%= commenter_pseud_or_name_text(@parent_comment) %> wrote: +<%= text_divider %> + +<%= to_plain_text(raw(@parent_comment.sanitized_mailer_content)) %> + +<%= text_divider %> + +You responded: +<%= text_divider %> + +<%= to_plain_text(raw(@comment.sanitized_mailer_content)) %> + +<%= render 'comment_notification_footer', formats: [:text] %><% end %> diff --git a/app/views/comment_mailer/comment_sent_notification.html.erb b/app/views/comment_mailer/comment_sent_notification.html.erb new file mode 100755 index 0000000..7141c69 --- /dev/null +++ b/app/views/comment_mailer/comment_sent_notification.html.erb @@ -0,0 +1,14 @@ +<% content_for :message do %> + + <%# i18n-tasks-use t("comment_mailer.comment_sent_notification.chapter.titled") %> + <%# i18n-tasks-use t("comment_mailer.comment_sent_notification.chapter.untitled") %> + <%# i18n-tasks-use t("comment_mailer.comment_sent_notification.content.chapter.html") %> + <%# i18n-tasks-use t("comment_mailer.comment_sent_notification.content.other.html") %> + <%# i18n-tasks-use t("comment_mailer.comment_sent_notification.content.tag.html") %> + <%= content_for_commentable_html(@comment) %> + + <%= style_quote(raw(@comment.sanitized_mailer_content)) %> + + <%= render 'comment_notification_footer' %> + +<% end %> diff --git a/app/views/comment_mailer/comment_sent_notification.text.erb b/app/views/comment_mailer/comment_sent_notification.text.erb new file mode 100755 index 0000000..fe3f651 --- /dev/null +++ b/app/views/comment_mailer/comment_sent_notification.text.erb @@ -0,0 +1,12 @@ +<% content_for :message do %> +<%# i18n-tasks-use t("comment_mailer.comment_sent_notification.content.chapter.titled_text") %> +<%# i18n-tasks-use t("comment_mailer.comment_sent_notification.content.chapter.untitled_text") %> +<%# i18n-tasks-use t("comment_mailer.comment_sent_notification.content.other.text") %> +<%# i18n-tasks-use t("comment_mailer.comment_sent_notification.content.tag.text") %> +<%= content_for_commentable_text(@comment) %> + +<%= text_divider %> + +<%= to_plain_text(raw(@comment.sanitized_mailer_content)) %> + +<%= render 'comment_notification_footer', formats: [:text] %><% end %> diff --git a/app/views/comment_mailer/edited_comment_notification.html.erb b/app/views/comment_mailer/edited_comment_notification.html.erb new file mode 100755 index 0000000..1bda4f2 --- /dev/null +++ b/app/views/comment_mailer/edited_comment_notification.html.erb @@ -0,0 +1,16 @@ +<% content_for :message do %> + + <%# i18n-tasks-use t("comment_mailer.edited_comment_notification.chapter.titled") %> + <%# i18n-tasks-use t("comment_mailer.edited_comment_notification.chapter.untitled") %> + <%# i18n-tasks-use t("comment_mailer.edited_comment_notification.content.chapter.html") %> + <%# i18n-tasks-use t("comment_mailer.edited_comment_notification.content.other.html") %> + <%# i18n-tasks-use t("comment_mailer.edited_comment_notification.content.tag.html") %> + <%= content_for_commentable_html(@comment) %> + +

    + <%= style_quote(raw(@comment.sanitized_mailer_content)) %> +

    + + <%= render 'comment_notification_footer' %> + +<% end %> diff --git a/app/views/comment_mailer/edited_comment_notification.text.erb b/app/views/comment_mailer/edited_comment_notification.text.erb new file mode 100755 index 0000000..3d4e6d5 --- /dev/null +++ b/app/views/comment_mailer/edited_comment_notification.text.erb @@ -0,0 +1,11 @@ +<% content_for :message do %> +<%# i18n-tasks-use t("comment_mailer.edited_comment_notification.content.chapter.titled_text") %> +<%# i18n-tasks-use t("comment_mailer.edited_comment_notification.content.chapter.untitled_text") %> +<%# i18n-tasks-use t("comment_mailer.edited_comment_notification.content.other.text") %> +<%# i18n-tasks-use t("comment_mailer.edited_comment_notification.content.tag.text") %> +<%= content_for_commentable_text(@comment) %> +<%= text_divider %> + +<%= to_plain_text(raw(@comment.sanitized_mailer_content)) %> + +<%= render 'comment_notification_footer', formats: [:text] %><% end %> diff --git a/app/views/comment_mailer/edited_comment_reply_notification.html.erb b/app/views/comment_mailer/edited_comment_reply_notification.html.erb new file mode 100755 index 0000000..885e925 --- /dev/null +++ b/app/views/comment_mailer/edited_comment_reply_notification.html.erb @@ -0,0 +1,22 @@ +<% content_for :message do %> + + <%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.chapter.titled") %> + <%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.chapter.untitled") %> + <%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.content.chapter.html") %> + <%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.content.other.html") %> + <%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.content.tag.html") %> + <%= content_for_commentable_html(@comment) %> + +

    + You wrote: + <%= style_quote(raw(@your_comment.sanitized_mailer_content)) %> +

    + +

    + <%= commenter_pseud_or_name_link(@comment) %> edited their response to: + <%= style_quote(raw(@comment.sanitized_mailer_content)) %> +

    + + <%= render 'comment_notification_footer' %> + +<% end %> diff --git a/app/views/comment_mailer/edited_comment_reply_notification.text.erb b/app/views/comment_mailer/edited_comment_reply_notification.text.erb new file mode 100755 index 0000000..25c57f8 --- /dev/null +++ b/app/views/comment_mailer/edited_comment_reply_notification.text.erb @@ -0,0 +1,20 @@ +<% content_for :message do %> +<%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.content.chapter.titled_text") %> +<%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.content.chapter.untitled_text") %> +<%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.content.other.text") %> +<%# i18n-tasks-use t("comment_mailer.edited_comment_reply_notification.content.tag.text") %> +<%= content_for_commentable_text(@comment) %> + +You wrote: +<%= text_divider %> + +<%= to_plain_text(raw(@your_comment.sanitized_mailer_content)) %> + +<%= text_divider %> + +<%= commenter_pseud_or_name_text(@comment) %> edited their response to: +<%= text_divider %> + +<%= to_plain_text(raw(@comment.sanitized_mailer_content)) %> + +<%= render 'comment_notification_footer', formats: [:text] %><% end %> diff --git a/app/views/comments/_comment_abbreviated_list.html.erb b/app/views/comments/_comment_abbreviated_list.html.erb new file mode 100755 index 0000000..d2cea62 --- /dev/null +++ b/app/views/comments/_comment_abbreviated_list.html.erb @@ -0,0 +1,15 @@ +<% # this partial is used for an abbreviated list of unthreaded comments (by a single user) %> +<% # expects local "comments" %> + +
    + <% comments.each do |comment| %> +
    + <%= comment_link_with_commentable_name(comment) %> + <%= time_in_zone(comment.created_at) %> +
    +
    + <%= truncate(comment.comment_content, length: 100, separator: ' ') %> +
    + <% end %> +
    + diff --git a/app/views/comments/_comment_actions.html.erb b/app/views/comments/_comment_actions.html.erb new file mode 100755 index 0000000..aecccb0 --- /dev/null +++ b/app/views/comments/_comment_actions.html.erb @@ -0,0 +1,76 @@ +
    <%= ts("Comment Actions") %>
    + + + + + +<% if params[:delete_comment_id] && params[:delete_comment_id] == comment.id.to_s %> +
    + <%= render 'comments/confirm_delete', :comment => comment %> +<% else %> + + +<% if can_reply_to_comment?(comment) %> + <% # This is where the reply-to box will be added when "Reply" is hit, if the user has JavaScript. %> + <% # If not, we will render the comment form if this is the comment we are replying to. %> + <% if focused_on_comment(comment) %> +
    "> + <%= render 'comments/comment_form', + :comment => Comment.new, + :commentable => comment, + :button_name => ts("Comment") %> + <% else %> + +<% end %> diff --git a/app/views/comments/_comment_form.html.erb b/app/views/comments/_comment_form.html.erb new file mode 100755 index 0000000..47067ec --- /dev/null +++ b/app/views/comments/_comment_form.html.erb @@ -0,0 +1,113 @@ + +<% if !commentable && @commentable %> + <% commentable = @commentable %> +<% end %> +
    + <%= form_for value_for_comment_form(commentable, comment), remote: !comment.new_record?, authenticity_token: true, html: { id: "comment_for_#{commentable.id}" } do |f| %> +
    + <%= t(".legend") %> + + <% if local_assigns[:show_errors] %> + <%= error_messages_for :comment %> + <% end %> + + <%# here come the hacks (hidden fields to transmit various info to the create action) %> + <% if commentable.is_a?(Tag) %> + <%= hidden_field_tag :tag_id, commentable.name %> + <% end %> + + <% if params[:view_full_work] %> + <%= hidden_field_tag :view_full_work, params[:view_full_work] %> + <% end %> + + <% if controller.controller_name == "inbox" && params[:filters] %> + <%= hidden_field_tag "filters[read]", params[:filters][:read] %> + <%= hidden_field_tag "filters[replied_to]", params[:filters][:replied_to] %> + <%= hidden_field_tag "filters[date]", params[:filters][:date] %> + <% end %> + + <% if params[:page] %> + <%= hidden_field_tag :page, params[:page] %> + <% end %> + + <% if comments_are_moderated(commentable) && !current_user_is_work_creator(commentable) %> +

    + <% if commentable.is_a?(AdminPost) %> + <%= t("comments.commentable.permissions.moderated_commenting.notice.admin_post") %> + <% else %> + <%= t("comments.commentable.permissions.moderated_commenting.notice.work") %> + <% end %> +

    + <% end %> + + <% if logged_in? %> + <% if current_user_is_anonymous_creator(commentable) %> +

    + <%= t(".anonymous_forewarning") %> +

    + <% end %> + + <% if current_user.pseuds.count > 1 %> +

    <%= t(".comment_as") %> <%= f.collection_select :pseud_id, current_user.pseuds, :id, :name, { selected: (comment.pseud ? comment.pseud.id.to_s : current_user.default_pseud.id.to_s) }, id: "comment_pseud_id_for_#{commentable.id}", title: t(".choose_name_field_title") %> + <% if controller.controller_name == "inbox" %> + <%= t(".inbox_reference_html", + commentable_creator: commentable.by_anonymous_creator? ? t(".anonymous_creator") : get_commenter_pseud_or_name(commentable), + commentable_link: commentable_description_link(commentable)) %> + <% end %> + (<%= allowed_html_instructions %>) +

    + <% else %> +

    <%= t(".comment_as") %> + <%= f.hidden_field :pseud_id, value: current_user.default_pseud.id.to_s, id: "comment_pseud_id_for_#{commentable.id}" %> + <% if controller.controller_name == "inbox" %> + <%= t(".inbox_reference_html", + commentable_creator: commentable.by_anonymous_creator? ? t(".anonymous_creator") : get_commenter_pseud_or_name(commentable), + commentable_link: commentable_description_link(commentable)) %> + <% end %> +

    +

    (<%= allowed_html_instructions %>)

    + <% end %> + + <% else %> +
    +
    <%= t(".landmark.note") %>:
    +
    <%= t(".guest_instructions") %>
    +
    <%= f.label "name_for_#{commentable.id}", t(".guest_name") %>
    +
    + <%= f.text_field :name, id: "comment_name_for_#{commentable.id}" %> + <%= live_validation_for_field("comment_name_for_#{commentable.id}", failureMessage: t(".guest_name_failure")) %> +
    +
    <%= f.label "email_for_#{commentable.id}", t(".guest_email") %>
    +
    + <%= f.text_field :email, id: "comment_email_for_#{commentable.id}" %> + <%= live_validation_for_field("comment_email_for_#{commentable.id}", failureMessage: t(".guest_email_failure")) %> +
    +
    +

    (<%= allowed_html_instructions %>)

    + <% end %> + +

    + <% content_id = "comment_content_for_#{commentable.id}" %> + + <%= f.text_area :comment_content, id: content_id, class: "comment_form observe_textlength", title: t(".comment_field_title") %> + +

    + <%= generate_countdown_html("comment_content_for_#{commentable.id}", ArchiveConfig.COMMENT_MAX) %> + <%= live_validation_for_field "comment_content_for_#{commentable.id}", + failureMessage: t(".comment_too_short"), + maximum_length: ArchiveConfig.COMMENT_MAX, + tooLongMessage: t(".comment_too_long", count: ArchiveConfig.COMMENT_MAX) %> +

    + <%= f.submit button_name, id: "comment_submit_for_#{commentable.id}", data: { disable_with: t(".processing_message") } %> + <% if controller.controller_name == 'inbox' %> + <%= t(".cancel_action") %> + <% elsif comment.persisted? %> + <%= cancel_edit_comment_link(comment) %> + <% elsif commentable.is_a?(Comment) || commentable.is_a?(CommentDecorator) %> + <%= cancel_comment_reply_link(commentable) %> + <% end %> +

    +
    + <% end %> +
    +
    diff --git a/app/views/comments/_comment_thread.html.erb b/app/views/comments/_comment_thread.html.erb new file mode 100755 index 0000000..13e27eb --- /dev/null +++ b/app/views/comments/_comment_thread.html.erb @@ -0,0 +1,23 @@ + +
      + <% for comment in comments %> + <% if comment.approved? || logged_in_as_admin? %> + + <%= render 'comments/single_comment', single_comment: comment %> + <% child_comments = comment.reviewed_replies %> + + <% if child_comments && child_comments.size > 0 %> + + <% if depth >= ArchiveConfig.COMMENT_THREAD_MAX_DEPTH && child_comments.size > 1 %> +
    1. (<%= link_to ts("%{count} more comments in this thread", count: comment.children_count), comment_path(comment) %>)

    2. + <% else %> +
    3. + <%= render 'comments/comment_thread', comments: child_comments, depth: depth+1 %> +
    + + <% end %> + <% end %> + + <% end %> + <% end %> + diff --git a/app/views/comments/_commentable.html.erb b/app/views/comments/_commentable.html.erb new file mode 100755 index 0000000..79e9d73 --- /dev/null +++ b/app/views/comments/_commentable.html.erb @@ -0,0 +1,159 @@ + + + diff --git a/app/views/comments/_confirm_delete.html.erb b/app/views/comments/_confirm_delete.html.erb new file mode 100755 index 0000000..a7cde8c --- /dev/null +++ b/app/views/comments/_confirm_delete.html.erb @@ -0,0 +1,5 @@ +

    <%= ts("Are you sure you want to delete this comment?") %>

    + \ No newline at end of file diff --git a/app/views/comments/_single_comment.html.erb b/app/views/comments/_single_comment.html.erb new file mode 100755 index 0000000..c87a82a --- /dev/null +++ b/app/views/comments/_single_comment.html.erb @@ -0,0 +1,78 @@ + +
  • + <% if params[:edit_comment_id] && params[:edit_comment_id] == single_comment.id.to_s && can_edit_comment?(single_comment) %> + + <%= render 'comments/comment_form', + :comment => single_comment, + :commentable => single_comment.commentable, + :button_name => ts('Update') %> + <% else %> + <% if single_comment.is_deleted %> +

    + <%= ts("(Previous comment deleted.)") %> +

    + <% elsif !can_see_hidden_comment?(single_comment) %> +

    <%= ts("(This comment is under review by an admin and is currently unavailable.)") %>

    + <% else %> + <%# FRONT END, update this if a.user comes in %> + + <% cache([single_comment, single_comment.comment_owner, "body", image_safety_mode_cache_key(single_comment)], expires_in: 1.week) do %> +
    + <% if !single_comment.pseud.nil? %> + <% if single_comment.by_anonymous_creator? %> + + <% else %> + <%= icon_display(single_comment.pseud.user, single_comment.pseud) %> + <% end %> + <% else %> + + <% end %> +
    + <% unless single_comment.approved? %> +

    <%= ts("This comment has been marked as spam.") %>

    + <% end %> + <% if single_comment.hidden_by_admin? %> +

    <%= ts("This comment has been hidden by an admin.") %>

    + <% end %> +
    + <%= raw single_comment.sanitized_content %> +
    + <% end %> + <% if single_comment.edited_at.present? %> +

    + <%= ts("Last Edited") %> <%= time_in_zone(single_comment.edited_at) %> +

    + <% end %> + + <% if policy(single_comment).show_email? && single_comment.email.present? %> + + <% end %> + <% if policy(:user_creation).show_ip_address? %> +

    <%= ts("IP Address: %{ip_address}", ip_address: single_comment.ip_address.blank? ? "No address recorded" : single_comment.ip_address) %>

    + <% end %> + <%= render "comments/comment_actions", comment: single_comment %> + <% end %> + <% end %> +
  • + diff --git a/app/views/comments/add_comment_reply.js.erb b/app/views/comments/add_comment_reply.js.erb new file mode 100755 index 0000000..e705f81 --- /dev/null +++ b/app/views/comments/add_comment_reply.js.erb @@ -0,0 +1,5 @@ +/* hide redundant navigation */ +$j("#navigation_for_comment_<%= "#{@commentable.id}" %>").hide(); +/* render the form into the spot for it on the page */ +$j("#add_comment_reply_placeholder_<%= "#{@commentable.id}" %>").html("<%= escape_javascript(render :partial => "comments/comment_form", :locals => {:comment => @comment, :commentable => @commentable, :button_name => ts("Comment")}) %>"); +$j("#add_comment_reply_placeholder_<%= "#{@commentable.id}" %>").show(); diff --git a/app/views/comments/cancel_comment_delete.js.erb b/app/views/comments/cancel_comment_delete.js.erb new file mode 100755 index 0000000..f753499 --- /dev/null +++ b/app/views/comments/cancel_comment_delete.js.erb @@ -0,0 +1,5 @@ +/* hide, then remove the delete confirmation form */ +$j("#delete_comment_placeholder_<%= "#{@comment.id}" %>").slideUp(); +$j("#delete_comment_placeholder_<%= "#{@comment.id}" %>").html(""); +/* unhide the navigation */ +$j("#navigation_for_comment_<%= "#{@comment.id}" %>").show(); diff --git a/app/views/comments/cancel_comment_edit.js.erb b/app/views/comments/cancel_comment_edit.js.erb new file mode 100755 index 0000000..9a1d6a0 --- /dev/null +++ b/app/views/comments/cancel_comment_edit.js.erb @@ -0,0 +1,11 @@ +<% comment_field_id = "#comment_#{@comment.id}" %> +/* roll up the comment form */ +$j("<%= comment_field_id %>").slideUp(); +/* render the comment again + must use replaceWith() rather than html() because the single_comment partial already contains the comment li + and we would end up with li within li for the same comment + */ +$j("<%= comment_field_id %>").replaceWith("<%= escape_javascript(render :partial => "comments/single_comment", + :locals => {:single_comment => @comment, :commentable => @comment.commentable}) %>"); +/* roll down the comment */ +$j("<%= comment_field_id %>").slideDown(); diff --git a/app/views/comments/cancel_comment_reply.js.erb b/app/views/comments/cancel_comment_reply.js.erb new file mode 100755 index 0000000..37e68b0 --- /dev/null +++ b/app/views/comments/cancel_comment_reply.js.erb @@ -0,0 +1,5 @@ +/* unhide the original navigation */ +$j("#navigation_for_comment_<%= "#{@commentable.id}" %>").show(); +/* get rid of the comment form */ +$j("#add_comment_reply_placeholder_<%= "#{@commentable.id}" %>").slideUp(); +$j("#add_comment_reply_placeholder_<%= "#{@commentable.id}" %>").html(""); diff --git a/app/views/comments/delete_comment.js.erb b/app/views/comments/delete_comment.js.erb new file mode 100755 index 0000000..1efdaff --- /dev/null +++ b/app/views/comments/delete_comment.js.erb @@ -0,0 +1,5 @@ +/* hide redundant navigation */ +$j("#navigation_for_comment_<%= "#{@comment.id}" %>").hide(); +/* render the delete confirmation form into its spot, then make it visible */ +$j("#delete_comment_placeholder_<%= "#{@comment.id}" %>").html("<%= escape_javascript(render :partial => "comments/confirm_delete", :locals => {:comment => @comment}) %>"); +$j("#delete_comment_placeholder_<%= "#{@comment.id}" %>").slideDown(); diff --git a/app/views/comments/edit.html.erb b/app/views/comments/edit.html.erb new file mode 100755 index 0000000..0bd7dd7 --- /dev/null +++ b/app/views/comments/edit.html.erb @@ -0,0 +1,21 @@ + +

    <%= t(".page_heading") %>

    + +<%= error_messages_for :comment %> + + + + + + +
  • + <%= render partial: "comments/comment_form", locals: { comment: @comment, commentable: @comment.commentable, button_name: t(".update") } %> +
  • + + + + + diff --git a/app/views/comments/edit.js.erb b/app/views/comments/edit.js.erb new file mode 100755 index 0000000..7551ccd --- /dev/null +++ b/app/views/comments/edit.js.erb @@ -0,0 +1,8 @@ +<% comment_field_id = "#comment_#{@comment.id}" %> +/* roll up the original comment */ +$j("<%= comment_field_id %>").slideUp(); +/* render the comment form in its place */ +$j("<%= comment_field_id %>").html("<%= escape_javascript(render partial: "comments/comment_form", + locals: { comment: @comment, commentable: @comment.commentable, button_name: t(".update"), show_errors: true }) %>"); +/* roll down the comment form */ +$j("<%= comment_field_id %>").slideDown(); diff --git a/app/views/comments/hide_comments.js.erb b/app/views/comments/hide_comments.js.erb new file mode 100755 index 0000000..2d14bd4 --- /dev/null +++ b/app/views/comments/hide_comments.js.erb @@ -0,0 +1,7 @@ +/* replace the top "Hide Comments" link on works with "Comments" */ +$j("#show_comments_link_top").html("<%= escape_javascript(show_hide_comments_link(@commentable)) %>"); +/* replace the "Hide Comments (#) link with "Comments (#)" */ +$j("#show_comments_link").html("<%= escape_javascript(show_hide_comments_link(@commentable, :show_count => true)) %>"); +/* roll up, then remove the comments */ +$j("#comments_placeholder").slideUp(); +$j("#comments_placeholder").html(""); diff --git a/app/views/comments/index.html.erb b/app/views/comments/index.html.erb new file mode 100755 index 0000000..93b0294 --- /dev/null +++ b/app/views/comments/index.html.erb @@ -0,0 +1,10 @@ + +

    <%= title_for_comment_page(@commentable) %>

    + + + +<%= render "comments/commentable", commentable: @commentable %> + + + + diff --git a/app/views/comments/new.html.erb b/app/views/comments/new.html.erb new file mode 100755 index 0000000..1802d05 --- /dev/null +++ b/app/views/comments/new.html.erb @@ -0,0 +1,17 @@ + +

    <%= ts("New comment on %{name}", :name => @name) %>

    +<%= error_messages_for :comment %> + + + +<%= render :partial => 'comments/comment_form', :locals => { + :comment => @comment, + :commentable => @commentable, + :button_name => ts("Comment") + } +%> + + + + + diff --git a/app/views/comments/review.js.erb b/app/views/comments/review.js.erb new file mode 100755 index 0000000..9576742 --- /dev/null +++ b/app/views/comments/review.js.erb @@ -0,0 +1,10 @@ +<% comment_container_id = "#feedback_comment_#{@comment.id}" %> +<% read_comment_form_id = "#read_comment_form_#{@comment.id}" %> +<% review_comment_list_item_id = "#review_comment_link_#{@comment.id}" %> +<% reply_button_html = "#{j render('inbox/reply_button', feedback_comment: @comment)}" %> + +$j("<%= comment_container_id %>").toggleClass("unreviewed unread read"); +$j("<%= comment_container_id %>").children("h4").children(".unreviewed").remove(); +$j("<%= comment_container_id %>").children(".actions").find(".unread").remove(); +$j("<%= read_comment_form_id %>").remove(); +$j("<%= review_comment_list_item_id %>").replaceWith("
  • " + "<%= reply_button_html.html_safe %>" + "
  • "); diff --git a/app/views/comments/show.html.erb b/app/views/comments/show.html.erb new file mode 100755 index 0000000..06290d6 --- /dev/null +++ b/app/views/comments/show.html.erb @@ -0,0 +1,7 @@ +<%= flash_div :comment_error, :comment_notice %> + +

    + <%= t(".comment_on_html", commentable_link: link_to_comment_ultimate_parent(@comment)) %> +

    + +<%= render :partial => 'comments/comment_thread', :locals => { :comments => @comments, :depth => 0 } %> diff --git a/app/views/comments/show_comments.js.erb b/app/views/comments/show_comments.js.erb new file mode 100755 index 0000000..79089b4 --- /dev/null +++ b/app/views/comments/show_comments.js.erb @@ -0,0 +1,11 @@ +/* replace the top "Comments" link on works with "Hide Comments" */ +$j("#show_comments_link_top").html("<%= escape_javascript(show_hide_comments_link(@commentable, :link_type => "hide")) %>"); +/* replace the top "Comments (#)" link with "Hide Comments (#)" */ +$j("#show_comments_link").html("<%= escape_javascript(show_hide_comments_link(@commentable, :link_type => "hide", :show_count => true)) %>"); +/* load up the comments in their placeholder div */ +$j("#comments_placeholder").html("<%= escape_javascript(will_paginate(@comments, {:remote => true})) %>"); +$j("#comments_placeholder").append("<%= escape_javascript(render "comments/comment_thread", {:comments => @comments, :depth => 0}) %>"); +$j("#comments_placeholder").append(""); +$j("#comments_placeholder").append("<%= escape_javascript(will_paginate(@comments, {:remote => true})) %>"); +/* roll down the comments */ +$j("#comments_placeholder").slideDown(); diff --git a/app/views/comments/unreviewed.html.erb b/app/views/comments/unreviewed.html.erb new file mode 100755 index 0000000..f70d576 --- /dev/null +++ b/app/views/comments/unreviewed.html.erb @@ -0,0 +1,31 @@ + +

    <%= t(".page_heading_html", commentable_link: link_to(@commentable.commentable_name, @commentable)) %>

    + + + +<% if can_review_all_comments?(@commentable) %> + +<% end %> + + + +<%# i18n-tasks-use t("comments.unreviewed.note.admin_post") + i18n-tasks-use t("comments.unreviewed.note.work") %> +

    <%= t(".note.#{@commentable.model_name.i18n_key}") %>

    + +<% if @comments.count > 0 %> + <%= will_paginate @comments %> + <% @comments.each do |comment| %> + <%= render partial: "comments/single_comment", object: comment %> + <% end %> + <%= will_paginate @comments %> +<% else %> +

    <%= t(".no_unreviewed") %>

    +<% end %> + + + + diff --git a/app/views/comments/update.js.erb b/app/views/comments/update.js.erb new file mode 100755 index 0000000..59440ba --- /dev/null +++ b/app/views/comments/update.js.erb @@ -0,0 +1,11 @@ +<% comment_field_id = "#comment_#{@comment.id}" %> +/* roll up the comment form */ +$j("<%= comment_field_id %>").slideUp(); +/* render the updated comment + must use replaceWith() rather than html() because the single_comment partial already contains the comment li + and we would end up with li within li for the same comment + */ +$j("<%= comment_field_id %>").replaceWith("<%= escape_javascript(render :partial => "comments/single_comment", + :locals => {:single_comment => @comment, :commentable => @comment.commentable}) %>"); +/* roll down the updated comment */ +$j("<%= comment_field_id %>").slideDown(); diff --git a/app/views/creatorships/show.html.erb b/app/views/creatorships/show.html.erb new file mode 100755 index 0000000..e513b36 --- /dev/null +++ b/app/views/creatorships/show.html.erb @@ -0,0 +1,63 @@ + +

    <%= ts("Co-Creator Requests") %>

    + + + + + + +<%= will_paginate @creatorships %> +<% if @creatorships.blank? %> +

    <%= ts("No co-creator requests found.") %>

    +<% else %> + <%= form_tag user_creatorships_path(@user, page: params[:page]), method: :put do %> +
    + <%= ts("Mass Edit Options") %> + + +
    + +
    + <%= ts("List of Co-Creator Requests") %> + + + + + + + + + + <%= collection_check_boxes "", :selected, @creatorships, :id, :id do |builder| %> + <% creatorship = builder.object %> + <% next unless (creation = creatorship.creation) %> + + + + + + + + <% end %> +
    <%= ts("Creation") %><%= ts("Type") %><%= ts("Invited Pseud") %><%= ts("Date") %><%= ts("Selected?") %>
    <%= link_to title_for_creation(creation), creation %><%= creatorship.creation_type %><%= creatorship.pseud.name %><%= set_format_for_date(creatorship.created_at) %><%= builder.check_box %>
    +
    + +
    + <%= ts("Mass Edit Options") %> + + +
    + <% end %> +<% end %> +<%= will_paginate @creatorships %> + diff --git a/app/views/downloads/_download_afterword.html.erb b/app/views/downloads/_download_afterword.html.erb new file mode 100755 index 0000000..5ae55c1 --- /dev/null +++ b/app/views/downloads/_download_afterword.html.erb @@ -0,0 +1,32 @@ +
    +

    <%= t(".afterword") %>

    + + <% unless @work.endnotes.blank? && @work.approved_children.blank? %> +
    + <% unless @work.endnotes.blank? %> +
    +

    <%= t(".end_notes") %>

    +
    <%= raw sanitize_field(@work, :endnotes) %>
    +
    + <% end %> + + <%# i18n-tasks-use t("downloads.download_afterword.inspired_by.restricted_html") %> + <%# i18n-tasks-use t("downloads.download_afterword.inspired_by.revealed_html") %> + <%# i18n-tasks-use t("downloads.download_afterword.inspired_by.unrevealed") %> + <% if @work.approved_children.present? %> +
    +
    <%= t(".inspired_by.title") %>
    + <% for child_work in @work.approved_related_works %> + <% next if child_work.translation %> + +
    + <%= related_work_note(child_work.work, "inspired_by", download: true) %> +
    + <% end %> +
    + <% end %> +
    + <% end %> + +

    <%= t(".please_comment_html", comment_link: link_to(t(".comment"), new_work_comment_url(@work))) %>

    +
    diff --git a/app/views/downloads/_download_chapter.html.erb b/app/views/downloads/_download_chapter.html.erb new file mode 100755 index 0000000..55ae51d --- /dev/null +++ b/app/views/downloads/_download_chapter.html.erb @@ -0,0 +1,39 @@ +<% @chapter = chapter if defined?(chapter) %> + +
    +

    <%= @chapter.chapter_title.html_safe %>

    + <% if (!@chapter.pseuds.blank? && (@chapter.pseuds != @work.pseuds) && (!@work.anonymous?)) %> + <%# only display byline if different from the main byline %> + + <% end %> + + <% unless @chapter.summary.blank? %> +

    <%= t(".chapter_summary") %>

    +
    <%= raw sanitize_field(@chapter, :summary) %>
    + <% end %> + + <% unless @chapter.notes.blank? && @chapter.endnotes.blank? %> +

    <%= t(".chapter_notes") %>

    + <% unless @chapter.notes.blank? %> +
    <%= raw sanitize_field(@chapter, :notes) %>
    + <% end %> + <% unless @chapter.endnotes.blank? %> + + <% end %> + <% end %> +
    + + +
    + <%= raw defined?(@content) ? @content : sanitize_field(@chapter, :content) %> +
    + + +<% unless @chapter.endnotes.blank? %> +
    +

    <%= t(".section_chapter_end_notes") %>

    +
    <%= raw sanitize_field(@chapter, :endnotes) %>
    +
    +<% end %> diff --git a/app/views/downloads/_download_preface.html.erb b/app/views/downloads/_download_preface.html.erb new file mode 100755 index 0000000..08cf5c3 --- /dev/null +++ b/app/views/downloads/_download_preface.html.erb @@ -0,0 +1,92 @@ +
    +

    <%= t(".preface") %>

    + +

    + <%= @work.title %>
    + <%= t(".originally_posted_html", + archive_link: link_to(ArchiveConfig.APP_NAME, root_url), + work_url: link_to(work_url(@work), work_url(@work))) %> +

    + +
    +
    + <% Tag::VISIBLE.each do |type| %> + <% tags = @work.tag_groups[type] %> + <% unless tags.blank? %> +
    <%= t(".tag_type", tag_type: tags.size == 1 ? type.constantize::NAME : type.constantize::NAME.pluralize) %>
    +
    <%= safe_join(tags.map { |t| link_to(t.display_name, tag_url(t)) }, t("support.array.words_connector")) %>
    + <% end %> + <% end %> + + <% unless @work.language.blank? %> +
    <%= t(".language") %>
    +
    <%= @work.language.name %>
    + <% end %> + + <% series_list = @work.serial_works.reject { |sw| sw.series.nil? } %> + <% unless series_list.blank? %> +
    <%= t(".series") %>
    +
    <%= safe_join(series_list.map { |s| t(".series_list_html", position: s.position, series_link: link_to(s.series.title, series_url(s.series))) }, t("support.array.words_connector")) %>
    + <% end %> + <% unless @work.approved_collections.empty? %> +
    <%= t(".collections") %>
    +
    <%= safe_join(@work.approved_collections.map { |c| link_to(c.title, collection_url(c)) }, t("support.array.words_connector")) %>
    + <% end %> +
    <%= t(".stats") %>
    +
    + <%= t(".published", date: l(@work.first_chapter.published_at)) %> + <% if @work.first_chapter.published_at < @work.revised_at.to_date %> + <%= @work.is_wip ? t(".updated", date: l(@work.revised_at.to_date)) : t(".completed", date: l(@work.revised_at.to_date)) %> + <% end %> + <%= t(".words", count_with_delimiters: number_with_delimiter(@work.word_count)) %> + <%= t(".chapters", chapter_total_display: chapter_total_display(@work)) %> +
    +
    +

    <%= @work.title %>

    + + <% unless @work.summary.blank? %> +

    <%= t(".summary") %>

    +
    <%= raw sanitize_field(@work, :summary) %>
    + <% end %> + + <% unless @work.notes.blank? && @work.endnotes.blank? %> +

    <%= t(".notes") %>

    + <% unless @work.notes.blank? %> +
    <%= raw sanitize_field(@work, :notes) %>
    + <% end %> + <% unless @work.endnotes.blank? %> + + <% end %> + <% end %> + + <%# i18n-tasks-use t("downloads.download_preface.translated_to.restricted_html") %> + <%# i18n-tasks-use t("downloads.download_preface.translated_to.revealed_html") %> + <%# i18n-tasks-use t("downloads.download_preface.translated_to.unrevealed_html") %> + <%# i18n-tasks-use t("downloads.download_preface.inspired_by.restricted_html") %> + <%# i18n-tasks-use t("downloads.download_preface.inspired_by.revealed_html") %> + <%# i18n-tasks-use t("downloads.download_preface.inspired_by.unrevealed") %> + <%# i18n-tasks-use t("downloads.download_preface.translation_of.restricted_html") %> + <%# i18n-tasks-use t("downloads.download_preface.translation_of.revealed_html") %> + <%# i18n-tasks-use t("downloads.download_preface.translation_of.unrevealed") %> + <% translations = @work.approved_related_works.where(translation: true) %> + <% related_works = @work.parent_work_relationships.reject { |wr| !wr.parent } %> + <% if translations.any? || related_works.any? %> +
      + <% translations.each do |related_work| %> +
    • + <%= related_work_note(related_work.work, "translated_to", download: true) %> +
    • + <% end %> + <% related_works.each do |work| %> +
    • + <% relation = work.translation ? "translation_of" : "inspired_by" %> + <%= related_work_note(work.parent, relation, download: true) %> +
    • + <% end %> +
    + <% end %> + +
    +
    diff --git a/app/views/downloads/show.html.erb b/app/views/downloads/show.html.erb new file mode 100755 index 0000000..03feed1 --- /dev/null +++ b/app/views/downloads/show.html.erb @@ -0,0 +1,17 @@ +<%= render "downloads/download_preface" %> + +
    + <% if @chapters.size > 1 %> + <% for chapter in @chapters %> + <%= render "downloads/download_chapter", chapter: chapter %> + <% end %> + <%# Use elsif so we don't error when there are no chapters. %> + <% elsif @chapters.size == 1 %> +

    <%= @work.title %>

    +
    + <%= raw sanitize_field(@chapters.first, :content) %> +
    + <% end %> +
    + +<%= render "downloads/download_afterword" %> diff --git a/app/views/errors/403.html.erb b/app/views/errors/403.html.erb new file mode 100755 index 0000000..d857368 --- /dev/null +++ b/app/views/errors/403.html.erb @@ -0,0 +1,3 @@ +

    Error 403

    +

    Forbidden

    +

    You do not have permission to access the requested file on this server.

    diff --git a/app/views/errors/404.html.erb b/app/views/errors/404.html.erb new file mode 100755 index 0000000..1571cad --- /dev/null +++ b/app/views/errors/404.html.erb @@ -0,0 +1,8 @@ +

    Error 404

    +

    The page you were looking for doesn't exist.

    +<% if defined? @message %> +

    + <%= @message %> +

    +<% end %> +

    You may have mistyped the address or the page may have been deleted.

    diff --git a/app/views/errors/422.html.erb b/app/views/errors/422.html.erb new file mode 100755 index 0000000..1a12605 --- /dev/null +++ b/app/views/errors/422.html.erb @@ -0,0 +1,3 @@ +

    Error 422

    +

    The change you wanted was rejected.

    +

    Maybe you tried to change something you didn't have access to.

    diff --git a/app/views/errors/500.html.erb b/app/views/errors/500.html.erb new file mode 100755 index 0000000..669f044 --- /dev/null +++ b/app/views/errors/500.html.erb @@ -0,0 +1,3 @@ +

    Error 500

    +

    We're sorry, but something went wrong.

    +

    If you are receiving this error repeatedly, please <%= link_to ts('contact Support'), new_feedback_report_path %>. In the form, please include a link to the page you're trying to reach and how you're trying to reach this page.

    diff --git a/app/views/errors/auth_error.html.erb b/app/views/errors/auth_error.html.erb new file mode 100755 index 0000000..47956f3 --- /dev/null +++ b/app/views/errors/auth_error.html.erb @@ -0,0 +1,2 @@ +

    Session Expired

    +

    Your current session has expired and we can't authenticate your request. Try logging in again, refreshing the page, or clearing your cache if you continue to experience problems.

    diff --git a/app/views/errors/timeout_error.html.erb b/app/views/errors/timeout_error.html.erb new file mode 100755 index 0000000..81df9fb --- /dev/null +++ b/app/views/errors/timeout_error.html.erb @@ -0,0 +1,3 @@ +

    <%= t(".page_heading") %>

    +

    <%= t(".subtitle") %>

    +

    <%= t(".html", contact_support_link: link_to(t(".contact_support"), new_feedback_report_path)) %>

    diff --git a/app/views/external_authors/_external_author_blurb.html.erb b/app/views/external_authors/_external_author_blurb.html.erb new file mode 100755 index 0000000..90d5302 --- /dev/null +++ b/app/views/external_authors/_external_author_blurb.html.erb @@ -0,0 +1,19 @@ +
  • + <%= render "external_authors/external_author_description", :external_author => external_author %> + + +
  • diff --git a/app/views/external_authors/_external_author_description.html.erb b/app/views/external_authors/_external_author_description.html.erb new file mode 100755 index 0000000..275cd7e --- /dev/null +++ b/app/views/external_authors/_external_author_description.html.erb @@ -0,0 +1,35 @@ +<% # expects "external_author" local %> +

    <%= ts("External Author Listing") %>

    + +

    "> + <%= external_author.email %> + <% if !@user && external_author.is_claimed? %> + (Claimed by <%= link_to external_author.user.login, external_author.user %>) + <% end %> +

    + +<% if external_author.do_not_import %> +

    + <%= ts("No imports may be made for this email address.") %> +

    +<% end %> + +<% if external_author.do_not_email %> +

    + <%= ts("No import notifications may be sent to this email address.") %> +

    +<% end %> + +

    Names used:

    +
      + <% external_author.external_author_names.pluck(:name).each do |name| %> +
    • <%= name %>
    • + <% end %> +
    + +

    Imported Works:

    +
      + <% external_author.external_creatorships.each do |ext_creatorship| %> +
    • <%= link_to(ext_creatorship.creation.title, work_path(ext_creatorship.creation)) %>
    • + <% end %> +
    diff --git a/app/views/external_authors/_external_author_form.html.erb b/app/views/external_authors/_external_author_form.html.erb new file mode 100755 index 0000000..50efa7f --- /dev/null +++ b/app/views/external_authors/_external_author_form.html.erb @@ -0,0 +1,38 @@ +<%= form_for([@user, @external_author]) do |f| %> + <%= error_messages_for @external_author %> +
    + External Author Identity +
    +
    <%= f.label :email %>
    +
    <%= f.text_field :email %>
    +
    +
    + +
    + External Author Names + <%= f.fields_for :external_author_names do |name_form| %> + <%= render :partial => 'external_author_name', :locals => {:form => name_form} %> + <% end %> + +

    <%= add_name_link(f) %>

    +
    + +
    + External Author Preferences +
    +
    <%= f.label :do_not_email, ts("Don't email when works are imported: ") %>
    +
    <%= f.check_box :do_not_email %>
    + +
    <%= f.label :do_not_import, ts("Don't import works: ") %>
    +
    <%= f.check_box :do_not_import %>
    +
    +
    + +
    + <%= ts("Submit") %> +

    + <%= f.submit ts("Submit") %> +

    +
    + +<% end %> diff --git a/app/views/external_authors/_external_author_name.html.erb b/app/views/external_authors/_external_author_name.html.erb new file mode 100755 index 0000000..1442461 --- /dev/null +++ b/app/views/external_authors/_external_author_name.html.erb @@ -0,0 +1,9 @@ +
    +
    +
    <%= form.label :name, t('.label_external_author_name', :default => "Name: ") %>
    +
    + <%= form.text_field :name %> + <%= remove_name_link(form) %> +
    +
    +
    \ No newline at end of file diff --git a/app/views/external_authors/_external_author_navigation.html.erb b/app/views/external_authors/_external_author_navigation.html.erb new file mode 100755 index 0000000..bc4fa6d --- /dev/null +++ b/app/views/external_authors/_external_author_navigation.html.erb @@ -0,0 +1,16 @@ + diff --git a/app/views/external_authors/claim.html.erb b/app/views/external_authors/claim.html.erb new file mode 100755 index 0000000..6a8d00f --- /dev/null +++ b/app/views/external_authors/claim.html.erb @@ -0,0 +1,121 @@ +

    <%= ts("Claiming Your Imported Works") %>

    + +

    + <%= ts("An archive including some of your work(s) has been moved to the Archive of Our Own. Please let us know what you'd + like us to do with them. If you do nothing, the work(s) will remain attached to the archivist account.") %> +

    + +

    + <%= ts("If you would like to edit the work(s), or handle different work(s) separately, please claim them first. + You can then use the Edit Works feature on your personal archive home page to orphan, delete, or edit them either + in groups or one at a time. (You will be able to delete the account if you wish after editing.)") %> +

    + +

    + <%= ts("If you want to take another look at your work(s) before you make your decision, but don’t have an Archive + account,") %> + <%= link_to ts("contact Open Doors"), "https://opendoors.transformativeworks.org/en/contact-open-doors/" %> + <%= ts("with your pseud and the titles of your work(s) and we will send you a copy.") %> +

    + +
    +

    <%= ts("Claim All Works") %>

    + + <% if logged_in? %> +

    + <%= ts("Claim your works with your logged-in account. If you would like to claim + these works under a different account (or create a new account to claim them with), log out and reload this + page first.") %> +

    +

    <%= button_to ts("Add these works to my currently-logged-in account"), complete_claim_path(invitation_token: @invitation.token) %>

    + <% else %> +

    + <%= ts("We invite you to join our beta and create an account! The works will automatically be added + to your account and you will have full control over them.") %> +

    +

    + <%= ts("If you already have an archive account, log in and reload this page, and we'll assign you the works.") %> + <%= button_to ts("Sign me up and give me my works!"), signup_path(invitation_token: @invitation.token), method: :get %> +

    + <% end %> +
    + +
    +

    <%= ts("My Imported Works") %>

    +
      + <% @external_author.works.each do |work| %> + <%= render "works/work_blurb", work: work %> + <% end %> +
    +

    + <% if logged_in? %> + <%= button_to ts("Add these works to my currently-logged-in account"), complete_claim_path(invitation_token: @invitation.token) %> + <% else %> + <%= button_to ts("Sign me up and give me my works!"), signup_path(invitation_token: @invitation.token), method: :get %> + <% end %> +

    +
    + +

    <%= ts("Other Options") %>

    +<%= form_for @external_author do |f| %> +
    + <%= ts("Other Options") %> +

    <%= ts("Actions")%>

    +
      +
    • + <%= radio_button_tag "imported_stories", "nothing" %> + <%= label_tag "imported_stories_nothing", ts("Leave my works in the care of the archivist.") %> +
    • +
    +
      +
    • + <%= hidden_field_tag :invitation_token, @invitation.token %> + <%= radio_button_tag "imported_stories", "orphan" %> + <%= label_tag "imported_stories_orphan", ts("Orphan my works and take my email address off them, but keep my name.") %> + <%= link_to ts("View orphaning FAQ"), archive_faq_path("17") %> +
        +
      • + <%= check_box_tag "remove_pseud" %> + <%= label_tag "remove_pseud", ts("Assign my works to the AO3 orphan_account, removing both my name and email address.") %> +
      • +
      +
    • +
    • + <%= radio_button_tag "imported_stories", "delete" %> + <%= label_tag "imported_stories_delete", ts("Please remove my works from the archive entirely.") %> +
    • +
    • + <%= f.check_box :do_not_import %> + <%= f.label :do_not_import, ts("From now on, do not import works with this email address.") %> +
    • +
    +

    <%= ts("Notifications") %>

    +
      +
    • + <%= f.check_box :do_not_email %> + <%= f.label :do_not_email, ts("Do not email me in the future when works are imported with this email address.") %> +
    • + +
    +

    + <%= ts("Important: If you tick \"Do not email me in future\" but do not tick \"Do not import works\", works may be imported without you being told. If that's not what you want, turn off importing as well as emails.") %> +

    + <%= submit_fieldset(f) %> +
    + +<% end %> + +
    +

    <%= ts("Wait, wait, go over this again?") %>

    +
      +
    • <%= ts("If you do nothing, the work(s) will remain attached to the archivist account.") %>
    • + <% if logged_in? %> +
    • <%= ts("You can claim your works.") %>
    • + <% else %> +
    • <%= ts("You can create an account and claim your works (if you already have an account, log in to claim them)") %>
    • + <% end %> +
    • <%= ts("You can also choose to delete or orphan your works.") %>
    • +
    • <%= ts("Orphaning keeps them in the archive so future fans can still enjoy them, but with your contact information and/or your name removed.") %>
    • +
    • <%= ts("You can also tell us not to email you or import works with this email address in the future.") %>
    • +
    +
    diff --git a/app/views/external_authors/edit.html.erb b/app/views/external_authors/edit.html.erb new file mode 100755 index 0000000..c6ec48e --- /dev/null +++ b/app/views/external_authors/edit.html.erb @@ -0,0 +1,6 @@ +

    <%= t('.edit_external_author', :default => 'Editing external author identity') %>

    + +<%= render "external_author_form" %> + + + diff --git a/app/views/external_authors/index.html.erb b/app/views/external_authors/index.html.erb new file mode 100755 index 0000000..d40471f --- /dev/null +++ b/app/views/external_authors/index.html.erb @@ -0,0 +1,52 @@ +<% if @user && current_user == @user %> +

    <%= ts("Author Identities for %{user}", :user => @user.login) %>

    + +

    + <%= ts("If an archive that includes your works is backed up to the AO3, here's where you'll get control over those works.") %> +

    + + +<% elsif current_user.archivist %> +

    <%= ts("External Authors Imported") %>

    +<% end %> + +
      + <% @external_authors.each do |external_author| %> +
    • +

      Identity: <%= external_author.external_author_names.collect(&:name).join(", ") %> +

      + <% if external_author.do_not_email %> +

      <%= ts("No notifications will be sent to this email address." ) %>

      + <% end %> + + <% if external_author.do_not_import %> +

      <%= ts("Archivists may not import works with this email." ) %>

      + <% end %> + +

      Works:

      +
        + <% external_author.external_creatorships.each do |ext_creatorship| %> +
      • <%= link_to(ext_creatorship.creation.title, work_path(ext_creatorship.creation)) %>
      • + <% end %> +
      + + <% if @user && current_user == @user %> + + <% end %> +
    • + <% end %> +
    + diff --git a/app/views/external_works/_blurb.html.erb b/app/views/external_works/_blurb.html.erb new file mode 100755 index 0000000..f36eb46 --- /dev/null +++ b/app/views/external_works/_blurb.html.erb @@ -0,0 +1,57 @@ +
  • + + +
    + +

    + <%= link_to external_work.title, external_work.url %> + <%= ts("by") %> + <%= byline(external_work) %> +

    + +
    + <%= ts("Fandoms") %>: + <% fandoms = external_work.tag_groups["Fandom"] %> + <%= fandoms.collect{ |tag| link_to_tag_works(tag) }.join(", ").html_safe if fandoms %> +
    + + <%= get_symbols_for(external_work) %> +

    <%= set_format_for_date(external_work.created_at) %>

    +
    + +

    <%= t("external_works.notice") %>

    + + +
    <%= ts('Tags') %>
    +
      + <%= blurb_tag_block(external_work) %> +
    + + + <% unless external_work.summary.blank? %> +
    <%= ts('Summary') %>
    +
    + <%=raw strip_images(sanitize_field(external_work, :summary)) %> +
    + <% end %> + + +
    + <% unless external_work.language.blank? %> +
    <%= ts("Language:") %>
    +
    <%= external_work.language.name %>
    + <% end %> + <% if Bookmark.count_visible_bookmarks(external_work) > 0 %> +
    <%= Bookmark.model_name.human(count: :many) %>:
    +
    <%= link_to_bookmarkable_bookmarks(external_work) %>
    + <% end %> + +
    <%= RelatedWork.model_name.human(count: :many) %>:
    +
    <%= link_to number_with_delimiter(external_work.related_works.count), external_work %>
    +
    + + <% if policy(external_work).show_admin_options? %> + <%= render "admin/admin_options", item: external_work %> + <% end %> + +
  • diff --git a/app/views/external_works/_work_module.html.erb b/app/views/external_works/_work_module.html.erb new file mode 100755 index 0000000..2d195fb --- /dev/null +++ b/app/views/external_works/_work_module.html.erb @@ -0,0 +1,57 @@ + +
    + +

    + <% # so bookmarks go to the external work page, not directly to the external link %> + <% if external_work ||= @bookmarkable %> + <%= link_to bookmarkable.title, bookmarkable %> + <% else %> + <%= link_to external_work.title, external_work.url %> + <% end %> + <%= ts("by") %> + <%= byline(external_work) %> +

    + +
    + <%= ts("Fandoms") %>: + <% fandoms = external_work.tag_groups["Fandom"] %> + <%= fandoms.collect{ |tag| link_to_tag_works(tag) }.join(", ").html_safe if fandoms %> +
    + + <%= get_symbols_for(external_work) %> +

    <%= set_format_for_date(external_work.created_at) %>

    +
    + +

    <%= t("external_works.notice") %>

    + + +
    <%= ts("Tags") %>
    +
      + <%= blurb_tag_block(external_work) %> +
    + + +<% unless external_work.summary.blank? %> +
    <%= ts("Summary") %>
    +
    + <%=raw strip_images(sanitize_field(external_work, :summary)) %> +
    +<% end %> + + +
    + <% unless external_work.language.blank? %> +
    <%= ts("Language:") %>
    +
    <%= external_work.language.name %>
    + <% end %> + + <% if Bookmark.count_visible_bookmarks(external_work) > 0 %> +
    <%= Bookmark.model_name.human(count: :many) %>:
    +
    <%= link_to_bookmarkable_bookmarks(external_work) %>
    + <% end %> + + <% if external_work.related_works.count > 0 %> +
    <%= RelatedWork.model_name.human(count: :many) %>:
    +
    <%= link_to number_with_delimiter(external_work.related_works.count), external_work %>
    + <% end %> +
    diff --git a/app/views/external_works/edit.html.erb b/app/views/external_works/edit.html.erb new file mode 100755 index 0000000..1347b25 --- /dev/null +++ b/app/views/external_works/edit.html.erb @@ -0,0 +1,56 @@ + +

    + <%= ts("Edit External Work") %> +

    + + + + + + +<%= form_for(@external_work, html: { class: "external work post" }) do |f| %> +

    * <%= ts("Required information") %>

    +
    + <%= ts("Work Preface") %> +
    +
    <%= f.label :url, ts("URL") + "*" %>
    +
    + <%= f.text_field :url %> +
    +
    <%= f.label :author, ts("Creator") + "*" %>
    +
    + <%= f.text_field :author, class: "observe_textlength" %> + <%= generate_countdown_html("external_work_author", + ExternalWork::AUTHOR_LENGTH_MAX) %> +
    +
    <%= f.label :title, ts("Title") + "*" %>
    +
    + <%= f.text_field :title, class: "observe_textlength" %> + <%= generate_countdown_html("external_work_title", + ArchiveConfig.TITLE_MAX) %> +
    +
    + <%= f.label :language_id, ts("Language") %> + <%= link_to_help "languages-help" %> +
    +
    + <%= f.select(:language_id, language_options_for_select(sorted_languages, "id"), prompt: " ") %> +
    +
    + <%= f.label :summary, ts("Creator's Summary") %> + <%= ts("(please copy and paste from original work)") %> +
    +
    + <%= f.text_area :summary, rows: 5, class: "observe_textlength" %> + <%= generate_countdown_html("external_work_summary", + ArchiveConfig.SUMMARY_MAX) %> +
    +
    +
    + + <%= render 'works/work_form_tags', work: @external_work, + include_blank: false %> + +

    <%= f.submit %>

    +<% end %> + diff --git a/app/views/external_works/fetch.js.erb b/app/views/external_works/fetch.js.erb new file mode 100755 index 0000000..cb20f79 --- /dev/null +++ b/app/views/external_works/fetch.js.erb @@ -0,0 +1,20 @@ +<% unless @external_work.blank? %> + $j('#external_work_author').val("<%= escape_javascript(@external_work.author.html_safe) %>").change(); + $j('#external_work_title').val("<%= escape_javascript(@external_work.title) %>").change(); + $j('#external_work_summary').val("<%= escape_javascript(@external_work.summary&.html_safe) %>").change(); + $j('#fetched').val("<%= @external_work.id %>"); + $j('#external_work_rating_string').val("<%= @external_work.rating_string %>"); + var categories = <%= @external_work.category_strings.to_json.html_safe %>; + $j('input[id^="external_work_category_strings_"]').each(function() { + $j(this).prop("checked", categories.indexOf(this.value) >= 0 ); + }); + + <% # clear existing autocompletes %> + $j("#external_work_fandom_string_autocomplete").parent().parent().find(".delete a").click() + $j("#external_work_relationship_string_autocomplete").parent().parent().find(".delete a").click() + $j("#external_work_character_string_autocomplete").parent().parent().find(".delete a").click() + + $j('#external_work_fandom_string_autocomplete').val("<%= @external_work.fandom_string %>"); + $j('#external_work_relationship_string_autocomplete').val("<%= @external_work.relationship_string %>"); + $j('#external_work_character_string_autocomplete').val("<%= @external_work.character_string %>"); +<% end %> diff --git a/app/views/external_works/index.html.erb b/app/views/external_works/index.html.erb new file mode 100755 index 0000000..4f5368f --- /dev/null +++ b/app/views/external_works/index.html.erb @@ -0,0 +1,23 @@ +

    External Works

    + + +<% if logged_in_as_admin? %> + +<% end %> + +<%= will_paginate @external_works %> + +<% unless @external_works.blank? %> +

    Listing External Works

    + +
      + <% for external_work in @external_works %> + <%= render "external_works/blurb", { external_work: external_work } %> + <% end %> +
    + + <%= will_paginate @external_works %> +<% end %> diff --git a/app/views/external_works/new.html.erb b/app/views/external_works/new.html.erb new file mode 100755 index 0000000..4ba948a --- /dev/null +++ b/app/views/external_works/new.html.erb @@ -0,0 +1,2 @@ +

    <%= ts("Bookmark an external work") %>

    +<%= render 'bookmarks/bookmark_form', :bookmarkable => @bookmarkable, :bookmark => @bookmark, :button_name => ts("Create"), :action => 'create' %> diff --git a/app/views/external_works/show.html.erb b/app/views/external_works/show.html.erb new file mode 100755 index 0000000..b8c71ac --- /dev/null +++ b/app/views/external_works/show.html.erb @@ -0,0 +1,6 @@ +<% unless @external_work.blank? %> +

    <%= ts('External Work') %>

    +
      + <%= render 'external_works/blurb', external_work: @external_work %> +
    +<% end %> diff --git a/app/views/fandoms/index.html.erb b/app/views/fandoms/index.html.erb new file mode 100755 index 0000000..4dc171f --- /dev/null +++ b/app/views/fandoms/index.html.erb @@ -0,0 +1,61 @@ + +

    + <% if @collection %> + <%= link_to(@collection.title, @collection) %> > <%= t(".page_heading") %> + <% elsif @medium %> + <%= link_to t(".page_heading"), media_index_path %> > <%= @medium.name %> + <% else %> + <%= link_to t(".page_heading"), media_index_path %> + <% end %> +

    +

    You can search this page by pressing ctrl F / cmd F and typing in what you are looking for.

    +<% if @collection %> +

    <%= ts("Filters") %>

    + <%= form_tag "", method: :get, class: "filter", id: "media-filter" do %> +
    +

    "> + <%= select_tag :media_id, options_for_select(["All Media Types"] + @media.map(&:name), params[:media_id]) %> + <%= submit_tag ts("Show") %> +

    +
    + <% end %> +<% end %> + + + +<% if @fandoms_by_letter && !@fandoms_by_letter.empty? %> +

    <%= ts("Alphabet Navigation") %>

    + +

    <%= ts("Alphabetised List of Fandoms") %>

    +
      "> + <% @fandoms_by_letter.each_pair do |letter, fandoms| %> +
    1. +

      + <%= letter %> + + <%= link_to "↑".html_safe, "#alphabet" %> + +

      +
        + <% for fandom in fandoms %> +
      • + <%= link_to_tag_works(fandom, collection: @collection) %> + <% if fandom.respond_to?(:count) %> + (<%= fandom.count %>) + <% elsif @counts&.key?(fandom.id) %> + (<%= @counts[fandom.id] %>) + <% end %> +
      • + <% end %> +
      +
    2. + <% end %> +
    +<% else %> +

    <%= ts("No fandoms found") %>

    +<% end %> + diff --git a/app/views/fandoms/show.html.erb b/app/views/fandoms/show.html.erb new file mode 100755 index 0000000..2937e09 --- /dev/null +++ b/app/views/fandoms/show.html.erb @@ -0,0 +1,31 @@ + +

    <%= @fandom.name %>

    + + + + + +<% cache("/v1/#{@fandom.name}", :expires_in => 20.minutes, skip_digest: true) do %> + +

    <%= ts('Relationships by Character') %>

    +<% unless @characters.blank? %> +
      + <% for character in @characters %> +
    • +

      <%= link_to character.name, tag_works_path(character) %>

      + <% unless character.relationships.empty? %> +
        + <% for relationship in character.relationships %> +
      • <%= link_to relationship.name, tag_works_path(relationship) %>
      • + <% end %> +
      + <% end %> +
    • + <% end %> +
    +<% end %> +<% end %> + diff --git a/app/views/fandoms/unassigned.html.erb b/app/views/fandoms/unassigned.html.erb new file mode 100755 index 0000000..ec6f879 --- /dev/null +++ b/app/views/fandoms/unassigned.html.erb @@ -0,0 +1,62 @@ + +

    <%= ts("Fandoms in Need of a Wrangler") %>

    + + + +<% # Filters button for narrow screens jumps to filters when JavaScript is disabled and opens filters when JavaScript is enabled %> + + + +<%= will_paginate(@fandoms) %> + + +

    <%= ts("Listing Fandoms") %>

    + +<% unless @fandoms.blank? %> +
      + <% for fandom in @fandoms %> +
    • + <%= link_to fandom.name + " (#{fandom.count})", {:controller => :tags, :action => :show, :id => fandom.to_param} %> +
    • + <% end %> +
    +<% end %> + + +<%= form_tag unassigned_fandoms_path, + method: :get, + class: 'narrow-hidden filters', + id: 'fandom-filters' do %> + <%= field_set_tag ts('Filter results:') do %> +

    <%= ts('Filters') %>

    +
    +
    <%= ts("Submit") %>
    +
    <%= submit_tag ts('Sort and Filter') %>
    +
    <%= label_tag :sort, ts("Sort by") %>
    +
    + <%= select_tag :sort, options_for_select({'Name' => 'name', 'Work Count' => 'count'}, params[:sort]) %> +
    +
    <%= label_tag :media_id, ts("Media") %>
    +
    + <%= select_tag :media_id, options_for_select([''] + Media.canonical.by_name.map{|m| m.name}, params[:media_id]) %> +
    +
    <%= ts("Submit") %>
    +
    <%= submit_tag ts('Sort and Filter') %>
    +
    + <% end %> + <% # On narrow screens, link jumps to top of index when JavaScript is disabled and closes filters when JavaScript is enabled %> + +<% end %> + + +<%= will_paginate(@fandoms) %> \ No newline at end of file diff --git a/app/views/favorite_tags/_form.html.erb b/app/views/favorite_tags/_form.html.erb new file mode 100755 index 0000000..7c52c1c --- /dev/null +++ b/app/views/favorite_tags/_form.html.erb @@ -0,0 +1,13 @@ +<% # expects favorite_tag and current_user %> +<%= form_for([current_user, favorite_tag], + method: favorite_tag.new_record? ? 'post' : 'delete', + html: { + class: 'ajax-create-destroy', + data: { + create_value: ts('Favorite Tag'), + destroy_value: ts('Unfavorite Tag') + } + }) do |f| %> + <%= f.hidden_field :tag_id %> + <%= f.submit favorite_tag.new_record? ? ts('Favorite Tag') : ts('Unfavorite Tag') %> +<% end %> diff --git a/app/views/feedbacks/new.html.erb b/app/views/feedbacks/new.html.erb new file mode 100755 index 0000000..4392909 --- /dev/null +++ b/app/views/feedbacks/new.html.erb @@ -0,0 +1,99 @@ + +<%= error_messages_for :feedback %> + +

    <%= t(".heading.page_title") %>

    + + + +

    <%= t(".heading.landmark.reference") %>

    + + + + +<% if @admin_setting.disable_support_form %> +
    + <%= raw sanitize_field(@admin_setting, :disabled_support_form_text) %> +
    +<% else %> +

    <%= t(".heading.instructions") %>

    +
    +

    <%= t(".status.current", twitter_link: link_to(t(".status.twitter"), "https://twitter.com/AO3_Status"), tumblr_link: link_to(t(".status.tumblr"), "https://ao3org.tumblr.com")).html_safe %>

    +

    <%= t(".abuse.reports", contact_link: link_to(t(".abuse.contact"), new_abuse_report_path)).html_safe %>

    +

    <%= t(".reportable.intro") %>

    +
      +
    • <%= t(".reportable.fnok.concerning_html", fnok_link: link_to(t(".reportable.fnok.fnok"), tos_faq_path(anchor: "next_of_kin"))) %>
    • +
    • <%= t(".reportable.bugs") %>
    • +
    • <%= t(".reportable.site_questions") %>
    • +
    • <%= t(".reportable.account_creation") %>
    • +
    • <%= t(".reportable.lost_access") %>
    • +
    • <%= t(".reportable.tag_changes") %>
    • +
    • <%= t(".reportable.new_features") %>
    • +
    • <%= t(".reportable.orphaned_works") %>
    • +
    • <%= t(".reportable.work_problems") %>
    • +
    • <%= t(".reportable.policy_questions") %>
    • +
    +

    <%= t(".do_not_spam_html") %>

    +

    <%= t(".languages_html", list: @support_languages.map { |language| tag.span(language.name, lang: language.short) }.to_sentence.html_safe) %>

    +
    + <%= form_for(@feedback, html: {class: "post feedback"}) do |f| %> +
    + <%= t(".form.legend.contact_info") %> +
    +
    <%= f.label :username, t(".form.name.label") %>
    +
    + <%= f.text_field :username %> +
    +
    <%= f.label :email, t(".form.email.label") %>
    +
    + <%= f.text_field :email, size: 60 %> +
    +
    +
    + +
    + <%= t(".form.legend.feedback") %> + <%= f.hidden_field :referer %> +
    +
    + <%= f.label :language, t(".form.language.label") %> +
    +
    + <%= f.select(:language, language_options_for_select(@support_languages, "name"), + { selected: @feedback.language || Language.default.name }) %> +
    +
    + <%= f.label :summary, t(".form.summary.label") %> +
    +
    + <%= f.text_field :summary, size: 60, class: "observe_textlength" %> + <%= generate_countdown_html("feedback_summary", ArchiveConfig.FEEDBACK_SUMMARY_MAX_DISPLAYED) %> + <%= live_validation_for_field("feedback_summary", + failureMessage: t(".form.summary.error")) %> +
    +
    + <%= f.label :comment, t(".form.comment.label") %> +
    +
    +

    + <%= t(".form.comment.description") %> +

    + <%= f.text_area :comment, cols: 60, "aria-describedby" => "comment-field-description" %> + <%= live_validation_for_field("feedback_comment", + failureMessage: t(".form.comment.error")) %> +
    +
    +
    + +
    + <%= t(".form.legend.send") %> +

    + <%= f.submit t(".form.submit.active"), data: { disable_with: t(".form.submit.disabled") } %> +

    +
    + <% end %> +<% end %> + diff --git a/app/views/gifts/_gift_blurb.html.erb b/app/views/gifts/_gift_blurb.html.erb new file mode 100755 index 0000000..19be590 --- /dev/null +++ b/app/views/gifts/_gift_blurb.html.erb @@ -0,0 +1,10 @@ +<% # expects "work" and "gift" %> +
  • + <%= render "works/work_module", work: work %> + <% if @user && @user == current_user && (gift = work.gifts.where(:pseud_id => current_user.pseuds.pluck(:id)).first) %> +
    <%= ts("Recipient Actions") %>
    +

    + <%= link_to (gift.rejected? ? ts("Accept Gift") : ts("Refuse Gift")), toggle_rejected_gift_path(gift), method: :post %> +

    + <% end %> +
  • diff --git a/app/views/gifts/_gift_search.html.erb b/app/views/gifts/_gift_search.html.erb new file mode 100755 index 0000000..4bcc7b7 --- /dev/null +++ b/app/views/gifts/_gift_search.html.erb @@ -0,0 +1,10 @@ +<%= form_tag (@collection ? collection_gifts_path(@collection) : gifts_path), :method => :get, :id => 'gift-search', :class => 'simple search' do %> +
    + Find gifts for +

    + <%= label_tag :recipient, t('.gifts.recipient_field', :default => "Find gifts for: ")%> + <%= text_field_tag :recipient, params[:recipient], :class => 'text', :title => 'gift search' %> + <%= submit_tag t('.forms.gift_search', :default => 'Search'), :class => 'button', :name => nil %> +

    +
    +<% end %> diff --git a/app/views/gifts/index.html.erb b/app/views/gifts/index.html.erb new file mode 100755 index 0000000..df9c938 --- /dev/null +++ b/app/views/gifts/index.html.erb @@ -0,0 +1,42 @@ + +

    + <% if @user && @user == current_user && params[:refused] %> + <%= ts("Refused Gifts for %{recipient}", recipient: @user ? @user.login : h(@recipient_name)) %> + <% else %> + <%= ts("Gifts for %{recipient}", recipient: @user ? @user.login : h(@recipient_name)) %> + <% end %> + <%= @collection ? ts("in %{collection}", collection: h(@collection.title)) : "" %> +

    + + + +<% if @user && @user == current_user %> +

    <%= ts("Navigation") %>

    + +<% elsif !@user %> + <%= render 'gifts/gift_search' %> +<% end %> + + +<% if @works.respond_to?(:total_pages) %> + <%= will_paginate @works %> +<% end %> + + +

    <%= ts("List of Gifts") %>

    +
      + <% for work in @works %> + <%= render 'gifts/gift_blurb', work: work, gift: work %> + <% end %> +
    + +<% if @works.respond_to?(:total_pages) %> + <%= will_paginate @works %> +<% end %> \ No newline at end of file diff --git a/app/views/hit_count/_include.html.erb b/app/views/hit_count/_include.html.erb new file mode 100755 index 0000000..3307e12 --- /dev/null +++ b/app/views/hit_count/_include.html.erb @@ -0,0 +1,19 @@ +<% unless RedisHitCounter.prevent_hits?(@work) || current_user&.is_author_of?(@work) %> + <% content_for :footer_js do %> + + <% end %> +<% end %> diff --git a/app/views/home/_content.html.erb b/app/views/home/_content.html.erb new file mode 100755 index 0000000..be899fd --- /dev/null +++ b/app/views/home/_content.html.erb @@ -0,0 +1,21 @@ +<%# IMPORTANT: Also update current_tos_version in application_controller %> +<%# To ensure proper formatting, this must always be rendered inside an element + with the userstuff class. The userstuff element must be inside an element with + the classes "docs system". %> +

    +More information can be found here at the FAQ.
    We're pretty chill here at Sunset. We allow most forms of content, with the following exceptions: +1. Explicit RPF (real person fiction) about real people, alive or not, under the age of 18 at present or in the work; +and 2. any visual artistic depictions of characters under the age of 14 that appear hyperrealistic or could be mistaken as real. If you're not sure, you can email me at femslashclub@proton.me.

    +

    + +The only other content rule is that all works posted to Sunset must be F/F, NB/F, or NB/NB. As of October 2025, we allow gender/cisswaps of M/F, M/M, or M/NB to the archive categories, but for those works, please use the freeform tag "Canon Gender Swap". You can also optionally specify what the swap is, e.g. Canon Gender Swap - M/M to F/F, M/M/F to F/F/NB, or whatever applies. + + +Thank you! +

    + +Oh yeah, important stuff here: SUNSET IS AN 18+ ARCHIVE. Ao3 may be 13+; we are not. PLEASE do not join or attempt to join after September 2025 if you are under 18. + +

    + +

    diff --git a/app/views/home/_dmca.html.erb b/app/views/home/_dmca.html.erb new file mode 100755 index 0000000..978d039 --- /dev/null +++ b/app/views/home/_dmca.html.erb @@ -0,0 +1,188 @@ +

    + <%= t(".intro.purpose_html", + reproduce_unauthorized_link: link_to(t(".intro.reproduce_unauthorized"), tos_faq_path(anchor: "copyright_plagiarism_faq")), + uscode_link: link_to(t(".intro.uscode"), "https://www.law.cornell.edu/uscode/text/17/512")) %> +

    +

    + <%= t(".intro.legality_html", + requirements_link: link_to(t(".intro.requirements"), "#takedown_requirements"), + transformative_works_legal_link: link_to(t(".intro.transformative_works_legal"), "https://www.transformativeworks.org/faq/#faq-WhydoestheOTWbelievethattransformativeworksarelegal"), + contact_legal_link: link_to(t(".intro.contact_legal"), "https://www.transformativeworks.org/contact_us/?who=Legal%20Advocacy")) %> +

    + + + +

    <%= t(".removal.heading") %>

    +

    <%= t(".removal.intro") %>

    +
      +
    • + <%= t(".removal.abuse_report_html", + submit_abuse_bold: tag.strong(t(".removal.submit_abuse_html", + submit_abuse_link: link_to(t(".removal.submit_abuse"), new_abuse_report_path))), + tos_link: link_to(t(".removal.tos"), tos_path), + confidentiality_link: link_to(t(".removal.confidentiality"), tos_faq_path(anchor: "report_anonymity")), + tos_faq_link: link_to(t(".removal.tos_faq"), tos_faq_path(anchor: "report_infringement"))) %> +
    • +
    • + <%= t(".removal.dmca_html", + file_dmca_bold: tag.strong(t(".removal.file_dmca_html", + file_dmca_link: link_to(t(".removal.file_dmca"), "#takedown_instructions"))), + requirements_link: link_to(t(".removal.requirements"), "#takedown_requirements"), + not_confidential_link: link_to(t(".removal.not_confidential"), tos_faq_path(anchor: "dmca_complaint"))) %> +
    • +
    +

    + <%= t(".removal.do_not_spam_html", + do_not_bold: tag.strong(t(".removal.do_not"))) %> +

    + +

    <%= t(".takedown_instructions.heading") %>

    +

    + <%= t(".takedown_instructions.initiate_html", + contact_legal_link: link_to(t(".takedown_instructions.contact_legal"), "https://www.transformativeworks.org/contact_us/?who=Legal%20Advocacy")) %> +

    +
    +

    + <%= t(".takedown_instructions.address_org") %>
    + <%= t(".takedown_instructions.address_street") %>
    + <%= t(".takedown_instructions.address_state") %>
    + <%= t(".takedown_instructions.address_attn") %> +

    +
    +

    <%= t(".takedown_instructions.prefer") %>

    + +

    <%= t(".takedown_requirements.heading") %>

    +

    <%= t(".takedown_requirements.intro") %>

    +
      +
    1. <%= t(".takedown_requirements.signature") %>
    2. +
    3. <%= t(".takedown_requirements.contact") %>
    4. +
    5. <%= t(".takedown_requirements.source") %>
    6. +
    7. <%= t(".takedown_requirements.url") %>
    8. +
    9. <%= t(".takedown_requirements.good_faith") %>
    10. +
    11. +
        +
      1. <%= t(".takedown_requirements.authorized_html", + perjury_bold: tag.strong(t(".takedown_requirements.perjury"))) %>
      2. +
      3. <%= t(".takedown_requirements.accurate") %>
      4. +
      +
    12. +
    +

    <%= t(".takedown_requirements.liability") %>

    + +

    <%= t(".takedown_process.heading") %>

    +

    + <%= t(".takedown_process.valid_html", + requirements_link: link_to(t(".takedown_process.requirements"), "#takedown_requirements")) %> +

    +

    + <%= t(".takedown_process.notification_html", + lumen_link: link_to(t(".takedown_process.lumen"), "https://lumendatabase.org/")) %> +

    +

    <%= t(".takedown_process.dispute") %>

    +

    <%= t(".takedown_process.counternotify") %>

    + +

    <%= t(".appeal.heading") %>

    +

    + <%= t(".appeal.violations_html", + copyright_link: link_to(t(".appeal.copyright"), content_path(anchor: "II.D")), + plagiarism_link: link_to(t(".appeal.plagiarism"), content_path(anchor: "II.E")), + tos_link: link_to(t(".appeal.tos"), tos_path), + tos_faq_link: link_to(t(".appeal.tos_faq"), tos_faq_path(anchor: "copyright_plagiarism_faq"))) %> +

    +

    + <%= t(".appeal.removal_html", + notify_link: link_to(t(".appeal.notify"), tos_faq_path(anchor: "complaint_notification")), + lumen_link: link_to(t(".appeal.lumen"), "https://lumendatabase.org/")) %> +

    +

    + <%= t(".appeal.reupload_html", + dispute_bold: tag.strong(t(".appeal.dispute_html", cannot_italic: tag.em(t(".appeal.cannot")))), + suspend_link: link_to(t(".appeal.suspend"), "#repeat_offenses")) %> +

    + +

    <%= t(".counternotice_instructions.heading") %>

    +

    + <%= t(".counternotice_instructions.dispute_html", + defend_bold: tag.strong(t(".counternotice_instructions.defend"))) %> +

    +

    + <%= t(".counternotice_instructions.consider_html", + lumen_faq_link: link_to(t(".counternotice_instructions.lumen_faq"), "https://lumendatabase.org/topics/14")) %> +

    +

    + <%= t(".counternotice_instructions.initiate_html", + contact_legal_link: link_to(t(".counternotice_instructions.contact_legal"), "https://www.transformativeworks.org/contact_us/?who=Legal%20Advocacy")) %> +

    +
    +

    + <%= t(".counternotice_instructions.address_org") %>
    + <%= t(".counternotice_instructions.address_street") %>
    + <%= t(".counternotice_instructions.address_state") %>
    + <%= t(".counternotice_instructions.address_attn") %> +

    +
    +

    <%= t(".counternotice_instructions.prefer") %>

    +

    <%= t(".counternotice_instructions.time_limit") %>

    + +

    <%= t(".counternotice_requirements.heading") %>

    +

    <%= t(".counternotice_requirements.intro") %>

    +
      +
    1. <%= t(".counternotice_requirements.signature") %>
    2. +
    3. <%= t(".counternotice_requirements.contact") %>
    4. +
    5. <%= t(".counternotice_requirements.url") %>
    6. +
    7. <%= t(".counternotice_requirements.mistake_html", + perjury_bold: tag.strong(t(".counternotice_requirements.perjury"))) %> +
    8. +
    9. <%= t(".counternotice_requirements.consent") %> +
        +
      1. <%= t(".counternotice_requirements.usa_resident") %>
      2. +
      3. + <%= t(".counternotice_requirements.non_us_resident_html", + new_york_link: link_to(t(".counternotice_requirements.new_york"), tos_path(anchor: "I.A.3"))) %> +
      4. +
      +
    10. +
    11. <%= t(".counternotice_requirements.service") %>
    12. +
    +

    <%= t(".counternotice_requirements.liability") %>

    + +

    <%= t(".counternotice_process.heading") %>

    +

    + <%= t(".counternotice_process.valid") %> +

    +

    + <%= t(".counternotice_process.notification_html", + lumen_link: link_to(t(".counternotice_process.lumen"), "https://lumendatabase.org/")) %> +

    + +

    <%= t(".repeat.heading") %>

    +

    + <%= t(".repeat.required_html", + suspend_link: link_to(t(".repeat.suspend"), tos_faq_path(anchor: "penalty"))) %> +

    +
    +

    + + <%= t(".license.credit_html", + cc_license_link: link_to(t(".license.cc_license"), "https://creativecommons.org/licenses/by-sa/4.0/")) %> + +

    diff --git a/app/views/home/_fandoms.html.erb b/app/views/home/_fandoms.html.erb new file mode 100755 index 0000000..6d073c8 --- /dev/null +++ b/app/views/home/_fandoms.html.erb @@ -0,0 +1,11 @@ +
      +
    • <%= link_to t(".all_fandoms"), media_index_path %>
    • + <%# When changing the cache key, also update Media#expire_caches %> + <% cache "homepage-fandoms-version2", skip_digest: true do %> + <% Media.for_menu.each do |medium| %> + <% unless medium.id.nil? %> +
    • <%= link_to medium.name, media_fandoms_path(medium) %>
    • + <% end %> + <% end %> + <% end %> +
    diff --git a/app/views/home/_inbox_module.html.erb b/app/views/home/_inbox_module.html.erb new file mode 100755 index 0000000..ee0847e --- /dev/null +++ b/app/views/home/_inbox_module.html.erb @@ -0,0 +1,41 @@ +<% # expects inbox_comments %> +
    +

    + <%= ts('Unread messages') %> + <%= link_to ts('My Inbox'), user_inbox_path(current_user) %> +

    +
    +

    <%= ts('The latest unread items from your inbox.') %>

    +
      + <% inbox_comments.each do |inbox_comment| %> +
    • + <% if !can_see_hidden_comment?(inbox_comment.feedback_comment) %> +

      <%= ts("(This comment is under review by an admin and is currently unavailable.)") %>

      + <% else %> + <%= render 'inbox/inbox_comment_contents', feedback_comment: inbox_comment.feedback_comment %> + <% end %> +
        + <% if inbox_comment.feedback_comment.iced? %> +
      • <%= frozen_comment_indicator %>
      • + <% end %> + <% if inbox_comment.feedback_comment.unreviewed? %> + + <% elsif can_reply_to_comment?(inbox_comment.feedback_comment) %> +
      • + <%= render 'inbox/reply_button', feedback_comment: inbox_comment.feedback_comment %> +
      • + <% end %> +
      • + <%= render 'inbox/read_form', inbox_comment: inbox_comment, current_user: current_user %> +
      • +
      • + <%= render 'inbox/delete_form', inbox_comment: inbox_comment, current_user: current_user %> +
      • +
      +
    • + <% end %> +
    + +
    diff --git a/app/views/home/_intro_module.html.erb b/app/views/home/_intro_module.html.erb new file mode 100755 index 0000000..d4ec4a3 --- /dev/null +++ b/app/views/home/_intro_module.html.erb @@ -0,0 +1,40 @@ +
    +

    <%= ts("A fan-created, fan-run, nonprofit, noncommercial archive for transformative fanworks, like fanfiction, fanart, fan videos, and podfic") %>

    +

    <%= ts("more than %{fandom_count} fandoms | %{user_count} users | %{work_count} works", fandom_count: content_tag(:span, number_with_delimiter(@fandom_count), class: "count"), user_count: content_tag(:span, number_with_delimiter(@user_count), class: "count"), work_count: content_tag(:span, number_with_delimiter(@work_count), class: "count")).html_safe %>

    +

    <%= ts("Sunset is a project dedicated to hosting femslash (F/F, F/NB, NB/NB) fanworks.") %>

    + + +
    diff --git a/app/views/home/_news_module.html.erb b/app/views/home/_news_module.html.erb new file mode 100755 index 0000000..4ac4b39 --- /dev/null +++ b/app/views/home/_news_module.html.erb @@ -0,0 +1,35 @@ +<% # expects admin_posts %> +
    +

    + <%= ts('News') %> + <%= link_to ts('All News'), admin_posts_path %> +

    +
      + <% admin_posts.each do |admin_post| %> +
    • +
      +

      + <%= link_to admin_post.title.html_safe, admin_post %> +

      +

      + + <%= ts('Published:') %> <%= time_in_zone(admin_post.created_at) %> + + + <%= ts('Comments:') %> <%= link_to(admin_post.count_visible_comments, polymorphic_path(admin_post, show_comments: true, anchor: :comments)) %> + +

      +
      +
      + <%= first_paragraph(admin_post.content, 'No preview is available for this news post.') %> +
      +

      + <%= link_to ts('Read more...'), + admin_post, + id: "post_#{admin_post.id}_more", + :"aria-labelledby" => "post_#{admin_post.id}_more post_#{admin_post.id}_title" %> +

      +
    • + <% end %> +
    +
    diff --git a/app/views/home/_privacy.html.erb b/app/views/home/_privacy.html.erb new file mode 100755 index 0000000..066d28a --- /dev/null +++ b/app/views/home/_privacy.html.erb @@ -0,0 +1,236 @@ +<%# IMPORTANT: Also update current_tos_version in application_controller %> +<%# To ensure proper formatting, this must always be rendered inside an element + with the userstuff class. The userstuff element must be inside an element with + the classes "docs system". %> +

    <%= t(".intro.archive_description") %>

    +

    + <%= t(".intro.ao3_exists_to_host_html", + personal_information_link: link_to(t(".intro.personal_information"), "#III.A.1")) %> +

    +
      +
    • <%= t(".intro.host_your_fanworks") %>
    • +
    • <%= t(".intro.show_you_works") %>
    • +
    • <%= t(".intro.enable_post_information") %>
    • +
    +

    + <%= t(".intro.details_how_and_why_html", + common_questions_bold: tag.strong(t(".intro.answers_common_questions_html", + tos_faq_link: link_to(t(".intro.tos_faq"), tos_faq_path(anchor: "privacy_faq"))))) %> +

    + +<% unless local_assigns[:suppress_toc] %> + +<% end %> + +

    <%= t(".privacy_policy_heading") %>

    +

    <%= t(".applicability.heading") %>

    +
      +
    1. <%= t(".applicability.policy_covers") %>

    2. +
    3. +

      + <%= t(".applicability.global_subprocessors_html", + subprocessors_link: link_to(t(".applicability.subprocessors"), + "https://www.transformativeworks.org/otw_tos/organization-for-transformative-works-subprocessor-list/")) %> +

      +

      + <%= t(".applicability.transfers_necessary_html", consent_to_us_processing_bold: tag.strong(t(".applicability.consent_to_us_processing"))) %> +

      +
    4. +
    + +

    <%= t(".information_scope.heading") %>

    +
      +
    1. +

      + <%= t(".information_scope.information_in_content_html", + content_link: link_to(t(".information_scope.content"), tos_path(anchor: "I.A.1")), + special_categories_link: link_to(t(".information_scope.special_categories"), "https://gdpr-info.eu/art-9-gdpr/")) %> +

      +
    2. +
    3. <%= t(".information_scope.collect_through_use") %>

    4. +
    + +

    <%= t(".types_of_information.heading") %>

    +
      +
    1. +

      <%= t(".types_of_information.emails.heading") %>

      +

      <%= t(".types_of_information.emails.collect_process_retain") %>

      +

      + <%= t(".types_of_information.emails.address_usage_html", + challenge_link: link_to(t(".types_of_information.emails.challenge"), archive_faq_path("glossary", anchor: "challengedef"))) %> +

      +

      <%= t(".types_of_information.emails.unsubscribe") %>

      +
    2. +
    3. +

      + <%= t(".types_of_information.ip_addresses.heading") %> + <%= t(".types_of_information.ip_addresses.text") %> +

      +
    4. +
    5. +

      + <%= t(".types_of_information.logs.heading") %> + <%= t(".types_of_information.logs.text") %> +

      +
    6. +
    7. +

      + <%= t(".types_of_information.cookies.heading") %> + <%= t(".types_of_information.cookies.text") %> +

      +
    8. +
    9. +

      + <%= link_to t(".types_of_information.fnok.heading"), archive_faq_path("fannish-next-of-kin") %> + <%= t(".types_of_information.fnok.text") %> +

      +
    10. +
    11. +

      + <%= t(".types_of_information.other_information.heading") %> +

      +

      <%= t(".types_of_information.other_information.to_maintain_integrity") %>

      +

      + <%= t(".types_of_information.other_information.to_make_content_available_html", + tos_faq_link: link_to(t(".types_of_information.other_information.tos_faq"), tos_faq_path(anchor: "feature_information"))) %> +

      +
    12. +
    + +

    <%= t(".aggregate_anonymous_info.heading") %>

    +
      +
    1. <%= t(".aggregate_anonymous_info.understand_ao3_usage") %>

    2. +
    3. <%= t(".aggregate_anonymous_info.anonymous_non_personal") %>

    4. +
    + +

    <%= t(".your_rights.heading") %>

    +
      +
    1. +

      + <%= t(".your_rights.request_data_html", + applicable_jurisdiction_link: link_to(t(".your_rights.applicable_jurisdiction"), tos_faq_path(anchor: "privacy_rights"))) %> +

      +
    2. +
    3. +

      + <%= t(".your_rights.potential_other_rights_html", + other_rights_link: link_to(t(".your_rights.other_rights"), tos_faq_path(anchor: "privacy_rights_faq"))) %> +

      +
    4. +
    5. <%= t(".your_rights.require_user_specific_proof") %>

    6. +
    + +

    <%= t(".third_parties.heading") %>

    +
      +
    1. <%= t(".third_parties.do_not_sell_information") %>

    2. +
    3. <%= t(".third_parties.third_party_tools") %>

    4. +
    5. +

      <%= t(".third_parties.sharing_exceptions.intro") %>

      +
        +
      1. +

        + <%= t(".third_parties.sharing_exceptions.external_processing.heading") %> + <%= t(".third_parties.sharing_exceptions.external_processing.html", + subprocessor_list_link: link_to(t(".third_parties.sharing_exceptions.external_processing.subprocessor_list"), "https://www.transformativeworks.org/otw_tos/organization-for-transformative-works-subprocessor-list/")) %> +

        +
      2. +
      3. +

        + + <%= t(".third_parties.sharing_exceptions.challenge_signup.heading_html", + challenge_link: link_to(t(".third_parties.sharing_exceptions.challenge_signup.challenge"), archive_faq_path("glossary", anchor: "challengedef"))) %> + + <%= t(".third_parties.sharing_exceptions.challenge_signup.text") %> +

        +
      4. +
      5. +

        + + <%= t(".third_parties.sharing_exceptions.open_doors_import.heading_html", + open_doors_link: link_to(t(".third_parties.sharing_exceptions.open_doors_import.open_doors"), "https://opendoors.transformativeworks.org/")) %> + + <%= t(".third_parties.sharing_exceptions.open_doors_import.text") %> +

        +
      6. +
      7. +

        + <%= t(".third_parties.sharing_exceptions.handle_complaints.heading") %> + <%= t(".third_parties.sharing_exceptions.handle_complaints.html", + dmca_notice_link: link_to(t(".third_parties.sharing_exceptions.handle_complaints.dmca_notice"), tos_faq_path(anchor: "dmca_complaint")), + pac_confidentiality_policy_link: link_to(t(".third_parties.sharing_exceptions.handle_complaints.pac_confidentiality_policy"), "https://www.transformativeworks.org/committees/policy-abuse-confidentiality-policy/")) %> +

        +
      8. + +
      9. + <%= t(".third_parties.sharing_exceptions.legal_reasons.heading") %> + <%= t(".third_parties.sharing_exceptions.legal_reasons.intro") %> +
          +
        1. <%= t(".third_parties.sharing_exceptions.legal_reasons.legally_compelled") %>
        2. +
        3. <%= t(".third_parties.sharing_exceptions.legal_reasons.good_faith_comply") %>
        4. +
        5. <%= t(".third_parties.sharing_exceptions.legal_reasons.cooperating_law_enforcement") %>
        6. +
        +

        <%= t(".third_parties.sharing_exceptions.legal_reasons.law_enforcement_cooperation_details") %>

        +

        <%= t(".third_parties.sharing_exceptions.legal_reasons.attempt_to_notify") %>

        +
      10. +
      +
    6. +
    + +

    <%= t(".account_termination.heading") %>

    +
      +
    1. +

      + <%= t(".account_termination.deletion_after_termination_html", + terminate_your_account_link: link_to(t(".account_termination.terminate_your_account"), archive_faq_path("your-account", anchor: "deleteaccount"))) %> +

      +
        +
      1. +

        + <%= t(".account_termination.orphans_excluded_html", + orphan_link: link_to(t(".account_termination.orphan"), archive_faq_path("orphaning")), + pseud_link: link_to(t(".account_termination.pseud"), archive_faq_path("pseuds", anchor: "whatisapseud"))) %> +

        +
      2. +
      3. +

        + <%= t(".account_termination.backup_copies_html", + general_principles_link: link_to(t(".account_termination.general_principles"), tos_path(anchor: "I.E.2"))) %> +

        +
      4. +
      +
    2. +
    3. <%= t(".account_termination.legal_enforcement_retention") %>

    4. +
    + +

    <%= t(".retention_of_information.heading") %>

    +

    <%= t(".retention_of_information.text") %>

    + +

    <%= t(".contact_us.heading") %>

    +

    + <%= t(".contact_us.html", + contact_pac_link: link_to(t(".contact_us.contact_pac"), new_abuse_report_path)) %> +

    + +
    +

    <%= t(".effective") %>

    +

    + + <%= t(".license_html", + terms_of_service_link: link_to(t(".terms_of_service"), tos_path), + content_policy_link: link_to(t(".content_policy"), content_path), + privacy_policy_link: link_to(t(".privacy_policy"), privacy_path), + cc_attribution_4_0_international_link: link_to(t(".cc_attribution_4_0_international"), + "https://creativecommons.org/licenses/by/4.0/", + rel: "nofollow")) %> + +

    diff --git a/app/views/home/_tos.html.erb b/app/views/home/_tos.html.erb new file mode 100755 index 0000000..20d6c9d --- /dev/null +++ b/app/views/home/_tos.html.erb @@ -0,0 +1,26 @@ +<%# IMPORTANT: Also update current_tos_version in application_controller %> +<%# To ensure proper formatting, this must always be rendered inside an element + with the userstuff class. The userstuff element must be inside an element with + the classes "docs system". %> +

    In addition to our content policy, which is explained more on its own page but outlined briefly here: +

    + +

    1. NO RPF (real person fiction) about real people, alive or not, under the age of 18 at present or in the work; +and 2. any visual artistic depictions of characters under the age of 14 that appear hyperrealistic or could be mistaken as real. If you're not sure, you can email me at symphonicstarship(@)gmail.com.

    +

    +2. All works posted to Sunset must be femslash. We use a loose definition of femslash that includes unaligned and feminine aligned nonbinary folks here; we leave the decision up to you when it comes to the inclusion of these characters, as long as you'd feel comfortable including them in the term femslash. + + +

    + 3. All users as of September 28, 2025 must be 18+. + +

    We also ask...

    +

    1. You do not harass others. Ever. Over ships, over characters, over beliefs. If you have any issues with a member, email me at femslashclub@proton.me.
    +2. You understand that we will not take down a work for anything other than works written with intentional spite or bigotry, or works that break our content policy.
    +3. You wait to request an invitation until you are eighteen years of age or older.
    +4. You do not use Sunset to distribute links to illegal content (including pirated content).
    +5. No AI generated stuff, even in user icons.
    +6. Please do NOT post Ko-fi or Patreon or any sort of financial donation links here. I can get in legal trouble and then no more femslash archive. +

    + + diff --git a/app/views/home/_tos_navigation.html.erb b/app/views/home/_tos_navigation.html.erb new file mode 100755 index 0000000..3529b2e --- /dev/null +++ b/app/views/home/_tos_navigation.html.erb @@ -0,0 +1,6 @@ + diff --git a/app/views/home/about.html.erb b/app/views/home/about.html.erb new file mode 100755 index 0000000..30bb26a --- /dev/null +++ b/app/views/home/about.html.erb @@ -0,0 +1,15 @@ +

    <%= t(".heading.html", otw: tag.abbr(t(".heading.otw"), title: t(".heading.otw_long"))) %>

    + +
    + Sunset is a website established in 2025 dedicated to hosting F/F, NB/F and NB/NB fanworks. It holds pro-freedom of fiction, queer and trans inclusive, anti-bigotry and generally compassionate ideals. We're here to have fun and love fictional characters. Sunset is run by one person, Agnes the Alien, who dreamed this up in zher bedroom. Please be nice to zher!

    THIS IS AN 18+ ARCHIVE. Sorry :(

    + I'd like to shout out the websites who helped me make Sunset possible, other otwarchive instances: Squidgeworld, Superlove, Ad Astra, and Comic Fanfiction Authors Archive.


    You can link to us with the following button!


    +You can read our content policy here. +

    +
    + | |
    + previous + random + next +
    + +
    diff --git a/app/views/home/content.html.erb b/app/views/home/content.html.erb new file mode 100755 index 0000000..cdb1b36 --- /dev/null +++ b/app/views/home/content.html.erb @@ -0,0 +1,20 @@ + +

    <%= t(".page_heading") %>

    + + + +

    <%= t("a11y.navigation") %>

    +<%= render "tos_navigation" %> + + + +

    <%= t(".page_content_landmark") %>

    +
    + <%= render "content" %> +
    + + + +

    <%= t("a11y.navigation") %>

    +<%= render "tos_navigation", top_link: true %> + diff --git a/app/views/home/diversity_statement.html.erb b/app/views/home/diversity_statement.html.erb new file mode 100755 index 0000000..f8cf5e0 --- /dev/null +++ b/app/views/home/diversity_statement.html.erb @@ -0,0 +1,47 @@ +

    <%= t(".welcome_header") %>

    + +
    +

    <%= t(".archive_for_you") %>

    + +

    + <%= t(".archive_description_html", + your_feedback_link: link_to(t(".your_feedback"), new_feedback_report_path)) %> +

    + +

    + <%= t(".what_we_do_html", + archive_team_link: link_to(t(".archive_team"), admin_posts_path)) %> +

    + +

    + <%= t(".you_can_html", + few_restrictions_link: link_to(t(".few_restrictions"), content_path), + terms_of_service_link: link_to(t(".terms_of_service"), tos_path)) %> +

    + +

    + <%= t(".still_missing_html", + some_essential_parts_link: link_to(t(".some_essential_parts"), admin_post_path(295))) %> +

    + +

    <%= t(".why_we_build") %>

    + +

    <%= t(".we_build_for") %>

    + +
    +

    + <%= t(".dreamwidth_remix_html", + dreamwidth_link: link_to(t(".dreamwidth"), "http://www.dreamwidth.org"), + diversity_statement_link: link_to(t(".diversity_statement"), "http://www.dreamwidth.org/legal/diversity")) %> +

    + +

    + + <%= t(" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /> + +
    + <%= t(".license.html", + creative_commons_by_sa_link: link_to(t(".license.creative_commons_by_sa"), + "http://creativecommons.org/licenses/by-sa/3.0/")) %> +

    +
    diff --git a/app/views/home/dmca.html.erb b/app/views/home/dmca.html.erb new file mode 100755 index 0000000..957c740 --- /dev/null +++ b/app/views/home/dmca.html.erb @@ -0,0 +1,4 @@ +

    <%= t(".page_heading") %>

    +
    + <%= render "dmca" %> +
    diff --git a/app/views/home/donate.html.erb b/app/views/home/donate.html.erb new file mode 100755 index 0000000..cbcd4ce --- /dev/null +++ b/app/views/home/donate.html.erb @@ -0,0 +1,9 @@ +

    Donate

    + +
    + You can volunteer as a tag wrangler by emailing femslashclub@proton.me. + +

    + + You can donate to keep the site up and running here. +
    diff --git a/app/views/home/first_login_help.html.erb b/app/views/home/first_login_help.html.erb new file mode 100755 index 0000000..f5694fb --- /dev/null +++ b/app/views/home/first_login_help.html.erb @@ -0,0 +1,155 @@ +<%# Expects current_user %> +
    +

    + <%= t(".welcome_header", app_name: ArchiveConfig.APP_NAME) %> +

    +

    <%= t(".tips_to_start") %>

    + +

    <%= t(".table_of_contents") %>

    +
      +
    • <%= link_to t(".logging_in_out.header"), "#logging_in" %>
    • +
    • <%= link_to t(".editing_profile.header"), "#edit_profile" %>
    • +
    • <%= link_to t(".pseuds.header"), "#pseuds" %>
    • +
    • <%= link_to t(".posting_works.header"), "#posting" %>
    • +
    • <%= link_to t(".browsing.header"), "#browsing" %>
    • +
    • <%= link_to t(".tags.header"), "#tags" %>
    • +
    • <%= link_to t(".warnings.header"), "#warnings" %>
    • +
    • <%= link_to t(".bookmarking_works.header"), "#bookmarking" %>
    • +
    • <%= link_to t(".preferences.header"), "#preferences" %>
    • +
    • + <%= link_to t(".additional_info.header"), "#additional" %> +
        +
      • <%= link_to t(".additional_info.history_mark_later.header"), "#history" %>
      • +
      • <%= link_to t(".additional_info.subscriptions.header"), "#subscriptions" %>
      • +
      +
    • +
    • <%= link_to t(".tos.header"), "#legal_stuff" %>
    • +
    • <%= link_to t(".support_and_feedback.header"), "#support" %>
    • +
    + +

    <%= t(".logging_in_out.header") %>

    +

    + <%= t(".logging_in_out.html", + forgot_password_link: link_to(t(".logging_in_out.forgot_password"), new_user_password_path)) %> +

    + +

    <%= t(".editing_profile.header") %>

    +

    + <%= t(".editing_profile.html", + your_dashboard_link: link_to(t(".editing_profile.your_dashboard"), user_path(current_user)), + profile_link: link_to(t(".editing_profile.profile"), user_profile_path(current_user)), + edit_my_profile_link: link_to(t(".editing_profile.edit_my_profile"), edit_user_path(current_user)), + profile_faq_link: link_to(t(".editing_profile.profile_faq"), archive_faq_path("profile"))) %> +

    + +

    <%= t(".pseuds.header") %>

    +

    + <%= t(".pseuds.html", + manage_your_pseuds_link: link_to(t(".pseuds.manage_your_pseuds"), user_pseuds_path(current_user)), + pseuds_faq_link: link_to(t(".pseuds.pseuds_faq"), archive_faq_path("pseuds"))) %> +

    + +

    <%= t(".posting_works.header") %>

    +

    + <%= t(".posting_works.html", + post_new_link: link_to(t(".posting_works.post_new"), new_work_path), + posting_editing_faq_link: link_to(t(".posting_works.posting_editing_faq"), + archive_faq_path("posting-and-editing")), + tutorial_link: link_to(t(".posting_works.tutorial"), + archive_faq_path("tutorial-posting-a-work-on-ao3"))) %> +

    + +

    <%= t(".browsing.header") %>

    +

    + <% media_movie = Media.find_by_name("Movies") %> + <%= t(".browsing.html", + fandoms_link: link_to(t(".browsing.fandoms"), menu_fandoms_path), + all_fandoms_link: link_to(t(".browsing.all_fandoms"), media_index_path), + movies_link: if media_movie + link_to(t(".browsing.movies"), media_fandoms_path(media_movie)) + else + t(".browsing.movies") + end, + search_feature_link: link_to(t(".browsing.search_feature"), search_works_path), + search_browse_faq_link: link_to(t(".browsing.search_browse_faq"), archive_faq_path("search-and-browse")), + search_browse_tutorial_link: link_to(t(".browsing.search_browse_tutorial"), admin_post_path(259))) %> +

    + +

    <%= t(".tags.header") %>

    +

    + <%= t(".tags.html", + tags_faq_link: link_to(t(".tags.tags_faq"), archive_faq_path("tags"))) %> +

    + +

    <%= t(".warnings.header") %>

    +

    + <%= t(".warnings.description_html", + archive_specific_warnings_link: link_to(t(".warnings.archive_specific_warnings"), + tos_faq_path(anchor: "warnings_list"))) %> +

    +

    + <%= t(".warnings.symbols_html", + symbols_key_chart_link: link_to(t(".warnings.symbols_key_chart"), "/help/symbols-key.html")) %> +

    + +

    <%= t(".bookmarking_works.header") %>

    +

    + <%= t(".bookmarking_works.html", + bookmarks_faq_link: link_to(t(".bookmarking_works.bookmarks_faq"), archive_faq_path("bookmarks"))) %> +

    + +

    <%= t(".preferences.header") %>

    +

    + <%= t(".preferences.html", + set_my_preferences_link: link_to(t(".preferences.set_my_preferences"), user_preferences_path(current_user)), + edit_my_profile_link: link_to(t(".preferences.edit_my_profile"), edit_user_path(current_user)), + preferences_faq_link: link_to(t(".preferences.preferences_faq"), archive_faq_path("preferences"))) %> +

    +

    + <%= t(".preferences.skins_detail_html", + skins_faq_link: link_to(t(".preferences.skins_faq"), + archive_faq_path("skins-and-archive-interface")), + tutorials_list_link: link_to(t(".preferences.tutorials_list"), + archive_faq_path("tutorials"))) %> +

    + +

    <%= t(".additional_info.header") %>

    +

    <%= t(".additional_info.history_mark_later.header") %>

    +

    + <%= t(".additional_info.history_mark_later.html", + your_dashboard_link: link_to(t(".additional_info.history_mark_later.your_dashboard"), user_path(current_user)), + history_link: link_to(t(".additional_info.history_mark_later.history"), user_readings_path(current_user)), + history_faq_link: link_to(t(".additional_info.history_mark_later.history_faq"), + archive_faq_path("History-and-mark-for-later"))) %>

    + +

    <%= t(".additional_info.subscriptions.header") %>

    +

    + <%= t(".additional_info.subscriptions.html", + your_dashboard_link: link_to(t(".additional_info.subscriptions.your_dashboard"), user_path(current_user)), + subscriptions_feed_faq_link: link_to(t(".additional_info.subscriptions.subscriptions_feed_faq"), + archive_faq_path("subscriptions-and-feeds"))) %> +

    + + +

    + <%= t(".tos.info_html", + tos_link: link_to(t(".tos.tos"), tos_path), + content_policy_link: link_to(t(".tos.content_policy"), content_path), + privacy_policy_link: link_to(t(".tos.privacy_policy"), privacy_path), + tos_faq_link: link_to(t(".tos.tos_faq"), tos_faq_path)) %> +

    +

    + <%= t(".tos.additional_questions_html", + contact_abuse_link: link_to(t(".tos.contact_abuse"), new_abuse_report_path)) %> +

    + +

    <%= t(".support_and_feedback.header") %>

    +

    + <%= t(".support_and_feedback.html", + archive_faq_link: link_to(t(".support_and_feedback.archive_faq"), archive_faqs_path), + known_issues_link: link_to(t(".support_and_feedback.known_issues"), known_issues_path), + contact_support_link: link_to(t(".support_and_feedback.contact_support"), new_feedback_report_path), + unofficial_tools_faq_link: link_to(t(".support_and_feedback.unofficial_tools_faq"), + archive_faq_path("unofficial-browser-tools"))) %> +

    +
    diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb new file mode 100755 index 0000000..919798c --- /dev/null +++ b/app/views/home/index.html.erb @@ -0,0 +1,57 @@ +
    + <% if !logged_in? %> + <%= render 'intro_module' %> + <% end %> + + <% if logged_in? && @homepage.favorite_tags.present? %> +
    +

    <%= t(".find_your_favorites") %>

    +
      + <% @homepage.favorite_tags.each do |favorite_tag| %> +
    • + <%= link_to_tag_works(favorite_tag.tag) %> +
    • + <% end %> +
    +
    + <% else %> +
    " class="browse module"> +

    <%= t(".find_your_favorites") %>

    + <% if logged_in? %> +

    <%= t(".browse_or_favorite", count: ArchiveConfig.MAX_FAVORITE_TAGS) %>

    + <% end %> +Or, try a new author... + <% if @random_user %> + <%= link_to @random_user.login, user_path(@random_user) %> +<% else %> + No authors available +<% end %>

    + <%= render 'fandoms' %> +
    + <% end %> + + <% if @homepage.admin_posts.present? %> + <%= render 'news_module', admin_posts: @homepage.admin_posts %> + <% end %> + + <% if logged_in? && @homepage.readings.present? %> +
    +

    + <%= t(".readings.heading.title") %> + <%= link_to t(".readings.heading.history_link"), user_readings_path(current_user) %> +

    +
    +

    <%= t(".readings.note") %>

    +
      + <% @homepage.readings.each do |reading| %> + <%= render "readings/reading_blurb", work: reading.work, reading: reading %> + <% end %> +
    +
    + <% end %> + + <% if logged_in? && @homepage.inbox_comments.present? %> + <%= render 'inbox_module', inbox_comments: @homepage.inbox_comments %> + <% end %> + +
    diff --git a/app/views/home/lost_cookie.html.erb b/app/views/home/lost_cookie.html.erb new file mode 100755 index 0000000..13c5c41 --- /dev/null +++ b/app/views/home/lost_cookie.html.erb @@ -0,0 +1,5 @@ +

    <%= ts('Forced Logout') %>

    + +
    +

    <%= ts("You have been automatically logged out to protect your privacy. Please make sure that your browser is set to accept cookies from archiveofourown.org and delete any existing Archive cookies. If you continue to have problems logging in, please try using the Log In page. If you still have problems after trying that, please contact Support.".html_safe) %>

    +
    diff --git a/app/views/home/privacy.html.erb b/app/views/home/privacy.html.erb new file mode 100755 index 0000000..bb9a551 --- /dev/null +++ b/app/views/home/privacy.html.erb @@ -0,0 +1,20 @@ + +

    <%= t(".page_heading") %>

    + + + +

    <%= t("a11y.navigation") %>

    +<%= render "tos_navigation" %> + + + +

    <%= t(".page_content_landmark") %>

    +
    + I don't collect any data besides IP addresses and emails, and I will NEVER upload your information elsewhere. The OTWArchive software collects IP addresses and emails by design.

    If you would like your work data to be removed, please email me. However, any tags you use will remain on the archive.

    Sunset's server is based in the United States. +
    + + + +

    <%= t("a11y.navigation") %>

    +<%= render "tos_navigation", top_link: true %> + diff --git a/app/views/home/site_map.html.erb b/app/views/home/site_map.html.erb new file mode 100755 index 0000000..a0b40af --- /dev/null +++ b/app/views/home/site_map.html.erb @@ -0,0 +1,65 @@ +

    <%= t(".page_heading") %>

    +
    +

    <%= t(".explore.header") %>

    +
      +
    • <%= link_to t(".explore.homepage"), root_path %>
    • +
    • <%= link_to t(".explore.fandoms"), media_index_path %>
    • +
    • <%= link_to t(".explore.recent_works"), works_path %>
    • +
    • <%= link_to t(".explore.people"), search_people_path %>
    • +
    • <%= link_to t(".explore.bookmarks"), bookmarks_path %>
    • +
    • <%= link_to t(".explore.additional_tags_cloud"), tags_path %>
    • +
    • <%= link_to t(".explore.languages"), languages_path %>
    • +
    • <%= link_to t(".explore.collections_and_challenges"), collections_path %>
    • +
    + +

    <%= t(".about.header") %>

    +
      +
    • <%= link_to t(".about.terms_of_service"), tos_path %>
    • +
    • <%= link_to t(".about.content_policy"), content_path %>
    • +
    • <%= link_to t(".about.archive_faq"), archive_faqs_path %>
    • + +
    • + <%= t(".about.project_of_otw_html", + otw_link: link_to(content_tag(:acronym, t("Agnes the Alien"), title: t("Agnes the Alien")), + "https://kissing.computer/")) %> + +
    • +
    + + <% if logged_in? %> +

    <%= t(".access_your_account.header") %>

    +
      +
    • <%= link_to t(".access_your_account.my_home"), user_path(current_user) %>
    • +
    • <%= link_to t(".access_your_account.post_new"), new_work_path %>
    • +
    • <%= link_to t(".access_your_account.my_works"), user_works_path(current_user) %>
    • +
    • <%= link_to t(".access_your_account.drafts"), drafts_user_works_path(current_user) %>
    • +
    • <%= link_to t(".access_your_account.my_series"), user_series_index_path(current_user) %>
    • +
    • <%= link_to t(".access_your_account.my_bookmarks"), user_bookmarks_path(current_user) %>
    • +
    • <%= link_to t(".access_your_account.my_collections_and_challenges"), user_collections_path(current_user) %>
    • +
    • <%= link_to t(".access_your_account.my_inbox"), user_inbox_path(current_user) %>
    • + <% if current_user.preference.history_enabled? %> +
    • <%= link_to t(".access_your_account.my_history"), user_readings_path(current_user) %>
    • + <% end %> +
    • <%= link_to t(".access_your_account.my_subscriptions"), user_subscriptions_path(current_user) %>
    • +
    • <%= link_to t(".access_your_account.set_my_preferences"), user_preferences_path(current_user) %>
    • +
    + +

    <%= t(".change_your_account_settings.header") %>

    +
      +
    • <%= link_to t(".change_your_account_settings.edit_my_profile"), edit_user_path(current_user) %>
    • +
    • <%= link_to t(".change_your_account_settings.my_profile"), user_profile_path(current_user) %>
    • +
    • <%= link_to t(".change_your_account_settings.manage_my_pseuds"), user_pseuds_path(current_user) %>
    • +
    • + <%= link_to t(".change_your_account_settings.delete_my_account"), + user_path(current_user), + data: { confirm: t(".change_your_account_settings.delete_account_confirmation") }, + method: :delete %> +
    • +
    + <% end %> + +

    <%= t(".contact_us.header") %>

    +
      +
    • <%= link_to t(".contact_us.policy_questions_and_abuse_reports"), new_abuse_report_path %>
    • + +
    diff --git a/app/views/home/site_pages.html.erb b/app/views/home/site_pages.html.erb new file mode 100755 index 0000000..12b66b9 --- /dev/null +++ b/app/views/home/site_pages.html.erb @@ -0,0 +1,41 @@ + +
    +

    Archive Pages

    + +

    + The following links will take you to all of the possible pages in the archive. + These are only links! You will still need the appropriate permissions to actually see the pages! + If you have trouble, try logging in as the test user or test admin accounts. (Those will only work on webdev or test, FYI.) +

    + +

    + If any of these pages do not work at all (ie if you get a 404 or a notice that no action matches), please notify a senior + coder, since that probably means it is an unused route that should get cleaned up to improve performance. +

    + +

    + Where an existing object is required to see a form (for instance when looking at a nested form), + we will attempt to make the link using one that you (that is, the user you are currently logged in as) can access. + If that doesn't work, you may need to manually edit the URL to put in the ID of an object + that you can see, or make a new object. +

    + +

    Pages

    +
      + <%= @paths.sort {|a,b| a[0] <=> b[0]}.map {|path, name| content_tag(:li, link_to("#{path} (#{name})", path))}.join("\n").html_safe %> +
    + +<% unless @errors.empty? %> +

    Errors

    +

    + There were problems linking to the following pages, either because we couldn't find an object to use or because it's a + weird kind of page. You can manually fix and paste these routes in to see those pages. +

    + +
      + <%= @errors.map {|error| content_tag(:li, error)}.join("\n").html_safe %> +
    +<% end %> + + +
    \ No newline at end of file diff --git a/app/views/home/tos.html.erb b/app/views/home/tos.html.erb new file mode 100755 index 0000000..0145d1c --- /dev/null +++ b/app/views/home/tos.html.erb @@ -0,0 +1,25 @@ +<%# IMPORTANT: Also update current_tos_version in application_controller %> +<%# To ensure proper formatting, this must always be rendered inside an element + with the userstuff class. The userstuff element must be inside an element with + the classes "docs system". %> +

    A reminder of our content policy: +We're pretty chill here at Sunset. We allow most forms of content, with the following exceptions: +1. Explicitly sexual RPF (real person fiction) about real people, alive or not, under the age of 18 at present or in the work; +and 2. any visual artistic depictions of characters under the age of 14 that appear hyperrealistic or could be mistaken as real. If you're not sure, you can email me at femslashclub@proton.me.

    +

    + +The only other content rule is that all works posted to Sunset must be F/F, NB/F, or NB/NB. As of October 2025, we allow gender/cisswaps of M/F, M/M, or M/NB to the archive categories, but for those works, please use the freeform tag "Canon Gender Swap". Thanks to the community for feedback on this. You can also optionally specify what the swap is, e.g. Canon Gender Swap - M/M to F/F, M/M/F to F/F/NB, or whatever applies. + +Thank you! +

    + +

    We also ask...

    +

    1. You do not harass others. Ever. Over ships, over characters, over beliefs. If you have any issues with a member, email me at femslashclub@proton.me.
    +2. You understand that we will not take down a work for anything other than works written with the intention to harass another Sunset user, or works that break our content policy.
    +3. You wait to request an invitation until you are eighteen years of age or older.
    +4. You do not use Sunset to distribute links to illegal content (including pirated content).
    +5. No AI generated stuff, even in user icons.
    +6. Please do NOT post Ko-fi or Patreon or any sort of financial donation links here. I can get in legal trouble and then no more archive. +

    + + diff --git a/app/views/home/tos_faq.html.erb b/app/views/home/tos_faq.html.erb new file mode 100755 index 0000000..bb4bfd2 --- /dev/null +++ b/app/views/home/tos_faq.html.erb @@ -0,0 +1,1247 @@ + +

    Terms of Service FAQ

    + + + +

    <%= t("a11y.navigation") %>

    +<%= render "tos_navigation" %> + + + +

    Main Text

    +
    +

    This document addresses common questions about the AO3 Terms of Service and how our policies are implemented. If you have any questions not answered by this FAQ, you can contact the Policy & Abuse committee.

    + +

    General Principles FAQ

    +

    Answers to common questions about the General Principles of the AO3 Terms of Service are available below. If you have additional questions that are not covered here, you can contact the Policy & Abuse committee.

    + +

    General Questions

    +
    + +
    Table of Contents
    +
    + +
    +
    Why does the Archive of Our Own (AO3) have a goal of maximum inclusiveness of fanwork content?
    +

    AO3 was founded partly in response to a growing trend of fanworks being removed from websites that had previously allowed them. Commercial entities have frequently permitted fanworks in the early stage of their existence in order to expand their userbase, only to later prohibit certain types of fanworks from being shared on their platform. This pattern has been observed numerous times throughout fandom history. We want AO3 to be a non-commercial space where creators are able to permanently preserve and freely share as many of their fanworks as possible.

    +
    What does it mean for AO3's Terms of Service (TOS) to be governed by the laws of New York? What if I am a resident of a different state or country?
    +

    AO3 operates under the jurisdiction of Manhattan, New York in the United States. As such, the interactions between AO3 and its users, as well as the definitions in the TOS, will comply with U.S. legislative interpretations. If you reside in a different state or country, it is your responsibility – not AO3's – to know about and follow the laws in your local jurisdiction. For example, if certain content on AO3 is restricted under your local laws, it is not AO3's duty to delete that content for you; instead, it is your responsibility to avoid accessing that content.

    +
    What is an "implied warranty of merchantability"?
    +

    An implied warranty of merchantability is a legal agreement between a seller and a buyer that goods will be reasonably fit for the general purpose for which they are sold. For example, if you buy a toaster, it should be able to toast bread. It doesn't have to be perfect, but it should function as a typical toaster would.

    +

    This warranty is governed in the United States by the Uniform Commercial Code (UCC), which allows sellers to "disclaim" it. Disclaiming a warranty cancels the promise, which means the buyer takes on the risk that the product may not work as expected. By disclaiming this warranty about AO3, we are saying that you cannot hold us legally responsible if AO3 does not work as expected (in other words, you can't sue us).

    +
    What is an "implied warranty of fitness for a particular purpose"?
    +

    An implied warranty of fitness for a particular purpose is a legal agreement that exists when a buyer relies upon the seller to provide goods to fit a specific request. For example, if you ask a salesperson for a pair of boots to hike in the snow, and they sell you boots based on that request, they are making a promise (warranty) that those boots will be good for hiking in the snow. The seller has to know two things: 1) the buyer has a specific need, and 2) the buyer is relying on their recommendation. If both of those conditions are met, this warranty applies.

    +

    This warranty is governed in the United States by the Uniform Commercial Code (UCC). Like the implied warranty of merchantability, sellers can disclaim it, thereby shifting the risk back to the buyer. By disclaiming this warranty about AO3, we are saying that you cannot hold us legally responsible if AO3 does not suit the purpose you wanted to use it for, even if we know why you wanted to use it and you are relying on our recommendation to use it. For example, if you want to use AO3 to post your fanworks, but you find that you don't like AO3's posting interface and prefer to use another fanwork site, you can't sue us because our site doesn't meet your needs.

    +
    Why are you talking about buyers and sellers? Are you selling things?
    +

    No, AO3 is and always will be free to use. We don't sell anything. We don't sell products to you, and we also don't sell advertisement space or user data to third parties. AO3 is run by the Organization for Transformative Works (OTW), a non-profit which is funded by donations, not sales or advertisements. However, U.S. law regarding services and contracts generally assumes that one party is a buyer and one party is a seller, even if the service being "sold" is free (as in our case). We use this standard language to make sure that we aren't promising you something that we can't provide.

    +
    What counts as an official statement from the OTW?
    +

    Official statements are communications made by volunteers while they are fulfilling their formal volunteering responsibilities. These can include news posts and comments from official accounts.

    +

    Comments from official accounts are only official OTW statements when the volunteer is both acting in their official OTW role and providing information about the OTW or any of its projects or policies. For example, a news post moderator using an official account to reply to a question about a news post is acting in an official capacity; however, a volunteer who is using an official account to reply to a comment on a "Five Things" post about them (which is about that volunteer's personal opinions) is not acting in an official capacity.

    +
    What do you mean by "a worldwide, royalty-free, nonexclusive license"?
    +

    This means that we can make the content you post on AO3 available to other people who use AO3, without paying you. We will never charge for access to AO3 or otherwise sell your content. You can also put your content on other sites if you want, or remove it from AO3 if you no longer want it here.

    +
    What do you mean by modifying or adapting content?
    +

    This refers to how your work is displayed on the site, not how it is written, drawn, or otherwise created. For example, we may display portions of your content on some pages of the site, such as by showing your work's summary and tags in search results. We may also make changes to the formatting or display of your content in order to adapt to the technical requirements of different networks or devices, or to improve accessibility. For example, we may automatically convert HTML tags to our standard forms (for example, changing <bold> html tags to <strong>) or allow you to use nonstandard fonts and formatting while providing an alternate format for accessibility.

    +
    What are the rules for removing and retaining content on various parts of AO3 that are not fully controlled by the original poster?
    +
      +
    • Orphaning a work: Orphaned works will not be edited or removed unless they contain unauthorized information which may identify the creator or otherwise violate the Terms of Service.
    • +
    • Participation in a Challenge: The maintainer(s) of the challenge may edit or delete the sign-up or prompt, or remove a work from their collection, at any time.
    • +
    • + Comments on someone else's work: +
        +
      • The creator(s) of the work may freeze or delete comments on their work at any time and for any reason. They may also enable comment moderation and choose to leave comments unreviewed, or mark guest comments as spam.
      • +
      • Registered users can delete their own comments at any time. Guest users cannot delete their own comments.
      • +
      • The Policy & Abuse committee may delete comments in situations where a violation of the Terms of Service has occurred.
      • +
      +
    • +
    • Comments on an official AO3 or OTW post: Comments on official AO3 or OTW posts may be frozen, hidden, marked as spam, or deleted in accordance with the OTW News Post Moderation Policy.
    • +
    +
    How can I check if my country is under a comprehensive trade embargo by the US?
    +

    The U.S. Office of Foreign Assets Control (OFAC) provides up-to-date details regarding all current embargoes (including but by no means limited to comprehensive trade embargoes) on their website. Princeton University has a list of countries that are comprehensively sanctioned by OFAC.

    +
    Under what circumstances would you suspend an account for an invalid email address?
    +

    If we need to communicate with you to resolve an Abuse report, we will email you at the address associated with your AO3 account. If you do not check your email, or if you cannot receive emails because your email address is inaccurate or invalid, then we will have to resolve the complaint without your input. A sufficient number of sustained Abuse reports that fail to be delivered ("bounce") or do not receive a response could lead to permanent suspension.

    +

    If our emails to you repeatedly bounce, then we may suspend your account because we need to be able to communicate with you if necessary. In that situation, you can log in and get your account reinstated by associating it with a working email address. Then, if necessary, you can deal with whatever problem led to the Abuse report in the first place.

    +

    Having an invalid email address will not necessarily cause you to be suspended. However, if you violated the Terms of Service in other ways, those violations will not be excused just because you didn't receive our emails. It is your responsibility to ensure your email address is accurate and messages can be delivered to it. Repeated violations of the Terms of Service may result in a temporary suspension or a permanent ban, regardless of whether or not you were able to receive our emails warning you about the violations.

    +

    If we send a routine email about general site policies and it bounces, that will not lead to account suspension, but whatever policies we announce will still apply to all account owners. We will only suspend accounts with invalid email addresses when individual Policy & Abuse–related communications bounce.

    +
    Why did you license the Terms of Service under the Creative Commons Attribution 4.0 International License? What does that mean?
    +

    Creative Commons licenses allow people to use others' works under certain predefined conditions. The Creative Commons Attribution 4.0 International License (CC BY 4.0) permits you to use material from our Terms of Service (including the Content Policy and Privacy Policy) for any purpose, as long as you meet all of the following requirements:

    +
      +
    1. Give appropriate credit: You need to say that the material was created by us and provide a link to the CC license.
    2. +
    3. Indicate if changes were made: If you changed something from our original material, say so when crediting us.
    4. +
    5. Don't suggest we endorse your use: While you're free to adapt our material for your own use, you can't claim that we reviewed or authorized your specific work.
    6. +
    7. Don't impose additional restrictions: You may not apply legal terms or technological measures that restrict others from doing anything that this license permits.
    8. +
    +

    An example of appropriate attribution would be: "This work uses material from AO3's Terms of Service, which was released under a CC BY 4.0 license."

    +
    Does AO3's Terms of Service use material or inspiration from documents by other people?
    +

    Material in AO3's Terms of Service has been drawn from imeem and NearlyFreeSpeech.NET.

    +

    Back to Top | General Questions

    +
    +

    Age Policy

    +
    + +
    Table of Contents
    +
    + +
    +
    Why are children under the age of 13 not permitted to have an AO3 account or upload content?
    +

    In the United States, the Children's Online Privacy Protection Act (COPPA) governs the collection of personal information, including usernames and email addresses, from children under 13. Because the Organization for Transformative Works is a non-profit and does not sell any data, COPPA does not apply to AO3; however, we adhere to the same restriction as a matter of policy.

    +
    Why are children under the age of sixteen (16) who are residents/citizens of certain countries not permitted to have an account or upload content?
    +

    In some countries in Europe, the General Data Protection Regulation (GDPR) governs the collection and processing of personal data, including email addresses and IP addresses, as well as certain uses of cookies. Other countries may have similar data privacy laws. The age at which someone can consent to the collection of personal data without written permission from their parent or legal guardian may be higher than 13, depending on their country of residence. We do not want to store the type of detailed personal information about users that would be required to verify and accept such permission. Therefore, children who wish to create an account or upload content to AO3 must meet their country's minimum age requirements to legally consent to personal data collection without written permission.

    +
    What happens to an account or its content if the account owner is reported for violating the Age Policy?
    +

    If the Policy & Abuse committee determines that a violation of the Age Policy has occurred, the account will be suspended and content on the account may be removed. If the content is not removed, the suspended user or their parent or guardian can contact the Policy & Abuse committee to request deletion of the content associated with the account.

    +

    If you were previously suspended because of your age and you are now old enough to have an account, you may contact the Policy & Abuse committee to regain access to your account.

    +
    Why are children in the EU not allowed to ask their parent or legal guardian to upload content for them? Does this apply to children elsewhere, such as in the UK or the EEA?
    +

    AO3 adheres to the GDPR's requirements for handling the content and information of children within the GDPR's jurisdiction. Accordingly, the parents or legal guardians of children within the European Union are not allowed to upload their child's content under their own (the parent or guardian's) account.

    +

    This restriction does not apply to children in the United Kingdom or the European Economic Area (unless the child is also a resident or citizen of an EU country).

    +

    Back to Top | Age Policy FAQ

    +
    +

    Abuse Policy and Procedures

    +
    + +
    Table of Contents
    +
    + +
    +
    How do I report a violation of the Terms of Service (TOS)?
    +

    Please contact the Policy & Abuse committee. You must provide your email address and a direct link to the specific content you want to report. In the subject and description of your report, please briefly describe the content you are reporting, explain why you are reporting it, and include any additional links or other details that could help us investigate the violation. If you don't provide this information in your report, we may not be able to investigate or act upon your complaint.

    +

    If you are reporting a specific comment or comment thread, you can get the direct link by selecting the "Thread" button on the comment and copying the URL of that page.

    +

    If you are reporting multiple works or comments posted by the same user, please compile all relevant links and other information into a single report, rather than reporting each link individually.

    +

    If you wish to report content posted by multiple unrelated users (such as two different works by different people in the same fandom), please submit separate reports for each user.

    +
    What language should I select when submitting a report?
    +

    In general, if you are not comfortable with reading and writing in English, you should use the language you are most fluent in. If you are fluent in English and you are reporting something written in another language, you can either select English or choose the language of the content you are reporting.

    +
    Why aren't Digital Millennium Copyright Act (DMCA) notices covered by the Abuse Policy? What's the difference between a DMCA notice and an Abuse report?
    +

    A DMCA takedown notice is a legal mechanism that a copyright owner can use to request removal of their copyrighted material from a hosting site. The takedown notice must meet certain legal requirements. For example, you must declare under penalty of perjury that you are the copyright owner or are legally authorized to act on their behalf. As such, DMCA notices are assessed by the Legal committee, and valid notices may be forwarded to the user who posted the work. We reserve the right to make public all DMCA notices that we receive, though some information may be redacted for privacy. DMCA notices are not subject to the procedures described in the Abuse Policy, nor are they governed by the Policy & Abuse confidentiality policy.

    +

    Abuse reports, on the other hand, are held to a very high standard of confidentiality. They can be about any violation of the Terms of Service, including copyright infringement, harassment, commercial promotion, etc. Abuse reports are evaluated by the Policy & Abuse committee, who will never publish the details of a report or reveal any information about who submitted it.

    +

    Please do not submit an Abuse report if you intend to file a DMCA notice. Submitting both an Abuse report and a DMCA notice about the same content may delay the processing of both requests.

    +
    Can I submit an Abuse report even if I don't have an AO3 account?
    +

    Yes, but your report will be screened by our automated spam filters. If your report is rejected as spam, try using a different email address or removing extra links from your report description. Please also enter a valid email address so that we can contact you to request any additional evidence.

    +

    Reports from registered users are not subject to the spam filter, so long as you are logged in and the email address entered into the form is the one associated with your AO3 account (this will be prefilled for you).

    +
    Will I receive notification that my complaint was resolved? How long will it take?
    +

    We will make a reasonable attempt to accommodate a complainant's reply preferences. However, we may choose not to reply to complaints at our discretion, particularly if it is a non-urgent matter or if the complainant submits frequent, duplicate, or baseless reports.

    +

    Whether or not we reply to the complainant, our volunteers do evaluate all reports and act upon them as necessary. Complaints will generally be prioritized based on urgency, but because the Policy & Abuse committee is a small team of volunteers, we cannot guarantee any particular timeframe for the resolution of a complaint.

    +
    Do you monitor content on AO3 for violations of the Terms of Service?
    +

    No. We do not prescreen content on AO3, nor do we review content that has not been reported. If you believe you have encountered content that violates our Terms of Service, you will need to submit an Abuse report.

    +

    Please refrain from seeking out works that are in violation of the Terms of Service for the sole purpose of reporting or mass-reporting them. We investigate every report we receive, so submitting duplicate reports will only serve to delay the processing of the original complaint.

    +
    I'm not sure whether something is against the rules. What happens if I report something that doesn't violate the Terms of Service?
    +

    You can submit a report even if you aren't sure something is a violation. If the Policy & Abuse committee determines that what you reported is not in violation, you will receive an email letting you know and explaining why that type of content is allowed on AO3.

    +

    If you repeatedly submit reports about similar non-violating material, your subsequent reports may not receive a reply.

    +
    How do you determine whether content needs to be removed?
    +

    Abuse reports are reviewed by humans, not algorithms or bots. After a report is submitted, the Policy & Abuse committee reviews the reported content and independently evaluates whether or not it complies with our Terms of Service. If we determine that the content is in violation of the Terms of Service, only then do we take action to resolve the matter.

    +
    Would a work be removed if enough people reported it? What if someone repeatedly or intentionally submits complaints about something that doesn't violate the Terms of Service?
    +

    Multiple complaints about the same issue increases the time it takes for us to investigate, but we don't make decisions based on how many times something is reported. Mass reporting will not change whether or not the reported content is in violation of the Terms of Service, nor will it cause an issue to be addressed faster.

    +

    You don't need to worry that anyone's works will be taken down due to a baseless report or a mass-reporting campaign. We will only contact the subject of a complaint if they have in fact violated the Terms of Service. If we receive a report about something that isn't a violation, we will let the reporter know and close the report. If someone attempts to abuse our reporting system, such as by intentionally submitting baseless complaints, we may consider that harassment and take appropriate action.

    +
    What if the content I reported was deleted or edited before the Policy & Abuse team can investigate?
    +

    We appreciate good-faith attempts to resolve disputes, and in most such cases will close the complaint with no further action. However, we reserve the right to consider individual circumstances, including whether the poster has engaged in a pattern of such conduct. In such cases, if we verify that the original content violated the TOS, we may still decide to warn or suspend the original poster.

    +
    The instructions on the Policy & Abuse form say to include the username of the person I'm reporting. What if I want to report a guest comment or an anonymous or orphaned work?
    +

    You can mention in your report that the content was posted anonymously or orphaned. Content that violates the Terms of Service will be removed regardless of whether the original poster's name is publicly displayed. Penalties may be applied to the accounts of users responsible for posting violating content.

    +
    If I submit an Abuse report, will the subject be told who reported them?
    +

    In general, no. Abuse reports are kept strictly confidential. We do our best not to reveal any information about the identity of a complainant (such as a username), though in some circumstances it may be impossible to keep the source of the report completely anonymous. We do not ever disclose information that would be sufficient to identify a person in the physical world, such as an email address or legal name. For more information, please refer to the Policy & Abuse Confidentiality Policy.

    +

    Complaints can be submitted anonymously, but an email address is required. If you do not provide a valid email address and the complaint requires follow-up, we may be unable to take action.

    +
    Will I be informed if an Abuse report is filed about me or my work?
    +

    In general, the Policy & Abuse committee will only contact the subject of a complaint if there appears to be a violation of the Terms of Service, or if the team needs more information to resolve the issue.

    +

    If someone files an invalid report against you, we will inform them that their complaint has not been upheld. You will not be told about the complaint and no action will be taken against your account or content.

    +

    If we determine that you have in fact violated the Terms of Service, an email will be sent to the address associated with your account.

    +
    How do I find out who reported or complained about me?
    +

    Anonymity and privacy are essential to maintaining a fair reporting system. The Policy & Abuse committee will not disclose the identity of any complainant as part of an Abuse case.

    +

    All users are responsible for following the Terms of Service, and all users have the right to file a complaint if they witness someone violating the Terms of Service.

    +

    The Policy & Abuse committee will not uphold a complaint without investigating and confirming that a violation of the Terms of Service has occurred. This means that if the Policy & Abuse committee contacts you, their investigation has independently concluded that you have violated the Terms of Service.

    +
    What happens if a report is made about me and the Policy & Abuse committee determines that the complaint is valid?
    +

    The Policy & Abuse committee will send an email to the address associated with your AO3 account. That email will explain what the violating content or behavior is, where it occurred, and (if applicable) what you need to do to resolve it. If you cannot locate the email notifying you of your violation (please check your spam folder), you can submit an Abuse report and we will resend the original email to you.

    +

    What happens when a complaint is upheld depends greatly on the severity of the violation. For very minor issues, such as tag miscategorizations, we will simply ask you to fix the problem on your work. Violations of other portions of the Content Policy may result in content being temporarily hidden or permanently deleted, and/or a penalty being applied to your account.

    +
    Will I be notified if my work is hidden or deleted, or if I get suspended?
    +

    If your work is hidden, you'll receive an automatic email informing you that it's been hidden and providing you with a direct link to the work. You must be logged in to your account to access the hidden work.

    +

    If your work is deleted, you'll receive an automatic email informing you that it's been deleted. A copy of the work will be attached to that email.

    +

    In addition, the Policy & Abuse committee will also separately email you to explain why your work was hidden or deleted. If you've received an automatic "your work was hidden" or "your work was deleted" notification without also receiving an explanatory email from the Policy & Abuse committee, please check your spam folder. If you still can't find it, please contact the Policy & Abuse committee to let us know that you didn't receive our explanation.

    +

    If you are suspended, the email from the Policy & Abuse committee will inform you why you are suspended and how long your suspension will last. You will be further reminded automatically by the site if you attempt to post, edit, or delete content during the suspension period. If you were asked to edit or delete violating content on your account, you must wait until your suspension has ended in order to do so. You will not receive an email notification when your suspension is over.

    +
    I received an email from the Policy & Abuse committee, but I don't agree with or understand their decision. How do I appeal?
    +

    If you were contacted about something you did that is in violation of the AO3 Terms of Service, you can appeal the decision or request clarification by replying directly to the original email. If you cannot locate the email notifying you of your violation (please check your spam folder), you can submit an Abuse report, but please do not submit multiple appeals before receiving a response to the first one. Submitting multiple appeals will delay the processing of your appeal, because it creates more paperwork for us to handle before we can respond to you.

    +

    If you submitted a complaint and were told that the subject of your complaint is not in violation of the Terms of Service, then you can appeal the decision by replying directly to that email.

    +

    At least one Policy & Abuse administrator who was not previously involved with the original investigation will evaluate all information provided in an appeal to determine whether or not the appeal should be granted. Additional reviewers may be involved at the discretion of the Policy & Abuse committee. Please note that it may take some time to process your appeal and inform you of the result. The Policy & Abuse committee's decisions are final.

    +
    Are there any appeals that you will not grant?
    +

    In general, we do not email users or respond to complaints until after we have investigated the reported content and determined whether or not a violation of the Terms of Service has occurred. In order to appeal successfully, you will need to provide evidence demonstrating that our original decision was incorrect or did not adhere to the Terms of Service. If you only tell us "I want to appeal", then you haven't provided enough information for us to overturn our original ruling.

    +

    If you are notified that your content was removed in order to resolve a lawsuit or mitigate other liability, an appeal is unlikely to succeed. These cases are extremely rare, and are thoroughly discussed and reviewed at multiple levels before any action is taken.

    +
    If I disagree with the Policy & Abuse committee's decision, can I appeal to someone else, like the Support committee or the OTW Board?
    +

    No. If your appeal to the Policy & Abuse committee was rejected, you cannot appeal to any other committee. The Policy & Abuse committee is the final authority on TOS violations. To protect user privacy, other committees such as the Support committee and the OTW Board of Directors do not have information about Policy & Abuse cases. If you file an appeal with a different committee, they will simply forward the complaint to the Policy & Abuse committee or tell you to contact Policy & Abuse directly.

    +
    I was given a deadline to edit or delete my work, and I have done so. What happens next?
    +

    After the deadline, a member of the Policy & Abuse committee will review your work. The following situations may occur:

    +
      +
    • If you have already deleted your work, then there is no further action you need to take.
    • +
    • If you sufficiently edited your work, we will verify your edits. If your work was hidden, we will unhide the work. You will not receive a notification when your work is unhidden.
    • +
    • If you didn't sufficiently edit your work, and the work was not already hidden, we may hide the work. Please review the original email you received from us and contact us promptly if you don't understand what further edits you need to make. Failure to make all required edits may result in the deletion of your work.
    • +
    • If your work was hidden and you did not edit or delete all violating content, we will delete the work. You will automatically be emailed a copy of the work.
    • +
    +

    As a general rule, we will not review content in advance of any stated deadlines. While we strive to review content promptly after the deadline, the Policy & Abuse committee is composed entirely of volunteers. We therefore cannot guarantee a timeframe in which your content will be reviewed.

    +
    I was given a deadline to edit or delete my work, but I'm not going to make it in time. Can I have an extension?
    +

    If you need an extension on a deadline, please reply to the email the Policy & Abuse committee sent you. The Policy & Abuse committee will accommodate requests for extensions, within reason. Note that any hidden content will usually remain hidden during any extensions.

    +
    My work was removed by the Policy & Abuse committee. Can I repost it?
    +

    Works that have been hidden or deleted due to violations of the Terms of Service may not be reposted as-is. If you don't understand why your work was removed, do not re-upload the work. Instead, contact the Policy & Abuse committee to request clarification.

    +

    If you know what the original problem with the work was, you may be able to edit the work and upload a non-violating version. However, if you have not sufficiently edited your work and the new work is still in violation, you may be reported again. Violating the Terms of Service in a manner similar to a previous violation is grounds for suspension.

    +
    What if the violating content was posted years ago?
    +

    Content that is in violation of the Terms of Service may be reported and removed regardless of how long it has been since it was posted. The user responsible for uploading the violating content may be warned or suspended, subject to the discretion of the Policy & Abuse committee.

    +
    What do the different penalties mean?
    +

    Penalties are issued by the Policy & Abuse committee as a result of violating the Terms of Service. They are defined as follows:

    +
      +
    • +

      Warning: A warning is a formal notification to a user who has posted content that violates the TOS. Warnings do not affect the function of the user's account, but they are a permanent administrative record and a reminder not to repeat the behavior. At the discretion of the Policy & Abuse committee, a warning may be issued as a result of minor or unintentional violations of the TOS. A user who has previously received a warning and who violates the TOS again, especially in the same or a similar manner, is likely to incur a suspension.

      +
    • +
    • +

      Temporary Suspension: A temporary suspension is a time-limited restriction on the uploading of new content and creation of new accounts. During this time, the suspended user cannot upload new content, nor can they edit or delete content uploaded prior to the suspension. The duration of each suspension is subject to the discretion of the Policy & Abuse committee. A user who has previously been suspended and who violates the TOS again, especially in the same or a similar manner, may incur a longer temporary suspension or a permanent ban.

      +
    • +
    • +

      Permanent Suspension: A permanent suspension is a permanent ban on the uploading of new content and creation of new accounts. Permanently suspended users retain the right to remove, but not edit, content uploaded prior to their suspension.

      +
    • +
    +
    What happens to a user's works or other content when they are temporarily suspended?
    +

    In general, non-violating content is not removed from the site when a user is suspended. If a user is temporarily suspended, then they will be able to edit or delete their content after their suspension is over. Otherwise, suspended users who wish to delete their fanworks may contact the Policy & Abuse committee to have this done for them.

    +

    A user who has been temporarily suspended is not permitted to upload new content while they are suspended. Any new content uploaded to AO3 during the suspension would automatically be in violation. Such content may be removed and/or the alternate account(s) may be suspended. The duration of the original suspension may also be extended at the discretion of the Policy & Abuse committee.

    +

    After the suspension has ended, the user will have full access to their account(s) again.

    +
    What happens to a user's works or other content when they are permanently suspended/banned?
    +

    Permanent suspension doesn't delete someone's account or content. In general, any content that doesn't violate the Content Policy or other parts of the Terms of Service will remain on the account unless the user deletes it themselves or requests that the content be deleted by the Policy & Abuse committee.

    +

    A user who has been permanently suspended is not permitted to create a new account or upload new content to AO3. Any new content or accounts created by a permanently suspended user would automatically be in violation. The content may be removed and/or the alternate account(s) may be permanently suspended.

    +
    What sort of things would lead to each type of penalty?
    +

    It's impossible to define everything in advance. We are most concerned with people who are actively and deliberately hostile to the community. Small and honest mistakes are likely to result in warnings, especially on a first offense. More serious or deliberate violations of the Terms of Service may justify temporary suspension on a first or subsequent offense. Repeated and/or particularly severe TOS violations may result in permanent suspension.

    +
    What constrains the Policy & Abuse committee's discretion?
    +

    We are committed to building a community that welcomes anyone with a willingness to learn the rules while also safeguarding against those who intentionally violate them. Our discretion is aimed at that objective. We strive to handle all Abuse reports consistently, no matter which volunteer is doing the work. Procedurally, appeals undergo review by multiple Policy & Abuse committee members, and we require consensus or majority vote for major decisions. Our internal decision-making processes are designed to build in checks on individual discretion without trying to resolve every possible situation in advance.

    +
    What happens if someone who's a friend of someone on the Policy & Abuse committee is involved in a complaint?
    +

    We expect the members of the Policy & Abuse committee to behave professionally, even though the Organization for Transformative Works is an all-volunteer organization. We take the responsibilities of serving on the Policy & Abuse committee seriously, and a member of the team with a personal relationship to any party in a complaint is expected to recuse themselves entirely from the case, and, of course, to maintain our standards of confidentiality at all times. Failure to do so is grounds for dismissal from the Policy & Abuse committee.

    +
    AO3 is still being actively developed. How will the Abuse Policy apply to planned future features?
    +

    Since new features may be added at any time, the Abuse Policy only applies to active features. As we develop features, we will strive to be transparent and communicate with users about our policies as much as possible.

    +

    Back to Top | Abuse Policy and Procedures FAQ

    +
    +

    Content Policy FAQ

    +

    Answers to common questions about the Content Policy are available below. If you have additional questions that are not covered here, you can contact the Policy & Abuse committee.

    + +

    General Questions about the Content Policy

    +
    + +
    Table of Contents
    +
    + +
    +
    What is "content"?
    +

    Content is anything that you post on AO3 or otherwise submit to us. This includes, but is not limited to:

    +
      +
    • works
    • +
    • bookmarks
    • +
    • comments
    • +
    • tags
    • +
    • collections
    • +
    • links
    • +
    • icons
    • +
    • embedded text, image, audio, or video files
    • +
    • usernames and pseuds
    • +
    • profile and pseud descriptions
    • +
    • fannish next-of-kin information
    • +
    • Personal Information, such as an email address
    • +
    • any other item of information or type of content
    • +
    +

    All content on AO3 must comply with our Content Policy.

    +
    What happens if someone posts content that violates the Content Policy?
    +

    We do not prescreen content on AO3, nor do we review content that has not been reported to us. If you believe you have encountered content that violates our Terms of Service, you will need to submit an Abuse report.

    +

    The Policy & Abuse committee will investigate each report and independently determine whether a violation of the Terms of Service has occurred. Penalties may be applied to the accounts of users responsible for posting violating content. For more information, please refer to the Abuse Policy and Procedures FAQ.

    +

    Back to Top | General Questions about the Content Policy

    +
    +

    Offensive Content vs Illegal Content

    +
    + +
    Table of Contents
    +
    + +
    +
    Why doesn't AO3 remove extremely offensive content?
    +

    The Archive of Our Own was created in 2008 as a response to several challenges fandom faced at the time.

    +

    One common challenge was that platforms would unilaterally remove content without warning. The decisions were often shaped by the platform owner's preferences or determined by what was more friendly to advertisers. This meant that platforms frequently banned explicit sexual content.

    +

    Such prohibitions were often disproportionately enforced against minorities and marginalized groups. For example, fanworks featuring LGBT+ characters were (and still are) more likely to be reported and removed for having "sexual content". This is due to societal bias: a story featuring a romantic relationship between two women would be considered more sexual or adult than one with an equivalent relationship between a man and a woman. Such works would either be required to have a higher rating or were often removed entirely.

    +

    Biased enforcement of content rules has been shown to occur even when the purpose of the rule is to push back against discrimination. For example, rules intended to reduce racial hate speech on social media often end up being disproportionately enforced against racial minorities speaking out against racism or discussing their own lived experiences. To date, the problem of unbiased content moderation hasn't been solved by any large internet site.

    +

    Challenges such as these led AO3 to adopt a policy that welcomes all forms of fictional, transformative fanwork content. Our mission is to host transformative fanworks without making judgments based on morality or personal preferences. If it's a fictional fanwork that is legal to post in the United States, then it is welcome on AO3. This approach is intended to reduce the risk that content will be removed as a result of cultural or personal bias against marginalized communities.

    +

    We recognize that there are works on AO3 that contain or depict bigotry and objectionable content. However, we are dedicated to safeguarding all fanworks, without consideration of any work's individual merits or how we personally feel about it. We will not remove works from AO3 simply because someone believes they are offensive or objectionable.

    +

    All users who would like to avoid encountering particular types of content are recommended to make use of our filters and muting features.

    +
    Why does AO3 allow fanworks about things that are illegal in real life?
    +

    AO3's Terms of Service are designed to comply with United States law. It is legal in the U.S. to create and share fictional content about murder, theft, assault, or other such crimes. It is also generally legal in the U.S. to create and share fictional content about topics such as child sexual abuse, rape, incest, or bestiality. AO3 allows users to post and access fiction about all of these topics.

    +

    In accordance with U.S. law, AO3 prohibits Child Sexual Abuse Material (sexually explicit photorealistic images of real children). However, stories and non-photorealistic artwork are allowed, both under U.S. law and on AO3. Fiction about real people is still fiction, and therefore it is allowed on AO3.

    +

    Depending on your country of residence or citizenship, the laws that apply to you may be more restrictive than those of the United States. All users are responsible for following the laws that apply to them. If certain content on AO3 is illegal for you to access, then you should ensure you carefully observe all relevant ratings and warnings, and avoid opening any work that indicates it may contain such content.

    +
    What does banning "sexually explicit or suggestive photographic or photorealistic images of real children" mean, particularly for works featuring sexual content with underage characters?
    +

    Sexually explicit photographs, videos, and other photorealistic images of children (also known as Child Sexual Abuse Material, or CSAM) are prohibited in the United States and on AO3. Users who embed, link to, solicit, distribute, or otherwise provide access to such material will be banned and reported to the appropriate authorities.

    +

    Stories and non-photorealistic artwork (such as drawings or cartoons) that depict sexual activity involving characters under the age of eighteen are allowed, provided that the works are properly rated and carry the appropriate Archive Warning. However, photographic or photorealistic images of humans may not be used to illustrate works featuring underage sexual content. This includes (but is not limited to) photographs of children, porn gifs, photo manipulations, computer-generated or "AI" images, or other linked or embedded images that could potentially be mistaken for photographs of real humans.

    +

    We understand that not all photorealistic images of humans are actually documenting the real-life abuse of a child or derived from illegal material, but we decided to use a guideline that can be uniformly applied without relying on subjective judgment. If the work appears to feature underage sexual content (as indicated by the "Underage Sex" Archive Warning or other contextual markers present in the work's tags, notes, or text), then the Policy & Abuse committee may require all photographic or photorealistic images of humans, regardless of age, to be removed from the work.

    +
    Does AO3 screen for quality?
    +

    No. We welcome creators and fanworks of all skill levels, and we will never remove a work on account of its quality, grammar, spelling, or punctuation.

    +
    How can I avoid works that contain content I don't want to encounter?
    +

    When browsing a tag, you can use the Filters sidebar to filter out works. If you are on a mobile device, select the "Filters" button at the top of the page to bring up this sidebar. Adding tags under the Exclude section will remove all works that use an excluded tag. For example, you can exclude any ratings and Archive Warnings that you don't want to encounter (make sure to also exclude the non-specific Rating and Archive Warning tags). You can also exclude other types of tags that users have chosen to add to their works.

    +

    You can use the Search within results box to filter works using keywords. This searches the metadata (title, summary, tags, and beginning/end notes) of a work, but not the chapter notes or body text. You can also use the following symbols to refine your search:

    +
      +
    • A minus sign (-) in front of a word (or a phrase in quotes) in the "Search within results" box will filter out all works that have the word anywhere in their metadata.
    • +
    • An asterisk (*) before or after your search term will allow you to look for partial matches.
    • +
    • If your search term has multiple words, using straight double quotation marks ("like this") on either side of your search term will allow you to search for the exact phrase. Single and/or curly “smart” quotation marks will not work.
    • +
    +

    For example, if you enter -sex* into the "Search within results" box, your results will exclude any works with metadata that contains words beginning with "sex" (including "sex", "sexual", "sexy", etc).

    +

    Once you have a search setup that works for you, you can bookmark the page in your browser in order to return to it later. If there's content you want to avoid on AO3, we recommend using filter keywords and browser bookmarks to exclude that content from what you encounter while browsing.

    +

    If you need help using filters, please contact the Support committee.

    +
    How can I avoid encountering works or other content by a specific user? What about anonymous or orphaned works?
    +
    Mute a specific user
    +

    If you want to avoid all content by a specific user, you should mute the user. To mute a user, go to their dashboard by following the link in their username. Then select the "Mute" button in the top-right corner, and confirm that you want to mute them on the next page. Muting a user means you will no longer be shown their works, series, bookmarks, or comments while browsing AO3. Please note that muting is a separate function from blocking.

    +
    Mute a specific work
    +

    If you want to hide a specific work (for example, a specific anonymous or orphaned work), you can mute it with a site skin. To do so, create a site skin and add .work-000 { display: none !important; } to it, replacing 000 with the ID of the work you want to mute. The work ID number can be found in the work's URL immediately after /works/. For example, 000 would be the work ID of https://archiveofourown.org/works/000/chapters/123. Make sure to apply your site skin after you've created it. You can contact the Support committee if you have any problems using site skins.

    +
    How can I prevent a user from commenting on my works or interacting with me?
    +
    Block a registered user
    +

    If you want a registered user to stop interacting with you, you can block the user. To block a user, select the "Block" button on any of the user's comments or on their user profile or dashboard, then confirm that you want to block them on the next page. Blocking a user means they cannot comment on or kudos your works, reply to your comments elsewhere, or give you gifts outside of a Challenge. Please note that blocking is a separate function from muting.

    +
    Block guest (anonymous) users
    +

    If you want to prevent a guest user from commenting on your works, you can disable guest comments or only allow registered users to access your works. You may also want to enable comment moderation.

    +

    To prevent guest users from replying to your comments on other users' works, go to your Preferences page and enable "Do not allow guests to reply to my comments on news posts or other users' works (you can still control the comment settings for your works separately)". Remember to select the "Update" button at the bottom of the page to save any changes to your preferences.

    +

    Back to Top | Offensive Content vs Illegal Content FAQ

    +
    +

    Fanworks and Non-Fanwork Content

    +
    + +
    Table of Contents
    +
    + +
    +
    What kinds of fanworks can I post?
    +

    AO3 allows a wide range of fanworks other than fanfiction, including but not limited to art, videos, crafts, games, fanmixes, authorized podfics, authorized translations, fannish nonfiction, original fiction, and more. You can post any non-commercial, non-ephemeral fanwork. Here are some examples of allowed fanwork content:

    +
      +
    • A retelling of an existing story from another character's point of view
    • +
    • An original fantasy story about a modern person traveling to medieval times
    • +
    • An alternative version of a published novel in which there's a zombie apocalypse
    • +
    • The supporting text for an original adventure for a tabletop roleplaying game
    • +
    • A fannish essay about vampire biology, or the same essay in audio or video form
    • +
    • Short clips of footage from existing sources, edited over a song to make an argument or tell a story
    • +
    • Artwork (such as a drawing) of an iconic scene from a book, movie, or TV show
    • +
    • A comic about the romantic adventures of a playful thief
    • +
    • Photographs of a crocheted (amigurumi) character you made
    • +
    +
    What if what I want to post isn't similar to one of the examples listed above?
    +

    In general, you can post any non-commercial, non-ephemeral, transformative content you created that is fannish in nature. If you're uncertain if your work can be posted on AO3, you can always contact the Policy & Abuse committee to ask.

    +
    How will "ephemeral" be defined?
    +

    Ephemeral content is material that exists primarily to share someone's impressions, reactions, or feelings about a current event, fandom, or trend. If the content contains limited analytical or interpretive content, or lacks any artistic material, it is likely to be classified as ephemeral. Some examples of ephemeral content include live reactions, announcements about upcoming fanworks, and requests for prompts.

    +

    While it may benefit general fannish history to keep a record of such moments, AO3 is not intended to host all content that is fannish in nature. This type of content is often better suited for social media, personal sites, or blogging services. The Organization for Transformative Works also runs Fanlore, a wiki about fanworks and fan communities, including fandom trends and current events.

    +

    Please use your best judgment. Our general policy is to defer to creators in cases of doubt; however, the Policy & Abuse committee has final discretion in determining ephemerality.

    +
    Can I post original fiction?
    +

    Yes. Original works are allowed, unless the work would be in violation of some other part of the Terms of Service.

    +

    Our vision of AO3 is for all fanworks, including those beyond traditional fanfiction, fanart, and fanvids. Original stories and artwork, including those imported as part of an Open Doors project, are permitted. Some examples of original fiction that we host include original slash, anthropomorphic works, and Regency romance. However, works intended for commercial publication are not suitable for AO3. The Policy & Abuse committee has final discretion in maintaining AO3's focus on non-commercial fannish works.

    +

    We generally presume that, by posting the work to AO3, the creator is making a statement that they believe it's a fanwork. As such, original work will be allowed to remain unless the work is in violation of some other part of the Terms of Service, such as our plagiarism or non-commercialization policies.

    +
    Can I post nonfiction?
    +

    Fannish nonfiction, which includes what is called "meta" by some fans, is allowed. However, it must still be fannish in some way and contain some kind of analytical or creative content. In addition, as an Archive whose goal is preservation, we want permanent, non-ephemeral content. If the content is meant to be ephemeral, such as a liveblog of episode reactions, it should be posted on a social media account rather than on AO3.

    +

    Examples of fannish nonfiction and things that are not fanworks are available below.

    +
    What falls within the definition of fannish nonfiction?
    +

    Examples of fannish nonfiction allowed on AO3 include:

    +
      +
    • Discussions of fannish tropes
    • +
    • Essays designed to entice other people into a fandom
    • +
    • Commentary on fandoms
    • +
    • Documentaries or podcasts about fandom
    • +
    • Explanations of the creative process behind one or more fanworks
    • +
    • Tutorials for creating fanworks
    • +
    • Guides for fan-created gaming campaigns
    • +
    • Detailed analyses of multiple fanworks
    • +
    • Essays on characters' narrative arcs in canon
    • +
    • Comparisons of the film and comics versions of a source
    • +
    +

    This isn't an exhaustive list – fannish nonfiction may take many other forms.

    +

    We will generally defer to the creator's characterization of a work as fannish nonfiction as long as it has a reasonably perceptible fannish connection, either to a specific source or to fandom in general, and takes the form of an independent, non-ephemeral commentary. However, not all nonfiction falls within our mandate. Please consider what isn't fannish nonfiction before posting your work. While we acknowledge the complexity of certain cases that may fall on the boundaries of categories, setting limits is necessary to maintain AO3's manageability for our dedicated volunteers and users.

    +
    What are some examples of non-fanwork content that should not be posted as works on AO3?
    +

    The examples are potentially limitless, but here are some examples that do not fall under AO3's definition of fannish fiction or nonfiction and should not be posted as a work:

    +
      +
    • ephemeral content (including personal journal or diary entries, reactions, or blog posts)
    • +
    • episode transcripts, reposted canon material, and other non-transformative fandom content
    • +
    • primarily autobiographical or non-fandom-related essays (for example, your science, math, or philosophy homework, even if it contains a reference to a fannish source)
    • +
    • lists of names, titles, or statistics (such as information about a character's name, age, pronouns, and personality traits) that contain little to no other analytical, narrative, or descriptive content
    • +
    • discussions of specific fandom-related events (such as conventions or debates over particular incidents), which are considered more appropriate for Fanlore
    • +
    • general statements, questions, or complaints about a person or group
    • +
    • suggestions that other fans contact the creator through email or other social networks
    • +
    • links, lists, or requests for recommendations, whether of fanworks or published works
    • +
    • ads for roleplaying partners, sessions, servers, sites, or games
    • +
    • advertisements, offers, and giveaways
    • +
    • technical instructions (for example, a recipe for making ice cream, or a list of steps explaining how to assemble an ice cream machine)
    • +
    • faceclaims, fancastings, or other reference lists (such as collections of photographs, media, or other resources)
    • +
    • a single word or phrase repeated hundreds or thousands of times
    • +
    • prompts or requests for prompts
    • +
    • announcements, placeholders, or updates about future, existing, or deleted works
    • +
    • an explanation of why a work was removed from AO3
    • +
    +

    Works that incorporate fannish content in clearly bad faith are not fanworks. For example, a work primarily composed of fic search requests is not a fanwork even if there are a few sentences of fandom-specific content.

    +

    In general, we presume good faith on the part of our users, and ask that you do the same for the fans who make up our Support and Policy & Abuse committees. The Policy & Abuse committee will exercise its discretion, which is final, in the service of maintaining AO3 as a place focused on non-ephemeral fanworks.

    +
    How will you draw the line between fanworks and non-fanworks?
    +

    The presumption is that a work is a fanwork, but if it's clear from context (summary, tags, notes, etc.) that it's not, it may be removed for violating the Content Policy. The Policy & Abuse committee will consider many factors when determining if something is a fanwork, such as whether the reported content is transformative, ephemeral, or fannish in nature.

    +

    Additionally, original works that are not based on a specific media source (canon) are considered fanworks. Please see Can I post original fiction? for more detail.

    +
    Can I post a "placeholder" work to tell other fans that I intend to post my story soon?
    +

    Placeholders are not allowed on AO3. This includes works in progress that do not have any story content, works where only the summary and tags have been posted, and lists of ship names, character profiles, or ideas for what you plan to publish. You can create a draft to edit your tags or preview your work before posting it publicly, but please don't post the work unless you have at least one chapter of your fanwork that is ready to be shared with other people.

    +
    Can I post fancastings for my story as a separate work? What about character notes or profiles?
    +

    A work that is simply a collection of actors' photos paired with character names would not be considered a fanwork, nor would a work that only consists of statistics or summaries of canon elements (such as what you might find on a fannish wiki). However, if you include more in-depth analytical, descriptive, or narrative content, then we would likely consider that fannish analysis (meta), which is allowed. An example would be an extended analysis of the character traits that led you to choose that particular fancasting.

    +

    If you would like to post fancastings, statistics, or a summary about your own fanwork, you can include it in the fanwork's notes or post it as an extra chapter inside the fanwork.

    +
    Can I post "incorrect quotes"?
    +

    No. The incorrect quotes meme format involves a collection of quotes where the names have been substituted with the names from a different source. While the amount of quoted text is relatively small, replacing names and minor rewording of quotations is not sufficiently transformative to make the resulting content a fanwork.

    +
    Can I post non-textual works (such as fanart, fanvids, or podfic)?
    +

    We currently don't host multimedia content other than user icons, though you can embed various kinds of files that are hosted elsewhere if it's a fannish transformative work (or part of one) and otherwise complies with the Content Policy. However, for technical and legal reasons we don't allow all kinds of embeds. Please read our policies about embedding images that you did not create, podfics of stories that you did not write, images that depict explicit content, and images in works featuring underage sexual content. In addition, keep in mind that embeds may break for various reasons, including trouble with the hosting site.

    +
    Can I post "directors' cut" or "commentary" versions of my own fanworks?
    +

    We consider those versions of your fanworks, so you may post them as you would any other fanwork. We suggest that you distinguish them from non-commentary versions, for example by adding "[Directors' Cut]" in the title or tagging them to indicate the difference between the original and the "DVD-style" version.

    +
    Can I post announcements or status updates as separate works? What about if I post it as a chapter of my fanwork?
    +

    No, you cannot post announcements or other blog-style updates as separate works. Status updates and other author notes are considered ephemeral content. If you want to discuss a fanwork you've posted or plan to post on AO3, we suggest including such information on your profile page or in the notes or comment sections of your existing fanworks.

    +

    In general, adding several announcement chapters to an existing fanwork will not cause your entire work to become a non-fanwork. However, if you want to talk extensively about your works or personal life, then we recommend linking to a social media site in the notes of your fanworks instead of posting announcement chapters.

    +
    Can I post roleplay ads?
    +

    No. Requests or calls for roleplay partners are not fanworks. We encourage you to seek and advertise for roleplaying partners or servers on your preferred social media platform(s) instead.

    + +

    No. Please use our search functions for this rather than creating a separate work. You can use our Work Search or Bookmark Search, or select a particular tag and then use the Filters sidebar to further refine the results.

    +

    Should you find that this is not sufficient to locate the work you are seeking, your preferred internet search engine (such as Google or DuckDuckGo) may be able to search for distinctive phrases within the work text itself. You can perform an AO3-specific sitewide search by adding the search term site:archiveofourown.org, which will limit your results to pages on AO3.

    +

    If you require assistance from other users, we advise seeking out fandom-specific or pairing-specific fic-finding communities on social media platforms such as Tumblr, Reddit, or Discord, whose members will be more than happy to help you locate the works you are looking for.

    +
    I have an idea that other people might want to write. Can I post my prompt or challenge as a work?
    +

    No. Please create a prompt meme to offer suggestions or challenges to other people, rather than posting a work.

    +
    Does that mean I can't write a short story scene or snippet and suggest that others continue where I left off?
    +

    A short, distinct piece (such as a drabble or vignette) would be considered a fanwork. If you have written a full scene or outlined the plot in enough detail that it could count as a fanwork in and of itself, that would also be allowed.

    +

    However, if you only have a handful of sentences or bullet points and there isn't much plot or characterization, that may be considered a non-fanwork placeholder or prompt. If your primary reason for posting the work is to offer ideas or suggestions for other people, please create a prompt meme instead of posting a work.

    +
    I want other people to give me prompts or requests for fanworks they'd like to see. Can I post a work so that they'll have a place to do that?
    +

    No, you cannot post a work that is only a request for other people to give you prompts. Please create a prompt meme instead. You can share the link to your prompt signup form on social media or in the notes of your fanworks.

    +
    Can I post a letter to someone I've been anonymously matched with for a challenge?
    +

    No. Since this content is designed to be ephemeral (it is directed at a particular person for a particular event), please do not create a separate work for it. If the challenge is hosted on AO3, please put your letter in the optional details for the challenge. If you want to share your general preferences such as your favorite fandoms or tropes, you can put that information in your profile.

    +
    Can I create a list of recommendations or a list of works that use certain tropes? If I want to include commentary on the fanworks I am recommending, would that count as meta?
    +

    Posting a "rec list" (one or more recommendations as a work) may be a violation of our non-fanwork policy. Please use our bookmark feature for this purpose instead. Bookmarks can include commentary, be marked as recommendations, and organized with tags or into collections.

    +

    Criticism of a fanwork is permitted in the tags or notes of a bookmark and will not be considered harassment. However, no matter its location on the site, all commentary must comply with our other policies, including our harassment policy.

    +

    The difference between a recommendation versus a general meta-discussion or analysis of a fanwork is determined through several factors, such as whether the content is ephemeral in nature or if it contains analytical or interpretive content. A work is more likely to be a non-fanwork if it's just a list of titles and summaries (such as a "Top 10 List" or "Recs for Fluff Fics") or if it's similar to a product review (for example, "This is the best slow burn fic in the fandom and here's why you should read it"). If the work contains extended commentary or analysis about the nature of the recommended work, it is more likely to be considered a fanwork and allowed on AO3.

    +

    Please use your judgment on the best way to categorize such commentary.

    +
    Are there any limits to what I can use AO3 bookmarks for?
    +

    On AO3, bookmarks are intended for organizing and recommending fanworks hosted on any site (not just AO3). For example, you can bookmark fanfic from FanFiction.Net, fanart on DeviantArt, fanvids on YouTube, or meta posts on Tumblr. However, you should not create a bookmark for something that isn't a fanwork. Bookmarking a news article, meme, or reaction gif would be in violation of our non-fanwork policy because those aren't fanworks.

    +

    In addition, please keep in mind that bookmarks are also subject to all of our general content rules, including our policies against harassment, commercial promotion, and copyright infringement. For example, you cannot use bookmarks to link to illegally distributed copies of copyrighted material.

    +

    As offsite ("external") bookmarks are described by users, their actual content may differ from the descriptions offered. Please exercise caution when following any links away from AO3, including external bookmarks.

    +

    Back to Top | Fanworks and Non-Fanwork Content FAQ

    +
    +

    Commercial Promotion

    +
    + +
    Table of Contents
    +
    + +
    +
    Why is commercial promotion prohibited on AO3?
    +

    The Organization for Transformative Works is committed to the defense and protection of fans and fanworks from commercial exploitation and legal challenges. AO3 was created to give fan creators a non-commercial space to share their works.

    +

    It is part of AO3's mission to remain a non-commercial space, so all forms of commercial promotion and activities are prohibited. AO3 isn't the right place for offering merchandise or requesting donations, whether for yourself or others. We enforce the non-commercialization policy strictly.

    +
    What kinds of things are considered "promotion, solicitation, and advertisement of commercial products or activities"?
    +

    Some examples of commercial activities include:

    +
      +
    • linking to or referencing the use of a commercial platform or the monetization features of a non-commercial platform
    • +
    • providing a "tip jar", bank information, or other method for people to give you money
    • +
    • offering paid commissions or other content in exchange for money, gift cards, or similar
    • +
    • stating that a fanwork was created as a result of a donation or paid commission
    • +
    • encouraging donations to a person or cause
    • +
    • listing potential benefits of a paid membership or subscription
    • +
    • posting free previews for paywalled content
    • +
    • advertising a paid service or product (linking to an item's product page, suggesting that others purchase an item, etc.)
    • +
    • selling merchandise, even if the merchandise is fannish in nature
    • +
    • discussing the sale of the creator's other works, even if that paid content is not itself hosted on AO3
    • +
    • creating or promoting an app or website that charges money to access works posted on AO3
    • +
    +

    In general, if a financial transaction is involved, you cannot discuss it on AO3. Commercial activity is prohibited regardless of the reason why the commercial activity is occurring.

    +
    What do you mean by "commercial platform"?
    +

    A commercial platform is a site whose primary purpose is to facilitate the exchange of money. This includes online storefronts as well as tipping, patronage, subscription, and crowdfunding services. Linking, discussing, or referencing someone's presence (including your own) on a commercial platform is prohibited.

    +

    Examples of commercial platforms include, but are by no means limited to:

    +
      +
    • Amazon, Etsy, Redbubble, and other online storefronts
    • +
    • Patreon, Ko-fi, and other patronage, tip-jar, or subscription services
    • +
    • Kickstarter, GoFundMe, and other crowdfunding services
    • +
    • PayPal, Venmo, and other money transfer services
    • +
    +

    As stated, this list is non-exhaustive. If the primary function of the platform involves allowing someone to give someone else money, then you should not advertise your presence on it in any way.

    +
    What do you mean by "monetization features of a non-commercial platform"?
    +

    Sometimes sites mainly dedicated to some other purpose (such as social media or image/audio/video hosting) will also have features or subsections of their platform dedicated to monetization. For example, DeviantArt is primarily a free-to-use art gallery and social media website, but it does have some specific sections of its platform that are commercial in nature, such as DeviantArt's Shop, Commissions, Premium Galleries, and Core Memberships. In such cases, you are allowed to link to content on the "free" portion of the website, so long as the page you are linking to is non-commercial in nature. However, linking to or mentioning the monetized content is not allowed.

    +
    Can I link to my Tumblr, Discord, Linktree, Wordpress, or other social media account or personal website? What if my profile or pinned post on that site has a link to a commercial platform?
    +

    In general, linking to your social media accounts or personal website is fine, even if you sometimes post about commercial activities on that site. However, you may not link to accounts, posts, sites, or pages that reference commercial activity in the URL, or that are primarily commercial in nature (such as a Carrd that lists your published novels and explains where to buy them). In addition, you may not provide instructions anywhere on AO3 for finding your commercial content elsewhere (for example, stating that information about your paid commissions is available on a specific webpage even if you don't link directly to that page).

    +
    I am a published author. Can I let people know what my pen name is or what my books' titles are?
    +

    Stating in general terms that you have written a book or providing your pen name is fine, even if you use that pen name for commercial works. However, you may not use AO3 to promote your commercial works, tell people where they can find or buy those works, or otherwise advertise your commercial works in a manner that could encourage others to seek out and purchase the works.

    +
    Can I ask for donations or tips on my account profile or my original works?
    +

    No. Our non-commercialization policy applies everywhere on AO3, including user profiles, comments, fanworks, and works in the "Original Work" fandom. Asking for donations or tips is considered engaging in commercial activities and is not allowed anywhere on the site.

    +
    Can I post the first chapter of my published original novel on AO3?
    +

    Posting a preview or advertisement for a commercial work is not allowed. This includes uploading only a "snippet" to promote a larger paid work, as well as removing significant portions of a fanwork that has been "pulled to publish" professionally. Even if it contains some fannish content, sharing excerpts intended to promote or sell paid content is prohibited.

    +
    I post all of my fanworks on AO3 for free, but I also have paid supporters on another site who get new chapters a week early. Can I let readers know that these "early access" chapters exist, if I don't explain how or where they can subscribe?
    +

    No. If you provide an "early access" service in exchange for money, you cannot reference it on AO3. This includes stating that additional "bonus content" is available elsewhere, regardless of whether you plan to make the content available to the public in the future. Advertising paywalled content is not allowed even if you don't provide instructions, include links, or name a specific commercial platform.

    +
    The stories posted on my Patreon are free for anyone to read, even if they're not one of my Patrons. Can I link to one of these stories from AO3?
    +

    No. Sites like Patreon are considered commercial platforms because their primary purpose is to enable creators to receive funding from their fans. Linking to commercial platforms is not allowed, even if some content on the platform is free.

    +
    I would like to thank one of my clients or patrons (someone who supported me monetarily). Can I acknowledge them in the notes of my work?
    +

    You may not indicate anywhere on AO3 that other people are financially supporting you due to your fanworks. This includes stating that they paid for a commission, donated money to you or others, or are a patron or paid subscriber. However, you are allowed to name someone in a non-commercial manner, such as by crediting them for a prompt or by using the Gift feature to dedicate your work to them.

    +
    This creator's work is amazing! Can I leave a comment telling them they should set up a tipping or subscription service, publish their work commercially, or otherwise get paid for it?
    +

    No. Our non-commercialization policy applies to the entirety of AO3, including the comments section of other users' works. Encouraging other users to engage in commercial activity is prohibited.

    +
    I paid someone else to create a story, artwork, or podfic. Can I post or link to their work, or suggest that other people commission them too?
    +

    You may not encourage commercial activity on behalf of someone else, which includes encouraging people to purchase a commission. If you are embedding commissioned images, audio, or videos, you must ensure that there are no ads, links, or watermarks for any commercial platforms. In addition, you may only upload someone else's work if you have their explicit permission to do so.

    +
    I take paid commissions on another site. Can I post the fanworks I create on AO3 and say that they were commissioned? Can I invite other people to commission me?
    +

    Offering paid commissions is not allowed. This includes posting links to pricelists or payment request forms. However, you are allowed to post fanworks that were created upon request and credit the person who made the request. If you do so, you must not indicate that you received payment for the commission or that you are available to create other paid commissions. Because not all commissioned fanworks were created for pay, we do permit usage of the word "commission" as long as there is no indication that a monetary transaction was involved in the creation of the work.

    +
    Can I post a work that was created for a charity drive or auction?
    +

    Yes. AO3 will host fanworks of any origin, including fanworks created in response to charity events or other challenges. A link to a charity to explain the origin of a fanwork is appropriate, but please do not link directly to any fundraising sites or pages. You may state that a work was produced for a particular charity event, project, or other entity, as long as you do not mention donating, bidding, or any specific contribution amounts or donation platforms.

    +
    Does that mean I can't ask people to support a charity or non-profit organization?
    +

    You are allowed to link to a charity's website, encourage people to learn more about the charity, or explain why you believe in its mission. However, you may not link directly to the charity's donation form, promote their fundraisers, or request that people donate to them.

    +
    Can I post a work that was originally part of a for-sale or charity zine, and if so, can I name the zine?
    +

    Yes. However, you may not encourage users to buy the zine or its merchandise, such as by linking to an advertisement or to a sales or orders page.

    +
    What if a zine or other merchandise is available on an optional "pay what you want" basis? On sites like Gumroad, it's possible to access or download the content completely for free.
    +

    Links to product purchase pages are not allowed, even if payment is optional. If the content is hosted on a non-commercial site that doesn't offer payment options, you can link to that site instead.

    +
    I created merch for one of my fanworks. I'd like to hold a giveaway and send it to one of my readers for the cost of shipping. Since I'm not making money off of it, can I advertise this on AO3?
    +

    No. Since this involves an exchange of money, it is considered a commercial activity regardless of whether you personally make a profit.

    +
    I bought some fan merch. Can I post an image of what I bought and talk about it in my work notes or comments?
    +

    In general, yes. However, you cannot encourage other users to go and buy it themselves. This includes providing links or directions to the place where you purchased the merchandise. You may want to take your own photographs in order to avoid linking to the product page.

    +
    I've created a mobile app with features that make AO3 easier to navigate and use. Can I charge people to use my app?
    +

    No. It is a violation of the Terms of Service to charge users money for access to content on AO3. That includes, for example, operating an app that restricts access to works on AO3 behind a paywall, or copying works from AO3 to sell.

    +
    Can I talk about prohibited commercial activities on AO3 if I don't include any direct links or name any commercial platforms?
    +

    No. Both direct and indirect references to commercial platforms or activities are not allowed.

    +
    Do the rules against commercial promotion mean that I can't write fanworks that reference real-world businesses or feature characters engaging in commercial activities?
    +

    No. You are allowed to create fanworks in which the characters engage in or reference commercial activities as part of the fictional story. For example, you could create a fanwork in which one character is an OnlyFans creator and another subscribes to them or buys their merchandise. However, you cannot link to or otherwise promote any real-world subscription, merchandise, or other commercial activity.

    +

    Please keep in mind that all Abuse reports are reviewed by the human volunteers on our Policy & Abuse committee. In general, we presume good faith on the part of our users. However, if we conclude that someone is deliberately trying to circumvent our rules by having fictional characters discuss commercial activities, then the fanwork may be deemed commercial in nature and unacceptable to post on AO3.

    +

    Back to Top | Commercial Promotion FAQ

    +
    + +
    + +
    Table of Contents
    +
    + +
    +
    What makes a fanwork "transformative"? Why is a "transformative work" not a copyright violation?
    +

    Copyright protects an individual's expression of an idea, not the idea itself. "Expression" refers to the work created, such as the wording of a paragraph in a book, while an "idea" covers general plots or tropes. For example, posting a transcript of a movie without permission constitutes copyright infringement, as it replicates a significant part of the original work (the spoken dialogue) exactly. In comparison, a transformative fanwork reframes existing material in a unique manner, such as retelling a superhero movie from the perspective of civilians.

    +

    The Supreme Court of the United States has explained transformative use as "add[ing] something new, with a further purpose or different character, altering the first [work] with new expression, meaning, or message." Essentially, by significantly reinterpreting the original material, the creator of a transformative work makes a new, distinct creation that does not require the copyright owner's permission to create or share.

    + +

    Yes. AO3 maintains that fanworks are transformative and that a fanwork's creator owns the rights to the expressions in their work that are unique to them. A fanwork creator holds the rights to their own content, just the same as any professional author, artist, or other creator.

    +
    May I post someone else's fanworks, giving them credit?
    +

    You may only post someone else's fanworks if they granted you permission to do so. If you do not have the creator's permission, you cannot post their work. Including a disclaimer that the work is not yours or crediting the original creator is not sufficient. Posting and then anonymizing or orphaning the work is also not allowed. Please use our bookmark feature to share other people's fanworks instead of reposting their works.

    +

    If you do have the creator's permission, you can upload their fanwork as long as you provide appropriate credit. For example, you could add the creator's name and include links to the work on the original site and to the place where they gave you permission.

    +

    If you created or moderate a fanwork archive or mailing list, you may be eligible to become an authorized Open Doors archivist and import your archive to AO3. The Open Doors committee will work with approved moderators to contact and fully credit the original creators of the fanworks, giving the creators as much control over their fanworks as possible.

    +
    Can I post a translation or a podfic of someone else's work?
    +

    Translations and podfics can be posted only if you have permission from the copyright owner (usually the creator or publisher) of the original work. If you do not have permission, then you may not post your work.

    +

    Under United States copyright law, translations and audiobooks are considered "derivative" works – not transformative works. Derivative works cannot be posted without the copyright holder's consent. AO3 adheres to U.S. law, so if you want to post a translation or podfic of a fanwork, you need the fanwork creator's permission.

    +

    If the original work is no longer under copyright because it is old enough that it has entered the public domain, refer to How do these rules apply to works that are in the public domain?

    +
    Can I post a conversion or adaptation of someone else's work? This is a type of work where the original content is modified slightly to fit a different fandom, ship, character, or format.
    +

    While you are welcome to create a fanwork that is based on or inspired by another work, you may not take someone else's work and only make minor changes to it (such as swapping out the names, changing the formatting, or rewording the original text). Unless the fanwork creator or copyright owner granted you permission to modify, convert, or adapt their work in this manner, posting this kind of work is a violation of our Terms of Service, even if you provide credit.

    +
    Can I post a sequel, prequel, or continuation of another fanwork? What about a recursive fic that's completely different from the original fanwork?
    +

    Yes. Fanworks based on other fanworks are also transformative, and are allowed. You can use the "Inspired By" feature to link to the original creator's work. Unlike with reposts, conversions, podfics, and translations, you don't need permission to create a recursive fanwork. However, you cannot include large excerpts from the original work unless the original creator gave you permission to do so.

    +
    What if the original creator deleted or orphaned their work, or posted it anonymously?
    +

    Even if someone deletes or orphans their work, or posts it anonymously, they still hold the copyright to their own work. If the original creator has chosen to remove their fanwork from the internet, or cannot be contacted, then please respect their decision. You cannot post, convert, podfic, or translate someone else's work without their explicit permission, even if you credit them or disclaim credit for yourself.

    +
    How can I obtain permission to post, convert, podfic, or translate someone else's work?
    +

    Some fanwork creators may list "blanket permission" statements in their profile or in the tags or notes of their work. An example of a blanket permission statement would be "Anyone can translate my works so long as they provide me credit and link back to the original here on AO3." In such cases, you have permission if and only if you meet the conditions of the permission statement.

    +

    If a creator doesn't have a blanket permission statement, then you can try to contact them directly and ask. This could be by commenting on their work or asking them via social media or email (if they have shared that information publicly). If the creator responds and gives you permission, then you're good to go. If they refuse or do not respond, then you do not have their permission and you may not post the work.

    +
    Can I post a transcript of a movie or a TV show?
    +

    Scripts of movies, TV shows, and plays are subject to copyright, just like published books, songs, poems, photographs, artwork, and other works. Transcribing and posting the content of a copyrighted work is not allowed. However, you may include a limited number of short quotes in your fanwork.

    +
    Can I post "reaction fic" or "MST3K or DVD-commentary–style" versions of other works? This is a type of fanwork where characters read/watch another work (such as the original canon or a popular fanwork) and "live react" to scenes or dialogue.
    +

    If you have permission from the copyright owner or if the work is in the public domain, then your fanwork can include as many quotes from the original work as you like.

    +

    If the work is still under copyright and you don't have permission from the copyright owner, then you can describe or paraphrase scenes to allude to what the characters are reacting to and include timestamps, page numbers, or occasional short quotes from the original. However, you cannot quote or otherwise reproduce large amounts of dialogue, lyrics, text, or other copyrighted material. If someone could access a substantial portion of the original material by skipping over your additions, your work likely violates our Terms of Service.

    +
    May I post the full lyrics of a song or an entire poem that isn't in the public domain without the copyright holder's permission?
    +

    No. Posting large portions of text from a song or poem is not allowed, unless it is in the public domain or you have the copyright owner's permission. You are only allowed to quote a limited amount of material from a copyrighted work, even if the lyrics or stanzas are broken up by your own original text. You can link to a licensed site such as Genius or Poetry Foundation instead.

    +
    Can I post a fanvid that uses a full song without the copyright owner's permission?
    +

    Fanvids where the audio is an entire song are allowed, so long as you have added or remixed a substantial number of visuals to accompany the song such that the video becomes a transformative work. For example, simply posting the text of the song's lyrics to accompany the song would not be considered transformative. A video consisting of an entire song accompanied by two or three long, unedited clips from a movie would also not be considered a transformative work.

    +
    Can I post character playlists or fanmixes?
    +

    A "fanmix" is a thematic compilation of songs curated by a fan to reflect a character, chapter, setting, theme, or other element of a work. If you wish to post character playlists or fanmixes, you may use licensed streaming sites such as Spotify, 8tracks, or YouTube. You may not provide links that could deliver individual music file downloads (such as a single zipped file containing music files) unless you have the right to distribute downloads (for example, a fan song or filk you composed and sang, a work in the public domain, or a Creative Commons-licensed download). Please also keep in mind that you may quote lyrics as part of a transformative work, but you may not reproduce the entire song text unless you have the right to do so. In addition, if you just post a list of song titles without including any way to listen to the songs, then your work may not be considered a transformative fanwork.

    +
    Can I embed someone else's artwork or photos to accompany a work that I wrote, or post someone else's story to accompany the art I created for it?
    +

    If you have the artist's or writer's permission, then you may embed or upload their work alongside your own as long as you credit them appropriately. If you do not have the creator's permission, you cannot repost their work, even if you credit them. We recommend that you instead provide a link to wherever the original creator has chosen to host it.

    +
    How do these rules apply to works that are in the public domain?
    +

    If a work is in the public domain, then it is no longer copyrighted. In this case, you can use as many excerpts from it in your fanwork as you like.

    +

    However, a public domain work is not in and of itself a fanwork. You cannot simply upload a public domain work to AO3 or make minor alterations such as replacing names or synonyms. You need to add your own content in order for your work to be considered a fanwork.

    +

    If you create your own fan translation or podfic of a public domain work, you can post your work on AO3. However, you can't repost someone else's translation or podfic without their explicit permission. Translations and audio recordings have their own copyright separate from the source work's. The translator or podficcer has ownership over their own specific translation or recording, even if the underlying work is in the public domain.

    +
    If I want to file a plagiarism or copyright infringement complaint, is there anything in particular I should include in my report?
    +

    Yes – please make sure you provide a link to the original work as well as a link to the infringing work in your report description. If you don't tell us what the original source is and which work is infringing upon it, then we may not be able to uphold your complaint.

    +

    If you want to report multiple instances of plagiarism or copyright infringement by a single user, please submit only one report rather than reporting each link individually. We'll be able to process your complaint faster if you take the time to compile all relevant links, excerpts, and other information into a single report and correctly pair each infringing work with the original source.

    +

    If you are reporting multiple works by different users, please submit a separate report for each user.

    +
    Can I submit a plagiarism complaint even if I am not the original creator whose work was stolen?
    +

    In general, yes, as long as you include a link to the alleged source work. If we cannot compare the two works, we will not be able to uphold your complaint. However, in some cases, we may require a report or other evidence from the original creator.

    +
    Can I submit a plagiarism or copyright infringement complaint even if the original work is not hosted on AO3?
    +

    Yes. However, such reports must include a link to the alleged source work. If we cannot compare the two works, we will not be able to uphold a complaint of plagiarism or copyright infringement.

    +
    Do you have a Digital Millennium Copyright Act (DMCA) notice and takedown policy?
    +

    Yes. Before filing a DMCA takedown notice, please read our DMCA Policy carefully. If you have any questions, contact the Legal committee.

    +

    DMCA takedowns and counternotices are not handled by the Policy & Abuse committee. Please do not submit both an Abuse report and a DMCA notice about the same content, as this may delay the processing of both requests.

    +
    What happens if someone reposts my fanwork to another site without my permission?
    +

    The Organization for Transformative Works does not hold the copyright to your fanworks, so we cannot contact other sites or organizations on your behalf. Because you are the copyright owner, you will have to contact the other site yourself to request that they remove the unauthorized copy of your work.

    +

    Back to Top | Copyright Infringement and Plagiarism FAQ

    +
    +

    Fannish Identities and Impersonation

    +
    + +
    Table of Contents
    +
    + +
    +
    I posted a guest comment that contained information about me. Can you delete it?
    +

    If the comment contained personal information sufficient to identify you in the real world (such as a full legal name, an email address, or a phone number) then you can contact the Policy & Abuse committee to request its removal. However, we will not remove guest comments simply because they contain a first name, username, or online handle.

    +
    I orphaned a work, and later realized that it contained my personal information. Can you delete it?
    +

    We will not delete orphaned works that don't violate our Terms of Service. However, if you left identifying information on an orphaned work (such as your name, email address, or social media account) and you would no longer like that information to be public, then you can contact the Support committee to request the removal of that specific information from the work.

    +
    What does banning "impersonation" mean? Does this mean I can't post first-person real-person fiction (RPF)?
    +

    We do not permit users to misrepresent themselves as another person or entity (such as a corporation or government agency), particularly in order to deceive others, violate our Terms of Service, or otherwise cause harm.

    +

    Roleplay is permitted when the assumption of such a persona is clearly disclosed (such as in a user profile or in another manner appropriate under the circumstances) and it doesn't otherwise violate the Terms of Service, including the harassment policy. Fiction (including RPF in first-person format) clearly marked as such will not be considered impersonation. Please consult our RPF policy for further information.

    +
    Can I use a celebrity name as a pseudonym, or is that impersonation?
    +

    In general, you can use a joke celebrity pseudonym, or roleplay as a celebrity, so long as you clearly disclaim that you are not actually that person.

    +
    What do you mean by banning impersonation of a "function"? Does this mean I can't have fake Tumblr or TikTok messages in my fanwork?
    +

    You're allowed to mimic functions inside fictional content, so long as the content is clearly fictional – fiction is not impersonation. However, if you're posting content outside of a fictional context, then you can't do so in an impersonating manner. For example, using the username "orphaned_account" is not allowed, as that could cause users to confuse your user page with AO3's official orphan_account.

    +

    Back to Top | Fannish Identities and Impersonation FAQ

    +
    +

    Harassment

    +
    + +
    Table of Contents
    +
    + +
    +
    Does the harassment policy cover everyone, or just AO3 users?
    +

    Both AO3 users and non-users can complain about harassment. The line between user and non-user can be blurry, so our policy covers both. However, writing RPF (real-person fiction) never constitutes harassment in and of itself, even if the content is objectionable. Please refer to our RPF policy for more information.

    +
    Does the harassment policy apply to every part of AO3?
    +

    Yes. This includes works, tags, comments, usernames, pseuds, profiles, icons, and every other type of content that can be submitted to, hosted on, or embedded on AO3, now or in the future. The harassment policy applies to everything a user does on AO3 and all communications with AO3 volunteers.

    +

    The use of any tool or feature could constitute harassment if it's being used to create a hostile environment. When investigating harassment, we will consider relevant context. For example, someone who has a username, pseud, or icon that is negative towards an individual or group could harass those people by leaving comments on their works, even if that same username, pseud, or icon would not be harassing in other contexts.

    +
    Is criticizing fanworks allowed? Is criticism a violation of the harassment policy?
    +

    Criticism is allowed on AO3 and is not considered harassment. This includes negative commentary in comments, bookmark notes, bookmark tags, and other locations. Criticizing a work is not a personal attack against the person who created that work, nor against people who enjoy that work. Issuing personal attacks or threats against other users for creating or enjoying a work is harassment and is not allowed.

    +
    How does the harassment policy apply to comments?
    +

    Criticism of a fanwork, even harsh criticism, is not by itself harassment. All creators have control over the comments on their works, and can delete comments or block users for any reason.

    +

    Calling a creator evil, wishing them harm, and repeatedly posting negative commentary in a manner designed to be seen by the creator (such as by posting multiple negative comments on their work) are potential examples of harassment.

    +
    Is it harassment if someone deletes my comment? My comment wasn't criticizing or attacking them.
    +

    No. Fanwork creators have control over the comments posted on their work. They can remove, freeze, moderate, or restrict comments as they please. This is never considered to be harassment.

    +
    Is it harassment if someone blocks me? They had no reason to do it.
    +

    No. Being blocked by someone is never harassment. If you are blocked by someone or if they told you to leave them alone, you are expected to stop interacting with them. Attempting to interact with someone after they have blocked you may be considered harassment.

    +
    Somebody bookmarked my fanwork and added a note to it that is really negative about my work. Is that harassment?
    +

    Criticism of a fanwork, even harsh criticism, is not by itself harassment. We do not consider criticism of a fanwork to be a personal attack against its creator. However, if the bookmark note includes harassing elements such as personal attacks or threats towards the creator of the work, then that would be considered harassment.

    +
    There's a person in my fandom who is harassing other people. Can I post a work, chapter, comment, or author's note to inform other people in my fandom who they are and that they should stay away?
    +

    No. Creating or sharing a "callout post" about another individual, or encouraging other users to shun them, is harassing behavior. We encourage you to mute and block anyone you don't want to interact with. If you witness or experience harassment on AO3, you should contact the Policy & Abuse committee. If you witness or experience harassment on a different platform, you should contact the moderators or Trust & Safety team for that platform.

    +
    Someone in my fandom is posting really disgusting content that is against the boundaries of the canon creators. Can I comment on their work and ask them to stop?
    +

    We recommend that you avoid engaging with content that you do not like. If you encounter content on AO3 that you find upsetting or disturbing, you should navigate away from the content and use filters or muting to avoid encountering it again. Users are allowed to post fanworks about any topic, regardless of how offensive it is to other users or if the canon creators would approve. If the content doesn't violate a specific clause of our Terms of Service, the fanwork is allowed – we do not remove content for offensiveness. In addition, be aware that joining in on group bullying to force someone to remove their works is likely to be deemed harassment.

    +
    There are some people in my fandom who ship things I think are disgusting or dangerous. I don't want them to comment on my works. Is it harassment if I tell them to stay away?
    +

    If you don't want people to comment on your works, then you should block them. You are allowed to make polite requests that other groups of fans do not interact with you. If you insult those people, or threaten them in any way, you are in violation of our harassment policy.

    +
    What if the tag I want to use is technically threatening, but it's actually a joke? I promise I'm not serious!
    +

    You may not threaten other groups of fans. There is no exception for jokes or memes.

    +
    Is it harassment if someone reports me for violating the Terms of Service?
    +

    As an AO3 user, it is your responsibility to ensure that you are following our Terms of Service. If we receive a report about you, you will only be told about it if our investigation reveals that you did in fact violate our Terms of Service. In such cases, we will let you know about your violation regardless of who reported it.

    +

    While malicious reporting is harassment, such reports are rarely about content that actually violates the Terms of Service. Most reports about violating content are submitted by users who happen to encounter such content during the course of their normal browsing. We do not generally consider a valid report to be harassment of the subject of the report.

    +

    Back to Top | Harassment FAQ

    +
    +

    Usernames, Icons, and Profiles

    +
    + +
    Table of Contents
    +
    + +
    +
    Are there any rules about what I can choose as my username?
    +

    Yes. Aside from technical limitations on your username, all of the regular content rules also apply to usernames. This means that (for example) you can't choose a username that impersonates someone else, or that violates our commercial promotion or harassment policies. Because usernames are highly visible content, we enforce our policies very strictly on usernames.

    +
    Can I reuse a username that belonged to a deleted account?
    +

    Yes, it is possible that a username that is no longer used by its original user will be available to you.

    +
    Someone is using a username on AO3 that I've used on a different site. Can you make them stop or make them give me the username?
    +

    Usernames on AO3 aren't reserved, even if you've used that name before on AO3 or another site. In general, we won't consider the mere existence of a similar or identical username to be impersonation. If another AO3 account is already using your desired username, then you can create a pseud with that name, but you can't make the other person give up their username. However, if someone starts claiming to be you on AO3, or otherwise starts behaving in a harassing manner, then you can submit an Abuse report.

    +
    Why are the rules for user icons more restrictive than the general content rules?
    +

    User icons appear on pages that don't have rating filters, such as user profiles and comments. This means that other users have little ability to avoid encountering them. Therefore, user icons operate under more restrictive rules than rated, tagged, and warned-for content.

    +

    The user icon policy is not the general fanart policy. Although AO3 does not have native media hosting, images and other file types can be embedded in a work. For more information about what is allowed in fanart, please refer to Can I embed explicit images in my fanworks?

    +
    What can be on a user profile?
    +

    User profiles can contain information about the user, such as their fandom preferences and links to other sites on which the user can be found. User profiles must comply with AO3's policies on commercial promotion, harassment, impersonation, copyright, and other general content rules.

    +

    Back to Top | Usernames, Icons, and Profiles FAQ

    +
    +

    Ratings and Archive Warnings

    +
    + +
    Table of Contents
    +
    + +
    +
    What kind of content do you allow?
    +

    AO3 was designed to be a permanent home for all transformative fanworks. We will not remove content from AO3 solely because it contains explicit, offensive, or upsetting material, as long as it doesn't violate any other part of the Content Policy (such as the harassment policy or the non-fanwork policy).

    +

    We allow content of any rating, and all kinds of fictional topics. Users are responsible for reading and heeding the ratings and warnings provided by the creator. If there is a type of content that you don't want to encounter, you should avoid opening any work tagged or rated to indicate that it may contain such content. Risk-averse users should keep in mind that not all content will carry full warnings. If you want to know more about a particular fanwork, you may also want to consult the bookmarks that people other than the creator have used to categorize it.

    +
    What kind of ratings or warnings must be present on works?
    +

    AO3 has a Ratings system and an Archive Warnings system. These provide basic information about the intensity and type of content that may be present in a work. The only rating or warning information AO3 requires is listed within these two systems. Creators may add more information in the summaries, notes, or Additional tags of their works, but they are not required to do so.

    +

    If a creator doesn't want to put a specific Rating and/or Archive Warning on their works, then they can opt out of one or both systems by applying a non-specific Rating and/or Archive Warning.

    +
    What do you mean by non-specific Rating or Archive Warning tags?
    +

    Non-specific tags indicate that the creator has chosen not to use a more specific tag in that field. Any user who wants to avoid a particular rating and/or type of content should also avoid any work labeled with a non-specific Rating and/or Archive Warning. The non-specific Rating tag is "Not Rated", and the non-specific Archive Warning is the "Creator Chose Not To Use Archive Warnings" label. (Tags are also sometimes referred to as labels.)

    +
    What is the Ratings system?
    +

    AO3 has five different rating tags that creators can apply to their works:

    +
      +
    • General Audiences: The content should be suitable for all ages.
    • +
    • Teen and Up Audiences: The content may be inappropriate for audiences under 13.
    • +
    • Mature: The content may contain adult themes (sex, violence, etc.) that aren't as graphic as Explicit-rated content.
    • +
    • Explicit: The content may contain explicit adult themes, such as detailed sex scenes, graphic violence, etc.
    • +
    • Not Rated: This non-specific rating tag means that the creator has chosen not to rate their work. It may contain content that is general, explicit, or anything in between.
    • +
    +

    If a creator doesn't want to apply a specific rating to their work, they are always welcome to use the non-specific "Not Rated" label.

    +
    Are there any rules about how I must rate my work?
    +

    If your work contains graphic or detailed sex, violence, gore, or other adult content, then you may not rate it "General" or "Teen". Whether you choose to rate the work "Mature", "Explicit", or "Not Rated" is up to you.

    +
    If I don't choose a rating, what's the default?
    +

    The default rating is the non-specific "Not Rated" tag.

    +
    What does the "Not Rated" label mean?
    +

    "Not Rated" means that the work may contain content of any rating – the creator has declined to choose a specific rating. A "Not Rated" work could contain anything from a very fluffy coffeeshop meet-cute to extremely graphic sexual content.

    +
    What's the difference between "General" and "Teen"?
    +

    This is left entirely up to the creator's judgment. People disagree passionately about the nature and explicitness of content to which younger audiences should be exposed. Therefore, the creator's discretion to choose between "General" and "Teen" is absolute: we will not mediate any disputes about those decisions. Instead, we encourage creators to consider community norms, whether fandom-specific or more general (such as how you'd expect a video game or movie with similar content to be rated), when selecting a rating.

    +
    What's the difference between "Teen" and "Mature"?
    +

    If the work contains graphic adult content, it should not be rated "General" or "Teen". In response to valid complaints about a misleading rating, the Policy & Abuse committee may redesignate a fanwork marked "General" or "Teen" to "Not Rated", but in other cases, we will defer to the creator's decision. In general, we will not recategorize a fanwork in response to a complaint when the content at issue is a reference or is otherwise not graphic.

    +
    What's the difference between "Mature" and "Explicit"?
    +

    This is left entirely up to the creator's judgment. Both of these ratings require a user to accept the adult content warning and agree to access adult content in order to access the work. The creator's discretion to choose between "Mature" and "Explicit" is absolute: we will not mediate any disputes about those decisions. Instead, we encourage creators to consider community norms, whether fandom-specific or more general (such as how you'd expect a video game or movie with similar content to be rated), when selecting a rating.

    +
    There's an explicit sex scene in one chapter of my work, but all of the other chapters are really fluffy material that would be suitable for general audiences. Which rating should I choose?
    +

    Individual chapters of a work cannot be rated separately, so the rating chosen should be sufficient to cover the highest-intensity content in the work. If you do not want to use a rating of "Mature" or "Explicit" in such a situation, then you can always opt out of the Ratings system by labeling your work as "Not Rated".

    +
    Does the gender or sexual identity of a character matter when determining what rating to use?
    +

    No. The Policy & Abuse committee will not treat works differently on account of the genders or sexual identities of the characters or the types of relationships featured in the work. Please also note that in general, the creator's choice of rating is presumed to be appropriate.

    +
    Do you ever require a rating change on works rated "Mature" or "Explicit"?
    +

    No. Choosing a rating of "Mature" or "Explicit" is always acceptable. We will not require that ratings be lowered, even if there is no intense or explicit content in the work.

    +
    If I want to avoid explicit fanworks, what ratings should I exclude in my search?
    +

    To avoid all fanworks that may contain explicit content, you should exclude or filter out the "Mature", "Explicit", and "Not Rated" labels.

    +
    What is the Archive Warnings system?
    +

    The Archive Warnings system consists of several warning tags, which creators are able to choose from when posting their fanwork. At least one of the following options must be chosen before a work can be posted:

    +
      +
    • Graphic Depictions of Violence: The work may contain detailed descriptions of gore or graphic violence.
    • +
    • Major Character Death: The work may include the death of a character who is prominently featured.
    • +
    • Rape/Non-Con: The work may contain non-consensual sexual activity.
    • +
    • Underage Sex: The work may contain descriptions or depictions of sexual activity involving characters under the age of eighteen.
    • +
    • Creator Chose Not To Use Archive Warnings: This non-specific warning tag means that the work may contain content pertaining to any of the Archive Warnings.
    • +
    • No Archive Warnings Apply: If this warning tag is used in the absence of other Archive Warnings, it means that the work does not contain detailed content pertaining to any of the four specific Archive Warnings. However, the work may briefly reference an Archive Warning topic and/or contain other intense or unpleasant content that is not covered by any of the Archive Warnings.
    • +
    +

    If a creator doesn't want to apply a specific Archive Warning to their work (for example, if they wish to avoid giving spoilers), they are always welcome to use the non-specific "Creator Chose Not To Use Archive Warnings" label.

    +
    Are there any rules about applying Archive Warnings to my work?
    +

    If your work contains graphic depictions of violence, major character death, depictions of rape or non-consensual sex, or depictions of underage sexual activity, then you must use either the relevant specific Archive Warning or the non-specific "Creator Chose Not To Use Archive Warnings" label.

    +
    Why is the number of Archive Warning tags so limited?
    +

    We wished to limit the number and type of Archive Warnings so that they could be easily used by creators from a wide variety of fandoms, and so that each Archive Warning could be fairly and consistently enforced by our all-volunteer Policy & Abuse committee. We decided that we could not reasonably expect fair enforcement of a rule requiring warnings for concepts beyond those listed in the Archive Warnings.

    +
    Something that I consider really upsetting or unpleasant is not on the list of Archive Warnings.
    +

    Because the Archive Warnings policy is deliberately minimal, this may be the case. We encourage you to use the Additional tags, summaries, and user-provided bookmarks and recommendations to screen for fanworks you'll enjoy, and you may wish to comment on a creator's work when you feel that further tags would be desirable. Please be respectful when you do, and keep in mind that they may choose not to add such extra tags.

    +
    My work includes content that I want to warn other users about, but it's something that's not on the list of Archive Warnings. How can I warn them?
    +

    Creators can add additional information about what their works contain in the Additional tags field. You can also add this type of information to the notes or summary of your work, including the notes and summaries on individual chapters. Doing so is entirely voluntary: the Policy & Abuse committee will not enforce the presence of any warnings outside of the Archive Warnings.

    +
    If I don't choose an Archive Warning, what's the default?
    +

    There is no default Archive Warning, so creators have to choose one or more of the Archive Warning options. A creator can opt out of using a specific Archive Warning by selecting "Creator Chose Not To Use Archive Warnings" instead.

    +
    What does the "Creator Chose Not To Use Archive Warnings" label mean?
    +

    "Creator Chose Not To Use Archive Warnings" means that the creator has opted out of using the Archive Warnings system. A work with this warning may or may not contain content covered by any of the specific Archive Warnings. Users who access a work labeled "Creator Chose Not To Use Archive Warnings" proceed entirely at their own risk, regardless of any other tags on the work.

    +
    Can I include multiple Archive Warnings?
    +

    Yes, you can. For example, you could select both "Major Character Death" and "Underage Sex" if a fanwork contains both elements, or "Creator Chose Not To Use Archive Warnings" and "Underage Sex" if you want to disclose the underage sexual content but don't want to say whether the work contains major character death.

    +
    Can a work have both "No Archive Warnings Apply" and one or more other Archive Warnings?
    +

    Yes. The "No Archive Warnings Apply" label can be added to a work regardless of any other Archive Warnings, so it only has meaning when no other Archive Warnings are present on the work.

    +

    If you would like to avoid encountering works with content pertaining to a specific Archive Warning when browsing AO3, then you should exclude the specific Archive Warning as well as the "Creator Chose Not To Use Archive Warnings" label.

    +
    If a story has only a brief reference to an Archive Warning topic, am I required to use either that warning or the "Creator Chose Not To Use Archive Warnings" label? Or can I still choose "No Archive Warnings Apply" if I think that's a better description?
    +

    This is the kind of decision that is up to the creator's discretion. In general, we will not recategorize a fanwork in response to a complaint when the content at issue is a reference or is otherwise not portrayed in explicit detail.

    +
    What does the "Underage Sex" Archive Warning mean?
    +

    Underage Sex refers to descriptions or depictions of sexual activity involving characters under the age of eighteen (18). In general, we rely on creators to use their judgment about the line between reference and description or depiction. Sexual activity does not include dating activities such as kissing; but again, we rely on creators to use their judgment about what is generally understood to be sexual activity. Creators may always specify the age of the characters in their work.

    +
    Why is "underage" defined as "under 18"?
    +

    Though there is no international consensus, there is a trend to focus on 18 as an important age for depictions of sexual activity. Thus, we decided that 18 would be helpful for the maximum number of users, including audiences as well as creators, though we recognize that no solution is perfect for everyone. We encourage creators and bookmarkers to be more specific in tags or notes where this would be useful to potential audiences.

    +
    What if the age of consent in my local jurisdiction is something other than 18, or if the age of majority in the fictional setting is under 18?
    +

    The "Underage Sex" warning on AO3 is used for fanworks depicting sexual activity involving humans under 18 as measured in Earth years, regardless of the fictional setting or users' local laws.

    +
    What about robots, computer simulations, elves, aliens, vampires who are three hundred years old but were turned into vampires at age 12, etc.?
    +

    The primary use of the "Underage Sex" warning is to identify fanworks depicting sexual activity involving humans under the age of 18 as measured in Earth years. Please use your judgment for other situations. If the fanwork does not include a depiction of sexual activity with a human under 18 years old, then we will not generally consider it "underage sex", though creators may use the Archive Warning if they feel it accurately represents their intent. As always, we encourage creators and bookmarkers to be more specific in tags or summaries where this would be useful to potential audiences.

    +
    What about when a fanwork isn't set during the canon timeline and doesn't specify the characters' ages?
    +

    If the characters' ages in the fanwork are ambiguous, then we will assume the characters have been "aged up", even if they are underage in the canon setting.

    +
    Is "Rape/Non-Con" or "Creator Chose Not To Use Archive Warnings" required for works featuring adult/minor relationships? In real life, that would be considered statutory rape in many jurisdictions, regardless of whether the underage participant was willing.
    +

    No. Archive Warnings apply to the fictional content depicted in the work, so a work featuring a sexual relationship between an adult and a minor would need to use the "Underage Sex" Archive Warning. However, unless a character is clearly depicted in the work as unwilling to engage in sexual activity, then the "Rape/Non-Con" warning (or the "Creator Chose Not To Use Archive Warnings" label) is not required, regardless of the age of any of the characters.

    +
    If consent is unclear or dubious, is the "Rape/Non-Con" or "Creator Chose Not To Use Archive Warnings" label needed?
    +

    The primary use of the "Rape/Non-Con" warning is to identify fanworks depicting characters who are clearly unwilling or otherwise forced to engage in sexual activities. Please use your judgment for other situations. When a fanwork features unclear or dubious consent ("dubcon"), we will defer to the creator's decision on how to categorize their work.

    +
    When is the "Major Character Death" warning needed? What makes a character "major"?
    +

    If a character has a significant presence in the fanwork, and they die during the course of the story, then the work would require the "Major Character Death" warning (or the "Creator Chose Not To Use Archive Warnings" label). This warning is also required when the fanwork is focused on the character's death, even if it happened prior to the start of the work. It doesn't matter whether the character is a main character or a side character in canon – it's what is in the fanwork that counts. For example, even if a character has only one line in canon, a fanwork that is primarily about that character's funeral and how much their partner misses them would merit this warning.

    +
    If a major character dies in my fanwork but later returns to life, does the "Major Character Death" warning apply?
    +

    If the character returns to life or is revealed to not be dead within the same fanwork, then you don't need to apply the "Major Character Death" warning (or the "Creator Chose Not To Use Archive Warnings" label) for this character.

    +

    Keep in mind that Archive Warnings apply to the entirety of an individual fanwork's posted content, not to any drafts or sequels. If you appear to have killed off a significant character in a specific work, but plan for them to return in a future chapter or sequel, we suggest using "Creator Chose Not To Use Archive Warnings" as the content currently posted does feature character death.

    +
    What about vampires, zombies, sentient robots, and other characters that aren't "alive"?
    +

    Please use your best judgment for characters who are or become undead, mechanized, or otherwise non-human. If the character is generally still able to think or act in a somewhat human fashion throughout the course of the story, then the "Major Character Death" warning is not needed. When in doubt, we will defer to the fanwork creator's discretion about whether a character has meaningfully died.

    +
    What if a major character's death is ambiguous or unclear?
    +

    This is the kind of decision that is up to the creator's discretion. In general, we will not recategorize a fanwork in response to a complaint when the content at issue is a reference or is otherwise not graphic.

    +
    Will you ever require that an Archive Warning be removed?
    +

    No. The presence of an Archive Warning indicates that the work may contain such content, but it is not a guarantee. This includes works marked with "No Archive Warnings Apply". If this warning is accompanied by another Archive Warning (including the non-specific "Creator Chose Not To Use Archive Warnings" label), then the other warning has precedence.

    +
    What's the difference between ratings and warnings?
    +

    Ratings are a measure of the intensity of overall content. Warnings refer to a specific type of content that is present.

    +

    For example, a work may be rated Explicit because it describes an extended, violent torture scene, or because it has a detailed depiction of consensual sex – or both. The rating tells you only that there may be adult content, and does not inform you what type of adult content it is. A warning indicates the work may contain an "onscreen" depiction of a specific type of content, and does not inform you of the level of detail in which it is described. For example, a work rated "Teen" might also carry the "Major Character Death" warning.

    +
    What sort of rating and warning information am I required to provide for my fanworks?
    +

    Some users may prefer not to read works with particular ratings and/or warnings, while others may search out works with those same ratings and/or warnings. Our goal is to provide the maximum amount of control and flexibility possible for all users of AO3, both creators and audiences alike, so that each user can customize their own experience. Creators can choose to provide a specific rating and/or Archive Warning(s), or they can choose to opt out of providing a specific rating and/or Archive Warning by using "Not Rated" and/or "Creator Chose Not To Use Archive Warnings", respectively.

    +
    Can I use "Not Rated" but not "Creator Chose Not To Use Archive Warnings," or vice versa?
    +

    Yes, absolutely. For example, you could use "Not Rated" and "Rape/Non-Con" for a work that has an explicit rape scene. Or you could rate a work "General" but choose not to warn about the main character dying by using "Creator Chose Not To Use Archive Warnings".

    +
    How do the ratings and warnings policies apply to embedded images, videos, etc.?
    +

    When making rating/warning decisions, creators should take into account any content within the work, including embedded images and videos. As with all other content, creators' decisions are presumed reasonable, and using "Not Rated" or "Creator Chose Not To Use Archive Warnings" will always be sufficient.

    +
    Can I embed explicit images in my fanworks?
    +

    Explicit drawings and other non-photorealistic artwork are generally allowed to be embedded in a work, as long as the work's rating and warnings appropriately describe both the embedded and the textual content. If you are using other people's images to illustrate your fanwork, you must embed from a source authorized by the creator and provide appropriate credit.

    +

    You may not embed sexually explicit or suggestive photographic or photorealistic images in works that contain underage sexual content or any other contextual indication (such as in the tags, notes, or text of the work) that the characters may be under the age of 18. This includes (but is not limited to) porn gifs, photo manipulations, and computer-generated or "AI" images.

    +
    How explicit or graphic can the summaries and tags on my fanworks be?
    +

    Explicit or graphic content in a summary or tag does not violate the Content Policy, as long as the work is appropriately rated and warned. Please use your judgment about what will best identify and describe your fanworks. The summary and tags are part of your work, and your choice of rating and warnings must reflect all parts of your work.

    +
    Do AO3 personnel prescreen works as they're uploaded to ensure that they comply with the ratings and warnings policies?
    +

    No. We will only review a work that has been reported to us for potentially violating the ratings or warnings policies.

    +
    What's the consequence of a violation of the ratings or warnings policies?
    +

    Please see the Mandatory Tags policy for details. If we uphold a complaint, we will ask the creator to amend the rating or warning as necessary. If the creator fails to do so, the Policy & Abuse committee may add the non-specific "Not Rated" and/or "Creator Chose Not To Use Archive Warnings" labels as appropriate. In general, a fanwork will not be removed from AO3 merely for not being correctly labeled. However, repeated or deliberate mislabeling may result in additional consequences.

    +
    What do you mean by "not all works will carry full warnings"?
    +

    Some creators prefer not to assign specific ratings or warnings to their works, or may not be certain if some content in their work "counts" for a required Archive Warning. Our policy aims to enable creators to opt in or out of using specific ratings or warnings while still allowing users to filter out unwanted content. Works for which creators have opted out of providing specific ratings and/or warnings will be labeled "Not Rated" and/or "Creator Chose Not To Use Archive Warnings". These options aid users in decision-making, albeit with more limited detail than a specific rating or warning tag would.

    +
    What type of rating and warning information will be provided when I am browsing fanworks?
    +

    Users who wish to avoid works labeled with specific ratings or Archive Warnings can filter them out or exclude them from searches. Users trying to avoid all possibility of encountering specific ratings or warnings should also avoid works marked as "Not Rated" or "Creator Chose Not To Use Archive Warnings" in the same way, because these works may contain content pertaining to any rating or warning, respectively.

    +

    Beyond the Archive Warnings, Additional tags can also be used to filter and/or search for works. Users who wish to screen works for other users may also add tags, notes, or recommendations to their bookmarks to warn other users about the subject matter contained in the bookmarked works. This can serve as an extra source of information for users who are trying to determine whether or not to access a work. However, please be aware that Additional tags are not mandatory.

    +

    If a user does not want to see Archive Warnings and/or Additional tags (for example, if they wish to avoid potential spoilers), then they can hide those tags in their preferences. Doing so will not hide any works that carry warning labels, only the warning labels themselves.

    +

    All users are responsible for reading and heeding the warnings provided by the creator. Risk-averse users should keep in mind that our ratings and warnings policies are deliberately minimal, and not all content will carry full warnings. If you want to know more about a particular fanwork, you may also wish to consult the bookmarks that people other than the creator have used to organize it.

    +
    If I'm not logged in, what can I see?
    +

    You can see the summary and tags (including Archive Warnings) of any work whose creator has not restricted access to AO3 users only. In addition, you can access any unrestricted work rated "General" or "Teen" without logging in or clicking anything else. For the other ratings ("Mature", "Explicit", and "Not Rated"), you will be asked to agree that you are willing to see adult content before you can access the work.

    +

    Back to Top | Ratings and Archive Warnings FAQ

    +
    +

    Other Tags

    +
    + +
    Table of Contents
    +
    + +
    +
    What are the minimum criteria for tags in mandatory fields?
    +

    The tags on your work must meet the following criteria:

    +
      +
    • Rating: If the work contains graphic adult content, you must rate the work as either "Mature" or "Explicit", or use the "Not Rated" tag.
    • +
    • Archive Warnings: If the work contains depictions of content described by one of the four specific Archive Warnings, you must apply that Archive Warning tag or the "Creator Chose Not To Use Archive Warnings" tag.
    • +
    • Fandoms: The work may only use fandom tags that directly relate to content currently present in the work.
    • +
    • Language: The language tag must indicate a language used in a major portion of the work text, unless no such language tag is available.
    • +
    +

    If you wish to provide other users with more information about your work, you are welcome to do so using the non-mandatory tag fields (such as Additional tags), your work summary, and/or the notes of your work.

    +
    What is a non-specific tag?
    +

    Some mandatory fields may have non-specific tags, such as "Not Rated", "Creator Chose Not To Use Archive Warnings", or "Unspecified Fandom". These tags indicate that the creator has deliberately chosen not to provide more specific information in the mandatory tag field. For example, sometimes creators aren't certain whether a specific tag would apply, or want to avoid using a specific tag because they believe it would reveal spoilers. Using a non-specific tag is always sufficient tagging for that tag field. The Policy & Abuse committee will not require any work that bears a non-specific tag to have more tags added to that field. Users who wish to avoid certain types of content should avoid all works that use non-specific tags.

    +
    What should I do if no language tag exists for the primary language used in my work?
    +

    If the language is one that you or someone else created, you can use the "Uncategorized Constructed Language" tag. If the language is not a constructed language ("conlang"), please contact the Support committee.

    +
    Will you require an incorrect language tag to be changed?
    +

    In general, we will assume good faith from creators. However, if it is clear that the language tag used does not apply to the work, then we may update the work's language tag.

    +

    In order to report a work that uses an incorrect language tag, please contact the Support committee and make sure to include a link to the work in your report.

    +
    In what circumstances will you remove a fandom tag from a work?
    +

    The Policy & Abuse committee may remove a fandom tag when there is no relationship between the particular fandom itself and the work. For example, a fanwork that discusses vampire physiology and uses only examples from Buffy the Vampire Slayer and The Vampire Diaries should not add in fifteen additional fandom tags simply because those fandoms also feature vampires.

    +

    Note that we will apply this rule restrictively. We will not intervene in cases of disagreement over, for example, whether a movie-based work can use the fandom tag for a comic when there are both movie and comics versions of a source. This is the kind of decision a creator is best suited to make and falls within our policy of deference to the creator.

    +

    If you believe a work's tags are misleading, then we encourage direct, polite conversation with the creator. However, if the work has fandom tags that aren't represented in the work, then you can report that to the Policy & Abuse committee.

    +
    This work is about a fandom that the creator hasn't tagged. Will you require them to add the fandom tag to their work?
    +

    No, we will not require that a creator add a specific fandom tag to their work. However, we may apply the non-specific "Unspecified Fandom" tag if the creator has not applied any suitable fandom tags themselves. If you would like to avoid encountering a particular work, then we recommend that you mute the creator or the work.

    +
    Why do some tags have "RPF" on the end? What's the difference between a fandom tag with RPF and without?
    +

    RPF stands for Real Person Fiction. "RPF" is often used to distinguish fandom tags intended for fanworks about a canon's real-life creators (actors, directors, voice actors, authors, etc.), as opposed to fanworks about the fictional characters that appear in any books, movies, or other canons.

    +

    When you are posting your work, you may find that entering the name of a canon into the fandom tag field results in two canonical tags appearing in the autocomplete, one with "RPF" at the end and one without. If your work is about the real people who created the canon, rather than about the fictional canon itself, then you should use the RPF fandom tag for your work. If your work is about the fictional characters or universe, you should use the non-RPF fandom tag instead.

    +

    In some cases, RPF fandoms and works don't have fandom tags with "RPF" at the end. For example, canonical fandom tags about musicians or bands may consist of the names of those individuals or groups. Fandom tags that consist of the name(s) of real people are also considered RPF fandom tags and can be used on works about those people.

    +

    For more information about RPF and non-RPF tags, please refer to the Tags FAQ. The Policy & Abuse committee may remove fandom tags from your work if you've used a non-RPF tag for RPF content, or vice versa.

    +
    Am I allowed to use an RPF fandom tag if my work is about the reader, or if it contains a self-insert character?
    +

    You should not use RPF fandom tags unless your work is about the real people who contributed to the creation of the fictional canon. If the reader or self-insert character is interacting with the fictional characters from the canon and not with the canon's writers, actors, etc., then the work is not RPF and should only be tagged with the non-RPF fandom tag.

    +
    I'm posting a work that will contain content for a particular fandom in a future chapter that I haven't posted yet. Can I use that fandom tag to advertise the upcoming content of my work?
    +

    No. To use a specific fandom tag, the work must currently contain fanwork content pertaining to that fandom. Once you post a chapter featuring characters from or set in the universe of that fandom, you may add the fandom tag to the work. Until then, you can use the notes, summary, or Additional tags to let other users know about your plans.

    +
    A work is appearing in my fandom's tag even though it's not tagged with or about my fandom. I think the tag the creator used was linked to my fandom by mistake. Can I report that?
    +

    Our volunteer tag wranglers connect tags to each other to help users locate fanworks. However, at times this can lead to unexpected search results. If you believe that a tag has been incorrectly wrangled, you can contact the Support committee with a brief explanation of why these tags shouldn't be connected together.

    +
    I want to report a work that has a wrong language tag and inapplicable fandom tags. Who should I report it to?
    +

    If the language tag is the only miscategorization on the work, you may report it to the Support committee. If there is any other type of miscategorization or violation of the Terms of Service (for example, if the work is not a fanwork or is incorrectly rated), you should report it to the Policy & Abuse committee instead, whether or not there is an incorrect language tag on the work.

    +
    What if a work has an incorrect category, relationship, character, or additional tag?
    +

    The Policy & Abuse committee will only evaluate the accuracy of tags in mandatory fields. We will not add, edit, or remove incorrect category, relationship, character, or additional tags. Our resources are limited and it would be challenging to impartially and fairly establish or enforce accuracy rules for these types of tags. However, our general policies against harassment and spam apply to all tags, as they do to any content posted on AO3.

    +
    Can other users add tags to my fanworks? How does that work?
    +

    The only tags displayed on the fanwork itself will be the tags that the creator added to it. If another user bookmarks the work, they may add tags to the bookmark. Users can search for bookmarks with Tag Search or Bookmark Search. Bookmark tags are also visible when viewing a user's public bookmarks. However, bookmark tags will not impact or appear in results when using Work Search or browsing works listings.

    +
    Someone has added a tag I hate to a bookmark of one of my fanworks!
    +

    We recommend that you mute the bookmarker. In general, tags and notes on bookmarks can be positive or negative. Like any other content, tags are subject to the Content Policy, so if the tag violates our harassment, personal information, or other policies, please report it. However, criticism of a fanwork is not considered harassment in and of itself. Bookmark tags and notes will not automatically be displayed on fanworks, in order to allow you to avoid them.

    +
    Where can I find more information about tags?
    +

    Please check out our Tags FAQ for more information about how tags function and how they are generally used.

    +

    Back to Top | Other Tags FAQ

    +
    +

    Spam and Technical Integrity

    +
    + +
    Table of Contents
    +
    + +
    +
    What's this about the spam filter? Can I be permanently suspended if I fail the filter?
    +

    You shouldn't encounter the spam filter if you're logged in. If we discover accounts created solely to post spam, we will permanently suspend those accounts, but such cases are always reviewed by members of the Policy & Abuse committee. If you're a human being reading this FAQ, you shouldn't worry about the automated spam-control measures.

    +
    What do you mean by "conduct that threatens the technical integrity of AO3"?
    +

    Basically, we mean attempts to hack the site or deliberately exploit a code vulnerability in order to engage in destructive behavior on AO3. Spreading viruses or other unwanted programs, redirecting users to spam sites, or trying to undermine or evade compliance with our Terms of Service through technological means are all examples of attempting to interfere with or threaten the technical integrity of the site.

    +
    Does that mean I can't have nifty formatting in my work?
    +

    No, this is just a security policy. You will be able to have plenty of nifty formatting, but not everything imaginable. As a practical security matter, we do not allow JavaScript in works posted on AO3, and only allow a limited subset of HTML and CSS. This is because there is no secure way to allow people to start uploading unfiltered code. For content that uses a lot of custom code, we recommend hosting it on your own website. You can make a bookmark or post a simpler version on AO3 and link to the fancier version in the notes.

    +
    Do you have a policy on bots or scraping? These are ways of extracting information from or indexing websites.
    +

    The use of bots or scraping for spam, commercial promotion, or other purposes that violate our policies is forbidden. This includes scraping AO3 for the purposes of obtaining material for commercial generative AI or creating an app that hosts or paywalls AO3 content.

    +

    The use of bots or scraping for purposes that do not violate our policies is generally allowed. However, we reserve the right to implement robots.txt or other protocols limiting what bots can do, or to notify you and ask you to discontinue if a bot or scraping program is causing problems for the site. At our discretion, we may also ban specific bots or other programs from accessing AO3.

    +

    Back to Top | Spam and Technical Integrity FAQ

    +
    +

    Privacy Policy FAQ

    +

    Answers to common questions about the Privacy Policy are available below. If you have additional questions that are not covered here, you can contact the Policy & Abuse committee.

    + +

    Information Collection and Use

    +
    + +
    Table of Contents
    +
    + +
    +
    Why do you use cookies?
    +

    Cookies may be required to facilitate and customize your site experience, such as by allowing you to log in to your AO3 account. If you do not accept cookies, you may not be able to use the site. There are many ways to remove both browser history and cookies, and we encourage people who are concerned about privacy to investigate broader solutions. For example, most internet browsers can be set to clear your private data automatically between sessions.

    +
    Which AO3 features collect, process, retain, and/or display my content or personal information, and how do they use it?
    +

    Some AO3 features may display your content to the public, to other AO3 users, and/or to yourself and AO3 administrators.

    +
    Display to the public
    +

    We may collect, process, retain, and display your content to the general public, including any personal information you've included in that content, when you use the following AO3 features:

    +
      +
    • Post or edit a work or chapter, when the work is available to the general public
    • +
    • Create or edit a work skin that is applied to a work that is available to the general public
    • +
    • Edit information about a series, when any work in that series is available to the general public
    • +
    • Create or edit a bookmark, when the bookmark is not marked private
    • +
    • Choose a username or pseud
    • +
    • Edit your profile page
    • +
    • Edit the description for one of your pseuds
    • +
    • Upload an icon
    • +
    • Give kudos, both when you are logged in and when you are not logged in
    • +
    • Create or edit information about a Challenge or other type of Collection
    • +
    • Submit a prompt to a Prompt Meme Challenge
    • +
    • Submit a sign-up to a Gift Exchange Challenge (note: the owners and moderators of the Challenge will have access to your email address)
    • +
    • Post or edit a comment, when you comment on a news post or on a work that is available to the general public
    • +
    +

    We also collect, process, and retain personal information that is associated with the content, including your IP address. We may display this information to AO3 administrators for the purposes of managing the site and enforcing the Terms of Service.

    +
    Display to other AO3 users
    +

    We may collect, process, retain, and display your content to other AO3 users, including any personal information you've included in that content, when you use the following AO3 features:

    + +

    We also collect, process, and retain personal information that is associated with the content, including your IP address. We may display this information to AO3 administrators for the purposes of managing the site and enforcing the Terms of Service.

    +
    Display to yourself and/or to AO3 administrators
    +

    We may collect, process, retain, and display your content and preferences to yourself and/or to AO3 administrators, including any personal information you've included in that content, when you use the following AO3 features:

    +
      +
    • Request an account invitation, whether or not you choose to create an account
    • +
    • Create an account
    • +
    • Save a work in draft form
    • +
    • Create or edit a private bookmark
    • +
    • Update your preferences
    • +
    • Mark a work for later
    • +
    • Favorite a tag
    • +
    • Block a user
    • +
    • Mute a user
    • +
    • Create or edit a site skin
    • +
    • Create or edit a work skin, even without applying it to a work
    • +
    +

    We also collect, process, and retain personal information that is associated with the content, including your IP address. We may display this information to AO3 administrators for the purposes of managing the site and enforcing the Terms of Service.

    +
    Why do AO3 features need to collect, process, retain, and/or display my content or information in the ways that they do?
    +
    Because you want your content or information to be available to other people
    +

    AO3 is a site for fans to share fanworks. When you post a work and set it to be available to the general public, you are agreeing to make that content available to everyone. Similarly, the purpose of using other public-facing AO3 features is because you want that content to be available to the public. When you post a work and set it to be available to registered AO3 users only, you are agreeing to make that content available to those users.

    +

    Similarly, other AO3 features or content may be accessible by all registered AO3 users or only accessible to specific registered AO3 users (such as the co-creator(s) of a work or the maintainer(s) of a collection). The purpose of using these features is because you want that content to be available to those people. For example, if you're collaborating with someone else on a draft work where you have added them as a co-creator, then you want your co-creator to be able to access the draft. If you have submitted a work to a collection, then you have chosen to submit content to a part of AO3 that the collection maintainer controls. In all cases, we need to collect, process, and retain certain information about you and your content in order to make it available to those people.

    +
    Because you want your content or information to be associated with your identity
    +

    Usernames and pseudonyms allow you to develop your account as a fannish identity on AO3. When you take actions while using a username or pseud (as opposed to not being logged in, or not using a pseud), it's because you want your username or pseud to be associated with those actions and/or the content that you've uploaded. In order to connect your actions and content to your AO3 account and/or pseud, we need to collect, process, and retain the associated personal information about your account, including the text you entered for your username or pseud.

    +
    Because you want your content or information to be available to yourself
    +

    Some of our features are designed to let you upload content that you want to access later. For example, when you create a draft work or a private bookmark, use the "Mark for Later" feature, or favorite a tag, your purpose is to be able to return to them later. In order to allow you to do so, we need to collect, process, and retain the content that you provided and the associated information.

    +
    To allow you to customize your AO3 experience
    +

    Several of our features are designed to let you customize the way AO3 is displayed to you or the ways in which other users can interact with you. We need the data collected by these features in order to customize your AO3 experience in the ways you've requested. For example, we need access to your blocklist in order to ensure that users you have blocked can't leave comments or kudos on your works or reply to your comments; and we need access to your mutelist to ensure that you won't be shown works, bookmarks, comments, or series by users you've muted. Similarly, when you update your preferences, we need to collect, process, and retain the content and/or information that you provided in order to implement those preferences for you.

    +
    To operate, maintain, and protect AO3
    +

    In order to be able to enforce the Terms of Service, ensure we are compliant with applicable legislation, and handle any legal matters that may arise, AO3 administrators (such as the Policy & Abuse committee, the Legal committee, and the OTW Board of Directors) may need to view content that was uploaded, or the associated data, even if that content is not visible to the general public or to other AO3 users.

    +

    We also need the data collected by each feature to internally manage AO3. For example, we want to count only one view of a URL per cookie session on the "Hit" count for a work. Temporarily collecting, processing, and retaining the IP addresses of users who leave kudos while logged out permits us to conduct internal management of kudos and avoid duplication of kudos, without requiring you to log in and associate your username with the kudos. Our systems and administrators need the data to manage our services, prevent abuse or spam, and maintain the integrity of AO3.

    +
    To assist you with using AO3
    +

    It's possible you may need assistance with your account. In such cases, the Support committee or other AO3 administrators may need to look at your content or associated data in order to troubleshoot a problem you're having, assist you with using a particular AO3 feature, or diagnose or solve a possible bug. For example, if you're having difficulty with not receiving emails about comments on your works, an administrator may need to check whether your Preferences are set correctly.

    +
    What happens if I change the privacy settings on my work?
    +

    When you post or edit a work on AO3, you can choose to restrict access to other logged-in users only. You can change this setting at any time. If the work was originally accessible to AO3 users only, and you (or a co-creator) update the work to make it accessible to the general public, then the work and any content associated with the work (such as bookmarks, comments, or series) will become accessible to the general public at that time. Similarly, if your work was previously set to be accessible to the general public, and you update the work to make it accessible to AO3 users only, then the content associated with the work will no longer be accessible to the general public.

    +

    If you have a series where all works in the series are only accessible to other AO3 users, and you (or a series co-creator) add to the series a work that is accessible to the general public, then the series content will also become accessible to the general public at that time. This applies to the series content only, and not to specific works in the series, which are all controlled separately.

    +

    You (or a co-creator) can add your work to a collection that is maintained by yourself and/or someone else. Adding your work to an anonymous and/or unrevealed collection will limit some information about and/or access to the work to yourself and to the collection maintainers. The collection maintainers can change the collection settings or remove your work from their collection at any time. You can remove your work from a collection at any time.

    +
    What information can a co-creator access? What privacy settings can they change?
    +

    When you invite a co-creator to a work you've uploaded to AO3, you are giving them the ability to edit or delete the work, add or remove the work from a series or collection, or delete any of its comments at any time, regardless of whether the work has been posted or is still in draft form. Any co-creators of a work can change the privacy settings for that work at any time, without notifying you. If the co-creators of a work have different account preferences regarding their works' accessibility or permissions, the work will adhere to the least restrictive preference. For example, if one co-creator allows their works to be invited to collections, and another co-creator does not, it will be possible to invite the co-created work to a collection.

    +

    When you invite a co-creator to a series you've created, you are giving them the ability to edit or delete the series (but not any works in the series, unless they are also a co-creator of the work(s) in question). If all works in the series are only accessible to other AO3 users, and your co-creator adds to the series a work that is accessible to the general public, then the series content will also become accessible to the general public at that time. This applies to the series content only, and not to specific works in the series, which are all controlled separately.

    +

    We recommend that you do not invite anyone as a co-creator of your work unless you are comfortable with giving that person equal access to and control over that work and the content and settings associated with it. You cannot remove a co-creator from your work after you have invited them. Co-creators can remove themselves from a work at any time.

    +
    What information can a challenge or collection maintainer access? What privacy settings can they change?
    +

    If you add your work to a collection, the owners and moderators of the collection ("collection maintainers") will be able to access (but not edit or delete) the content of the work. They will also know the usernames and pseuds of all creators associated with the work, even if the work is in a collection marked as anonymous or unrevealed. You can remove your work from a collection at any time. A collection maintainer can remove a work from their collection at any time, or remove the "anonymous" and/or "unrevealed" status provided by their collection, without notifying you. When this occurs, the creators' usernames and/or the content of the work will become accessible either to other AO3 users or to the general public, depending on the work settings.

    +

    A maintainer of a Gift Exchange challenge can access sign-ups as well as the usernames and email addresses that participants use to sign up. This is in case the maintainer needs to communicate with the exchange's participants. Maintainers of other types of collections do not have access to other users' email addresses.

    +

    Please note that using this information in any way other than to manage the collection or challenge is a violation of our Terms of Service and may result in the permanent suspension of the maintainer's account.

    +
    If a new feature is introduced, how will it handle my content and personal information?
    +

    If the feature is designed to display content to other users or to the general public, then when you choose to use that feature, your content may be displayed to other users or to the general public. Any personal information or other data we collect will be used to operate that feature and other integrated features on AO3, maintain AO3, and prevent spam and abuse of the feature or AO3. Administrators may have access to any content uploaded with the feature, and associated data, for these purposes.

    +

    AO3 is committed to protecting the privacy of our users. We will never sell your personal information, data, or other content. If you have a specific question about how your content and/or information is collected or used, please contact the Policy & Abuse committee.

    +

    Back to Top | Information Collection and Use FAQ

    +
    +

    User Privacy Rights

    +
    + +
    Table of Contents
    +
    + +
    +
    What information do you sell, trade, or rent to third parties?
    +

    None. We do not and will not sell, trade, or rent information, including your personal information.

    +
    What legal rights do I have under data privacy laws?
    +

    If you are located in the European Union, the United Kingdom, or parts of the United States, you may have rights regarding your personal information or personal data that qualifies as such under the laws of your jurisdiction.

    +

    As provided by the laws of your applicable jurisdiction, these rights may include:

    +
      +
    • The right to know what personal information we have collected about you
    • +
    • The right to request that we provide access to, correct, or delete your personal information
    • +
    • The right to request that your personal information be provided in portable form
    • +
    • The right to not be discriminated against for exercising your legal rights
    • +
    • The right to not be subject to a decision that would affect your legal rights based solely on automated processing of your personal information
    • +
    +
    What lawful grounds does AO3 rely upon to process personal information from users in the EU and the UK?
    +

    We rely on the following lawful grounds to process personal information from users in the EU and the UK:

    +
      +
    • It is necessary for the performance of a contract with you
    • +
    • Our or a third party's legitimate business interest
    • +
    • Your consent
    • +
    +

    If we are processing your personal information based on the grounds that you consented to it, you have the right to withdraw your consent for such processing at any time. Withdrawing your consent does not affect the lawfulness of consent-based processing that occurred prior to when your consent was withdrawn.

    +

    These protections are not limited specifically to users from the EU and the UK. We limit our data processing in this way for all users. If you have questions regarding the protection of your personal information, you can contact the Policy & Abuse committee.

    +
    How do I exercise my rights under data privacy laws such as the General Data Protection Regulation (GDPR) or the California Consumer Privacy Act (CCPA)?
    +

    To exercise the rights available to you as a data subject or consumer under applicable data privacy laws, contact the Policy & Abuse committee. In order for us to confirm your request, the email address you enter must be the one associated with your account (if applicable) and you must be able to send and receive emails from that address. In the subject and description of your request, please specify which data privacy law (GDPR, CCPA, etc.) applies to you, and clearly state what kind of data request you are making (for example, you can request a copy of your personal information). We may require you to submit additional personal information necessary to verify your identity and status as a data subject. Repeated requests within a 1-year timeframe may incur a fee.

    +

    Please note that you may be able to exercise some of these rights without our intervention. For example, if you are a registered user, you can access and update certain personal information via your account preferences.

    +
    What is the procedure for requesting details about the information you sell, trade, or rent to third parties for direct marketing purposes under the California Consumer Privacy Act (CCPA)?
    +

    The CCPA only applies to for-profit entities. Because the Organization for Transformative Works is a non-profit, we are not required to have such a procedure. More importantly, we do not have such a procedure because we do not sell, trade, or rent information to third parties for any reason, including for direct marketing purposes.

    +
    Do you recognize and comply with Do Not Track signals or opt-out preference signals?
    +

    Some web browsers, mobile applications, and operating systems allow users to signal their preferences regarding the tracking of their personal information. These are known as Do Not Track (DNT) signals or opt-out preference signals. AO3 does not respond to DNT or opt-out preference signals because we do not use, sell, or share your personal information for targeted advertising purposes. In addition, we collect only the minimum data necessary to operate the site and/or that you have consented to provide to us. Without this minimum data, you can't access the site.

    +

    If a standard for online tracking is adopted that we must follow in the future, we will inform you about that practice in a revised version of the Privacy Policy.

    +

    Back to Top | User Privacy Rights FAQ

    +
    + + + +

    <%= t("a11y.navigation") %>

    +<%= render "tos_navigation", top_link: true %> + diff --git a/app/views/home/unicorn_test.html.erb b/app/views/home/unicorn_test.html.erb new file mode 100755 index 0000000..c92ac77 --- /dev/null +++ b/app/views/home/unicorn_test.html.erb @@ -0,0 +1,3 @@ +

    +All is well +

    diff --git a/app/views/inbox/_approve_button.html.erb b/app/views/inbox/_approve_button.html.erb new file mode 100755 index 0000000..cbbf7d0 --- /dev/null +++ b/app/views/inbox/_approve_button.html.erb @@ -0,0 +1,7 @@ +<% # expects feedback_comment and approved_from %> + +<% # approve link that works with JavaScript enabled and is otherwise hidden %> +<%= link_to(ts("Approve"), review_comment_path(feedback_comment, approved_from: approved_from.to_s, page: params[:page], filters: @filters), method: :put, remote: true, class: 'hidden') %> + +<% # unreviewed comments page link for users with JavaScript disabled %> +<%= link_to(ts("Unreviewed Comments"), unreviewed_work_comments_path(feedback_comment.ultimate_parent), class: 'hideme') %> \ No newline at end of file diff --git a/app/views/inbox/_delete_form.html.erb b/app/views/inbox/_delete_form.html.erb new file mode 100755 index 0000000..59ca01e --- /dev/null +++ b/app/views/inbox/_delete_form.html.erb @@ -0,0 +1,6 @@ +<% # expects inbox_comment and current_user %> +<%= form_tag user_inbox_path(current_user), method: 'put', class: 'ajax-remove' do %> + <%= hidden_field_tag 'delete', true %> + <%= hidden_field_tag 'inbox_comments[]', inbox_comment.id, id: "inbox_comments_#{inbox_comment.id}" %> + <%= submit_tag ts('Delete') %> +<% end %> diff --git a/app/views/inbox/_inbox_comment_contents.html.erb b/app/views/inbox/_inbox_comment_contents.html.erb new file mode 100755 index 0000000..14f68d8 --- /dev/null +++ b/app/views/inbox/_inbox_comment_contents.html.erb @@ -0,0 +1,31 @@ + + +
    + <% if !feedback_comment.pseud.nil? %> + <% if feedback_comment.by_anonymous_creator? %> + + <% else %> + <%= icon_display(feedback_comment.pseud.user, feedback_comment.pseud) %> + <% end %> + <% else %> + + <% end %> +
    + +
    + <%= raw feedback_comment.sanitized_content %> +
    diff --git a/app/views/inbox/_read_form.html.erb b/app/views/inbox/_read_form.html.erb new file mode 100755 index 0000000..24eb345 --- /dev/null +++ b/app/views/inbox/_read_form.html.erb @@ -0,0 +1,6 @@ +<% # expects inbox_comment and current_user %> +<%= form_tag user_inbox_path(current_user), method: 'put', class: 'ajax-remove' do %> + <%= hidden_field_tag 'read', true %> + <%= hidden_field_tag 'inbox_comments[]', inbox_comment.id, id: "inbox_comments_#{inbox_comment.id}" %> + <%= submit_tag ts('Mark Read') %> +<% end %> diff --git a/app/views/inbox/_reply_button.html.erb b/app/views/inbox/_reply_button.html.erb new file mode 100755 index 0000000..e55bccc --- /dev/null +++ b/app/views/inbox/_reply_button.html.erb @@ -0,0 +1,4 @@ +<% # expects feedback_comment %> +<% unless feedback_comment.ultimate_parent.blank? %> + <%= link_to ts('Reply'), reply_user_inbox_path(current_user, comment_id: feedback_comment, filters: @filters), remote: true %> +<% end %> diff --git a/app/views/inbox/reply.js.erb b/app/views/inbox/reply.js.erb new file mode 100755 index 0000000..a34d6d4 --- /dev/null +++ b/app/views/inbox/reply.js.erb @@ -0,0 +1,9 @@ +$j('#reply-to-comment').show(); +window.location.hash = 'reply-to-comment'; +$j('#reply-to-comment').draggable({ opacity: 0.80 }); +$j('#reply-to-comment').html("<%= escape_javascript(render :partial => "comments/comment_form", + :locals => {:comment => @comment, :commentable => @commentable, :button_name => ts("Comment")}) %>"); +$j('#comment_cancel').click(function() { + $j('#reply-to-comment').hide(); + history.back(1); + }); diff --git a/app/views/inbox/show.html.erb b/app/views/inbox/show.html.erb new file mode 100755 index 0000000..23dbb40 --- /dev/null +++ b/app/views/inbox/show.html.erb @@ -0,0 +1,189 @@ + +

    <%= ts("My Inbox") %> (<%= ts("%{total} comments, %{unread} unread", total: @inbox_total, unread: @unread) %>)

    + +<%= flash_div :comment_error, :comment_notice %> + + + +<% # Filters button for narrow screens jumps to filters when JavaScript is disabled and opens filters when JavaScript is enabled %> + + + + +<% unless @inbox_comments.blank? %> + + <%= will_paginate @inbox_comments %> + + <%= form_tag user_inbox_path(@user, page: params[:page], filters: @filters), method: :put, id: "inbox-form", class: "inbox manage" do %> +
    + <%= ts("Mass Edit Options") %> + + +
    + +
    + <%= ts("List of Comments") %> + +
      + <% @inbox_comments.each do |inbox_comment| %> + <% feedback_comment = inbox_comment.feedback_comment %> + + +
    1. + <% if !can_see_hidden_comment?(feedback_comment) %> +

      <%= ts("(This comment is under review by an admin and is currently unavailable.)") %>

      + <% else %> + <%= render "inbox_comment_contents", feedback_comment: feedback_comment %> + <% end %> + +
      <%= ts("Comment Actions") %>
      + + +
    2. + + <% end %> +
    +
    + +
    + <%= ts("Mass Edit Options") %> + + +
    + + <% end %> + + + + +<% end %> + + + + +<%= form_tag(user_inbox_path(@user), method: :get, class: "narrow-hidden filters", id: "inbox-filters") do %> +

    <%= ts("Filter") %>

    + <%= field_set_tag do %> +
    +
    <%= ts("Filter by read") %>
    +
    +
      +
    • + <%= label_tag "filters_read_all" do %> + <%= radio_button_tag "filters[read]", "all", (!%w(true false).include?(@filters[:read])) %> + <%= label_indicator_and_text(ts("Show all")) %> + <% end %> +
    • +
    • + <%= label_tag "filters_read_false" do %> + <%= radio_button_tag "filters[read]", "false", @filters[:read] == "false" %> + <%= label_indicator_and_text(ts("Show unread")) %> + <% end %> +
    • +
    • + <%= label_tag "filters_read_true" do %> + <%= radio_button_tag "filters[read]", "true", @filters[:read] == "true" %> + <%= label_indicator_and_text(ts("Show read")) %> + <% end %> +
    • +
    +
    + +
    <%= ts("Filter by replied to") %>
    +
    +
      +
    • + <%= label_tag "filters_replied_to_all" do %> + <%= radio_button_tag "filters[replied_to]", "all", (!%w(true false).include?(@filters[:replied_to])) %> + <%= label_indicator_and_text(ts("Show all")) %> + <% end %> +
    • +
    • + <%= label_tag "filters_replied_to_false" do %> + <%= radio_button_tag "filters[replied_to]", "false", @filters[:replied_to] == "false" %> + <%= label_indicator_and_text(ts("Show without replies")) %> + <% end %> +
    • +
    • + <%= label_tag "filters_replied_to_true" do %> + <%= radio_button_tag "filters[replied_to]", "true", @filters[:replied_to] == "true" %> + <%= label_indicator_and_text(ts("Show replied to")) %> + <% end %> +
    • +
    +
    + +
    <%= ts("Sort by date") %>
    +
    +
      +
    • + <%= label_tag "filters_date_desc" do %> + <%= radio_button_tag "filters[date]", "desc", @filters[:date] != "asc" %> + <%= label_indicator_and_text(ts("Newest first")) %> + <% end %> +
    • +
    • + <%= label_tag "filters_date_asc" do %> + <%= radio_button_tag "filters[date]", "asc", @filters[:date] == "asc" %> + <%= label_indicator_and_text(ts("Oldest first")) %> + <% end %> +
    • +
    +
    +
    <%= ts("Submit") %>
    +
    <%= submit_tag ts("Filter") %>
    +
    + <% end %> + <% # On narrow screens, link jumps to top of index when JavaScript is disabled and closes filters when JavaScript is enabled %> + +<% end %> + + +<%= will_paginate @inbox_comments %> diff --git a/app/views/invitations/_invitation.html.erb b/app/views/invitations/_invitation.html.erb new file mode 100755 index 0000000..f3ba9a3 --- /dev/null +++ b/app/views/invitations/_invitation.html.erb @@ -0,0 +1,35 @@ +
    +
    <%= t(".sender") %>
    +
    <%= creator_link(@invitation) %>
    +
    <%= t(".invitation_token") %>
    +
    <%= @invitation.token %>
    +
    <%= t(".copy_link") %>
    +
    + <% unless @invitation.redeemed_at %> + <%= link_to t(".copy_and_use"), signup_path(invitation_token: @invitation.token) %> + <% end %> +
    +
    <%= t(".sent_to") %>
    +
    + <% if @invitation.redeemed_at %> + <%= @invitation.invitee_email %> + <% else %> + <%= form_for(@invitation) do |f| %> + <%= error_messages_for @invitation %> +

    <%= f.label :invitee_email, t(".email_address_label") %> <%= f.text_field :invitee_email %>

    +

    <%= hidden_field_tag :user_id, @user.try(:login) %>

    +

    <%= f.submit %>

    + <% end %> + <% end %> +
    +
    <%= t(".redeemed_by") %>
    +
    <%= invitee_link(@invitation) || "-" %>
    +
    <%= t(".created_at") %>
    +
    <%= @invitation.created_at || "-" %>
    +
    <%= t(".sent_at") %>
    +
    <%= @invitation.sent_at || "-" %>
    +
    <%= t(".last_resent_at") %>
    +
    <%= @invitation.resent_at || "-" %>
    +
    <%= t(".redeemed_at") %>
    +
    <%= @invitation.redeemed_at || "-" %>
    +
    diff --git a/app/views/invitations/_user_invitations.html.erb b/app/views/invitations/_user_invitations.html.erb new file mode 100755 index 0000000..a3a5d6c --- /dev/null +++ b/app/views/invitations/_user_invitations.html.erb @@ -0,0 +1,42 @@ +<% unless @invitations.blank? %> + "> + + + + + + + + + + + + <% @invitations.each do |invitation| %> + + + + + + + <% if logged_in_as_admin? && invitation.redeemed_at.blank? %> + + <% end %> + + <% end %> + +
    <%= t(".table.caption") %>
    <%= t(".table.headings.token") %><%= t(".table.headings.sent_to") %><%= t(".table.headings.username") %><%= t(".table.headings.external_author") %><%= t(".table.headings.copy_link") %>
    <%= link_to invitation.token, (invitation.creator.is_a?(User) ? [invitation.creator, invitation] : invitation) %><%= invitation.invitee_email %><%= invitee_link(invitation) %> + <%# TODO: internationalize this, including .to_sentence (and also do something about the parentheses) %> + <%= invitation.external_author ? "#{invitation.external_author.email} (#{invitation.external_author.names.collect(&:name).delete_if { |name| name == invitation.external_author.email } +.join(',')})" : "" %> + + <% unless invitation.redeemed_at %> + <% if invitation.external_author %> + <%= link_to t(".table.actions.copy_and_use"), claim_path(invitation_token: invitation.token) %> + <% else %> + <%= link_to t(".table.actions.copy_and_use"), signup_path(invitation_token: invitation.token) %><% end %> + <% end %> + + <%= link_to(t(".table.actions.delete"), + invitation, data: { confirm: t(".table.actions.delete_confirmation") }, method: :delete) %> +
    +<% end %> diff --git a/app/views/invitations/_user_invitations_navigation.html.erb b/app/views/invitations/_user_invitations_navigation.html.erb new file mode 100755 index 0000000..abaadc2 --- /dev/null +++ b/app/views/invitations/_user_invitations_navigation.html.erb @@ -0,0 +1,7 @@ +<% if logged_in? %> + +<% end %> diff --git a/app/views/invitations/index.html.erb b/app/views/invitations/index.html.erb new file mode 100755 index 0000000..834bcee --- /dev/null +++ b/app/views/invitations/index.html.erb @@ -0,0 +1,46 @@ + +<% if logged_in_as_admin? %> +

    <%= ts('Create more invitations for this user') %>

    + <%= form_for :invitation, url: user_invitations_url(@user) do |f| %> +

    <%= label_tag "invitation[number_of_invites]", ts('Number of invitations:') %> <%= f.text_field :number_of_invites %> <%= submit_tag 'Create' %>

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

    Invite a friend

    + + + + <%= render "user_invitations_navigation" %> + + + +
    + <% if @unsent_invitations.blank? %> +

    Sorry, you have no unsent invitations right now. <%= link_to ts('Request invitations'), new_user_invite_request_path %>

    + <% else %> +

    You have <%= @user.invitations.unsent.count.to_s %> open invitations and <%= @user.invitations.unredeemed.count.to_s %> that have been sent but not yet used.

    + <%= form_tag invite_friend_user_invitations_path(@user) do %> +
    +
    <%= label_tag "invitation[invitee_email]", t('.email address', :default => 'Email address') %>
    +
    <%= text_field_tag "invitation[invitee_email]" %>
    +
    <%= label_tag :id, t('.choose_invite', :default => 'Choose an invitation') %>
    +
    +
      + <% for unsent_invite in @unsent_invitations %> +
    • + <%= radio_button_tag "invitation[id]", unsent_invite.id, checked: (unsent_invite == @unsent_invitations.first) %> + <%= label_tag 'invitation_id_' + unsent_invite.id.to_s, unsent_invite.token %> +
    • + <% end %> +
    +
    +
    +

    <%= submit_tag t('.submit_invite', :default => 'Send Invitation') %>

    + <% end %> + <% end %> +
    + + + + +<% end %> diff --git a/app/views/invitations/manage.html.erb b/app/views/invitations/manage.html.erb new file mode 100755 index 0000000..97589ea --- /dev/null +++ b/app/views/invitations/manage.html.erb @@ -0,0 +1,31 @@ + +

    <%= logged_in_as_admin? ? (@user.login + "'s") : "Your" %> Invitations

    + + + +<%= render "user_invitations_navigation" %> + + + + + + +<%= render "invitations/user_invitations", invitations: @invitations %> + diff --git a/app/views/invitations/show.html.erb b/app/views/invitations/show.html.erb new file mode 100755 index 0000000..5f4e7e4 --- /dev/null +++ b/app/views/invitations/show.html.erb @@ -0,0 +1,9 @@ + +<% if @user %> + +<% end %> + + + +<%= render :partial => 'invitations/invitation', :locals => {:user => @user, :invitation => @invitation} %> + \ No newline at end of file diff --git a/app/views/invite_requests/_index_closed.html.erb b/app/views/invite_requests/_index_closed.html.erb new file mode 100755 index 0000000..47545d8 --- /dev/null +++ b/app/views/invite_requests/_index_closed.html.erb @@ -0,0 +1,18 @@ + +

    + <%= t(".page_heading") %> +

    + +

    + <%= t(".queue_disabled.html", + closed_bold: tag.strong(t(".queue_disabled.closed")), + news_link: link_to(t(".queue_disabled.news"), admin_posts_path(tag: 143))) %> +

    +

    + <%= t(".already_requested_html", check_waitlist_position_link: link_to(t(".check_waitlist_position"), status_invite_requests_path)) %> + <%= t(".waiting_list_count", count: InviteRequest.count) %> +

    + + + + diff --git a/app/views/invite_requests/_index_open.html.erb b/app/views/invite_requests/_index_open.html.erb new file mode 100755 index 0000000..c787217 --- /dev/null +++ b/app/views/invite_requests/_index_open.html.erb @@ -0,0 +1,38 @@ + +

    + <%= t(".page_heading") %> +

    + +

    +The invite queue may close sometimes. +

    +

    THIS IS AN 18+ ARCHIVE.

    +

    + + + +

    <%= t(".request_invitation_header") %>

    + +<%= form_for(@invite_request, html: { class: "simple" }) do |f| %> + <%= error_messages_for @invite_request %> +
    +

    + <%= f.label :email %> + <%= f.text_field :email %> +

    Please put a little bit about you and a statement affirming you agree with anti harassment & anti-censorship ideals in the field below. Requests without at least something in this field will be deleted without warning.

    +

    <%= f.label :note %> + <%= f.text_area :note, size: "60x10" %> + <%= f.submit t(".add_to_list") %> +

    +
    + +<% end %> + +

    + <%= t(".already_requested_html", check_waitlist_position_link: link_to(t(".check_waitlist_position"), status_invite_requests_path)) %> + <%= t(".waiting_list_count", count: InviteRequest.count) %> + <%= t(".invitation_send_rate", + queue_invitation_number: t(".invitation_number", count: AdminSetting.current.invite_from_queue_number), + queue_frequency: t(".frequency", count: AdminSetting.current.invite_from_queue_frequency)) %> +
    You will get your invite within 1-3 days of submitting your request. The queue is set to several decades from now to allow for manual reviewing of invites; it won't actually take that long!

    + diff --git a/app/views/invite_requests/_invitation.html.erb b/app/views/invite_requests/_invitation.html.erb new file mode 100755 index 0000000..217beb0 --- /dev/null +++ b/app/views/invite_requests/_invitation.html.erb @@ -0,0 +1,28 @@ + +

    + <%= t(".title", email: invitation.invitee_email) %> +

    + + + +

    + <% status = invitation.resent_at ? "resent" : "not_resent" %> + <%= t(".info.#{status}", + sent_at: l((invitation.sent_at || invitation.created_at).to_date), + resent_at: invitation.resent_at ? l(invitation.resent_at.to_date) : nil) %> +

    + +

    + <% if invitation.can_resend? %> + <%# i18n-tasks-use t("invite_requests.invitation.after_cooldown_period.not_resent") + i18n-tasks-use t("invite_requests.invitation.after_cooldown_period.resent_html")-%> + <% status = invitation.resent_at ? "resent_html" : "not_resent" %> + <%= t(".after_cooldown_period.#{status}", + count: ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION, + contact_support_link: link_to(t(".contact_support"), new_feedback_report_path)) %> + <%= button_to t(".resend_button"), resend_invite_requests_path(email: invitation.invitee_email) %> + <% else %> + <%= t(".before_cooldown_period", count: ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION) %> + <% end %> +

    + diff --git a/app/views/invite_requests/_invite_request.html.erb b/app/views/invite_requests/_invite_request.html.erb new file mode 100755 index 0000000..fd0e4a0 --- /dev/null +++ b/app/views/invite_requests/_invite_request.html.erb @@ -0,0 +1,14 @@ + +

    + <%= t(".title", email: invite_request.email) %> +

    + + + +

    + <%= t(".position_html", position: tag.strong(@position_in_queue)) %> + <% if AdminSetting.current.invite_from_queue_enabled? %> + <%= t(".date", date: l(invite_request.proposed_fill_time.to_date, format: :long)) %> + <% end %> +

    + diff --git a/app/views/invite_requests/_no_invitation.html.erb b/app/views/invite_requests/_no_invitation.html.erb new file mode 100755 index 0000000..dc55ef5 --- /dev/null +++ b/app/views/invite_requests/_no_invitation.html.erb @@ -0,0 +1,3 @@ +

    + <%= t(".email_not_found") %> +

    diff --git a/app/views/invite_requests/index.html.erb b/app/views/invite_requests/index.html.erb new file mode 100755 index 0000000..fbb4d62 --- /dev/null +++ b/app/views/invite_requests/index.html.erb @@ -0,0 +1,6 @@ +<% # Page changes depending on whether queue is enabled %> +<% if AdminSetting.current.invite_from_queue_enabled? %> + <%= render "index_open" %> +<% else %> + <%= render "index_closed" %> +<% end %> diff --git a/app/views/invite_requests/manage.html.erb b/app/views/invite_requests/manage.html.erb new file mode 100755 index 0000000..81290d5 --- /dev/null +++ b/app/views/invite_requests/manage.html.erb @@ -0,0 +1,66 @@ +
    + +

    <%= ts("Manage the Invitation Queue") %>

    + + + + + + + + "> + + + + + + + + + + + + <% @invite_requests.each_with_index do |request, index| %> + <% ip_address = if request.ip_address.present? + request.ip_address + else + ts("No IP recorded") + end %> + + <% position = if @filtered + request.position + else + @invite_requests.offset + index + 1 + end %> + + + + + + + + + <% end %> + +
    <%= ts("Manage the Invitation Queue") %>
    <%= ts("Queue Position") %><%= ts("Email Address") %><%= ts("Note") %><%= ts("IP Address") %><%= ts("Action") %>
    <%= position %><%= request.email %><%= request.note %><%= ip_address %> + <%= form_tag invite_request_path(request, page: params[:page], query: params[:query]), method: "delete", class: "ajax-remove" do |f| %> + <%= submit_tag ts("Delete") %> + <% end %> +
    + + + + <%= will_paginate @invite_requests %> + +
    diff --git a/app/views/invite_requests/show.html.erb b/app/views/invite_requests/show.html.erb new file mode 100755 index 0000000..aa36bc9 --- /dev/null +++ b/app/views/invite_requests/show.html.erb @@ -0,0 +1,11 @@ +<% if @invite_request %> + <%= render "invite_request", invite_request: @invite_request %> +<% elsif @invitation %> + <%= render "invitation", invitation: @invitation %> +<% else %> + <%= render "no_invitation" %> +<% end %> + +

    + <%= t(".instructions_html", status_link: link_to("Invitation Request Status page", status_invite_requests_path)) %> +

    diff --git a/app/views/invite_requests/show.js.erb b/app/views/invite_requests/show.js.erb new file mode 100755 index 0000000..05ea39c --- /dev/null +++ b/app/views/invite_requests/show.js.erb @@ -0,0 +1,14 @@ +<% if @invite_request %> + $j("#invite-status").html("<%= escape_javascript(render "invite_requests/invite_request", invite_request: @invite_request) %>"); +<% elsif @invitation %> + $j("#invite-status").html("<%= escape_javascript(render "invitation", invitation: @invitation) %>"); + + <%# Correct heading size for JavaScript display %> + $j(document).ready(function(){ + $j('#invite-heading').replaceWith(function () { + return '

    ' + $j(this).html() + "

    "; + }); + }) +<% else %> + $j("#invite-status").html("<%= escape_javascript(render "no_invitation") %>"); +<% end %> diff --git a/app/views/invite_requests/status.html.erb b/app/views/invite_requests/status.html.erb new file mode 100755 index 0000000..ae0d240 --- /dev/null +++ b/app/views/invite_requests/status.html.erb @@ -0,0 +1,30 @@ + +

    + <%= t(".heading") %> +

    + +

    + <%= t(".waiting_list", count: InviteRequest.count) %> + <% if AdminSetting.current.invite_from_queue_enabled? %> + <%= t(".invitation_send_rate", + queue_invitation_number: t(".invitation_number", count: AdminSetting.current.invite_from_queue_number), + queue_frequency: t(".frequency", count: AdminSetting.current.invite_from_queue_frequency)) %> + <% end %> +

    + + + +<%= form_tag show_invite_request_path, { remote: true, method: :get, class: "simple" } do %> +
    +

    + <%= label_tag :email %> + <%= text_field_tag :email %> + + <%= submit_tag t(".search") %> + +

    +
    +<% end %> + +
    + diff --git a/app/views/known_issues/_admin_index.html.erb b/app/views/known_issues/_admin_index.html.erb new file mode 100755 index 0000000..69d3f6c --- /dev/null +++ b/app/views/known_issues/_admin_index.html.erb @@ -0,0 +1,32 @@ + +

    <%= ts("Known Issues") %>

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

    There are no known issues posted, but you can <%= link_to 'make a new known issues post', new_known_issue_path %>

    +<% end %> + + + +<%= render :partial => 'admin/admin_nav' %> + + + +
      +<% @known_issues.each do |known_issue| %> +
    • + +
      +

      <%=raw sanitize_field(known_issue, :title) %>

      +
      <%= ts("Updated at:") %> <%= known_issue.updated_at %>
      + <%=raw sanitize_field(known_issue, :content) %> +
      +
    • +<% end %> +
    + + + + diff --git a/app/views/known_issues/_known_issues_form.html.erb b/app/views/known_issues/_known_issues_form.html.erb new file mode 100755 index 0000000..748c4ce --- /dev/null +++ b/app/views/known_issues/_known_issues_form.html.erb @@ -0,0 +1,37 @@ +
    + <%= form_for(@known_issue) do |f| %> + <%= error_messages_for @known_issue %> +
    +
    <%= f.label :title, ts("Beta Revision") + "*" %>
    +
    <%= f.text_field :title %>
    +
    <%= f.label :content, ts("Recent Known Issues") %>
    +
    + +

    + <%= allowed_html_instructions %> + +

    + <% use_tinymce %> + +
    + <%= f.text_area :content, :class => "mce-editor observe_textlength", :id => "content" %> + <%= live_validation_for_field('content', + :maximum_length => ArchiveConfig.CONTENT_MAX, :minimum_length => ArchiveConfig.CONTENT_MIN, + :tooLongMessage => ts("We salute your ambition! But sadly the content must be less than %{max} letters long.", :max => ArchiveConfig.CONTENT_MAX.to_s), + :tooShortMessage => ts("Brevity is the soul of wit, but your content does have to be at least %{min} letters long.", :min => ArchiveConfig.CONTENT_MIN.to_s), + :failureMessage => ts("You need to post some content here.")) + %> + <%= generate_countdown_html("content", ArchiveConfig.CONTENT_MAX) %> +
    +
    + +
    <%= ts("Post") %>
    +
    + <%= submit_tag ts("Post"), :name => 'post_button' %> +
    +
    + <% end %> +
    diff --git a/app/views/known_issues/edit.html.erb b/app/views/known_issues/edit.html.erb new file mode 100755 index 0000000..0b5d2d1 --- /dev/null +++ b/app/views/known_issues/edit.html.erb @@ -0,0 +1,14 @@ + +

    <%= ts("Edit Known Issues Post") %>

    + + + +<%= render :partial => 'admin/admin_nav' %> + + + +<%= render :partial => 'known_issues_form' %> + + + + diff --git a/app/views/known_issues/index.html.erb b/app/views/known_issues/index.html.erb new file mode 100755 index 0000000..6d550cd --- /dev/null +++ b/app/views/known_issues/index.html.erb @@ -0,0 +1,20 @@ + +<% if policy(KnownIssue).admin_index? %> + <%= render :partial => "admin_index" %> +<% else %> +

    <%= ts("Known Issues") %>

    + + + + + + + + <% @known_issues.each do |known_issue| %> +
    +

    <%= ts("Updated") %> <%= known_issue.updated_at %>

    + <%=raw sanitize_field(known_issue, :content) %> +
    + <% end %> + +<% end %> diff --git a/app/views/known_issues/new.html.erb b/app/views/known_issues/new.html.erb new file mode 100755 index 0000000..76703a4 --- /dev/null +++ b/app/views/known_issues/new.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts("New Known Issues Post") %>

    + + + +<%= render :partial => 'admin/admin_nav' %> + + + +<%= render :partial => 'known_issues_form' %> + diff --git a/app/views/known_issues/show.html.erb b/app/views/known_issues/show.html.erb new file mode 100755 index 0000000..1d43d66 --- /dev/null +++ b/app/views/known_issues/show.html.erb @@ -0,0 +1,23 @@ + +

    <%= ts("Known Issues") %>

    + + + + + + +
    +

    + <%= @known_issue.title %> +

    +

    <%= ts("Updated:") %> <%= @known_issue.updated_at %> + <% if logged_in_as_admin? %> + <%= link_to ts("Edit"), edit_known_issue_path(@known_issue) %> + <% end %> +

    + <%=raw sanitize_field(@known_issue, :content) %> +
    + + + + \ No newline at end of file diff --git a/app/views/kudo_mailer/batch_kudo_notification.html.erb b/app/views/kudo_mailer/batch_kudo_notification.html.erb new file mode 100755 index 0000000..c92e33f --- /dev/null +++ b/app/views/kudo_mailer/batch_kudo_notification.html.erb @@ -0,0 +1,26 @@ +<% content_for :message do %> + + <% @commentables.each_with_index do |commentable, index| %> + <% + commentable_link = style_creation_link(commentable.commentable_name, polymorphic_url(commentable)) + givers_hash = @user_kudos["#{commentable.class.name}_#{commentable.id}"] + names = givers_hash["names"] + guest_count = givers_hash["guest_count"].to_i + kudo_count = names.size + guest_count + givers = names.map { |name| style_link(name, user_url(name)) } + givers << t(".guest", count: guest_count) unless guest_count.zero? + givers_list = to_sentence(givers.map { |k| style_bold(k) }) + %> + + <% if kudo_count == 1 && guest_count == 1 %> + <%= t(".single_guest.html", giver: style_bold(t(".single_guest.giver")), commentable_link: commentable_link) %> + <% else %> + <%= t(".left_kudos.html", givers_list: givers_list, commentable_link: commentable_link, count: kudo_count) %> + <% end %> + + <% if (index < @commentables.length - 1) %> + <%= styled_divider %> + <% end %> + + <% end %> +<% end %> diff --git a/app/views/kudo_mailer/batch_kudo_notification.text.erb b/app/views/kudo_mailer/batch_kudo_notification.text.erb new file mode 100755 index 0000000..a79104b --- /dev/null +++ b/app/views/kudo_mailer/batch_kudo_notification.text.erb @@ -0,0 +1,28 @@ +<% content_for :message do %> +<% @commentables.each_with_index do |commentable, index| %> +<% + commentable_title = commentable.commentable_name.html_safe + commentable_url = polymorphic_url(commentable).html_safe + givers_hash = @user_kudos["#{commentable.class.name}_#{commentable.id}"] + names = givers_hash["names"] + guest_count = givers_hash["guest_count"].to_i + kudo_count = names.size + guest_count + # dup so we don't add "a guest" or "5 guests" to the original array. If that + # happens, kudo_count ends up too high whenever both named and guest kudos are + # present. + givers = names.dup + givers << t(".guest", count: guest_count) unless guest_count.zero? + givers_list = to_sentence(givers) +%> + +<% if kudo_count == 1 && guest_count == 1 %> +<%= t(".single_guest.text", commentable_title: commentable_title, commentable_url: commentable_url) %> +<% else %> +<%= t(".left_kudos.text", givers_list: givers_list, commentable_title: commentable_title, commentable_url: commentable_url, count: kudo_count) %> +<% end %> + +<% if (index < @commentables.length - 1) %> +<%= text_divider %> +<% end %> +<% end %> +<% end %> diff --git a/app/views/kudos/_kudos.html.erb b/app/views/kudos/_kudos.html.erb new file mode 100755 index 0000000..e9cb66a --- /dev/null +++ b/app/views/kudos/_kudos.html.erb @@ -0,0 +1,21 @@ +<% # expects local variables kudos, guest_kudos_count, commentable %> +

    <%= ts("Kudos") %>

    +
    + <% has_user_kudos = kudos.exists? %> + <% if has_user_kudos || guest_kudos_count > 0 %> + <% cache "#{commentable.cache_key}/kudos-v4", expires_in: ArchiveConfig.MINUTES_UNTIL_COMMENTABLE_KUDOS_LISTS_EXPIRE.minutes, race_condition_ttl: 10.seconds, skip_digest: true do %> +

    + <% if has_user_kudos %> + <%= kudos_user_links(commentable, kudos, showing_more: false) %> + <% end %> + <% if guest_kudos_count > 0 %> + <% if has_user_kudos %> + <%= ts(" as well as ") %> + <% end %> + <%= ts(pluralize(guest_kudos_count, "guest")) %> + <% end %> + <%= ts(" left kudos on this work!") %> +

    + <% end %> + <% end %> +
    diff --git a/app/views/kudos/create.js.erb b/app/views/kudos/create.js.erb new file mode 100755 index 0000000..451421b --- /dev/null +++ b/app/views/kudos/create.js.erb @@ -0,0 +1,2 @@ +$j("#kudos").replaceWith("<%= escape_javascript(render "kudos/kudos", + { kudos: @kudos, commentable: @commentable, guest_kudos_count: @commentable.guest_kudos_count }) %>"); diff --git a/app/views/kudos/index.html.erb b/app/views/kudos/index.html.erb new file mode 100755 index 0000000..c88458e --- /dev/null +++ b/app/views/kudos/index.html.erb @@ -0,0 +1,22 @@ +

    + <%= search_header(@kudos, nil, "User") %> Who Left Kudos on <%= link_to(@work.title, @work) %> +

    + +<% if @guest_kudos_count.positive? %> +

    + <%= t("kudos.guest_header", count: @guest_kudos_count) %> +

    +<% end %> + +<% if @kudos.present? %> + <%= will_paginate @kudos %> + +
    +

    + <%= @kudos.map { |kudo| link_to kudo.user.login, kudo.user }.to_sentence.html_safe %> + <%= ts(" left kudos on this work!") %> +

    +
    + + <%= will_paginate @kudos %> +<% end %> diff --git a/app/views/kudos/index.js.erb b/app/views/kudos/index.js.erb new file mode 100755 index 0000000..b072f03 --- /dev/null +++ b/app/views/kudos/index.js.erb @@ -0,0 +1,2 @@ +$j("#kudos_more_connector").remove(); +$j("#kudos_more_link").replaceWith("<%= j kudos_user_links(@work, @kudos) %>"); diff --git a/app/views/languages/_form.html.erb b/app/views/languages/_form.html.erb new file mode 100755 index 0000000..cdaff60 --- /dev/null +++ b/app/views/languages/_form.html.erb @@ -0,0 +1,51 @@ +<%= error_messages_for :language %> + +<%= form_for(@language, html: { class: "post" }) do |f| %> + +

    * <%= t(".required_notice") %>

    + +
    +
    +
    + <%= f.label :name, "#{t('.name')} *" %> +
    +
    + <%= f.text_field :name, disabled: !policy(@language).can_edit_non_abuse_fields? %> +
    + +
    + <%= f.label :short, "#{t('.short')} *" %> +
    +
    + <%= f.text_field :short, disabled: !policy(@language).can_edit_non_abuse_fields? %> +
    + +
    + <%= f.label :sortable_name, t(".sortable_name") %> +
    +
    + <%= f.text_field :sortable_name, disabled: !policy(@language).can_edit_non_abuse_fields? %> +
    + +
    + <%= f.check_box :support_available, disabled: !policy(@language).can_edit_non_abuse_fields? %> +
    +
    + <%= f.label :support_available, t(".support_available") %> +
    +
    + <%= f.check_box :abuse_support_available, disabled: !policy(@language).can_edit_abuse_fields? %> +
    +
    + <%= f.label :abuse_support_available, t(".abuse_support_available") %> +
    +
    +

    + <% if @language.new_record? %> + <%= f.submit t(".submit.create") %> + <% else %> + <%= f.submit t(".submit.update") %> + <% end %> +

    +
    +<% end %> diff --git a/app/views/languages/edit.html.erb b/app/views/languages/edit.html.erb new file mode 100755 index 0000000..03f5b6d --- /dev/null +++ b/app/views/languages/edit.html.erb @@ -0,0 +1,3 @@ +

    <%= t('.edit_language', :default => 'Edit Language') %>

    + +<%= render 'form' %> \ No newline at end of file diff --git a/app/views/languages/index.html.erb b/app/views/languages/index.html.erb new file mode 100755 index 0000000..6240561 --- /dev/null +++ b/app/views/languages/index.html.erb @@ -0,0 +1,43 @@ + +

    <%= t(".page_heading") %>

    + + + + + + + +
    + <% @languages.each do |language| %> + <% works_count = estimate_number(@works_counts[language.short] || 0) %> + <% if language == Language.default %> +
    + <%= language.name %> + <%= t(".language_code_format_html", code: content_tag(:abbr, language.short)) %> +
    +
    + <%= link_to t(".works_count", count: works_count, formatted_count: number_with_delimiter(works_count)), works_path %> +
    + <% else %> +
    + <%= link_to language.name, language, lang: language.short %> + <%= t(".language_code_format_html", code: content_tag(:abbr, language.short)) %> +
    +
    + <%= link_to t(".works_count", count: works_count, formatted_count: number_with_delimiter(works_count)), language_works_path(language) %> + <% if policy(Language).edit? %> +

    + <%= link_to t(".navigation.edit"), edit_language_path(language) %> +

    + <% end %> +
    + <% end %> + <% end %> +
    + diff --git a/app/views/languages/new.html.erb b/app/views/languages/new.html.erb new file mode 100755 index 0000000..777b2ef --- /dev/null +++ b/app/views/languages/new.html.erb @@ -0,0 +1,3 @@ +

    <%= t('.new_language', :default => 'New Language') %>

    + +<%= render 'form' %> \ No newline at end of file diff --git a/app/views/layouts/_banner.html.erb b/app/views/layouts/_banner.html.erb new file mode 100755 index 0000000..904afe9 --- /dev/null +++ b/app/views/layouts/_banner.html.erb @@ -0,0 +1,24 @@ +<% if @admin_banner&.active? %> + <% unless session[:hide_banner] || current_user&.preference&.banner_seen %> +
    +
    + <%= raw sanitize_field(@admin_banner, :content, image_safety_mode: true) %> +
    + <% if current_user.nil? %> +

    + <%= link_to current_path_with(hide_banner: true), "aria-label": t(".hide"), class: "showme action" do + content_tag(:span, "×".html_safe, "aria-hidden": true) + end %> +

    + <% else %> + <%= form_tag end_banner_user_path(current_user), method: :post, remote: true do %> +

    + <%= button_tag "aria-label": t(".hide"), class: "showme action" do + content_tag(:span, "×".html_safe, "aria-hidden": true) + end %> +

    + <% end %> + <% end %> +
    + <% end %> +<% end %> diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb new file mode 100755 index 0000000..1afca5a --- /dev/null +++ b/app/views/layouts/_footer.html.erb @@ -0,0 +1,57 @@ + + + diff --git a/app/views/layouts/_header.html.erb b/app/views/layouts/_header.html.erb new file mode 100755 index 0000000..f547ed0 --- /dev/null +++ b/app/views/layouts/_header.html.erb @@ -0,0 +1,78 @@ + + + +<% if @collection %> + + +<% end %> + + + +<%= render "layouts/banner" %> + + diff --git a/app/views/layouts/_includes.html.erb b/app/views/layouts/_includes.html.erb new file mode 100755 index 0000000..9610585 --- /dev/null +++ b/app/views/layouts/_includes.html.erb @@ -0,0 +1,11 @@ +<% # load and cache site skin %> +<%= skin_tag %> + + +<%= stylesheet_link_tag 'sandbox', skip_pipeline: true %> + +<%= mute_css %> + +<%= javascript_include_tag 'livevalidation_standalone', skip_pipeline: true %> + +<%= csrf_meta_tag %> diff --git a/app/views/layouts/_javascripts.html.erb b/app/views/layouts/_javascripts.html.erb new file mode 100755 index 0000000..b4ae300 --- /dev/null +++ b/app/views/layouts/_javascripts.html.erb @@ -0,0 +1,114 @@ + +<% if allow_tinymce?(controller) %> + <%= yield :tinymce %> +<% end %> + + + + + +<% if Rails.env.test? %> + + + + +<% end %> + + +<%= javascript_include_tag "jquery.scrollTo.min", "jquery.livequery.min", "rails", "application", "bootstrap/bootstrap-dropdown.min", "jquery-shuffle", "jquery.tokeninput.min", "jquery.trap.min", "ao3modal.min", "js.cookie.min", skip_pipeline: true %> + +<%= javascript_include_tag "filters.min", skip_pipeline: true %> + +<% if allow_tinymce?(controller) %> + <%= yield :tinymce_init %> +<% end %> + +<% unless Rails.env.test? || current_user.try(:accepted_tos_version) == @current_tos_version || tos_exempt_page? %> + <%= javascript_tag do %> + // We can't rely on !window.localStorage to test localStorage support in + // browsers like Safari 9, which technically support it, but which have a + // storage length of 0 in private mode. + // Credit: https://github.com/getgrav/grav-plugin-admin/commit/cfe2188f10c4ca604e03c96f3e21537fda1cdf9a + function isSupported() { + var item = "localStoragePolyfill"; + try { + localStorage.setItem(item, item); + localStorage.removeItem(item); + return true; + } catch (e) { + return false; + } + } + + function acceptTOS() { + if (isSupported()) { + localStorage.setItem("accepted_tos", "<%= @current_tos_version %>"); + } else { + Cookies.set("accepted_tos", "<%= @current_tos_version %>", { expires: 365 }); + } + } + + $j(document).ready(function() { + <% if current_user %> + <%# Users who haven't accepted this TOS need the popup. %> + $j("body").prepend("<%= escape_javascript(render "layouts/tos_prompt") %>"); + <% elsif params[:tos] == "yes" %> + <%# Guests can bypass the popup using ?tos=yes in the URLs. %> + acceptTOS(); + <% else %> + <%# Otherwise, guests who don't have the localStorage item or the + cookie need the popup. + We have to use JavaScript to remember their choice or risk issues + when full page caching is enabled. %> + if (localStorage.getItem("accepted_tos") !== "<%= @current_tos_version %>" && Cookies.get("accepted_tos") !== "<%= @current_tos_version %>") { + $j("body").prepend("<%= escape_javascript(render "layouts/tos_prompt") %>"); + } + <% end %> + }); + <% end %> +<% end %> + +<% # Renders layouts/proxy_notice below skip links in layouts/application. %> +<% if %w(staging production).include?(Rails.env) %> + <%= javascript_tag do %> + $j(document).ready(function() { + var permitted_hosts = <%= ArchiveConfig.PERMITTED_HOSTS.to_json.html_safe %>; + var current_host = window.location.hostname; + + if (!permitted_hosts.includes(current_host) && Cookies.get("proxy_notice") !== "0" && window.location.protocol !== "file:") { + $j("#skiplinks").after("<%= escape_javascript(render "layouts/proxy_notice") %>"); + } + }); + <% end %> +<% end %> + +<%= yield :footer_js %> diff --git a/app/views/layouts/_proxy_notice.html.erb b/app/views/layouts/_proxy_notice.html.erb new file mode 100755 index 0000000..92bc7c0 --- /dev/null +++ b/app/views/layouts/_proxy_notice.html.erb @@ -0,0 +1,35 @@ +
    +
    + <%# TODO: When the interface is localized, this should be revised to only show the notice in the user's selected language. %> +

    <%= t(".faux_heading") %>

    +
      +
    1. <%= t(".point1") %>
    2. +
    3. <%= t(".point2") %>
    4. +
    +

    <%= t(".faux_heading", locale: :ru) %>

    +
      +
    1. <%= t(".point1", locale: :ru) %>
    2. +
    3. <%= t(".point2", locale: :ru) %>
    4. +
    +

    <%= t(".faux_heading", locale: :uk) %>

    +
      +
    1. <%= t(".point1", locale: :uk) %>
    2. +
    3. <%= t(".point2", locale: :uk) %>
    4. +
    +

    <%= t(".faux_heading", locale: :"zh-CN") %>

    +
      +
    1. <%= t(".point1", locale: :"zh-CN") %>
    2. +
    3. <%= t(".point2", locale: :"zh-CN") %>
    4. +
    +

    +
    +
    + +<%= javascript_tag do %> + $j(document).ready(function() { + $j("#proxy-notice-dismiss").on("click", function() { + Cookies.set("proxy_notice", "0"); + $j("#proxy-notice").slideUp(); + }); + }); +<% end %> diff --git a/app/views/layouts/_tos_prompt.html.erb b/app/views/layouts/_tos_prompt.html.erb new file mode 100755 index 0000000..305710b --- /dev/null +++ b/app/views/layouts/_tos_prompt.html.erb @@ -0,0 +1,77 @@ + + +<%# content_for footer renders this when we don't want it %> +<%= javascript_tag do %> + $j(document).ready(function() { + var container = $j("#tos_prompt"); + var outer = $j("#outer"); + var button = $j("#accept_tos"); + var tosCheckbox = document.getElementById("tos_agree"); + var dataProcessingCheckbox = document.getElementById("data_processing_agree"); + + var checkboxClicked = function() { + button.attr("disabled", !tosCheckbox.checked || !dataProcessingCheckbox.checked); + if (this.checked) { + button.on("click", function() { + acceptTOS(); + outer.removeClass("hidden").removeAttr("aria-hidden"); + $j.when(container.fadeOut(500)).done(function() { + container.remove(); + }); + }); + }; + }; + + setTimeout(showTOSPrompt, 1500); + + function showTOSPrompt() { + $j.when(container.fadeIn(500)).done(function() { + outer.addClass("hidden").attr("aria-hidden", "true"); + }); + + $j("#tos_agree").on("click", checkboxClicked).change(); + $j("#data_processing_agree").on("click", checkboxClicked).change(); + }; + }); +<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb new file mode 100755 index 0000000..f3312d7 --- /dev/null +++ b/app/views/layouts/application.html.erb @@ -0,0 +1,57 @@ + + + + + + + + + + + + + <% item = @user || @work || @series %> + <% if disallow_robots?(item) %> + + + <% end %> + + + <%= browser_page_title(@page_title, @page_subtitle) %> + + <%= render :partial => 'layouts/includes' %> + <%= phraseapp_in_context_editor_js %> + + + > +
    + + <% # layouts/proxy_notice is rendered here by JavaScript found in layouts/javascripts. %> + <%= render :partial => 'layouts/header' %> +
    + + <% if @admin_posts && !@hide_dashboard %> + <%= render :partial => 'admin_posts/sidebar' %> + <% elsif @user && !@hide_dashboard %> + <%= render :partial => 'users/sidebar' %> + <% elsif @collection && !@hide_dashboard %> + <%= render :partial => 'collections/sidebar' %> + <% elsif show_wrangling_dashboard %> + <%= render :partial => 'tag_wranglings/wrangler_dashboard' %> + <% end %> + + + +
    + <%= flash_div :error, :caution, :notice, :alert %> +
    + <%= yield %> +
    +
    + +
    + <%= render :partial => 'layouts/footer' %> +
    + <%= render :partial => 'layouts/javascripts' %> + + diff --git a/app/views/layouts/barebones.html.erb b/app/views/layouts/barebones.html.erb new file mode 100755 index 0000000..8bb75af --- /dev/null +++ b/app/views/layouts/barebones.html.erb @@ -0,0 +1,29 @@ + + + + + + <%= @page_title %> + + + + +<%= yield %> + + + diff --git a/app/views/layouts/home.html.erb b/app/views/layouts/home.html.erb new file mode 100755 index 0000000..dae3dd5 --- /dev/null +++ b/app/views/layouts/home.html.erb @@ -0,0 +1,47 @@ + + + + + + + + + + + + + <%= phraseapp_in_context_editor_js %> + + <% if defined?(@page_title) %> + <%= @page_title %> + <% else %> + <% if defined?(@page_subtitle) %> + <%= @page_subtitle %> + <% else %> + <%= controller.action_name=="index" ? "" : controller.action_name.humanize.titleize %> + <%= controller.action_name=="index" ? controller.controller_name.humanize.titleize : controller.controller_name.singularize.humanize.titleize %> + <% end %> + | + <%= ArchiveConfig.APP_NAME %> + <% end %> + + + <%= render 'layouts/includes' %> + + + > +
    + + + + + <%= yield %> + + + + <%= render 'layouts/footer' %> +
    +<%= render 'layouts/javascripts' %> + + diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100755 index 0000000..da3c3a2 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,126 @@ + + + + + + + + + + +
    + + + + + + + + + + +
    + + + + + +
    + + + + + +
    +
    + + + Sunset + + + +
    +
    + + + + + +
    +
    + + + + + + + + +
    + + + + + + + + + + + + + + + +
    + + + + + + + +
    +
    + + + <% if content_for?(:message) %> + <%= yield(:message) %> + <% end %> + + +
    +
    +
    +
    + + + <% if content_for?(:footer_note) %> +

    <%= yield(:footer_note) %>

    + <% end %> + + <% if @pac_footer %> +

    <%= t("mailer.general.footer.why_policy_abuse.html", contact_policy_abuse_link: style_footer_link(t("mailer.general.footer.why_policy_abuse.contact_policy_abuse"), new_abuse_report_url)) %>

    + <% else %> +

    <%= t("mailer.general.footer.why_support.html", contact_support_link: style_footer_link(t("mailer.general.footer.why_support.contact_support"), new_feedback_report_url)) %>

    + <% end %> + +

    <%= t("mailer.general.footer.about.html", your_donations_link: style_footer_link(t("mailer.general.footer.about.your_donations"), donate_url)) %>

    + + <% if content_for?(:sent_at) %> +

    <%= t("mailer.general.footer.sent_at", sent_at: yield(:sent_at).strip) %>

    + <% end %> + + +
    +
    +
    +
    +
    + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100755 index 0000000..416bf0c --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1,25 @@ + +Sunset Archive +========================================= + + +<% if content_for?(:message) then %><%= yield(:message) %><% end %> + + +----------------------------------------- +<% if content_for?(:footer_note) %> +<%= yield(:footer_note) %> + +<% end %> +<% if @pac_footer %> +<%= t("mailer.general.footer.why_policy_abuse.text", contact_policy_abuse_url: new_abuse_report_url) %> +<% else %> +<%= t("mailer.general.footer.why_support.text", contact_support_url: new_feedback_report_url) %> +<% end %> + +<%= t("mailer.general.footer.about.text", your_donations_url: donate_url) %> +<% if content_for?(:sent_at) %> + +<%= t("mailer.general.footer.sent_at", sent_at: yield(:sent_at).strip) %> + +<% end %> diff --git a/app/views/layouts/session.html.erb b/app/views/layouts/session.html.erb new file mode 100755 index 0000000..0ebc0b6 --- /dev/null +++ b/app/views/layouts/session.html.erb @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + <% if defined?(@page_title) %> + <%= @page_title %> + <% else %> + <% if defined?(@page_subtitle) %> + <%= @page_subtitle %> + <% else %> + <%= controller.action_name=="index" ? "" : process_title(controller.action_name) %> + <%= controller.action_name=="index" ? process_title(controller.controller_name) : process_title(controller.controller_name.singularize) %> + <% end %> + | + <%= ArchiveConfig.APP_NAME %> + <% end %> + + + <%= render "layouts/includes" %> + <%= phraseapp_in_context_editor_js %> + + + > +
    + + <%= render "layouts/header" %> +
    + +
    + <%= flash_div :error, :caution, :notice, :alert %> +
    +
    + <%= yield %> +
    +
    + +
    + <%= render "layouts/footer" %> +
    + <%= render "layouts/javascripts" %> + + diff --git a/app/views/locales/_locale_form.html.erb b/app/views/locales/_locale_form.html.erb new file mode 100755 index 0000000..3cbb9c0 --- /dev/null +++ b/app/views/locales/_locale_form.html.erb @@ -0,0 +1,32 @@ +<%= form_for(@locale, html: { class: 'post' }) do |f| %> +

    * <%= t('.required_notice', :default => "Required information") %>

    + +
    + <%= t('.locale_legend', :default => "Locale") %> +

    <%= t('.locale_heading', :default => "Locale") %>

    +
    +
    <%= f.label :name, t('.name', :default => "Name") + '*' %>
    +
    <%= f.text_field :name %>
    + +
    <%= f.label :iso, t('.iso', :default => "ISO code") + '*' %>
    +
    <%= f.text_field :iso %>
    + +
    <%= f.label :language_id, t('.language', :default => "Language") + '*' %>
    +
    <%= f.select(:language_id, language_options_for_select(@languages, "id")) %>
    + +
    <%= f.check_box :email_enabled %>
    +
    <%= f.label :email_enabled, t('.enable_email', :default => "Use this locale to send email") %>
    + +
    <%= f.check_box :interface_enabled %>
    +
    <%= f.label :interface_enabled, t('.enable_interface', :default => "Use this locale for the interface") %>
    + +
    +
    +
    + <%= t('.actions_legend', :default => "Actions") %> +

    <%= t('.actions_heading', :default => "Actions") %>

    +

    + <%= f.submit @locale.new_record? ? t('.create_button', :default => "Create Locale") : t('.edit_button', :default => "Update Locale") %> +

    +
    +<% end %> diff --git a/app/views/locales/_navigation.html.erb b/app/views/locales/_navigation.html.erb new file mode 100755 index 0000000..3693e07 --- /dev/null +++ b/app/views/locales/_navigation.html.erb @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/app/views/locales/edit.html.erb b/app/views/locales/edit.html.erb new file mode 100755 index 0000000..30d0e1d --- /dev/null +++ b/app/views/locales/edit.html.erb @@ -0,0 +1,13 @@ + +

    <%= t('.edit_locale', :default => 'Edit Locale') %>

    +<%= error_messages_for :locale %> + + + +<%= render 'navigation' %> + + + +<%= render 'locale_form' %> + + diff --git a/app/views/locales/index.html.erb b/app/views/locales/index.html.erb new file mode 100755 index 0000000..422f14a --- /dev/null +++ b/app/views/locales/index.html.erb @@ -0,0 +1,40 @@ + +

    <%= t('.supported_locales', :default => 'Supported Locales') %>

    + + + +<%= render 'navigation' %> + + + + + + + + + + + + + + + + <% for locale in @locales %> + + + + + + + + + + <% end %> + +
    <%= t('.locale_table_caption', :default => 'Supported Locales') %>
    NameISO CodePrimary LocaleUse for EmailUse for InterfaceCreated atActions
    <%= locale.name %><%= locale.iso %><%= locale.main %><%= locale.email_enabled %><%= locale.interface_enabled %><%= locale.updated_at %> + <%= link_to ts('Edit'), {controller: :locales, action: :edit, id: locale.iso} %> +
    + + + + diff --git a/app/views/locales/new.html.erb b/app/views/locales/new.html.erb new file mode 100755 index 0000000..ddbe831 --- /dev/null +++ b/app/views/locales/new.html.erb @@ -0,0 +1,13 @@ + +

    <%= t('.add_new_locale', :default => 'New Locale') %>

    +<%= error_messages_for :locale %> + + + +<%= render 'navigation' %> + + + +<%= render 'locale_form' %> + + diff --git a/app/views/media/index.html.erb b/app/views/media/index.html.erb new file mode 100755 index 0000000..20f5b28 --- /dev/null +++ b/app/views/media/index.html.erb @@ -0,0 +1,28 @@ + +

    <%= t(".page_heading") %>

    + + + +
      +<% for medium in @media %> +
    • +

      <%= link_to medium.name, media_fandoms_path(medium) %>

      + +
        + <% for fandom in @fandom_listing[medium] %> +
      1. + <%= link_to_tag_works_with_text(fandom, fandom.name) %> + <% if fandom.respond_to?(:count) %> + (<%= fandom.count.to_s %>) + <% end %> +
      2. + <% end %> +
      + + <% unless @fandom_listing[medium].size < 5 %> + + <% end %> +
    • +<% end %> +
    + diff --git a/app/views/menu/_menu_about.html.erb b/app/views/menu/_menu_about.html.erb new file mode 100755 index 0000000..42e961c --- /dev/null +++ b/app/views/menu/_menu_about.html.erb @@ -0,0 +1,8 @@ + diff --git a/app/views/menu/_menu_browse.html.erb b/app/views/menu/_menu_browse.html.erb new file mode 100755 index 0000000..6975b70 --- /dev/null +++ b/app/views/menu/_menu_browse.html.erb @@ -0,0 +1,7 @@ + diff --git a/app/views/menu/_menu_fandoms.html.erb b/app/views/menu/_menu_fandoms.html.erb new file mode 100755 index 0000000..b6a0209 --- /dev/null +++ b/app/views/menu/_menu_fandoms.html.erb @@ -0,0 +1,11 @@ + diff --git a/app/views/menu/_menu_othersites.html.erb b/app/views/menu/_menu_othersites.html.erb new file mode 100644 index 0000000..dfe48bf --- /dev/null +++ b/app/views/menu/_menu_othersites.html.erb @@ -0,0 +1,8 @@ + + + diff --git a/app/views/menu/_menu_search.html.erb b/app/views/menu/_menu_search.html.erb new file mode 100755 index 0000000..c63ecad --- /dev/null +++ b/app/views/menu/_menu_search.html.erb @@ -0,0 +1,6 @@ + diff --git a/app/views/menu/about.html.erb b/app/views/menu/about.html.erb new file mode 100755 index 0000000..4265705 --- /dev/null +++ b/app/views/menu/about.html.erb @@ -0,0 +1,4 @@ +

    <%= ts('About', key: 'header') %>

    +
    + <%= render 'menu/menu_about' %> +
    diff --git a/app/views/menu/browse.html.erb b/app/views/menu/browse.html.erb new file mode 100755 index 0000000..b656c57 --- /dev/null +++ b/app/views/menu/browse.html.erb @@ -0,0 +1,4 @@ +

    <%= ts('Browse', key: 'header') %>

    +
    + <%= render 'menu/menu_browse' %> +
    diff --git a/app/views/menu/fandoms.html.erb b/app/views/menu/fandoms.html.erb new file mode 100755 index 0000000..53eaf23 --- /dev/null +++ b/app/views/menu/fandoms.html.erb @@ -0,0 +1,4 @@ +

    <%= ts('Fandoms', key: 'header') %>

    +
    + <%= render 'menu/menu_fandoms' %> +
    diff --git a/app/views/menu/search.html.erb b/app/views/menu/search.html.erb new file mode 100755 index 0000000..f8768aa --- /dev/null +++ b/app/views/menu/search.html.erb @@ -0,0 +1,4 @@ +

    <%= ts('Search', key: 'header') %>

    +
    + <%= render 'menu/menu_search' %> +
    diff --git a/app/views/muted/_muted_items_notice.html.erb b/app/views/muted/_muted_items_notice.html.erb new file mode 100755 index 0000000..c2cb516 --- /dev/null +++ b/app/views/muted/_muted_items_notice.html.erb @@ -0,0 +1,3 @@ +<% if user_has_muted_users? %> +

    <%= t("muted.muted_items_notice_html", muted_users_link: link_to(t("muted.muted_users_link_text"), user_muted_users_path(current_user))) %>

    +<% end %> diff --git a/app/views/muted/users/_muted_user_blurb.html.erb b/app/views/muted/users/_muted_user_blurb.html.erb new file mode 100755 index 0000000..b62bd1c --- /dev/null +++ b/app/views/muted/users/_muted_user_blurb.html.erb @@ -0,0 +1,9 @@ +<% pseud = mute.muted.default_pseud %> +
  • + <%= render "pseuds/pseud_module", pseud: pseud, date: mute.created_at %> + +
    User Actions
    + +
  • diff --git a/app/views/muted/users/confirm_mute.html.erb b/app/views/muted/users/confirm_mute.html.erb new file mode 100755 index 0000000..b9b6b31 --- /dev/null +++ b/app/views/muted/users/confirm_mute.html.erb @@ -0,0 +1,34 @@ +

    <%= t(".title", name: @muted.login) %>

    + +<%= form_tag user_muted_users_path(@user, muted_id: @muted) do %> +
    +

    + <%= t(".sure_html", mute: tag.strong(t(".mute")), username: @muted.login) %> + <%= t(".will.intro") %> +

    + +
      +
    • <%= t(".will.seeing_content") %>
    • +
    + +

    <%= t(".will_not.intro") %>

    + +
      +
    • <%= t(".will_not.prevent_emails") %>
    • +
    • <%= t(".will_not.hide_content_for_others") %>
    • +
    + +

    + <%= t(".block_users_instead_html", blocked_users_link: link_to(t(".blocked_users_link_text"), user_blocked_users_path(@user))) %> +

    + +

    + <%= t(".site_skin_warning_html", restore_site_skin_faq_link: link_to(t(".restore_site_skin_faq_link_text"), archive_faq_path("skins-and-archive-interface", anchor: :restoresiteskin))) %> +

    +
    + +

    + <%= link_to t(".cancel"), user_muted_users_path(@user) %> + <%= submit_tag t(".button") %> +

    +<% end %> diff --git a/app/views/muted/users/confirm_unmute.html.erb b/app/views/muted/users/confirm_unmute.html.erb new file mode 100755 index 0000000..cc8eeea --- /dev/null +++ b/app/views/muted/users/confirm_unmute.html.erb @@ -0,0 +1,19 @@ +

    <%= t(".title", name: @mute.muted.login) %>

    + +<%= form_tag user_muted_user_path(@user, @mute), method: :delete do %> +
    +

    + <%= t(".sure_html", unmute: tag.strong(t(".unmute")), username: @mute.muted.login) %> + <%= t(".resume.intro") %> +

    + +
      +
    • <%= t(".resume.see_content") %>
    • +
    +
    + +

    + <%= link_to t(".cancel"), user_muted_users_path(@user) %> + <%= submit_tag t(".button") %> +

    +<% end %> diff --git a/app/views/muted/users/index.html.erb b/app/views/muted/users/index.html.erb new file mode 100755 index 0000000..461b2b5 --- /dev/null +++ b/app/views/muted/users/index.html.erb @@ -0,0 +1,55 @@ +

    <%= t(".title") %>

    + + +

    <%= t("a11y.navigation") %>

    + + +
    +

    <%= t(".will.intro", mute_limit: number_with_delimiter(ArchiveConfig.MAX_MUTED_USERS), count: ArchiveConfig.MAX_MUTED_USERS) %>

    + +
      +
    • <%= t(".will.seeing_content") %>
    • +
    + +

    <%= t(".will_not.intro") %>

    + +
      +
    • <%= t(".will_not.prevent_emails") %>
    • +
    • <%= t(".will_not.hide_content_for_others") %>
    • +
    + +

    + <%= t(".block_users_instead_html", blocked_users_link: link_to(t(".blocked_users_link_text"), user_blocked_users_path(@user))) %> +

    + +

    + <%= t(".site_skin_warning_html", restore_site_skin_faq_link: link_to(t(".restore_site_skin_faq_link_text"), archive_faq_path("skins-and-archive-interface", anchor: :restoresiteskin))) %> +

    +
    + +<%# form for muting users %> + +<%= form_tag confirm_mute_user_muted_users_path(@user), method: :get, class: "single simple post" do %> +
    + <%= t(".legend") %> +

    + <%= label_tag :muted_id, t(".label"), class: "landmark" %> + <%= text_field_tag :muted_id, "", autocomplete_options("pseud", data: { autocomplete_token_limit: 1 }) %> + <%= submit_tag t(".button") %> +

    +
    +<% end %> + +

    <%= t(".heading.landmark.muted_users") %>

    +<% if @mutes.present? %> +
      + <%= render partial: "muted_user_blurb", collection: @mutes, as: :mute %> +
    +<% else %> +

    <%= t(".none") %>

    +<% end %> + +<%= will_paginate @mutes %> diff --git a/app/views/opendoors/external_authors/index.html.erb b/app/views/opendoors/external_authors/index.html.erb new file mode 100755 index 0000000..0ca5bfc --- /dev/null +++ b/app/views/opendoors/external_authors/index.html.erb @@ -0,0 +1,50 @@ +
    + +

    + <%= @query ? ts("External Author Identities") : ts("Unclaimed External Author Identities") %> +

    + + + +<%= render "opendoors/tools/tools_navigation" %> + + + +<% if @external_authors.empty? %> +

    <%= ts("No matching external authors found.") %>

    +

    <%= ts("Please try a different search.") %>

    +<% else %> + <%= will_paginate @external_authors %> + +

    <%= ts("Listing External Authors") %>

    + <% if params[:query] %>

    <%= ts("Matching: %{query}", :query => params[:query]) %>

    <% end %> +
    + <% @external_authors.each do |external_author| %> +
    + <%= external_author.email %> + <% if external_author.claimed? %> + (Claimed by <%= link_to external_author.user.login, external_author.user %>) + <% end %> +
    +
    + +
    + <% end %> +
    + + <%= will_paginate @external_authors %> +<% end %> +
    \ No newline at end of file diff --git a/app/views/opendoors/external_authors/show.html.erb b/app/views/opendoors/external_authors/show.html.erb new file mode 100755 index 0000000..76b36f3 --- /dev/null +++ b/app/views/opendoors/external_authors/show.html.erb @@ -0,0 +1,3 @@ +<%= render "opendoors/tools/tools_navigation" %> + +<%= render "external_authors/external_author_description", :external_author => @external_author %> diff --git a/app/views/opendoors/tools/_tools_navigation.html.erb b/app/views/opendoors/tools/_tools_navigation.html.erb new file mode 100755 index 0000000..744a662 --- /dev/null +++ b/app/views/opendoors/tools/_tools_navigation.html.erb @@ -0,0 +1,14 @@ + diff --git a/app/views/opendoors/tools/index.html.erb b/app/views/opendoors/tools/index.html.erb new file mode 100755 index 0000000..a7dd622 --- /dev/null +++ b/app/views/opendoors/tools/index.html.erb @@ -0,0 +1,46 @@ + +<% unless @imported_from_url.blank? %> +

    + <%= ts('Test redirect: ') %> + <%= link_to @imported_from_url, redirect_path(:original_url => @imported_from_url) %> +

    +<% end %> + +

    <%= ts("Open Doors Tools") %>

    + + + +<%= render "opendoors/tools/tools_navigation" %> + + + +<%= form_tag url_for(:controller => 'opendoors/tools', :action => 'url_update') do %> +
    + Update Redirect URL +

    <%= ts("Update Redirect URL") %>

    + +
    +
    <%= ts("Imported From")%>
    +
    <%= text_field_tag "imported_from_url" %>
    +
    <%= ts("Archive URL") %>
    +
    <%= text_field_tag "work_url" %>
    +
    + <%= submit_button %> +
    +<% end %> + +<%= form_for [:opendoors, @external_author] do |f| %> +
    + Block Email Address +

    <%= ts("Block Email Address") %>

    +
    +
    <%= f.label :email, ts("Email: ")%>
    +
    + <%= f.text_field :email %> + <%= f.hidden_field :do_not_import, :value => true %> +
    +
    + <%= submit_button(f) %> +
    +<% end %> + diff --git a/app/views/orphans/_choose_pseud.html.erb b/app/views/orphans/_choose_pseud.html.erb new file mode 100755 index 0000000..f2294ac --- /dev/null +++ b/app/views/orphans/_choose_pseud.html.erb @@ -0,0 +1,8 @@ +

    + <%= radio_button_tag 'use_default', 'true', true %> + <%= label_tag 'use_default_true', ts('Take my pseud off as well') %> +

    +

    + <%= radio_button_tag 'use_default', 'false' %> + <%= label_tag 'use_default_false', ts('Leave a copy of my pseud on') %> +

    diff --git a/app/views/orphans/_orphan_pseud.html.erb b/app/views/orphans/_orphan_pseud.html.erb new file mode 100755 index 0000000..9de5848 --- /dev/null +++ b/app/views/orphans/_orphan_pseud.html.erb @@ -0,0 +1,43 @@ + +<% works = pseud.works.to_a %> +

    <%= ts("Orphan All Works by %{name}", name: pseud.name) %>

    + +

    + <%= ts("Orphaning all works by %{name} will", name: pseud.name)%> + <%= ts("permanently")%> + <%= ts("remove the pseud %{name} from the following work(s), their chapters, associated series, and any feedback replies you may have left on them.", name: pseud.name) %> +

    + +

    + <%= ts("Unless another one of your pseuds is listed as a creator on the work(s) below, orphaning them will remove them from your account and re-attach them to the specially created orphan_account. Please note that this is")%> + <%= ts("permanent and irreversible.")%> + <%= ts("You are giving up control over the work(s),")%> + <%= ts("including the ability to edit or delete them.")%> +

    + +<%= render "works/work_abbreviated_list", works: works %> + +

    + <%= ts("Are you")%> + <%= ts("really")%> + <%= ts("sure you want to do this?")%> +

    + + + + + + + +<%= form_tag orphans_path do %> +

    + <% works.each do |work| %> + <%= hidden_field_tag "work_ids[]", work.id, id: "work_ids_#{work.id}" %> + <% end %> + <%= hidden_field_tag :pseud_id, pseud.id %> +

    + + <%= render "orphans/choose_pseud" %> +

    <%= submit_tag ts("Yes, I'm sure") %>

    +<% end %> + diff --git a/app/views/orphans/_orphan_series.html.erb b/app/views/orphans/_orphan_series.html.erb new file mode 100755 index 0000000..8687e8b --- /dev/null +++ b/app/views/orphans/_orphan_series.html.erb @@ -0,0 +1,24 @@ + +

    <%= ts("Orphan Series") %>

    + +

    + <%= ts('Are you sure you want to permanently remove all identifying data from your series "%{title}", its works and chapters, and any feedback replies you may have left on them?', +:title => series.title).html_safe %> +

    + + + + + + +<%= form_tag orphans_path do %> + + <%= render :partial => 'orphans/choose_pseud' %> + +

    <%= hidden_field_tag 'series_id', series.id %>

    +

    <%= submit_tag ts("Yes, I'm sure") %>

    +<% end %> + + + + diff --git a/app/views/orphans/_orphan_user.html.erb b/app/views/orphans/_orphan_user.html.erb new file mode 100755 index 0000000..7816fbf --- /dev/null +++ b/app/views/orphans/_orphan_user.html.erb @@ -0,0 +1,33 @@ + +<% works = user.works.to_a %> +

    <%= ts("Orphan All Works") %>

    + +

    <%= t(".orphaning_works_message_html") %>

    + +

    <%= t(".orphaning_bylines_only_message_html") %>

    + +

    + <%= ts("Orphaning a work removes it from your account and re-attaches it to the specially created orphan_account. Please note that this is")%> + <%= ts("permanent and irreversible.")%> + <%= ts("You are giving up control over the work,")%> + <%= ts("including the ability to edit or delete it.")%> +

    + +<%= render "works/work_abbreviated_list", works: works %> + +

    + <%= ts("Are you")%> + <%= ts("really")%> + <%= ts("sure you want to do this?")%> +

    + +<%= form_tag orphans_path do %> +

    + <% works.each do |work| %> + <%= hidden_field_tag "work_ids[]", work.id, id: "work_ids_#{work.id}" %> + <% end %> +

    + + <%= render "orphans/choose_pseud" %> +

    <%= submit_tag ts("Yes, I'm sure") %>

    +<% end %> diff --git a/app/views/orphans/_orphan_work.html.erb b/app/views/orphans/_orphan_work.html.erb new file mode 100755 index 0000000..7bb70e3 --- /dev/null +++ b/app/views/orphans/_orphan_work.html.erb @@ -0,0 +1,43 @@ + +

    <%= ts('Orphan Works') %>

    + +

    + <%= ts("Orphaning will")%> + <%= ts("permanently")%> + <%= ts("remove all identifying data from the following work(s), their chapters, associated series, and any feedback replies you may have left on them.") %> +

    + +

    + <%= ts("Orphaning a work removes it from your account and re-attaches it to the specially created orphan_account. Please note that this is")%> + <%= ts("permanent and irreversible.")%> + <%= ts("You are giving up control over the work,")%> + <%= ts("including the ability to edit or delete it.")%> +

    + +<%= render "works/work_abbreviated_list", :works => works %> + +

    + <%= ts("Are you")%> + <%= ts("really")%> + <%= ts("sure you want to do this?")%> +

    + + + + + + +<%= form_tag orphans_path do %> + + <%= render 'orphans/choose_pseud' %> + +

    + <% works.each_with_index do |work, index| %><%= hidden_field_tag "work_ids[]", work.id, :id => "work_ids_#{index}" %><% end %> +

    + +

    <%= submit_tag ts("Yes, I'm sure") %>

    +<% end %> + + + + diff --git a/app/views/orphans/index.html.erb b/app/views/orphans/index.html.erb new file mode 100755 index 0000000..34d97fa --- /dev/null +++ b/app/views/orphans/index.html.erb @@ -0,0 +1,17 @@ + +

    <%=h t('.orphaned_works', :default => 'Orphaned Works') %>

    + + + + + + +
      + <% for work in @works %> + <%= render :partial => 'works/work_blurb', :locals => {:work => work} %> + <% end %> +
    + + + + \ No newline at end of file diff --git a/app/views/orphans/new.html.erb b/app/views/orphans/new.html.erb new file mode 100755 index 0000000..a70d6e7 --- /dev/null +++ b/app/views/orphans/new.html.erb @@ -0,0 +1,6 @@ +<%= render_orphan_partial(@to_be_orphaned) %> + + diff --git a/app/views/owned_tag_sets/_internal_tag_set_fields.html.erb b/app/views/owned_tag_sets/_internal_tag_set_fields.html.erb new file mode 100755 index 0000000..b77e1ae --- /dev/null +++ b/app/views/owned_tag_sets/_internal_tag_set_fields.html.erb @@ -0,0 +1,30 @@ +<% TagSet::TAG_TYPES.each do |tag_type| %> +
    + <% unless TagSet::TAGS_AS_CHECKBOXES.include?(tag_type) %> + <% # fandoms, chars, relationships, freeforms %> + + <% if @tag_set.with_type(tag_type).empty? %> +

    <%= form.label "#{tag_type}_tagnames_to_add".to_sym, ts("Add #{tag_type_label_name(tag_type).pluralize}:") %>

    + <% else %> +

    <%= form.label "#{tag_type}_tags_to_remove".to_sym, ts("#{tag_type_label_name(tag_type).pluralize}") %>

    + <%= check_all_none %> + <%= checkbox_section(form, "#{tag_type}_tags_to_remove", @tag_set.with_type(tag_type).by_name_without_articles) %> +
    <%= form.label "#{tag_type}_tagnames_to_add".to_sym, ts("Add:") %>
    + <% end %> + +
    <%= form.text_field "#{tag_type}_tagnames_to_add".to_sym, autocomplete_options(tag_type) %>
    + + <% else %> + <% # ratings, categories, archive_warnings %> +

    + <%= ts("%{tag_type}", tag_type: tag_type_label_name(tag_type).pluralize) %> +

    + + <%= check_all_none %> + <% raise "Redshirt: Attempted to constantize invalid class initialize _internal_tag_set_fields.html.erb (2) #{tag_type.gsub(/\s+/, "").classify}" unless %w(Category Rating ArchiveWarning).include?(tag_type.gsub(/\s+/, "").classify) %> + <%= checkbox_section(form, "#{tag_type}_tagnames", tag_type.gsub(/\s+/, "").classify.constantize.pluck(:name), + :checked_method => "#{tag_type}_tagnames", :value_method => "to_s", :name_method => "to_s", + :checkbox_side => "left") %> + <% end %> +
    +<% end %> diff --git a/app/views/owned_tag_sets/_navigation.html.erb b/app/views/owned_tag_sets/_navigation.html.erb new file mode 100755 index 0000000..55855e4 --- /dev/null +++ b/app/views/owned_tag_sets/_navigation.html.erb @@ -0,0 +1,26 @@ +<% if logged_in? %> + +<% end %> diff --git a/app/views/owned_tag_sets/_show_fandoms_by_media.html.erb b/app/views/owned_tag_sets/_show_fandoms_by_media.html.erb new file mode 100755 index 0000000..c38ce22 --- /dev/null +++ b/app/views/owned_tag_sets/_show_fandoms_by_media.html.erb @@ -0,0 +1,47 @@ +<% @tag_hash[:fandom].keys.each do |media| %> +
  • +

    + <%= ts("%{media}", :media => media) %> + <% list_id = "list_for_media_#{media.gsub(/[^\w]/, '_')}" %> + (<%= @tag_hash[:fandom][media].size %>) + <%= expand_contract_shuffle(list_id) %><%= expand_contract_all %> +

    +
      + <% unless @tag_hash[:character] || @tag_hash[:relationship] %> + <% # we're just doing fandoms -- pop them into li and move on! %> + <%= @tag_hash[:fandom][media].map {|fandom| content_tag(:li, fandom)}.join("\n").html_safe %> + <% else %> + <% # some fandoms have chars or rels underneath %> + <% @tag_hash[:fandom][media].each do |fandom| %> + <% # test to make sure we've actually got chars or rels for this individual fandom %> + <% has_characters = (@tag_hash[:character] && @tag_hash[:character][fandom]) ? @tag_hash[:character][fandom].size : 0 %> + <% has_relationships = (@tag_hash[:relationship] && @tag_hash[:relationship][fandom]) ? @tag_hash[:relationship][fandom].size : 0 %> + <% + # this gets called a ton if there are a lot of fandoms so not doing it in a partial to save on time, although + # as a result it's duplicated in show_tag_set_tags :( + %> +
    1. + <% if (has_relationships + has_characters) > 0 %> +

      + <%= ts("%{fandom}", :fandom => fandom) %> + <% list_id = "list_for_fandom_#{fandom.gsub(/[^\w]/, '_')}_in_#{media.gsub(/[^\w]/, '_')}" %> + (<%= has_relationships + has_characters %>) + <%= expand_contract_shuffle(list_id, shuffle: false) %> +

      +
        + <% if has_characters > 0 %> + <%= @tag_hash[:character][fandom].map {|character| @character_seen[character] = true; content_tag(:li, character)}.join("\n").html_safe %> + <% end %> + <% if has_relationships > 0 %> + <%= @tag_hash[:relationship][fandom].map {|relationship| @relationship_seen[relationship] = true; content_tag(:li, relationship)}.join("\n").html_safe %> + <% end %> +
      + <% else %> +

      <%= ts("%{fandom}", :fandom => fandom) %> (0)

      + <% end %> +
    2. + <% end %> + <% end %> +
    +
  • +<% end %> diff --git a/app/views/owned_tag_sets/_show_tag_set_associations.html.erb b/app/views/owned_tag_sets/_show_tag_set_associations.html.erb new file mode 100755 index 0000000..fc26737 --- /dev/null +++ b/app/views/owned_tag_sets/_show_tag_set_associations.html.erb @@ -0,0 +1,15 @@ +<% if @associations && !@associations.empty? %> +

    <%= ts("Tag Set Associations") %> (<%= @associations.count %>)

    + +
      + <% @associations.group(:parent_tag_id).joins(:tag, :parent_tag). + select("parent_tags_tag_set_associations.name as parent, group_concat(tags.name ORDER BY tags.name) as children").each do |assoc| %> +
    1. +

      <%= assoc.parent %>

      +
        + <%= assoc.children.split(',').map {|child| content_tag(:li, child)}.join("\n").html_safe %> +
      +
    2. + <% end %> +
    +<% end %> \ No newline at end of file diff --git a/app/views/owned_tag_sets/_show_tag_set_tags.html.erb b/app/views/owned_tag_sets/_show_tag_set_tags.html.erb new file mode 100755 index 0000000..bd73e4a --- /dev/null +++ b/app/views/owned_tag_sets/_show_tag_set_tags.html.erb @@ -0,0 +1,70 @@ +
      + <% # first show any ratings, categories, or warnings, since there will only be a small number if any %> + <% TagSet::TAGS_AS_CHECKBOXES.each do |tag_type| %> + <% if @tag_set.has_type?(tag_type.classify) %> + <%= render "show_tags_in_single_list", :tag_type => tag_type.classify %> + <% end %> + <% end %> + + <% if @tag_hash[:fandom] %> + <% # we're doing the fandoms by media and any char/rel tags will be nested %> + <%= render "show_fandoms_by_media" %> + <% end %> + + <% if @tag_hash[:character] || @tag_hash[:relationship] %> + <% # if there was a fandom display, check for any that weren't shown in the fandom display %> + + <% if @tag_hash[:fandom] %> + <% @unassociated_chars.reject! {|c| @character_seen[c]} %> + <% @unassociated_rels.reject! {|r| @relationship_seen[r]} %> + <% unless @unassociated_chars.empty? && @unassociated_rels.empty? %> +
    1. +

      + <%= ts("Unassociated Characters & Relationships") %> (<%= @unassociated_chars.size + @unassociated_rels.size %>) + <%= expand_contract_shuffle("list_for_unassociated_char_and_rel") %> +

      +

      <%= ts("The following characters and relationships don't seem to be associated with any fandom in the tagset. You might need to add the fandom, or set up associations for them.") %>

      +
        + <%= @unassociated_chars.sort {|a,b| a.gsub(/^(the |an |a )/, '') <=> b.gsub(/^(the |an |a )/, '')}.map {|tag| content_tag(:li, tag)}.join("\n").html_safe %> + <%= @unassociated_rels.sort {|a,b| a.gsub(/^(the |an |a )/, '') <=> b.gsub(/^(the |an |a )/, '')}.map {|tag| content_tag(:li, tag)}.join("\n").html_safe %> +
      +
    2. + <% end %> + + <% else %> + + <% @fandom_keys_from_other_tags.each do |fandom| %> + <% + # this gets called a ton if there are a lot of fandoms so not doing it in a partial for performance, although + # as a result it's mostly duplicated in show_fandoms_by_media :( + %> + <% has_characters = (@tag_hash[:character] && @tag_hash[:character][fandom]) ? @tag_hash[:character][fandom].size : 0 %> + <% has_relationships = (@tag_hash[:relationship] && @tag_hash[:relationship][fandom]) ? @tag_hash[:relationship][fandom].size : 0 %> +
    3. + <% if (has_relationships + has_characters) > 0 %> +

      + <%= ts("%{fandom}", :fandom => fandom) %> + (<%= has_relationships + has_characters %>) + <% list_id = "list_for_fandom_#{fandom.gsub(/[^\w]/, '_')}" %> + <%= expand_contract_shuffle(list_id) %> +

      +
        + <% if has_characters > 0 %> + <%= @tag_hash[:character][fandom].map {|character| content_tag(:li, character)}.join("\n").html_safe %> + <% end %> + <% if has_relationships > 0 %> + <%= @tag_hash[:relationship][fandom].map {|relationship| content_tag(:li, relationship)}.join("\n").html_safe %> + <% end %> +
      + <% else %> +

      <%= ts("%{fandom}", :fandom => fandom) %> (0)

      + <% end %> +
    4. + <% end %> + + <% end %> + <% end %> + + <% # finally, freeform tags, if necessary broken up into alphabetical lists %> + <%= render "show_tags_by_alpha", :tag_type => "freeform" %> +
    diff --git a/app/views/owned_tag_sets/_show_tags_alpha_listbox.html.erb b/app/views/owned_tag_sets/_show_tags_alpha_listbox.html.erb new file mode 100755 index 0000000..99773ae --- /dev/null +++ b/app/views/owned_tag_sets/_show_tags_alpha_listbox.html.erb @@ -0,0 +1,36 @@ +<% # expects locals tag_type, tagname_list, and to be enclosed inside an ol/ul; can also pass itemcount to alter the number of items in a group %> +<% + # too many tags to throw at the user! + # this gets a little tricky: here's what this code does + # every time we see a new letter at the start of a tagname, we want to start a new heading + inner ol + # we only want one heading for 0-9 + # we start with that one, but we might not see any tags with a number, so we only display + # the heading if we actually see one + # once we've opened a new heading and inner ol if we're going to, we just show the tagname + # in a list item +%> +<% itemcount ||= 30 %> +
  • +

    + <%= ts("%{tag_type}", tag_type: tag_type_label_name(tag_type).pluralize) %> + <%= expand_contract_all %> +

    +
      + <% slice_index = 0 %> + <% tagname_list.each_slice(itemcount) do |tagnames| %> +
    1. +

      + + <%= tagnames.first %> + <% unless tagnames.size < 2 %> → <%= tagnames.last %><% end %> + + <%= expand_contract_shuffle("list_for_#{tag_type}_#{slice_index}") %> +

      +
        + <%= tagnames.map {|tn| content_tag(:li, tn)}.join(" ").html_safe %> +
      +
    2. + <% slice_index += 1 %> + <% end %> +
    +
  • diff --git a/app/views/owned_tag_sets/_show_tags_by_alpha.html.erb b/app/views/owned_tag_sets/_show_tags_by_alpha.html.erb new file mode 100755 index 0000000..55f29b5 --- /dev/null +++ b/app/views/owned_tag_sets/_show_tags_by_alpha.html.erb @@ -0,0 +1,9 @@ +<% # expects tag_type %> +<% if @tag_set.has_type?(tag_type) %> + <% tags = @tag_set.with_type(tag_type) %> + <% if tags.count <= ArchiveConfig.MAX_OPTIONS_TO_SHOW %> + <%= render "show_tags_in_single_list", :tag_type => tag_type %> + <% else %> + <%= render "show_tags_alpha_listbox", :tagname_list => tags.by_name_without_articles.pluck(:name), :tag_type => tag_type %> + <% end %> +<% end %> diff --git a/app/views/owned_tag_sets/_show_tags_in_single_list.html.erb b/app/views/owned_tag_sets/_show_tags_in_single_list.html.erb new file mode 100755 index 0000000..6144404 --- /dev/null +++ b/app/views/owned_tag_sets/_show_tags_in_single_list.html.erb @@ -0,0 +1,12 @@ +<% # not too many, so just show them in a single group %> +
  • +

    + <%= ts("%{tag_type}", tag_type: tag_type_label_name(tag_type).pluralize) %> + + (<%= @tag_set.with_type(tag_type).count %>) + <%= expand_contract_shuffle("list_for_#{tag_type}") %> +

    +
      + <%= tag_relation_to_list @tag_set.with_type(tag_type) %> +
    +
  • diff --git a/app/views/owned_tag_sets/_tag_set_association_fields.html.erb b/app/views/owned_tag_sets/_tag_set_association_fields.html.erb new file mode 100755 index 0000000..fd473a9 --- /dev/null +++ b/app/views/owned_tag_sets/_tag_set_association_fields.html.erb @@ -0,0 +1,18 @@ +<% index ||= 0 %> +
    +
    +

    <%= link_to_remove_section ts("x"), form %>

    +
    +
    <%= form.label :tag_id, ts("Tag: ") %>
    +
    + <%= form.hidden_field :create_association, :value => true %> + <%= form.select :tag_id, options_for_select(@child_tags_in_set, form.object.tag_id), :include_blank => true %> +
    +
    <%= form.label :parent_tag_id, ts("Parent tag: ") %>
    +
    <%= form.select :parent_tag_id, options_for_select(@parent_tags_in_set, form.object.parent_tag_id), :include_blank => true %>
    +
    +
    +
    + + + \ No newline at end of file diff --git a/app/views/owned_tag_sets/_tag_set_associations_remove.html.erb b/app/views/owned_tag_sets/_tag_set_associations_remove.html.erb new file mode 100755 index 0000000..17065ca --- /dev/null +++ b/app/views/owned_tag_sets/_tag_set_associations_remove.html.erb @@ -0,0 +1,12 @@ +<% # expects "form" and @tag_set %> +<% associations_for_remove = @tag_set.tag_set_associations.joins(:tag, :parent_tag).order("parent_tags_tag_set_associations.name, tags.name") %> +
    +
    +
    <%= ts('Currently in set') %>
    +
    +

    <%= ts('Tags') %>

    + <%= check_all_none %> + <%= checkbox_section(form, :associations_to_remove, associations_for_remove, :name_method => "to_s") %> +
    +
    +
    diff --git a/app/views/owned_tag_sets/_tag_set_blurb.html.erb b/app/views/owned_tag_sets/_tag_set_blurb.html.erb new file mode 100755 index 0000000..f25d0f4 --- /dev/null +++ b/app/views/owned_tag_sets/_tag_set_blurb.html.erb @@ -0,0 +1,49 @@ +
  • +
    +

    + <%= link_to tag_set.title, tag_set_path(tag_set) %>

    +

    <%= l(tag_set.updated_at.to_date) %>

    +
    <%= ts('Owners and Mods') %>
    +
      + <%= tag_set.owners.map {|owner| content_tag(:li, link_to(owner.byline, owner.user))}.join("\n").html_safe %> +
    + <% if tag_set.moderators.length > 0 %> +
      + <%= tag_set.moderators.map {|mod| content_tag(:li, link_to(mod.byline, mod.user))}.join("\n").html_safe %> +
    + <% end %> +
    +
    + + +
    <%= ts('Summary') %>
    +
    + <%=raw strip_images(sanitize_field(tag_set, :description)) || " ".html_safe %> +
    + + + <% if tag_set.tag_set %> +
    + <% %w(fandom character relationship freeform).each do |tag_type| %> +
    <%= ts("%{tag_type}", tag_type: tag_type_label_name(tag_type).pluralize) %>:
    +
    <%= tag_set.with_type(tag_type).count %>
    + <% end %> +
    + <% end %> + + <% if logged_in? && (tag_set.user_is_moderator?(current_user) || tag_set.nominated) %> +
    <%= ts('User Actions') %>
    + + <% end %> +
  • + diff --git a/app/views/owned_tag_sets/_tag_set_form.html.erb b/app/views/owned_tag_sets/_tag_set_form.html.erb new file mode 100755 index 0000000..ebe70fb --- /dev/null +++ b/app/views/owned_tag_sets/_tag_set_form.html.erb @@ -0,0 +1,73 @@ + +<% if @tag_set.new_record? %> + +<% else %> + <%= render "navigation" %> +<% end %> + + + +

    <%= ts('Notes') %>

    +
      +
    • <%= ts('Tag sets are used for running a challenge.') %>
    • +
    • <%= ts('"Visible" tag sets are shown to all users.') %>
    • +
    • <%= ts('"Usable" tag sets can be used by others in their challenges.') %>
    • +
    • <%= ts('Tag sets that are open to nominations can take nominations from the public.') %>
    • +
    • <%= ts('Tag names have to be unique. If necessary the archive may add on the tag type. (For instance, if you entered a character "Firefly", you\'d see "Firefly - Character" in your tag set instead since the tag Firefly is already used for the show.') %>
    • +
    + +

    <%= ts('Tag Set Settings') %>

    + +<%= form_for(@tag_set, :url => (@tag_set.new_record? ? tag_sets_path : tag_set_path(@tag_set)), :html => {:method => (@tag_set.new_record? ? :post : :put), :class => "tagset verbose post"}) do |tag_set_form| %> + <%= error_messages_for @tag_set %> + +
    + <%= ts('Management') %> + <%= render "tag_set_form_management", form: tag_set_form %> +
    + +
    + Tags In Set <% unless @tag_set.new_record? || !@tag_set.tag_set || @tag_set.tag_set.tags.empty? %><%= ts('(check to remove)') %><% end %> +

    <%= ts('Tags in Set') %>

    + <% @tag_set.build_tag_set unless @tag_set.tag_set %> + <%= tag_set_form.fields_for :tag_set do |internal_tag_set_form| %> +
    <%= internal_tag_set_form.hidden_field :from_owned_tag_set, :value => true %>
    + + <%= render "internal_tag_set_fields", :form => internal_tag_set_form %> + + <% end %> +
    + + +
    + <% associations_for_remove = @tag_set.tag_set_associations.reject {|assoc| assoc.new_record?} %> + <% associations_for_add = @tag_set.tag_set_associations.select {|assoc| assoc.new_record?} %> + Tag Associations <%= associations_for_remove.empty? ? '' : ts('(check to remove)') %> <%= link_to_help('tagset-tag-associations')%> + +

    <%= ts('Tag Associations') %>

    + <% unless associations_for_remove.empty? %> + <%= render "tag_set_associations_remove", :form => tag_set_form %> + <% end %> + <% unless @tag_set.new_record? || @child_tags_in_set.empty? || @parent_tags_in_set.empty? %> + <% + # this next div is used to hold the last id for adding new associations via javascript + # because we don't generate an initial tag set association form, we have to put one of these into the upper level form + # with the right id to start from + %> + <% associations_for_add.each do |assoc| %> + <%= tag_set_form.fields_for :tag_set_associations, assoc do |assoc_form| %> + <%= render "tag_set_association_fields", :form => assoc_form %> + <% end %> + <% end %> + +

    + <%= link_to_add_section(ts('Add Association'), tag_set_form, :tag_set_associations, "tag_set_association_fields") %> +

    + <% end %> +
    + + <%= submit_fieldset tag_set_form %> + +<% end %> diff --git a/app/views/owned_tag_sets/_tag_set_form_management.html.erb b/app/views/owned_tag_sets/_tag_set_form_management.html.erb new file mode 100755 index 0000000..a92756c --- /dev/null +++ b/app/views/owned_tag_sets/_tag_set_form_management.html.erb @@ -0,0 +1,63 @@ +<% # implied opening fieldset tag %> +

    + <%= ts("To add or remove an owner or moderator, enter their name. If they are already on the list they will be removed; if not, they will be added. + You can't remove the sole owner of a tag set.") %> +

    + +
    +
    <%= ts("Current Owners") %>
    +
    +
      + <%= @tag_set.new_record? ? content_tag(:li, current_user.default_pseud.byline) : @tag_set.owners.collect(&:byline).sort.map {|owner| content_tag(:li, owner)}.join("\n").html_safe =%> +
    +
    +
    <%= form.label :owner_changes, ts("Add/Remove Owners: ") %>
    +
    <%= form.text_field :owner_changes, autocomplete_options("pseud", :size => 80) %>
    + +
    <%= ts("Current Moderators") %>
    +
    +
      <%= @tag_set.moderators.empty? ? content_tag(:li, ts("None")) : @tag_set.moderators.collect(&:byline).sort.map {|mod| content_tag(:li, mod)}.join("\n").html_safe =%>
    +
    + +
    <%= form.label :moderator_changes, ts("Add/Remove Moderators: ") %>
    +
    <%= form.text_field :moderator_changes, autocomplete_options("pseud", :size => 80) %>
    +
    + + +
    + <%= ts("Description") %> +

    <%= ts("Description") %>

    +
    +
    <%= form.label :title, ts("Title* (text only)") %>
    +
    <%= form.text_field :title %>
    + +
    <%= form.label :description, ts("Brief Description") %>
    +
    <%= form.text_field :description %>
    + +
    <%= form.label :visible, ts("Visible tag list?") %>
    +
    <%= form.check_box :visible %>
    + +
    <%= form.label :usable, ts("Usable by others?") %>
    +
    <%= form.check_box :usable %>
    + +
    <%= form.label :nominated, ts("Currently taking nominations?") %>
    +
    <%= form.check_box :nominated, :onchange => "if ($j(this).is(':checked')){$j('#nomination_limits').show();} else {$j('#nomination_limits').hide();}" %>
    +
    +
    + +
    + <%= ts("Nomination Limits") %> +

    <%= ts("Nomination Limits") %>

    +
      +
    • <%= ts("If you allow both fandoms and characters/relationships in the same tag set, + the number of characters/relationships is per fandom.").html_safe %>
    • +
    • <%= ts("If that's not what you want, you + can have users nominate fandoms in one tag set, and characters/relationships in another tag set. Then use both tag sets in your challenge settings.").html_safe %>
    • +
    +
    + <% TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| %> +
    <%= form.label "#{tag_type}_nomination_limit".to_sym %>
    +
    <%= form.text_field "#{tag_type}_nomination_limit".to_sym, :class => "number" %>
    + <% end %> +
    +<% # implied closing fieldset tag %> diff --git a/app/views/owned_tag_sets/batch_load.html.erb b/app/views/owned_tag_sets/batch_load.html.erb new file mode 100755 index 0000000..ec2129d --- /dev/null +++ b/app/views/owned_tag_sets/batch_load.html.erb @@ -0,0 +1,30 @@ + +
    + +

    <%= ts('Batch Loading') %> <%= link_to_help "tagset-batch-load" %>

    + + + + <%= render "navigation" %> + + + + <%= form_for(@tag_set, :url => do_batch_load_tag_set_path(@tag_set), :html => {:method => :put, :class => "tagset post"}) do |form| %> +
    + <%= ts('Batch Load') %> +

    <%= ts('Batch Load Tag Associations') %>

    +
    +
    +
    +

    One line per fandom in the form: fandom,character,character,character,...

    + <%= text_area_tag "batch_associations", @failed_batch_associations %> +
    +
    <%= label_tag "batch_do_relationships", ts('Relationships instead?') %>
    +
    <%= check_box_tag "batch_do_relationships" %>
    +
    <%= ts('Submit') %>
    +
    <%= form.submit ts('Submit') %>
    +
    +
    + + <% end %> +
    \ No newline at end of file diff --git a/app/views/owned_tag_sets/confirm_delete.html.erb b/app/views/owned_tag_sets/confirm_delete.html.erb new file mode 100755 index 0000000..af9b12f --- /dev/null +++ b/app/views/owned_tag_sets/confirm_delete.html.erb @@ -0,0 +1,12 @@ + +

    <%= ts("Delete Tag Set?") %>

    + + +<%= form_for(@tag_set, :url => tag_set_path(@tag_set), :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    <%= ts("Are you certain you want to delete the %{tagset_title} Tag Set? This will delete all nominations and Tag Set associations as well!", :tagset_title => @tag_set.title).html_safe %>

    +

    + <%= f.submit ts("Yes, Delete Tag Set") %> + <%= link_to ts("Back to the Tag Set"), tag_set_path(@tag_set) %> +

    +<% end %> + diff --git a/app/views/owned_tag_sets/edit.html.erb b/app/views/owned_tag_sets/edit.html.erb new file mode 100755 index 0000000..48b3052 --- /dev/null +++ b/app/views/owned_tag_sets/edit.html.erb @@ -0,0 +1,7 @@ + +
    +

    <%= ts("Edit %{title}", :title => @tag_set.title) %>

    + + <%= render "tag_set_form" %> + +
    \ No newline at end of file diff --git a/app/views/owned_tag_sets/index.html.erb b/app/views/owned_tag_sets/index.html.erb new file mode 100755 index 0000000..44c78cc --- /dev/null +++ b/app/views/owned_tag_sets/index.html.erb @@ -0,0 +1,54 @@ + +
    + +

    + <% if @user %> + <%= ts('%{user_name}\'s Tag Sets', :user_name => @user.login) %> <%= link_to_help 'tagset-about' %> + <% elsif @restriction %> + <%= ts('Tag Sets Used In This Challenge') %> + <% elsif @query %> + <%= search_header @tag_sets, nil, ts('Tag Set') %> <%= link_to_help 'tagset-about' %> + <% else %> + <%= ts('Tag Sets') %> <%= link_to_help 'tagset-about' %> <%= ts('in the %{archive_name}', :archive_name => ArchiveConfig.APP_NAME) %> + <% end %> +

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

    <%= ts('No tag sets found.') %>

    + <% else %> + <% if @tag_sets.respond_to?(:total_pages) %> + <%= will_paginate @tag_sets %> + <% end %> + +

    <%= ts('Listing Tag Sets') %>

    +
      + <% @tag_sets.each do |tag_set| %> + <%= render 'tag_set_blurb', :tag_set => tag_set %> + <% end %> +
    + + <% if @tag_sets.respond_to?(:total_pages) %> + <%= will_paginate @tag_sets %> + <% end %> + <% end %> + +
    \ No newline at end of file diff --git a/app/views/owned_tag_sets/new.html.erb b/app/views/owned_tag_sets/new.html.erb new file mode 100755 index 0000000..e4de6ba --- /dev/null +++ b/app/views/owned_tag_sets/new.html.erb @@ -0,0 +1,6 @@ + +
    +

    <%= ts("Create A Tag Set") %>

    + + <%= render "tag_set_form" %> +
    \ No newline at end of file diff --git a/app/views/owned_tag_sets/show.html.erb b/app/views/owned_tag_sets/show.html.erb new file mode 100755 index 0000000..9c63f21 --- /dev/null +++ b/app/views/owned_tag_sets/show.html.erb @@ -0,0 +1,65 @@ +
    + + +

    <%= ts("About %{name}", :name => @tag_set.title) %>

    + + + + <%= render "navigation" %> + + + +

    <%= ts("Metadata") %>

    +
    +
    +
    <%= ts("Created on: ") %>
    +
    <%= l(@tag_set.created_at.to_date) %>
    +
    <%= ts("Maintainers:") %>
    +
    +
      + <%= (@tag_set.owners + @tag_set.moderators).map {|owner| content_tag(:li, link_to(owner.byline, owner.user))}.join("\n").html_safe %> +
    +
    +
    <%= ts("Description:")%>
    +
    + <%=raw sanitize_field(@tag_set, :description) %> + <% if @tag_set.description.blank? %> +

    <%= ts("No description given.") %>

    + <% end %> + <% if @tag_set.usable %> +

    <%= ts("This tag set can be used in challenge settings by anybody.") %>

    + <% end %> +
    + <% if @tag_set.nominated %> +
    <%= ts("Status:") %>
    +
    <%= ts("Open") %> <%= ts("to the public.") %>
    +
    <%= ts("Stats:")%>
    +
    +

    <%= ts("Nominations allowed per person:") %>

    +
    + <% TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| %> +
    <%= ts("#{tag_type.pluralize.capitalize}: ") %>
    +
    <%= @tag_set.send("#{tag_type}_nomination_limit") %>
    + <% end %> +
    + <% end %> +
    +
    +
    + + <% if @tag_set.visible || @tag_set.user_is_moderator?(current_user) %> + +

    <%= ts("Listing Tags") %>

    + + <% tagset_cache_key = @tag_type ? "tag_set_show_#{@tag_set.tag_set_id}_#{@tag_type}" : "tag_set_show_#{@tag_set.tag_set_id}" %> + <%= cache(tagset_cache_key, skip_digest: true) do %> + <%= render "show_tag_set_tags" %> + <%= render "show_tag_set_associations" %> + <% end %> + + <% else %> +

    <%= ts("The moderators have chosen not to make the tags in this set visible to the public (possibly while nominations are underway).") %>

    + <% end %> + + +
    diff --git a/app/views/owned_tag_sets/show_options.html.erb b/app/views/owned_tag_sets/show_options.html.erb new file mode 100755 index 0000000..c9a09c1 --- /dev/null +++ b/app/views/owned_tag_sets/show_options.html.erb @@ -0,0 +1,24 @@ +<% # ids of tag sets whose tags are being shown %> +<% ids = @tag_set_ids.join("-") %> + +<% # the show tag sets' most recent updated_at %> +<% newest_updated_at = @tag_sets.collect(&:updated_at).sort.last %> + +<% # cache key for all of the sets' tags, which expires when the number of tags changes or when the most recent updated_at changes %> +<% tags_cache_key = @tags.cache_key %> + +<% cache("tagsets_#{ids}_#{newest_updated_at}_#{tags_cache_key}", skip_digest: true) do %> +

    + <%= ts("%{tag_type} Options From", tag_type: tag_type_label_name(@tag_type)) %>: + <%= to_sentence(@tag_sets.map { |ts| link_to(ts.title, tag_set_path(ts)) }) %> +

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

    <%= ts("None to list!") %>

    + <% else %> +
      + <%= render "show_tags_alpha_listbox", + tagname_list: @tags.pluck(:name), tag_type: @tag_type %> +
    + <% end %> +<% end %> diff --git a/app/views/owned_tag_sets/wrangle.html.erb b/app/views/owned_tag_sets/wrangle.html.erb new file mode 100755 index 0000000..28a62d3 --- /dev/null +++ b/app/views/owned_tag_sets/wrangle.html.erb @@ -0,0 +1,4 @@ +<% + # this page will for wranglers: it will show them the noncanonical tags and associations in this tag set, which they can decide + # whether or not to make canonical. +%> \ No newline at end of file diff --git a/app/views/people/_author_blurb.html.erb b/app/views/people/_author_blurb.html.erb new file mode 100755 index 0000000..b94922b --- /dev/null +++ b/app/views/people/_author_blurb.html.erb @@ -0,0 +1,25 @@ +
  • +
    +

    <%= link_to(author.name, user_pseud_path(author.user, author)) %> + <% if (author.name != author.user.login) %> + (<%= link_to(author.user_name, user_path(author.user)) %>) + <% end %> +

    + <% if @search.present? %> + <% creations = author.authored_items_links(fandom_id: @search.options[:fandom_ids]).html_safe %> + <% else %> + <% creations = authored_items(author, @work_counts, @rec_counts) %> + <% end %> + <% if creations.present? %> +
    <%= creations %>
    + <% end %> +
    + <%= icon_display(author.user, author) %> +
    +
    + <% unless author.description.blank? %> +
    +

    <%=raw sanitize_field(author, :description) %>

    +
    + <% end %> +
  • \ No newline at end of file diff --git a/app/views/people/_search_form.html.erb b/app/views/people/_search_form.html.erb new file mode 100755 index 0000000..c98380a --- /dev/null +++ b/app/views/people/_search_form.html.erb @@ -0,0 +1,27 @@ +<%= form_for @search, as: :people_search, url: search_people_path, html: { class: "search", method: :get } do |f| %> +
    + <%= ts("Search people") %> +
    +
    + <%= f.label :query, ts("Search all fields") %> + <%= link_to_help "people-search-all-fields" %> +
    +
    + <%= f.text_field :query %> +
    +
    + <%= f.label :name, ts("Name") %> +
    +
    + <%= f.text_field :name, autocomplete_options("pseud") %> +
    +
    + <%= f.label :fandom, ts("Fandom") %> +
    +
    + <%= f.text_field :fandom, autocomplete_options("fandom") %> +
    +
    +

    <%= f.submit ts("Search People") %>

    +
    +<% end %> diff --git a/app/views/people/index.html.erb b/app/views/people/index.html.erb new file mode 100755 index 0000000..7ecd857 --- /dev/null +++ b/app/views/people/index.html.erb @@ -0,0 +1,22 @@ + + +

    + <%= ts("Participants in %{collection}", :collection => @collection.title) %> +

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

    <%= ts("No matching people found.") %>

    +<% else %> + <%= will_paginate(@people) %> + +

    Listing People

    +
      + <% for person in @people %> + <% unless person.nil? %> + <%= render 'people/author_blurb', :author => person %> + <% end %> + <% end %> +
    + <%= will_paginate(@people) %> +<% end %> diff --git a/app/views/people/search.html.erb b/app/views/people/search.html.erb new file mode 100755 index 0000000..604b428 --- /dev/null +++ b/app/views/people/search.html.erb @@ -0,0 +1,19 @@ + +

    <%= ts("People Search") %>

    + +<%= render 'shared/search_nav' %> + +<%= render :partial => 'people/search_form' %> + +<% if @people %> +

    <%= search_results_found(@people) %>

    +

    People List

    +
      + <% for person in @people %> + <% unless person.nil? %> + <%= render :partial => 'people/author_blurb', :locals => {:author => person} %> + <% end %> + <% end %> +
    + <%= will_paginate @people %> +<% end %> diff --git a/app/views/potential_match_settings/_potential_match_settings_form.html.erb b/app/views/potential_match_settings/_potential_match_settings_form.html.erb new file mode 100755 index 0000000..7614879 --- /dev/null +++ b/app/views/potential_match_settings/_potential_match_settings_form.html.erb @@ -0,0 +1,52 @@ + +<% @challenge.build_potential_match_settings unless @challenge.potential_match_settings %> +<% potential_match_settings = @challenge.potential_match_settings %> + +<%= challenge_form.fields_for(:potential_match_settings) do |match_settings_form| %> + +
    + <%= ts("Minimum Number to Match") %> +

    <%= ts("Minimum Number to Match") %>

    +

    + <%= ts("This means the") %> <%= ts("minimum") %> <%= ts("level of matching needed for an offer to match a request. + Any matches above the minimum required number will be used to rank the quality of potential matches.") %> +

    + +

    + <%= ts("If you change these + settings") %> <%= ts("after") %> <%= ts("you generate potential matches, + you will need to") %> <%= ts("regenerate potential matches") %> <%= ts("before your changes show.") %> +

    + +
    +
    + <%= match_settings_form.label(:num_required_prompts, ts("Requests:")) %> +
    +
    <%= match_settings_form.select(:num_required_prompts, PotentialMatchSettings::REQUIRED_MATCH_OPTIONS.select {|k,v| k != "0"}, :selected => potential_match_settings.num_required_prompts) %>
    + + <% TagSet::TAG_TYPES.map {|t| t.pluralize }.each do |type| %> +
    <%= match_settings_form.label("num_required_#{type}", ts("%{tag_type}:", tag_type: tag_type_label_name(type).pluralize)) %>
    +
    <%= match_settings_form.select("num_required_#{type}", PotentialMatchSettings::REQUIRED_MATCH_OPTIONS, :selected => potential_match_settings.send("num_required_#{type}")) %>
    + <% end %> + +
    + <%= ts("Count optional tags for...") %> + <%= link_to_help("challenge-include-optional-tags") %> +
    +
    +
    +
      + <% TagSet::TAG_TYPES.map.each do |type| %> +
    • + <%= match_settings_form.check_box("include_optional_#{type.pluralize}", :checked => potential_match_settings.send("include_optional_#{type.pluralize}")) %> + <%= match_settings_form.label("include_optional_#{type.pluralize}", ts("%{tag_type}", tag_type: tag_type_label_name(type).pluralize)) %> +
    • + <% end %> +
    +
    +
    +
    + +
    + +<% end %> diff --git a/app/views/potential_matches/_assignment_with_request.html.erb b/app/views/potential_matches/_assignment_with_request.html.erb new file mode 100755 index 0000000..e02f6d8 --- /dev/null +++ b/app/views/potential_matches/_assignment_with_request.html.erb @@ -0,0 +1,36 @@ + +<%= fields_for "challenge_assignments[]", assignment do |assignment_form| %> + <% request_signup = assignment.request_signup %> + <% offer_signup = assignment.offer_signup %> + + + <%= link_to assignment.id, collection_assignment_path(@collection, assignment) %> + + + <% if offer_signup %> + <% # offer an autocomplete of potential matches %> + <%= assignment_form.text_field :request_signup_pseud, autocomplete_options("potential_requests?signup_id=#{offer_signup.id}", + data: { autocomplete_min_chars: 0, autocomplete_token_limit: 1 }, size: ArchiveConfig.POTENTIAL_MATCHES_MAX) %> + <% else %> + <%= request_signup.pseud.byline %> + <% end %> + + + + <% if request_signup %> + <% # offer an autocomplete of potential matches %> + <%= assignment_form.text_field :offer_signup_pseud, autocomplete_options("potential_offers?signup_id=#{request_signup.id}", + data: { autocomplete_min_chars: 0, autocomplete_token_limit: 1 }, size: ArchiveConfig.POTENTIAL_MATCHES_MAX) %> + <% else %> + <%= offer_signup.pseud.byline %> + <% end %> + + + <% unless params[:no_recipient] %> + + <%= assignment_form.text_field :pinch_hitter_byline, autocomplete_options("pseud", data: { autocomplete_token_limit: 1 }, size: 20) %> + + <% end %> + + +<% end %> diff --git a/app/views/potential_matches/_assignments.html.erb b/app/views/potential_matches/_assignments.html.erb new file mode 100755 index 0000000..e85d57b --- /dev/null +++ b/app/views/potential_matches/_assignments.html.erb @@ -0,0 +1,32 @@ +<%= form_tag set_collection_assignments_path, :method => :put do %> + <% if @assignments.blank? %> +

    <%= ts("None here! Please check the other tabs.") %>

    + <% else %> + + + + "> + + + + + + + <% unless params[:no_recipient] %> + + <% end %> + + + + <% @assignments.each do |assignment| %> + <%= render "potential_matches/assignment_with_request", :assignment => assignment %> + <% end %> +
    <%= ts("Assignments") %>
    <%= ts("Assignment ID") %><%= ts("Recipient") %><%= ts("Giver") %><%= ts("Write-In Giver") %> <%= link_to_help "challenge-pinch-hitter" %>
    + + <% unless @assignments.is_a?(Array) %> + <% # if these are bad assignments with errors then it's an array and can't be paginated %> + <%= will_paginate @assignments %> + <% end %> + <% end %> + <%= render "potential_matches/match_navigation" %> +<% end %> \ No newline at end of file diff --git a/app/views/potential_matches/_in_progress.html.erb b/app/views/potential_matches/_in_progress.html.erb new file mode 100755 index 0000000..d6b97a6 --- /dev/null +++ b/app/views/potential_matches/_in_progress.html.erb @@ -0,0 +1,16 @@ +

    + <%= ts("The archive is generating potential matches for this challenge. This can take a long time, + especially for a large challenge! We'll send an email to the collection maintainers when + all potential matches have been generated. ") %> +

    + +

    + <%= ts("If the progress value below doesn't change when you reload the page + after about 10 minutes, there may have been a problem. Please check again after an hour, and then contact archive support.") %> +

    + +

    + <%= ts("Potential match generation progress:") %> <%= @progress %>% +

    + +<%= button_to ts("Cancel Potential Match Generation"), cancel_generate_collection_potential_matches_path(@collection), method: :post %> diff --git a/app/views/potential_matches/_invalid_signups.html.erb b/app/views/potential_matches/_invalid_signups.html.erb new file mode 100755 index 0000000..dd226b5 --- /dev/null +++ b/app/views/potential_matches/_invalid_signups.html.erb @@ -0,0 +1,15 @@ +

    <%= ts("Invalid Sign-ups Found!") %>

    +

    + <%= ts("Your challenge has the following invalid sign-ups. They may be duplicates or have + too-many or too-few prompts. You can review and edit or delete them, or contact the user + if you aren't sure what they wanted.") %> +

    +

    + <%= ts("When you are finished, try to generate potential matches again.") %> +

    + +
      +<% @invalid_signups.each do |signup| %> +
    • <%= link_to signup.pseud.byline, collection_signup_path(@collection, signup) %>
    • +<% end %> +
    diff --git a/app/views/potential_matches/_match_navigation.html.erb b/app/views/potential_matches/_match_navigation.html.erb new file mode 100755 index 0000000..9baaec0 --- /dev/null +++ b/app/views/potential_matches/_match_navigation.html.erb @@ -0,0 +1,29 @@ +<% if !@collection.challenge.signup_open %> +
    + +
    +<% end %> diff --git a/app/views/potential_matches/_no_match_required.html.erb b/app/views/potential_matches/_no_match_required.html.erb new file mode 100755 index 0000000..e079563 --- /dev/null +++ b/app/views/potential_matches/_no_match_required.html.erb @@ -0,0 +1,8 @@ +

    + <%= ts("Your challenge doesn't have any match settings defined, so the matching + will be purely random. + (You can adjust the assignments by hand afterwards, though!) + If you want participants matched up on the tags they signed up with, + please update your ") %> + <%= link_to ts("challenge match settings"), edit_collection_gift_exchange_path(@collection, :anchor => 'match_settings') %>. +

    diff --git a/app/views/potential_matches/_no_potential_givers.html.erb b/app/views/potential_matches/_no_potential_givers.html.erb new file mode 100755 index 0000000..cff5e25 --- /dev/null +++ b/app/views/potential_matches/_no_potential_givers.html.erb @@ -0,0 +1,30 @@ +<% if @assignments_with_no_potential_givers.present? %> +
    +

    <%= ts("Participants with No Potential Givers") %>

    +
    + <% @assignments_with_no_potential_givers.each do |assignment| %> +
    + +
    + <% end %> +
    +
    +<% else %> +

    <%= ts("All participants have at least one potential giver!")%>

    +<% end %> diff --git a/app/views/potential_matches/_no_potential_recipients.html.erb b/app/views/potential_matches/_no_potential_recipients.html.erb new file mode 100755 index 0000000..b35bb46 --- /dev/null +++ b/app/views/potential_matches/_no_potential_recipients.html.erb @@ -0,0 +1,24 @@ +<% if @assignments_with_no_potential_recipients.present? %> +
    +

    <%= ts("Participants with No Potential Recipients") %>

    +
    + <% @assignments_with_no_potential_recipients.each do |assignment| %> +
    + +
    + <% end %> +
    +
    +<% else %> +

    <%= ts("All participants have at least one potential recipient!")%>

    +<% end %> diff --git a/app/views/potential_matches/_potential_matches.html.erb b/app/views/potential_matches/_potential_matches.html.erb new file mode 100755 index 0000000..827246e --- /dev/null +++ b/app/views/potential_matches/_potential_matches.html.erb @@ -0,0 +1,71 @@ +

    + <%=ts("Reviewing Assignments") %> + <% if params[:no_potential_recipients] %> + <%=ts("With No Potential Recipients") %> + <% elsif params[:no_potential_givers] %> + <%=ts("With No Potential Givers") %> + <% elsif params[:no_recipient] %> + <%=ts("With No Recipient Assigned") %> + <% elsif params[:no_giver] %> + <%=ts("With No Giver Assigned") %> + <% elsif params[:dup_giver] %> + <%=ts("With The Same Giver Assigned More Than Once") %> + <% elsif params[:dup_recipient] %> + <%=ts("With The Same Recipient Assigned More Than Once") %> + <% end %> + <%= link_to_help "challenge-matching-assignments" %> +

    + +

    + <% if params[:no_potential_recipients] %> + <%=ts("No one wants what they're offering! You must edit their signup before you can assign them to give to anyone.") %> + <% elsif params[:no_potential_givers] %> + <%=ts("No one can give what they want! You must either edit their signup or write-in a volunteer giver.") %> + <% elsif params[:no_recipient] %> + <%=ts("You can double-assign recipients or shuffle around the completed assignments to match everyone off.") %> + <% elsif params[:no_giver] %> + <%=ts("You can write-in givers or shuffle around the completed assignments to match everyone off.") %> + <% elsif params[:dup_giver] %> + <%=ts("These may not be a problem as long as the givers are willing to get more than one assignment, + but you may want to put their name into the write-in field for all but their one official assignment.") %> + <% elsif params[:dup_recipient] %> + <%=ts("These are most likely not a problem: these recipients will simply get more than one gift.") %> + <% else %> + + <% end %> +

    + + + + + +<% if params[:no_potential_recipients] %> + <%= render "no_potential_recipients" %> +<% elsif params[:no_potential_givers] %> + <%= render "no_potential_givers" %> +<% else %> + <%= render "potential_matches/assignments" %> +<% end %> \ No newline at end of file diff --git a/app/views/potential_matches/index.html.erb b/app/views/potential_matches/index.html.erb new file mode 100755 index 0000000..f0ef1e1 --- /dev/null +++ b/app/views/potential_matches/index.html.erb @@ -0,0 +1,46 @@ + +

    <%= ts('Matching for %{collection_title}', :collection_title => @collection.title) %>

    + + + + + + +<% if @challenge.signup_open %> +

    + <%= ts("You can't generate matches while sign-up is still open. After you have closed sign-ups in Challenge Settings, + you will be able to generate potential matches here.") %> +

    +<% elsif @collection.signups.count < 2 %> +

    + <%= ts("You need at least two people to sign up before you can make assignments.") %> +

    +<% elsif @in_progress %> + <%= render "in_progress"%> +<% elsif @assignment_in_progress %> +

    <%= ts("Assignments Generating") %> <%= link_to_help "challenge-matching" %>

    +

    + <%= ts("We're now in the process of generating assignments. This should take less time than potential matching.") %> +

    +<% elsif @collection.potential_matches.empty? %> +

    <%= ts("Potential Match Generation") %> <%= link_to_help "challenge-matching" %>

    + + <%= render "match_navigation" %> +

    + <%= ts("No potential matches yet!") %> +

    + + <% if !@settings || @settings.no_match_required? %> + <%= render "no_match_required" %> + <% end %> + + <% if @invalid_signups %> + <%= render "invalid_signups" %> + <% end %> + +<% else %> + <% # we have potential matches! %> + <%= render "potential_matches/potential_matches" %> + +<% end %> + diff --git a/app/views/potential_matches/list_potential_matches.html.erb b/app/views/potential_matches/list_potential_matches.html.erb new file mode 100755 index 0000000..e69de29 diff --git a/app/views/potential_matches/show.html.erb b/app/views/potential_matches/show.html.erb new file mode 100755 index 0000000..96ae045 --- /dev/null +++ b/app/views/potential_matches/show.html.erb @@ -0,0 +1,31 @@ + +

    <%= ts("Potential Matches") %>

    + + + + + + +

    + <%= ts("Potential Match for %{requester}: %{offerer}", + :requester => @potential_match.request_signup.pseud.byline, :offerer => @potential_match.offer_signup.pseud.byline) %> +

    + +
    +
    +
    <%= ts("Requests Matched:") %>
    +
    <%= @potential_match.num_prompts_matched %>
    + +
    <%= ts("Most Tags Matched:") %>
    +
    <%= @potential_match.max_tags_matched %>
    +
    +
    + + + <%= render :partial => "challenge_signups/show_requests", :locals => {:challenge_signup => @potential_match.request_signup} %> + + <%= render :partial => "challenge_signups/show_offers", :locals => {:challenge_signup => @potential_match.offer_signup} %> + + + + diff --git a/app/views/preferences/index.html.erb b/app/views/preferences/index.html.erb new file mode 100755 index 0000000..a8c5447 --- /dev/null +++ b/app/views/preferences/index.html.erb @@ -0,0 +1,156 @@ + +

    <%= t(".page_heading") %>

    +<%= error_messages_for :preference %> + + + + +

    <%= t(".navigation.landmark") %>

    + + + + +<%= form_for(@preference, url: user_preference_path(@user, @preference), autocomplete: "off") do |f| %> +
    + <%= t(".privacy.legend") %> +

    <%= t(".privacy.heading") %> <%= link_to_help "privacy-preferences" %>

    +
      +
    • + <%= f.check_box :minimize_search_engines %> + <%= f.label :minimize_search_engines, t(".privacy.hide_work_from_search_engines") %> +
    • +
    • + <%= f.check_box :disable_share_links %> + <%= f.label :disable_share_links, t(".privacy.hide_share_buttons") %> +
    • +
    • + <%= f.check_box :allow_cocreator %> + <%= f.label :allow_cocreator, t(".privacy.allow_co_creator_invite") %> +
    • +
    +
    +
    + <%= t(".display.legend") %> +

    <%= t(".display.heading") %> <%= link_to_help "display-preferences" %>

    +
      +
    • + <%= f.check_box :adult %> + <%= f.label :adult, t(".display.show_adult_content") %> +
    • +
    • + <%= f.check_box :view_full_works %> + <%= f.label :view_full_works, t(".display.show_whole_work_default") %> +
    • +
    • + <%= f.check_box :hide_warnings %> + <%= f.label :hide_warnings, t(".display.hide_warnings") %> +
    • +
    • + <%= f.check_box :hide_freeform %> + <%= f.label :hide_freeform, t(".display.hide_additional_tags") %> +
    • +
    • + <%= f.check_box :disable_work_skins %> + <%= f.label :disable_work_skins, t(".display.hide_work_skins") %> <%= link_to_help "skins-basics" %> +
    • +
    +
    +
    +
    +
    <%= f.label :skin_id, t(".your_site_skin") %> <%= link_to_help "skins-basics" %>
    +
    + <%= link_to t(".public_site_skins"), skins_path %> + <%= f.select :skin_id, (@available_skins.collect { |s| [s.title, s.id] }) %> +
    +
    <%= f.label :time_zone, t(".your_time_zone") %>
    +
    <%= f.time_zone_select :time_zone, nil, default: Time.zone.name %>
    + <% if $rollout.active?(:set_locale_preference, @user) %> +
    <%= f.label :preferred_locale, t(".your_locale") %> <%= link_to_help "locale-preferences" %>
    +
    <%= f.select :preferred_locale, locale_options_for_select(@available_locales, "id"), + default: @preference.preferred_locale %>
    + <% end %> +
    <%= f.label :work_title_format, t(".browser_page_title_format") %> <%= link_to_help "work_title_format" %>
    +
    <%= f.text_field :work_title_format %>
    +
    +
    +
    + <%= t(".comments.legend") %> +

    <%= t(".comments.heading") %> <%= link_to_help "comment-preferences" %>

    +
      +
    • + <%= f.check_box :comment_emails_off %> + <%= f.label :comment_emails_off, t(".comments.turn_off_emails") %> +
    • +
    • + <%= f.check_box :comment_inbox_off %> + <%= f.label :comment_inbox_off, t(".comments.turn_off_inbox") %> +
    • +
    • + <%= f.check_box :comment_copy_to_self_off %> + <%= f.label :comment_copy_to_self_off, t(".comments.turn_off_copies_own_comments") %> +
    • +
    • + <%= f.check_box :kudos_emails_off %> + <%= f.label :kudos_emails_off, t(".comments.turn_off_kudos_emails") %> +
    • +
    • + <%= f.check_box :guest_replies_off %> + <%= f.label :guest_replies_off, t(".comments.guest_replies_off") %> +
    • +
    +
    +
    + <%= t(".collections_challenges_gifts.legend") %> +

    <%= t(".collections_challenges_gifts.heading") %> <%= link_to_help "collection-preferences" %>

    +
      +
    • + <%= f.check_box :allow_collection_invitation %> + <%= f.label :allow_collection_invitation, t(".collections_challenges_gifts.allow_collection_invitation") %> +
    • +
    • + <%= f.check_box :allow_gifts %> + <%= f.label :allow_gifts, t(".collections_challenges_gifts.allow_gifts") %> +
    • +
    • + <%= f.check_box :collection_emails_off %> + <%= f.label :collection_emails_off, t(".collections_challenges_gifts.turn_off_collection_emails") %> +
    • +
    • + <%= f.check_box :collection_inbox_off %> + <%= f.label :collection_inbox_off, t(".collections_challenges_gifts.turn_off_collection_inbox") %> +
    • +
    • + <%= f.check_box :recipient_emails_off %> + <%= f.label :recipient_emails_off, t(".collections_challenges_gifts.turn_off_gift_emails") %> +
    • +
    +
    +
    + <%= t(".misc.legend") %> +

    <%= t(".misc.heading") %> <%= link_to_help "misc-preferences" %>

    +
      +
    • + <%= f.check_box :history_enabled %> + <%= f.label :history_enabled, t(".misc.turn_on_history") %> +
    • +
    • + <%= f.check_box :first_login %> + <%= f.label :first_login, t(".misc.turn_on_new_user_help") %> +
    • +
    • + <%= f.check_box :banner_seen %> + <%= f.label :banner_seen, t(".misc.turn_off_banner_every_page") %> +
    • +
    +
    + <%= submit_fieldset(f) %> +<% end %> + diff --git a/app/views/profile/pseuds.js.erb b/app/views/profile/pseuds.js.erb new file mode 100755 index 0000000..12e98e9 --- /dev/null +++ b/app/views/profile/pseuds.js.erb @@ -0,0 +1,2 @@ +$j("#more_pseuds_connector").remove(); +$j("#more_pseuds").replaceWith("<%= j print_pseud_list(@user, @pseuds, first: false) %>") diff --git a/app/views/profile/show.html.erb b/app/views/profile/show.html.erb new file mode 100755 index 0000000..c4d9670 --- /dev/null +++ b/app/views/profile/show.html.erb @@ -0,0 +1,46 @@ +
    + <%= render 'users/header' %> + + + <% if @profile.title.present? %> +

    <%=h @profile.title %>

    + <% end %> + +
    +
    +
    <%= ts("My pseuds:") %>
    +
    <%= print_pseud_list(@user, @pseuds) %>
    +
    <%= ts("I joined on:") %>
    +
    <%= l(@user.created_at.to_date) %>
    +
    <%= ts("My user ID is:") %>
    +
    <%= @user.id %>
    +
    +
    + + <% if @profile.about_me.present? %> +
    +

    <%=h ts("Bio") %>

    +
    <%=raw sanitize_field(@profile, :about_me) %>
    +
    + <% end %> + + + + <% if logged_in? && current_user == @user %> +

    <%= ts("Actions") %>

    + + <% elsif policy(@user.profile).can_edit_profile? %> +

    <%= t("admin.admin_options.landmark") %>

    + + <% end %> + + +
    diff --git a/app/views/prompt_restrictions/_prompt_restriction_form.html.erb b/app/views/prompt_restrictions/_prompt_restriction_form.html.erb new file mode 100755 index 0000000..5b8d7d4 --- /dev/null +++ b/app/views/prompt_restrictions/_prompt_restriction_form.html.erb @@ -0,0 +1,90 @@ + +<% if is_offer %> + <% @challenge.build_offer_restriction unless @challenge.offer_restriction %> + <% restriction = @challenge.offer_restriction %> +<% else %> + <% @challenge.build_request_restriction unless @challenge.request_restriction %> + <% restriction = @challenge.request_restriction %> +<% end %> + +<%= challenge_form.fields_for(is_offer ? :offer_restriction : :request_restriction) do |prompt_restriction_form| %> + +
    + + <% if is_offer %> + + <%= ts("Offer Settings") %> +

    <%= ts("Offer Settings") %>

    +

    + <%= ts("These settings determine what each separate offer can contain. Note these can be entirely different from the request settings!") %> +

    + <% else %> + <%= ts("Request Settings") %> +

    <%= ts("Request Settings") %>

    +

    + <%= ts("These settings determine what each separate request can contain, and in particular how many different tags of each kind.") %> + <% unless type == "prompt_meme" %><%= ts("If you plan to use automated matching, keep in mind it will be slower the more tags you allow people to request.") %><% end %> +

    + <% unless type == "prompt_meme" %>

    + <%= ts('Checking "Allow Any?" allows users to select "Any" for that field; this means they will match') %> <%= ts("anything") %> <%= ts("put in that field. This option is safer for offers than requests!") %> +

    <% end %> +

    + <%= ts('If you allow three prompts and specify that fandom "must be unique", the user will have to choose completely different fandoms + for all three prompts -- no overlap allowed. Please explain this in your signup instructions!') %> +

    + <% end %> +
    + <% if @challenge.new_record? || !@challenge.collection.prompts.exists? %> +

    <%= ts("These settings can only be changed until prompts are added.") %>

    + <% elsif %> +

    <%= ts("Prompts have been added so these settings can no longer be changed.") %>

    + <% end %> + <% if type == "gift_exchange" %> + <%= prompt_restriction_settings(prompt_restriction_form, (is_offer ? false : true), true, (@challenge.new_record? || !@challenge.collection.prompts.exists?)) %> + <% else %> + <%= prompt_restriction_settings(prompt_restriction_form, (is_offer ? false : true), false, (@challenge.new_record? || !@challenge.collection.prompts.exists?)) %> + <% end %> +
    +
    + + <% if show_tag_options %> +
    + <%= ts("Tag Options") %> +

    <%= ts("Tag Options") %> <%= link_to_help("prompt-restriction-tag-set" + (type == "gift_exchange" ? "" : "-promptmeme")) %>

    +

    + <%= link_to(ts("Tag sets"), tag_sets_path) %> <%= ts("show what tags can be used in + your challenge. You can make your own or use any public tag set. Beware: owners can change the contents of their public tag set without warning.") %> +

    +
    + <% unless restriction.owned_tag_sets.empty? %> +
    <%= prompt_restriction_form.label :tag_sets_to_remove, ts("Current Tag Sets:") %>
    +
    +

    <%= ts("Check to remove") %>

    + <%= checkbox_section(prompt_restriction_form, :tag_sets_to_remove, restriction.owned_tag_sets, :name_method => "title") %> +
    + <% end %> +
    <%= prompt_restriction_form.label :tag_sets_to_add, ts("Tag Sets To Use:") %>
    +
    <%= prompt_restriction_form.text_field :tag_sets_to_add, autocomplete_options("owned_tag_sets") %>
    + <% TagSet::TAG_TYPES_RESTRICTED_TO_FANDOM.each do |tag_type| %> +
    + <%= ts("%{tag_type} Settings:", tag_type: tag_type_label_name(tag_type)) %> <%= link_to_help("prompt-restriction-character-and-relationship") %> +
    +
    +
      +
    • + <%= prompt_restriction_form.check_box "#{tag_type}_restrict_to_fandom", :checked => restriction.send("#{tag_type}_restrict_to_fandom") %> + <%= prompt_restriction_form.label "#{tag_type}_restrict_to_fandom", ts("Fandom only?") %> +
    • +
    • + <%= prompt_restriction_form.check_box "#{tag_type}_restrict_to_tag_set", :checked => restriction.send("#{tag_type}_restrict_to_tag_set") %> + <%= prompt_restriction_form.label "#{tag_type}_restrict_to_tag_set", ts("Tag set fandom only?") %> +
    • +
    +
    + <% end %> +
    +
    + <% end %> + +<% end %> diff --git a/app/views/prompts/_prompt_blurb.html.erb b/app/views/prompts/_prompt_blurb.html.erb new file mode 100755 index 0000000..d483450 --- /dev/null +++ b/app/views/prompts/_prompt_blurb.html.erb @@ -0,0 +1,96 @@ +<% # expects "prompt", if index is passed will use that in title if none exists, if suppress_claims is true will ignore %> +
  • +
    +

    + <% if !prompt.title.blank? %> + <%= prompt.title %> + <% else %> + <%= ts("#{prompt.class.to_s}%{index}", :index => (index ||= false) ? " #{index+1}" : '') %> + <% end %> + <% if prompt.anonymous? %> + <%= ts("by Anonymous") %> + <% else %> + <%= ts("by %{person}", :person => (prompt.pseud ? prompt.pseud.byline : prompt.challenge_signup.pseud.byline)) %> + <% end %> + <% unless @collection %> + <%= ts("in") %> <%= link_to prompt.collection.title, collection_path(prompt.collection) %> + <% end %> +

    + + <% tag_groups = prompt.tag_groups %> + + <% # eventually we should let mod specify topmost tag type to display -- ie chars and rels for single-fandom meme, freeforms for single-relationship meme %> +
    + <%= ts('Fandom') %>: + <%= tag_groups['Fandom'].collect{|tag| link_to_tag_works(tag) }.join(', ').html_safe if tag_groups['Fandom'] %> +   +
    + + + <%= get_symbols_for(prompt, tag_groups) %> +

    <%= set_format_for_date(prompt.created_at) %>

    +
    + +
    <%= ts("Tags") %>
    +
      + <%= blurb_tag_block(prompt, tag_groups) %> + <% any_types = TagSet::TAG_TYPES.select {|type| prompt.send("any_#{type}")} %> + <% unless any_types.empty? %> + <%= any_types.map { |type| content_tag(:li, ts("Any %{tag_type}", tag_type: tag_type_label_name(type)), :class => "tag") }.join("\n").html_safe %> + <% end %> +
    + <% if prompt.optional_tag_set && !prompt.optional_tag_set.tags.empty? %> +
    <%= ts("Optional Tags:") %>
    +
      + <%= tag_link_list(prompt.optional_tag_set.tags, link_to_works=true) %> +
    + <% end %> + + <% unless prompt.description.blank? %> +
    <%= ts("Summary") %>
    +
    + <%=raw sanitize_field(prompt, :description) %> +
    + <% end %> + + <% unless prompt.url.blank? %> +

    + <% url_label = prompt.collection.challenge.send("request_url_label") %><%= url_label.blank? ? ts("URL:") : url_label %> + <%= link_to(prompt.url, prompt.url) %> +

    + <% end %> + + <% if logged_in? %> + <%= render "prompts/prompt_controls", :challenge_signup => prompt.challenge_signup, :prompt => prompt %> + <% end %> + + <% unless (suppress_claims ||= false) %> + <% # if prompt has been claimed list by whom %> + <% unless prompt.unfulfilled_claims.empty? %> +
    +
    <%= ts("Claimed By")%>
    +
      + <% if prompt.collection.anonymous? %> + <%= ts("%{count} anonymous claimants", :count => prompt.unfulfilled_claims.count) %> + <% else %> + <%= User.for_claims(prompt.unfulfilled_claims.pluck(:id)).pluck(:login).map {|user| content_tag(:li, user)}.join("\n").html_safe %> + <% end %> +
    +
    + <% end %> + + <% # if prompt has been fulfilled list works %> + <% unless prompt.unfulfilled? %> +
    +
    <%= ts("Fulfilled By")%>
    +
      + <% prompt.fulfilled_claims.map(&:creation).each do |creation| %> + <% if creation.is_a?(Work) %> + <%= render "works/work_blurb", :work => creation %> + <% end %> + <% end %> +
    +
    + <% end %> + <% end %> +
  • diff --git a/app/views/prompts/_prompt_controls.html.erb b/app/views/prompts/_prompt_controls.html.erb new file mode 100755 index 0000000..32aaba8 --- /dev/null +++ b/app/views/prompts/_prompt_controls.html.erb @@ -0,0 +1,56 @@ +<% # requires 'challenge_signup' and 'prompt' locals %> +<% # to make the code more readable: %> +<% collection = challenge_signup.collection %> +<% challenge = collection.challenge %> +<% user = challenge_signup.pseud.user %> + +<% if challenge.signup_open || (!challenge.signup_open && collection.user_is_maintainer?(current_user)) || collection.challenge_type == "PromptMeme" %> + +<% end %> diff --git a/app/views/prompts/_prompt_form.html.erb b/app/views/prompts/_prompt_form.html.erb new file mode 100755 index 0000000..9454d37 --- /dev/null +++ b/app/views/prompts/_prompt_form.html.erb @@ -0,0 +1,114 @@ + +
    + <% # CODE NOTES: + # This is meant to be used as a nested form inside other forms, so that multiple prompts can be submitted within a single form. + # It is also meant to be used with javascript-based live adding (that is, not with ajax) which means locals will not be re-evaluated when it is added; + # keep this in mind when using the add_section code! + # It expects a form being passed in as "form" + # If the local variable "index" is passed in, that will represent which prompt this is, if there are multiple prompts being submitted + # If the local variable "required" is passed in, this prompt is required + # See the challenge_signup form for an example of how this is used. + %> + + <% index ||= 0 %> + <% required ||= false %> + <% prompt_label = form.object.class.name %> + <% prompt_type = prompt_label.downcase %> + <% prompt_types = prompt_type.pluralize %> + <% restriction = @challenge.send("#{prompt_type}_restriction") %> + +
    + <% if index.is_a? String %> + <% prompt_label += " #{index}" %> + <% else %> + <% prompt_label += " #{(index + 1)}" %> + <% end %> + + <%= prompt_label %> +

    <%= form.object.new_record? ? prompt_label : link_to(prompt_label, collection_prompt_path(@collection, form.object)) %>

    + +
    + <% if restriction.title_allowed %> + > + <% if restriction.title_required %> + <%= form.label :title, (ts("Title:") + " *") %> + <% else %> + <%= form.label :title, ts("Title:") %> + <% end %> + +
    <%= form.text_field :title %>
    + <% end %> + + + <%= render "prompts/prompt_form_tag_options", :form => form, :restriction => restriction %> + + <% if restriction.url_allowed %> + > + <% url_label = @challenge.send("#{prompt_type}_url_label") %> + <% if restriction.url_required %> + <%= form.label :url , (url_label.blank? ? (ts("Prompt URL:") + " *") : url_label + " *") %> + <% else %> + <%= form.label :url , (url_label.blank? ? ts("Prompt URL:") : url_label) %> + <% end %> + +
    <%= form.text_field :url %>
    + <% end %> + + <% if restriction.description_allowed %> + > + <% desc_label = @challenge.send("#{prompt_type}_description_label") %> + <% if restriction.description_required %> + <%= form.label :description, (desc_label.blank? ? (ts("Description:") + " *") : desc_label + " *") %> + <% else %> + <%= form.label :description, (desc_label.blank? ? ts("Description:") : desc_label) %> + <% end %> + +
    <%= form.text_area :description, :rows => 6, :cols => 50, :class => "observe_textlength" %> + <%= live_validation_for_field(field_id(form, "description").to_sym, :presence => false, :maximum_length => ArchiveConfig.NOTES_MAX) -%> + <%= generate_countdown_html(field_id(form, "description").to_sym, ArchiveConfig.NOTES_MAX) %> +
    + <% end %> + + <% if restriction.optional_tags_allowed %> + <% form.object.build_optional_tag_set unless form.object.optional_tag_set %> + <%= form.fields_for :optional_tag_set_attributes do |optional_tag_set_form| %> +
    + <%= optional_tag_set_form.label :tagnames, ts("Optional Tags:") %> <%= link_to_help("challenge-optional-tags-user")%> +
    +
    + <%= optional_tag_set_form.text_field :tagnames, autocomplete_options("tag?type=all", :value => form.object.optional_tag_set.tagnames) %> +
    + <% end %> + <% end %> + + <% if @collection.challenge.respond_to?(:anonymous) %> + <% # TODO ANONYMITY REFACTOR: Anonymity should not be based on a type of challenge but on whether the specific challenge ALLOWS anonymity or not, + # (currently the prompt memes don't allow a mod to specify no anonymity allowed) + # and should probably be done via an Anonymous user like the Orphan user. + %> +
    <%= form.label :anonymous, ts("Semi-anonymous Prompt?") %>
    +
    + <%= form.check_box :anonymous, :checked => @collection.challenge.anonymous? ? true : form.object.anonymous %> +

    <%= ts("(Note: This is not totally secure, and is still guessable in some places.)") %>

    +
    + <% end %> +
    + + <% unless required %> +

    + <%= link_to_remove_section(ts("Remove?"), form) %> + +

    + <% end %> +
    +
    + + + + + diff --git a/app/views/prompts/_prompt_form_tag_options.html.erb b/app/views/prompts/_prompt_form_tag_options.html.erb new file mode 100755 index 0000000..8efbd60 --- /dev/null +++ b/app/views/prompts/_prompt_form_tag_options.html.erb @@ -0,0 +1,117 @@ + +<% form.object.build_tag_set unless form.object.tag_set %> +<%= form.fields_for :tag_set do |tag_set_form| %> + + <% TagSet::TAG_TYPES.each do |tag_type| %> + <% tag_label = tag_type_label_name(tag_type) %> + + <% tag_name = tag_type.classify.constantize::NAME # constantize safe as iterating over safe list %> + <% num_allowed = restriction.allowed(tag_type) %> + <% num_required = restriction.required(tag_type) %> + + <% if num_allowed > 0 %> + <% # save some local variables to make the tag_set_form cleaner %> + <% tag_fieldname = field_name(tag_set_form, "#{tag_type}_tagnames") %> + <% tag_field_id = field_id(tag_set_form, "#{tag_type}_tagnames") %> + + 0 ? ' class="required"'.html_safe : '' %>> + <%= tag_set_form.label "#{tag_type}_tagnames".to_sym, challenge_signup_label(tag_name, num_allowed, num_required), class: tag_type_css_class(tag_type) %> + + <% # kludge required for bug in nested_attributes_for:https://rails.lighthouseapp.com/projects/8994/tickets/2646-validations-not-called-when-model-updating-using-nested-attributes %> + + + <% # Pseudocode for this long if + # if rating/warning/category + # checkboxes from tag set + # elsif character/rating and restricted to fandom/tagset + # autocomplete based on fandom + # else + # if anything in tagset + # if not too many things + # tickyboxes from tagset + # else + # autocomplete from tagset + # end + # else + # standard autocomplete by tag type + # end + # end + %> + + <% if TagSet::TAGS_AS_CHECKBOXES.include?(tag_type) %> + <% # do ratings, warnings, categories as taglists if not already specified %> +
    "> +

    <%= ts("#{tag_name.pluralize.titleize}") %>

    + <%= checkbox_section tag_set_form, "#{tag_type}_tagnames", + (restriction.has_tags?(tag_type) ? restriction.tags(tag_type) : tag_type.classify.constantize.canonical).map {|t| t.name}, # constantize safe as itterating over safe list + :checked_method => "#{tag_type}_tagnames", :value_method => "to_s", :name_method => "to_s" %> + <%= tag_set_form.hidden_field :updated_at, :value => Time.now %> +
    + + <% elsif TagSet::TAG_TYPES_RESTRICTED_TO_FANDOM.include?(tag_type) && (restriction.restricted?(tag_type, "fandom") || restriction.restricted?(tag_type, "tag_set")) %> + <% # characters or relationships restricted to fandom: use an autocomplete and either do/don't include wrangled tags %> + <% autocomplete_method = "associated_tags?fallback=false&tag_type=#{tag_type}&tag_set=#{restriction.tag_set_ids.join(',')}" %> + <% autocomplete_method += "&include_wrangled=false" if restriction.restricted?(tag_type, "tag_set") %> +
    "> + <%= tag_set_form.text_field "#{tag_type}_tagnames", + autocomplete_options(autocomplete_method, + data: { + autocomplete_min_chars: 0, + autocomplete_token_limit: num_allowed, + autocomplete_hint_text: ts("Please select a fandom first!"), + autocomplete_searching_text: ts("Searching by fandom..."), + autocomplete_live_params: "fandom=#{@fandom_tag_id}" + }) %> + <%= tag_set_form.hidden_field :updated_at, :value => Time.now %> +
    + <% else # all other cases %> + <% # save the field id to pass for autocompleting based on fandoms in autocomplete if we use autocomplete %> + <% @fandom_tag_id = tag_field_id if tag_type == 'fandom' %> + + <% if restriction.has_tags?(tag_type) # tags are specified in the tag set %> + <% if restriction.tags(tag_type).count <= ArchiveConfig.MAX_OPTIONS_TO_SHOW %> + + <% # save the field id to pass for autocompleting based on fandoms tickyed instead of autocomplete %> + <% @fandom_tag_id += "_checkboxes" if tag_type == 'fandom' %> + + <% # create a scrollable checkboxes section to wrap the tags, see application_helper %> +
    listbox group" title="<%= ts("choose #{tag_name.pluralize.downcase}") %>"> +

    <%= ts("#{tag_name.titleize}") %>

    + <%= checkbox_section tag_set_form, "#{tag_type}_tagnames", restriction.tags(tag_type).by_name_without_articles.pluck(:name), + :checked_method => "#{tag_type}_tagnames", :value_method => "to_s", :name_method => "to_s" %> + <%= tag_set_form.hidden_field :updated_at, :value => Time.now %> +
    + <% else # we have set options but too many for tickyboxes, do autocomplete instead %> +
    "> + <%= tag_set_form.text_field "#{tag_type}_tagnames", + autocomplete_options("tags_in_sets?tag_type=#{tag_type}&tag_set=#{restriction.tag_set_ids.join(',')}", + data: { autocomplete_token_limit: num_allowed }) %> +

    + <% # TODO: would be nice to improve this for the case of multiple tag sets, currently it links to just an index of all the tag sets for this challenge %> + <%= link_to( ts("List %{taglist_size} %{tag_name}", :taglist_size => restriction.tags(tag_type).count, :tag_name => tag_name.pluralize.titleize), + show_options_tag_sets_path(:restriction => restriction.id, :tag_type => tag_type), :target => "_blank", :class => "toggle") %> +

    + <%= tag_set_form.hidden_field :updated_at, :value => Time.now %> +
    + <% end %> + <% else # no specified tags so let's just go with standard autocomplete %> +
    "> + <%= tag_set_form.text_field "#{tag_type}_tagnames", autocomplete_options(tag_type, data: { autocomplete_token_limit: num_allowed }) %> + <%= tag_set_form.hidden_field :updated_at, :value => Time.now %> +
    + <% end %> + + <% end # long if for the dd %> + + <% if restriction.allow_any?(tag_type) %> +
    + <%= form.label "any_#{tag_type}", :class => 'action' do %> + <%= form.check_box "any_#{tag_type}".to_sym %> + <%= ts("Any #{tag_name.singularize.titleize}") %> + <% end %> + <%= link_to_help("challenge-any") %> +
    + <% end %> + <% end # if num_allowed > 0 %> + <% end # each tag_type %> +<% end # do tag_set_form %> diff --git a/app/views/prompts/_prompt_navigation.html.erb b/app/views/prompts/_prompt_navigation.html.erb new file mode 100755 index 0000000..7e59cea --- /dev/null +++ b/app/views/prompts/_prompt_navigation.html.erb @@ -0,0 +1,10 @@ + diff --git a/app/views/prompts/edit.html.erb b/app/views/prompts/edit.html.erb new file mode 100755 index 0000000..a6741c7 --- /dev/null +++ b/app/views/prompts/edit.html.erb @@ -0,0 +1,18 @@ + +

    <%= ts("Edit Prompt") %>

    + + + +<% if @prompt.challenge_signup %> + <%= render "prompt_navigation" %> +<% end %> + + + +<%= form_for @prompt, :as => :prompt, :url => collection_prompt_path(@collection, @prompt), :html => {:method => :put} do |form| %> +

    <%= ts("* Required information") %>

    + <%= error_messages_for @prompt %> + <%= render "prompt_form", :form => form, :required => true, :index => @index %> + <%= submit_fieldset form %> +<% end %> + diff --git a/app/views/prompts/index.html.erb b/app/views/prompts/index.html.erb new file mode 100755 index 0000000..c449051 --- /dev/null +++ b/app/views/prompts/index.html.erb @@ -0,0 +1,9 @@ +<% + # this currently doesn't get called anywhere + # presumably this rather than the challenge signups index should be the list of prompts eg in a prompt meme +%> +

    <%= ts("Prompts") %>

    + +
      + for each render partial _prompt_blurb +
    \ No newline at end of file diff --git a/app/views/prompts/new.html.erb b/app/views/prompts/new.html.erb new file mode 100755 index 0000000..9e5314b --- /dev/null +++ b/app/views/prompts/new.html.erb @@ -0,0 +1,16 @@ + +

    <%= ts("New Prompt") %>

    + + + +<% if @prompt.challenge_signup %> + <%= render "prompt_navigation" %> +<% end %> + + + +<%= form_for @prompt, :as => :prompt, :url => collection_prompts_path(@collection), :html => {:method => :post} do |form| %> + <%= render "prompt_form", :form => form, :required => true, :index => @index %> + <%= submit_fieldset form %> +<% end %> + diff --git a/app/views/prompts/show.html.erb b/app/views/prompts/show.html.erb new file mode 100755 index 0000000..d0a3955 --- /dev/null +++ b/app/views/prompts/show.html.erb @@ -0,0 +1,13 @@ +<% # prompt_form links here when called from prompts/edit %> + +

    <%= ts("#{@prompt.class.name} by %{person}", :person => @prompt.anonymous? ? "Anonymous" : @prompt.challenge_signup.pseud.byline) %>

    + + + + + + +
      + <%= render "prompts/prompt_blurb", :prompt => @prompt %> +
    + diff --git a/app/views/pseuds/_byline.html.erb b/app/views/pseuds/_byline.html.erb new file mode 100755 index 0000000..896b99d --- /dev/null +++ b/app/views/pseuds/_byline.html.erb @@ -0,0 +1,90 @@ +<% # expects locals form, object %> +<% + editor_pseuds = User.current_user.pseuds.to_a + editor_selected = (object.current_user_pseuds || object.pseuds) & editor_pseuds + editor_selected << User.current_user.default_pseud if editor_selected.empty? + + valid_creatorships = object.creatorships_after_saving + + selected = valid_creatorships.map(&:pseud) + + invited = valid_creatorships.reject(&:approved?).map(&:pseud) - editor_pseuds + approved = valid_creatorships.select(&:approved?).map(&:pseud) - editor_pseuds + saved = valid_creatorships.reject(&:new_record?).map(&:pseud) + + if object.is_a?(Chapter) + approved = (approved + object.work.pseuds - editor_pseuds).uniq + end +%> +<%= form.fields_for :author_attributes do |creator_form| %> + <% if editor_pseuds.size == 1 %> + <%= creator_form.hidden_field :ids, value: editor_pseuds.first.id, multiple: true %> + <% else %> + + + <% end %> + + <% if approved.any? %> + + + <% end %> + + <% if invited.any? %> + + + <% end %> + + + +<% end %> diff --git a/app/views/pseuds/_pseud_blurb.html.erb b/app/views/pseuds/_pseud_blurb.html.erb new file mode 100755 index 0000000..fa12d9b --- /dev/null +++ b/app/views/pseuds/_pseud_blurb.html.erb @@ -0,0 +1,45 @@ +
  • + <%= render "pseud_module", pseud: pseud %> + + <% if current_user == pseud.user || policy(pseud).edit? %> +
    <%= t(".user_actions") %>
    + + <% end %> +
  • diff --git a/app/views/pseuds/_pseud_module.html.erb b/app/views/pseuds/_pseud_module.html.erb new file mode 100755 index 0000000..2e4dd36 --- /dev/null +++ b/app/views/pseuds/_pseud_module.html.erb @@ -0,0 +1,22 @@ +
    +

    <%= link_to(pseud.name, user_pseud_path(pseud.user, pseud)) %> + <% if (pseud.name != pseud.user_name || pseud.user.pseuds.size > 1) %> + (<%= link_to(pseud.user_name, user_path(pseud.user)) %>) + <% end %> +

    + <% unless authored_items(pseud, @work_counts, @rec_counts).blank? %> +
    <%= authored_items(pseud, @work_counts, @rec_counts) %>
    + <% end %> +
    + <%= icon_display(pseud.user, pseud) %> +
    + <%# created_at date to display to admins for mutes and blocks %> + <% if local_assigns[:date] && logged_in_as_admin? %> +

    <%= date %>

    + <% end %> +
    +<% if pseud.description.present? %> +
    + <%= raw sanitize_field(pseud, :description, image_safety_mode: true) %> +
    +<% end %> diff --git a/app/views/pseuds/_pseuds_form.html.erb b/app/views/pseuds/_pseuds_form.html.erb new file mode 100755 index 0000000..03640d7 --- /dev/null +++ b/app/views/pseuds/_pseuds_form.html.erb @@ -0,0 +1,72 @@ +<%= form_for([@user, @pseud], html: { multipart: true }) do |f| %> +
    +
    <%= f.label :name, t(".name") %>
    +
    + <% if @pseud&.name == @user.login %> +

    <%= @pseud.name %>

    +

    <%= t(".cannot_change_matching_pseud_html", change_username_link: link_to(t(".change_username"), change_username_user_path(@user))) %>

    + <% else %> + <%= f.text_field :name, class: "observe_textlength", disabled: logged_in_as_admin? %> + <%= generate_countdown_html("pseud_name", Pseud::NAME_LENGTH_MAX) %> + <% end %> +
    + +
    <%= f.label :is_default, t(".make_default") %>
    +
    <%= f.check_box :is_default, disabled: ((@pseud.name && @user.login == @pseud.name && @pseud.is_default?) || logged_in_as_admin?) %>
    + +
    <%= f.label :description, t(".description") %>
    +
    +

    <%= allowed_html_instructions %>

    + <%= f.text_area :description, class: "observe_textlength" %> + <%= generate_countdown_html("pseud_description", Pseud::DESCRIPTION_MAX) %> +
    + +
    <%= t(".icon") %>
    +
    +
      + <% unless @pseud.new_record? %> +
    • <%= icon_display(@user, @pseud) %> <%= t(".icon_notes.current") %>
    • + <% end %> +
    • <%= t(".icon_notes.limit") %>
    • +
    • <%= t(".icon_notes.format") %>
    • +
    • <%= t(".icon_notes.size") %>
    • +
    + <% if @pseud.icon.attached? %> + <%= f.check_box :delete_icon, checked: false %> + <%= f.label :delete_icon, t(".icon_delete") %> + <% end %> +
    + +
    <%= f.label :icon, t(".icon_upload") %>
    +
    <%= f.file_field :icon, disabled: logged_in_as_admin? %>
    + +
    + <%= f.label :icon_alt_text, t(".icon_alt") %> + <%= link_to_help "icon-alt-text" %> +
    +
    + <%= f.text_field :icon_alt_text, class: "observe_textlength", disabled: logged_in_as_admin? %> + <%= generate_countdown_html("pseud_icon_alt_text", ArchiveConfig.ICON_ALT_MAX) %> +
    + +
    + <%= f.label :icon_comment_text, t(".icon_comment") %> + <%= link_to_help("pseud-icon-comment") %> +
    +
    + <%= f.text_field :icon_comment_text, class: "observe_textlength", disabled: logged_in_as_admin? %> + <%= generate_countdown_html("pseud_icon_comment_text", ArchiveConfig.ICON_COMMENT_MAX) %> +
    + + <% if policy(@pseud).can_edit? %> +
    <%= f.label :ticket_number, class: "required" %>
    +
    + <%= f.text_field :ticket_number, class: "required" %> +
    + <% end %> + +
    <%= t(".submit") %>
    +
    <%= f.submit button_text %>
    +
    + +<% end %> diff --git a/app/views/pseuds/delete_preview.html.erb b/app/views/pseuds/delete_preview.html.erb new file mode 100755 index 0000000..c2d8a94 --- /dev/null +++ b/app/views/pseuds/delete_preview.html.erb @@ -0,0 +1,26 @@ +

    <%=h t(".heading") %>

    + +

    + <%= t(".notice") %> +

    + +<% if @pseud.bookmarks %> + <%= form_tag({:action => "destroy"}, :method => :delete) do %> +

    <%= t(".saved_bookmarks", count: @pseud.bookmarks.count) %> +

    + +

    + <%= radio_button_tag 'bookmarks_action', "delete_bookmarks", true %> + <%= label_tag 'bookmarks_action_delete_bookmarks', t(".delete", count: @pseud.bookmarks.count) %> +

    + +

    + <%= radio_button_tag 'bookmarks_action', "transfer_bookmarks" %> + <%= label_tag 'bookmarks_action_transfer_bookmarks', t(".transfer", count: @pseud.bookmarks.count) %> +

    + +

    + <%= submit_tag ts("Submit"), data: {confirm: t(".confirm")} %> <%= submit_tag t(".cancel"), :name => 'cancel_button', :class => 'cancel' %> +

    + <% end %> +<% end %> diff --git a/app/views/pseuds/edit.html.erb b/app/views/pseuds/edit.html.erb new file mode 100755 index 0000000..a79eca1 --- /dev/null +++ b/app/views/pseuds/edit.html.erb @@ -0,0 +1,18 @@ + +

    <%= ts('Editing pseud') %>

    +<%= error_messages_for :pseud %> + + + + + + + +<%= render :partial => 'pseuds_form', :locals => { :button_text => t('.forms.update', :default => "Update") } %> + + + + \ No newline at end of file diff --git a/app/views/pseuds/index.html.erb b/app/views/pseuds/index.html.erb new file mode 100755 index 0000000..db2071e --- /dev/null +++ b/app/views/pseuds/index.html.erb @@ -0,0 +1,26 @@ + +

    <%= ts("Pseuds for %{user}", :user => @user.login) %>

    + + + +<% if current_user == @user %> +

    <%= ts("Navigation") %>

    + +<% end %> +<%= will_paginate @pseuds %> + + + +

    <%= ts("List of Pseuds") %>

    +
      + <% @pseuds.each do |pseud| %> + <%= render :partial => 'pseuds/pseud_blurb', :locals => {:pseud => pseud} %> + <% end %> +
    + + + +<%= will_paginate @pseuds %> + diff --git a/app/views/pseuds/new.html.erb b/app/views/pseuds/new.html.erb new file mode 100755 index 0000000..889f08a --- /dev/null +++ b/app/views/pseuds/new.html.erb @@ -0,0 +1,14 @@ + +

    <%= ts('New pseud') %>

    +<%= error_messages_for :pseud %> + + + + + + + +<%= render :partial => 'pseuds_form', :locals => { :button_text => ts("Create") }%> + \ No newline at end of file diff --git a/app/views/pseuds/show.html.erb b/app/views/pseuds/show.html.erb new file mode 100755 index 0000000..ac1cd9e --- /dev/null +++ b/app/views/pseuds/show.html.erb @@ -0,0 +1,14 @@ +
    + <%= render "users/header" %> + <%= render "users/contents" %> +
    + + +

    Navigation

    + + diff --git a/app/views/questions/manage.html.erb b/app/views/questions/manage.html.erb new file mode 100755 index 0000000..e127cad --- /dev/null +++ b/app/views/questions/manage.html.erb @@ -0,0 +1,41 @@ +
    + +

    <%= ts("Reorder questions") %>

    + +

    <%= ts("Drag questions to change their order.") %>

    + + <%= form_tag url_for(action: 'update_positions') do %> +
      + <% for question in @questions %> +
    • + <%= text_field_tag 'questions[]', nil, size: 3, maxlength: 3, class: 'number question-position-field', id: 'questions_' + question.position.to_s %> + <%= question.position %>. + <%= question.question.html_safe %> +
    • + <% end %> +
    +

    + <%= submit_tag ts("Update Positions") %> + <%= link_to ts("Back"), url_for(@archive_faq) %> +

    + <% end %> +
    + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j("#sortable_question_list").sortable({ + delay: 300, + update: function(event, ui) { + $j(".question-position-list").each(function(index, li){ + var questionId = $j(li).attr("id").replace("question_",""); + $j("#position-for-"+questionId).html(index+1); + }); + $j.ajax({ + type: 'post', + data: $j("#sortable_question_list").sortable("serialize") + "&archive_faq_id=<%= @archive_faq.id %>", + dataType: 'script', + url: "<%= url_for(action: :update_positions) %>"}) + } + }) + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/readings/_reading_blurb.html.erb b/app/views/readings/_reading_blurb.html.erb new file mode 100755 index 0000000..4020c93 --- /dev/null +++ b/app/views/readings/_reading_blurb.html.erb @@ -0,0 +1,64 @@ +<% # expects "work" and "reading" %> +<% css_classes = if work.nil? + "deleted reading work blurb group" + elsif is_author_of?(work) + "own reading work #{css_classes_for_creation_blurb(work)}" + else + "reading work #{css_classes_for_creation_blurb(work)}" + end %> +
  • id="work_<%= work.id %>"<% end %> class="<%= css_classes %>" role="article"> + + <% unless reading.work.nil? %> + + <%= render 'works/work_module', work: reading.work %> + + <% end %> + +
    +

    + + <% if work.nil? %> + + <%= ts('(Deleted work, last visited %{date})', date: set_format_for_date(reading.last_viewed)) %> + + <% else %> + + <%= ts('Last visited:') %> <%= set_format_for_date(reading.last_viewed) %> + + <% if reading.major_version_read != work.major_version %> + <%= ts('(Update available.)') %> + <% elsif reading.minor_version_read != work.minor_version %> + <%= ts('(Minor edits made since then.)') %> + <% else %> + <%= ts('(Latest version.)') %> + <% end %> + + <% if reading.view_count == 1 %> + <%= ts('Visited once') %> + <% else %> + <%= ts('Visited %{count} times', count: reading.view_count) %> + <% end %> + + <% if reading.toread? %> + <%= ts('(Marked for Later.)') %> + <% end %> + <% if reading.toskip? %> + <%= ts('(Flagged to skip.)') %> + <% end %> + + <% end %> + +

    + + + +
    + +
  • diff --git a/app/views/readings/index.html.erb b/app/views/readings/index.html.erb new file mode 100755 index 0000000..424f814 --- /dev/null +++ b/app/views/readings/index.html.erb @@ -0,0 +1,40 @@ +<% mode = params[:show] == "to-read" ? "marked_for_later" : "history" %> + + +

    + <%= t(".#{mode}.page_heading") %> +

    + + + +<% if logged_in? && !current_user.readings.empty? %> + +<% end %> + + + +

    + <%= t(".#{mode}.landmark") %> +

    +<% if logged_in? && @readings.present? %> +
      + <% @readings.each do |reading| %> + <%= render 'reading_blurb', :work => reading.work, :reading => reading %> + <% end %> +
    +<% end %> + + + +<%== pagy_nav @pagy %> + diff --git a/app/views/redirect/show.html.erb b/app/views/redirect/show.html.erb new file mode 100755 index 0000000..35467c9 --- /dev/null +++ b/app/views/redirect/show.html.erb @@ -0,0 +1,18 @@ +

    Lookup Original Stories

    + +

    + If you are looking for a story that might have been imported into the archive from another URL, you can enter it here and + we will try and look it up. +

    + +<%= form_tag redirect_path, method: :get do %> +
    + Find story by URL +

    + <%= label_tag "original_url", ts('Original URL of work:') %>
    + <%= text_field_tag "original_url", "", :size => 70 %> + <%= submit_tag "Go" %> +

    +
    + +<% end %> diff --git a/app/views/related_works/_approve.html.erb b/app/views/related_works/_approve.html.erb new file mode 100755 index 0000000..ede95a4 --- /dev/null +++ b/app/views/related_works/_approve.html.erb @@ -0,0 +1,18 @@ +

    <%= ts('Approve Link') %>

    + +

    + <%= ts('Would you like to create a link from your work') %> + <%= link_to(related_work.parent.title, related_work.parent) %> + <%= ts("to") %> + <%= link_to(related_work.work.title, related_work.work) %> + <%= ts("by") %> + <%= byline(related_work.work) %>? +

    + +

    <%= ts('Nothing will be linked directly from your works without your express approval.') %> <%= ts('You can come back to this page if you change your mind.') %>

    + +<%= form_for(related_work) do |f| %> +

    + <%= f.submit ts("Yes, link me!") %> +

    +<% end %> diff --git a/app/views/related_works/_remove.html.erb b/app/views/related_works/_remove.html.erb new file mode 100755 index 0000000..2875dfa --- /dev/null +++ b/app/views/related_works/_remove.html.erb @@ -0,0 +1,18 @@ +

    <%= ts('Remove Link') %>

    + +

    + <%= ts('Would you like to remove the link from your work') %> + <%= link_to(related_work.parent.title, related_work.parent) %> + <%= ts("to") %> + <%= link_to(related_work.work.title, related_work.work) %> + <%= ts("by") %> + <%= byline(related_work.work) %>? +

    + +

    <%= ts('(You can come back to this page if you change your mind.)') %>

    + +<%= form_for(related_work) do |f| %> +

    + <%= f.submit ts("Remove link") %> +

    +<% end %> diff --git a/app/views/related_works/index.html.erb b/app/views/related_works/index.html.erb new file mode 100755 index 0000000..14898dd --- /dev/null +++ b/app/views/related_works/index.html.erb @@ -0,0 +1,156 @@ + +<% if @user %> +

    <%= t(".page_heading", login: @user.login) %>

    +<% end %> + + + + + + +<% unless @translations_of_user.blank? %> +

    <%= ts("Translations of %{user_login}'s works", :user_login => @user.login) %>

    + <% # FRONT END!!! + # This page is: + # Foo's Related Works + # works by foo that someone has translated + # works by others that foo has translated + # works by foo that inspired other people + # works by others that inspired foo + # this should be four listboxes + %> + @user.login) %><% if current_user == @user %><%= ' ' + ts("Also includes management options.") %><% end %>" id="translationsofme"> + + + + + + + <% if current_user == @user %> + + <% end %> + + + + <% @translations_of_user.each do |related_work| %> + <% if related_work.parent && related_work.work %> + + <% if related_work.work.unrevealed? %> + + <% else %> + + + + <% if current_user == @user %> + + <% end %> + <% end %> + + <% end %> + <% end %> + +
    <%= ts("Translations of %{user_login}'s Works", :user_login => @user.login) %>
    <%= ts("Translation") %><%= ts("Original") %><%= ts("Language") %><%= ts("Modify Link") %>
    <%= ts("A work in an unrevealed collection") %><%= link_to related_work.work.title, related_work.work %> <%= ts("by") %> <%= byline(related_work.work) %><%= link_to related_work.parent.title, related_work.parent %> + <%= ts("From") %> <%= language_link(related_work.parent) %> <%= ts("to") %> <%= language_link(related_work.work) %> + + <% if related_work.reciprocal? %> + <%= link_to ts("Remove"), related_work %> + <% else %> + <%= link_to ts("Approve"), related_work %> + <% end %> +
    +<% end %> + +<% unless @translations_by_user.blank? %> +

    <%= ts("Works translated by %{user_login}", :user_login => @user.login) %>

    + @user.login) %><% if current_user == @user %><%= ' ' + ts("Also includes management options.") %><% end %>" id="translationsbyme"> + + + + + + + <% if current_user == @user %> + + <% end %> + + + + <% @translations_by_user.each do |related_work| %> + <% if related_work.parent && related_work.work %> + + + + + <% if current_user == @user %> + + <% end %> + + <% end %> + <% end %> + +
    <%= ts("Works Translated by %{user_login}", :user_login => @user.login) %>
    <%= ts("Original") %><%= ts("Translation") %><%= ts("Language") %><%= ts("Modify Link") %>
    + <% if related_work.parent.is_a?(Work) && related_work.parent.unrevealed? %> + <%= ts("A work in an unrevealed collection") %> + <% else %> + <%= link_to related_work.parent.title, related_work.parent %> <%= ts("by") %> <%= byline(related_work.parent) %> + <% end %> + <%= link_to related_work.work.title, related_work.work %> + <%= ts("From") %> <%= language_link(related_work.parent) %> <%= ts("to") %> <%= language_link(related_work.work) %> + <%= button_to ts("Remove"), related_work_path(related_work), data: { confirm: ts("Are you sure?") }, method: :delete %>
    +<% end %> + +<% unless @remixes_of_user.blank? %> +

    <%= ts("Works inspired by %{user_login}", :user_login => @user.login) %>

    +
    + <% @remixes_of_user.each do |related_work| %> + <% if related_work.parent && related_work.work %> +
    + <% if related_work.work.unrevealed? %> + <%= ts("A work in an unrevealed collection") %> + <% else %> + <%= link_to related_work.work.title, related_work.work %> <%= ts("by") %> <%= byline(related_work.work) %> +
    +
    <%= ts("was inspired by ") %><%= link_to related_work.parent.title, related_work.parent %> + <% if current_user == @user %> + + <% if related_work.reciprocal? %> + <%= link_to ts("Remove"), related_work %> + <% else %> + <%= link_to ts("Approve"), related_work %> + <% end %> + + <% end %> +
    + <% end %> + <% end %> + <% end %> +
    +<% end %> + +<% unless @remixes_by_user.blank? %> +

    <%= ts("Works that inspired %{user_login}", :user_login => @user.login) %>

    +
    + <% @remixes_by_user.each do |related_work| %> + <% unless related_work.translation? %> + <% if related_work.parent && related_work.work %> +
    + <% if related_work.parent.is_a?(Work) && related_work.parent.unrevealed? %> + <%= ts("A work in an unrevealed collection") %> + <% else %> + <%= link_to related_work.parent.title, related_work.parent %> <%= ts("by") %> <%= byline(related_work.parent) %> + <% end %> +
    +
    + <%= ts("inspired") %> + <%= link_to related_work.work.title, related_work.work %> + <% if current_user == @user %> + <%= button_to ts("Remove"), related_work_path(related_work), data: { confirm: ts("Are you sure?") }, method: :delete %> + <% end %> +
    + <% end %> + <% end %> + <% end %> +
    +<% end %> + + diff --git a/app/views/related_works/show.html.erb b/app/views/related_works/show.html.erb new file mode 100755 index 0000000..f59919d --- /dev/null +++ b/app/views/related_works/show.html.erb @@ -0,0 +1,13 @@ + + + + + + + +<% if @related_work.reciprocal? %> + <%= render :partial => 'remove', :locals => { :related_work => @related_work } %> +<% else %> + <%= render :partial => 'approve', :locals => { :related_work => @related_work } %> +<% end %> + \ No newline at end of file diff --git a/app/views/series/_series_blurb.html.erb b/app/views/series/_series_blurb.html.erb new file mode 100755 index 0000000..d0f8565 --- /dev/null +++ b/app/views/series/_series_blurb.html.erb @@ -0,0 +1,7 @@ +
  • + <%= render 'series/series_module', :series => series %> + <% if is_author_of?(series) %> +
    <%= ts("Author Actions") %>
    + + <% end %> +
  • diff --git a/app/views/series/_series_module.html.erb b/app/views/series/_series_module.html.erb new file mode 100755 index 0000000..c2a0414 --- /dev/null +++ b/app/views/series/_series_module.html.erb @@ -0,0 +1,52 @@ +<% # expects "series" %> + + +
    +

    + <%= link_to series.title, series %> + <%= ts('by') %> + <%= byline(series) %> + <% if series.restricted %> + <%= image_tag("lockblue.png", size: "15x15", alt: ts("(Restricted)"), + title: ts("Restricted"), + skip_pipeline: true) %> + <% end %> + <% if series.hidden_by_admin %> + <%= image_tag("lockred.png", size: "15x15", alt: ts("(Hidden by Admin)"), + title: ts("Hidden by Administrator"), + skip_pipeline: true) %> + <% end %> +

    +
    + <%= ts('Fandom') %>: + <%= series.work_tags.select{ |tag| tag.type == "Fandom" }. + sort.collect{ |tag| link_to_tag_works(tag) }. + join(', ').html_safe %> +
    + <%= get_symbols_for(series) %> +

    <%= set_format_for_date(series.revised_at) %>

    +
    + + +
      + <%= blurb_tag_block(series) %> +
    + + +<% unless series.summary.blank? %> +
    <%= ts("Summary") %>
    +
    + <%=raw strip_images(sanitize_field(series, :summary)) %> +
    +<% end %> + +
    +
    <%= Work.human_attribute_name("word_count") %>:
    +
    <%= number_with_delimiter(series.visible_word_count) %>
    +
    <%= Work.model_name.human(count: :many) %>:
    +
    <%= number_with_delimiter(series.visible_work_count) %>
    + <% if (bookmark_count = series.bookmarks.is_public.count) > 0 %> +
    <%= Bookmark.model_name.human(count: :many) %>:
    +
    <%= link_to_bookmarkable_bookmarks(series, number_with_delimiter(bookmark_count)) %>
    + <% end %> +
    diff --git a/app/views/series/_series_navigation.html.erb b/app/views/series/_series_navigation.html.erb new file mode 100755 index 0000000..6b08d40 --- /dev/null +++ b/app/views/series/_series_navigation.html.erb @@ -0,0 +1,22 @@ + diff --git a/app/views/series/_series_order.html.erb b/app/views/series/_series_order.html.erb new file mode 100755 index 0000000..ab42bc5 --- /dev/null +++ b/app/views/series/_series_order.html.erb @@ -0,0 +1,35 @@ +
    + <%= form_tag update_positions_series_path, method: :post do %> +
      + <% @serial_works.each_with_index do |serial, i| %> +
    • + <%= text_field_tag 'serial_works[]', nil, :size => 3, :maxlength => 3, :class => 'number serial-position-field', :id => "serial_#{i}" %> + <%= serial.position %>. +

      + <%= serial.work.posted? ? serial.work.title : t(".draft_work_title", title: serial.work.title) %> +

      +
    • + <% end %> +
    +

    <%= submit_tag "Update Positions" %>

    + <% end %> +
    + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j("#sortable_series_list").sortable({ + delay: 300, + update: function(event, ui) { + $j(".serial-position-list").each(function(index, li){ + var serialId = $j(li).attr("id").replace("serial_",""); + $j("#position-for-"+serialId).html(index+1); + }); + $j.ajax({ + type: 'post', + data: $j("#sortable_series_list").sortable("serialize"), + dataType: 'json', + url: "<%= update_positions_series_path %>"}) + } + }) + <% end %> +<% end %> diff --git a/app/views/series/confirm_delete.html.erb b/app/views/series/confirm_delete.html.erb new file mode 100755 index 0000000..cb3edaa --- /dev/null +++ b/app/views/series/confirm_delete.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts("Delete Series") %>

    + + +<%= form_for(@series, :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    <%= ts('Are you sure you want to delete the series "%{series_title}"? This will not delete the individual works.', :series_title => @series.title).html_safe %>

    +

    + <%= f.submit ts("Yes, Delete Series") %> +

    +<% end %> + diff --git a/app/views/series/edit.html.erb b/app/views/series/edit.html.erb new file mode 100755 index 0000000..8abba95 --- /dev/null +++ b/app/views/series/edit.html.erb @@ -0,0 +1,82 @@ + +

    <%= ts("Edit Series") %>

    + + + +<%= render "series/series_navigation" %> + + + + +
    +<%= form_for(@series) do |f| %> + <%= error_messages_for @series %> +

    <%= ts("* Required information") %>

    +
    + <%= ts('Meta') %> +
    +
    + <%= f.label :title, ts("Series Title*"), :class => "required" %> +
    +
    + <%= f.text_field :title, :class => "observe_textlength text" %> + <%= live_validation_for_field('series_title', + :maximum_length => ArchiveConfig.TITLE_MAX, :minimum_length => ArchiveConfig.TITLE_MIN, + :failureMessage => ts("We need a title! (At least %{min_length} characters long, please.)", :min_length => ArchiveConfig.TITLE_MIN.to_s)) + %> + <%= generate_countdown_html("series_title", ArchiveConfig.TITLE_MAX) %> +
    + + + <%= render 'pseuds/byline', form: f, object: @series %> + +
    + <%= f.label :summary, ts("Series Description", :max => ArchiveConfig.SUMMARY_MAX.to_s) %> +
    +
    + <%= allowed_html_instructions %> + <%= f.text_area :summary, :class => "observe_textlength" %> + <%= live_validation_for_field('series_summary', :presence => false, :maximum_length => ArchiveConfig.SUMMARY_MAX) %> + <%= generate_countdown_html("series_summary", ArchiveConfig.SUMMARY_MAX) %> +
    + +
    + <%= f.label :series_notes, ts("Series Notes") %> +
    +
    + <%= allowed_html_instructions %> + <%= f.text_area :series_notes, :class => "observe_textlength" %> + <%= live_validation_for_field('series_notes', :presence => false, :maximum_length => ArchiveConfig.NOTES_MAX) %> + <%= generate_countdown_html("series_notes", ArchiveConfig.NOTES_MAX) %> +
    +
    + <%= f.check_box :complete %> +
    +
    + <%= f.label :complete, ts("This series is complete") %> +
    +
    +
    + +
    + <%= ts('Post') %> +

    + <%= f.submit ts("Update") %> + <%= link_to ts("Cancel"), series_path %> +

    +
    +<% end %> +
    + + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(document).ready(function(){ + $j(".toggle_formfield").click(function() { + var targetId = $j(this).attr("id").replace("-show", ""); + toggleFormField(targetId); + }); + }) + <% end %> +<% end %> + diff --git a/app/views/series/index.html.erb b/app/views/series/index.html.erb new file mode 100755 index 0000000..9c1391b --- /dev/null +++ b/app/views/series/index.html.erb @@ -0,0 +1,28 @@ + +<%= render "muted/muted_items_notice" %> + +

    + <% if @user %> + <%= search_header @series, nil, "Series", @pseud ? @pseud : @user %> + <% else %> + <%=h "View All Series" %> + <% end %> +

    + + + +<%= will_paginate @series %> + + + +

    Listing Series

    +
      + <% for series in @series %> + <%= render :partial => 'series/series_blurb', :locals => {:series => series} %> + <% end %> +
    + + + +<%= will_paginate @series %> + diff --git a/app/views/series/manage.html.erb b/app/views/series/manage.html.erb new file mode 100755 index 0000000..3357be9 --- /dev/null +++ b/app/views/series/manage.html.erb @@ -0,0 +1,10 @@ + +

    <%=h t('.manage_series', :default => "Manage Series:") %> <%=h @series.title %>

    + + + + + + +<%= render :partial => 'series_order' %> + \ No newline at end of file diff --git a/app/views/series/new.html.erb b/app/views/series/new.html.erb new file mode 100755 index 0000000..1419b26 --- /dev/null +++ b/app/views/series/new.html.erb @@ -0,0 +1,22 @@ + +

    <%=h 'New series' %>

    + + + + + + +<%= form_for(@series) do |f| %> + <%= error_messages_for @series %> + +

    + <%= f.submit "Create" %> +

    +<% end %> + + + + + \ No newline at end of file diff --git a/app/views/series/show.html.erb b/app/views/series/show.html.erb new file mode 100755 index 0000000..029c373 --- /dev/null +++ b/app/views/series/show.html.erb @@ -0,0 +1,102 @@ + +<% if @series.user_has_creator_invite?(current_user) %> +

    + <%= ts("You've been invited to become a co-creator of this series. To accept or reject the request, visit your %{creator_requests_page}.", + creator_requests_page: link_to(ts("Co-Creator Requests page"), user_creatorships_path(current_user))).html_safe %> +

    +<% end %> +

    + <%= @series.title %> + <% if @series.restricted %> + <%= image_tag("lockblue.png", size: "15x15", alt: "(Restricted)", title: "Restricted", skip_pipeline: true) %> + <% end %> + <% if @series.hidden_by_admin %> + <%= image_tag("lockred.png", size: "15x15", alt: ts("(Hidden by Admin)"), + title: ts("Hidden by Administrator"), + skip_pipeline: true) %> + <% end %> +

    + + +<% if policy(@series).show_admin_options? %> +
    <%= render "admin/admin_options", item: @series %>
    +<% end %> + + +<% if logged_in? %> + <%= render "series/series_navigation" %> +<% end %> + + + +

    <%= ts("Series Metadata") %>

    +
    +
    + + <% if @series.pseuds.many?%> +
    <%= ts("Creators:") %>
    +
    <%= byline(@series) %>
    + <% else %> +
    <%= ts("Creator:") %>
    +
    <%= byline(@series) %>
    + <% end %> + +
    <%= ts("Series Begun:") %>
    +
    <%= @series.published_at.to_date %>
    +
    <%= ts("Series Updated:") %>
    +
    <%= @series.revised_at ? @series.revised_at.to_date : @series.published_at %>
    + + <% unless @series.summary.blank? %> +
    <%= ts("Description:") %>
    +
    <%=raw sanitize_field(@series, :summary) %>
    + <% end %> + <% unless @series.series_notes.blank? %> +
    <%= ts("Notes:") %>
    +
    <%=raw sanitize_field(@series, :series_notes) %>
    + <% end %> + +
    <%= ts("Stats:") %>
    +
    +
    +
    <%= Work.human_attribute_name("word_count") %>:
    +
    <%= number_with_delimiter(@series.visible_word_count) %>
    +
    <%= Work.model_name.human(count: :many) %>:
    +
    <%= number_with_delimiter(@series.visible_work_count) %>
    +
    <%= ts("Complete:") %>
    +
    <%= @series.complete? ? ts("Yes") : ts("No") %>
    + <% if (bookmark_count = @series.bookmarks.is_public.count) > 0 %> +
    <%= Bookmark.model_name.human(count: :many) %>:
    +
    <%= link_to_bookmarkable_bookmarks(@series, number_with_delimiter(bookmark_count)) %>
    + <% end %> +
    +
    + +
    +
    +<% if logged_in? %> +
    + <% if @bookmark %> + <%= render "bookmarks/bookmark_form", bookmarkable: @series, bookmark: @bookmark, button_name: ts("Update"), action: :update, in_page: true %> + <% else %> + <%= render "bookmarks/bookmark_form", bookmarkable: @series, bookmark: Bookmark.new, button_name: ts("Create"), action: :create, in_page: true %> + <% end %> +
    +<% end %> + +

    <%= ts("Listing Series") %>

    +<% unless @works.blank? %> + + <%= will_paginate @works %> +<% end %> +
      + <%= render partial: "works/work_blurb", collection: @works, as: :work %> +
    + +<% unless @works.blank? %> + + <%= will_paginate @works %> +<% end %> + + + + diff --git a/app/views/share/_embed_link_bookmark.html.erb b/app/views/share/_embed_link_bookmark.html.erb new file mode 100755 index 0000000..5676c8d --- /dev/null +++ b/app/views/share/_embed_link_bookmark.html.erb @@ -0,0 +1,4 @@ +<% if item.bookmarkable.is_a?(Work) %> +<%= render "share/embed_link_work", item: item.bookmarkable %> +<%= render "share/embed_meta_bookmark", bookmark: item %> +<% end %> diff --git a/app/views/share/_embed_link_header.html.erb b/app/views/share/_embed_link_header.html.erb new file mode 100755 index 0000000..a74fa67 --- /dev/null +++ b/app/views/share/_embed_link_header.html.erb @@ -0,0 +1,10 @@ +<% creators = if work.anonymous? + ts("Anonymous") + else + work.pseuds.map { |pseud| link_to(tag.strong(pseud.name), user_url(pseud.user)) }.join(", ") + end %> + +<%= ts("%{work_link} (%{word_count} words) by %{creators}", + work_link: link_to(tag.strong(work.title), work_url(work)), + word_count: work.word_count, + creators: creators).html_safe %> diff --git a/app/views/share/_embed_link_work.html.erb b/app/views/share/_embed_link_work.html.erb new file mode 100755 index 0000000..e834291 --- /dev/null +++ b/app/views/share/_embed_link_work.html.erb @@ -0,0 +1,2 @@ +<%= render "share/embed_link_header", work: item %>
    +<%= render "share/embed_meta", work: item %> diff --git a/app/views/share/_embed_meta.html.erb b/app/views/share/_embed_meta.html.erb new file mode 100755 index 0000000..02f9333 --- /dev/null +++ b/app/views/share/_embed_meta.html.erb @@ -0,0 +1,19 @@ +<%= ts("Chapters: ") %> +<%= chapter_total_display(work) %>
    +<%= ts("Fandom: ") %> +<%= work.tag_groups["Fandom"].map { |fandom| link_to fandom.name, tag_url(fandom) }.join(", ").html_safe %>
    +<% [Rating, ArchiveWarning, Relationship, Character, Freeform].each do |klass| %> +<% if (tags = work.tag_groups[klass.to_s]).present? %> +<%= ts("#{klass.label_name}: ") %> +<%= tags.map(&:display_name).join(", ").html_safe %> +
    +<% end %> +<% end %> +<% if work.series.exists? %> +<%= ts("Series: ") %> +<%= series_list_for_feeds(work).html_safe %>
    +<% end %> +<% if work.summary.present? %> +<%= ts("Summary: ") %> +<%= sanitize_field(work, :summary).html_safe %> +<% end %> diff --git a/app/views/share/_embed_meta_bookmark.erb b/app/views/share/_embed_meta_bookmark.erb new file mode 100755 index 0000000..ee24474 --- /dev/null +++ b/app/views/share/_embed_meta_bookmark.erb @@ -0,0 +1,10 @@ +<% if bookmark.bookmarkable.is_a?(Work) %> +<% if bookmark.tags.exists? %> +<%= ts("Bookmarker's Tags: ").html_safe %> +<%= bookmark.tags.pluck(:name).join(", ") %>
    +<% end %> +<% if bookmark.bookmarker_notes.present? %> +<%= ts("Bookmarker's Notes: ").html_safe %> +<%= raw sanitize_field(bookmark, :bookmarker_notes, image_safety_mode: true) %> +<% end %> +<% end %> diff --git a/app/views/share/_share.html.erb b/app/views/share/_share.html.erb new file mode 100755 index 0000000..2461817 --- /dev/null +++ b/app/views/share/_share.html.erb @@ -0,0 +1,29 @@ +
    + +

    <%= ts("Copy and paste the following code to link back to this work (") %><%= ts("CTRL A") %><%= ts("/") %><%= ts("CMD A") %><%= ts(" will select all), or use the Tweet or Tumblr links to share the work on your Twitter or Tumblr account.") %>

    + + <%# HTML share code %> +

    + <% id_suffix = shareable.is_a?(Bookmark) ? "_#{shareable.id}" : "" %> + <% embed_partial = shareable.is_a?(Bookmark) ? "share/embed_link_bookmark" : "share/embed_link_work" %> + +

    + +
      + + +
    • + <% work = shareable.is_a?(Bookmark) ? shareable.bookmarkable : shareable %> + <% tumblr_url = work_url(work) %> + <% tumblr_title = get_tumblr_embed_link_title(work) %> + <% tumblr_caption = shareable.is_a?(Bookmark) ? render("share/embed_link_bookmark", item: shareable) : render("share/embed_meta", work: shareable) %> + <% tumblr_address = "http://tumblr.com/widgets/share/tool?canonicalUrl=#{u(tumblr_url)}&title=#{u(tumblr_title)}&caption=#{u(tumblr_caption)}" %> + <%= sharing_button("tumblr", tumblr_address, ts("Tumblr"), target: "_blank") %> +
    • +
    +
    diff --git a/app/views/shared/_search_nav.html.erb b/app/views/shared/_search_nav.html.erb new file mode 100755 index 0000000..bccc12b --- /dev/null +++ b/app/views/shared/_search_nav.html.erb @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/app/views/skins/_form.html.erb b/app/views/skins/_form.html.erb new file mode 100755 index 0000000..ec7ae9f --- /dev/null +++ b/app/views/skins/_form.html.erb @@ -0,0 +1,99 @@ +

    * <%= ts('Required information') %>

    +
    + <%= ts('About') %> +

    <%= ts('About') %>

    +
    +
    <%= label_tag 'skin_type', ts('Type') + "*" %> <%= link_to_help 'skins-basics' %>
    +
    + <% if @skin.id %> + <% # don't let user change the type of an already-created skin %> + <%= (@skin.type && @skin.type == 'WorkSkin') ? ts('Work Skin') : ts('Site Skin') %> + <% else %> + <%= select_tag 'skin_type', options_for_select(Skin::TYPE_OPTIONS, @skin.type || params[:skin_type] ), + :onchange => 'if ($j(this).val() == "WorkSkin") {$j("#advanced_skin_fieldset").hide();} else {$j("#advanced_skin_fieldset").show();}' %> + <% end %> +
    + +
    <%= f.label :title, ts('Title') + "*" %>
    +
    <%= f.text_field :title %>
    + +
    <%= f.label :description, ts('Description') %>
    +
    <%= f.text_field :description %>
    + +
    <%= f.label :icon, ts('Upload a preview (png, jpeg or gif)') %>
    +
    <%= f.file_field :icon %>
    + +
    <%= f.label :public, ts('Apply to make public') %> <%= link_to_help 'skins-approval' %>
    +
    <%= f.check_box :public %>
    +
    +
    + +
    + <%= ts('CSS') %> +

    <%= f.label :css, ts('CSS') %> <%= link_to_help 'skins-creating' %>

    +

    + <%= f.text_area :css, :cols => 70, :class => 'large observe_textlength' %> + <%= live_validation_for_field("skin_css", maximum_length: ArchiveConfig.CONTENT_MAX_DISPLAYED) %> + <%= generate_countdown_html("skin_css", ArchiveConfig.CONTENT_MAX_DISPLAYED) %> +

    +
    + +
    + <%= ts('Advanced') %> + + + + + +
    +
    + <%= ts('Conditions') %> <%= link_to_help 'skins-conditions' %> +

    <%= ts('Conditions') %>

    +
    +
    <%= f.label :role, ts('What it does: ')%>
    +
    + <%= f.select :role, options_for_select(Skin::ROLE_NAMES.invert, @skin.role || Skin::DEFAULT_ROLE), {}, + :onchange => 'if ($j(this).val() == "override") {$j(".archive_parents").show();} else {$j(".archive_parents").hide();}' %> +
    + +
    <%= f.label :ie_condition, ts('IE Only: ')%>
    +
    <%= f.select :ie_condition, options_for_select(Skin::IE_CONDITIONS, @skin.ie_condition), :include_blank => true %>
    + +
    <%= f.label :unusable, ts('Parent Only: ')%>
    +
    <%= f.check_box :unusable %>
    + +
    <%= f.label :media, ts('Media: ')%>
    +
    +
    <%= ts('Choose @media') %>
    + <%= checkbox_section(f, :media, Skin::MEDIA, :checked_method => @skin.media || Skin::DEFAULT_MEDIA, :value_method => "to_s", :name_method => "to_s", :include_blank => false) %> +
    +
    +
    + +
    + <%= ts('Parent Skins') %> <%= link_to_help 'skins-parents' %> +

    <%= ts('Parent Skins') %>

    +
      + <% f.object.skin_parents.each_with_index do |parent, index| %> + <%= f.fields_for :skin_parents, parent do |parent_form| %> + <%= render 'skin_parent_fields', :form => parent_form, :index => index %> + <% end %> + <% end %> + + <% if f.object.skin_parents.count == 0 %><% end %> +
    • <%= link_to_add_section(ts('Add parent skin'), f, :skin_parents, "skin_parent_fields") %>
    • + +
    • +

      + +

      +
    • +
    +
    +
    +
    + +<%= submit_fieldset(f) %> diff --git a/app/views/skins/_header.html.erb b/app/views/skins/_header.html.erb new file mode 100755 index 0000000..5e90a2e --- /dev/null +++ b/app/views/skins/_header.html.erb @@ -0,0 +1,42 @@ +
    +

    + <%= ts("%{title} skin by %{creator}", title: @skin.title, creator: skin_author_link(@skin)).html_safe %> +

    + +

    <%= skin_preview_display(@skin) %>

    + + + +
    + <%= @skin.description.blank? ? ts('(No Description Provided)') : raw(sanitize_field(@skin, :description)) %> +
    + +
    +
    <%= ts('Role:') %>
    +
    <%= @skin.role %>
    +
    <%= ts('Media:') %>
    +
    <%= @skin.get_media %>
    +
    <%= ts('Condition:') %>
    +
    + <% unless @skin.ie_condition.present? || @skin.unusable? %>Normal<% end %> + <% if @skin.ie_condition.present? %> + <%= @skin.ie_condition %> + <% end %> + <% if @skin.unusable? %>Parent only<% end %> +
    +
    +
    diff --git a/app/views/skins/_revert_skin_form.html.erb b/app/views/skins/_revert_skin_form.html.erb new file mode 100755 index 0000000..bbfa024 --- /dev/null +++ b/app/views/skins/_revert_skin_form.html.erb @@ -0,0 +1,10 @@ +<% # Revert from session skin (for admins, users, maybe one day guests again) %> +<% if session[:site_skin] %> + <%= button_to t(".revert_to_default"), unset_skins_path, method: :post %> +<% # Revert skin a logged in user set in their preferences %> +<% elsif logged_in? && current_user.preference.skin_id != AdminSetting.default_skin_id %> + <%= form_for(current_user.preference, url: user_preference_path(current_user, current_user.preference), method: :patch) do |f| %> + <%= f.hidden_field :skin_id, value: AdminSetting.default_skin_id %> + <%= f.submit t(".revert_to_default") %> + <% end %> +<% end %> diff --git a/app/views/skins/_skin_actions.html.erb b/app/views/skins/_skin_actions.html.erb new file mode 100755 index 0000000..52bcf0a --- /dev/null +++ b/app/views/skins/_skin_actions.html.erb @@ -0,0 +1,25 @@ +<% # expects skin %> +<% # shared between skin blurbs and the bottom of skin pages %> +<% if (logged_in? && !skin.is_a?(WorkSkin)) || skin.editable? %> +
      + <% if logged_in? && !skin.is_a?(WorkSkin) && !skin.unusable? %> +
    • <%= render "update_skin_form", skin: skin %>
    • +
    • <%= span_if_current ts("Preview"), preview_skin_path(skin) %>
    • + <% end %> + + <% if (logged_in? || logged_in_as_admin?) && skin.cached? %> +
    • <%= button_to ts("Set For Session"), set_skin_path(skin), method: :post %>
    • + <% end %> + + <% if skin.editable? && (policy(skin).update? || !logged_in_as_admin?) %> +
    • <%= span_if_current ts('Edit'), edit_skin_path(skin) %>
    • + <% unless logged_in_as_admin? %> +
    • + <%= link_to ts("Delete"), + confirm_delete_skin_path(skin), + data: { confirm: ts("Are you sure you want to delete this skin?") } %> +
    • + <% end %> + <% end %> +
    +<% end %> diff --git a/app/views/skins/_skin_module.html.erb b/app/views/skins/_skin_module.html.erb new file mode 100755 index 0000000..f0a61b5 --- /dev/null +++ b/app/views/skins/_skin_module.html.erb @@ -0,0 +1,28 @@ +<% # expects skin %> +
    +

    + <%= link_to skin.title, skin %> + <%= ts("by %{byline}", byline: skin.byline) %> +

    + <% if @user %> + <% if skin.official? %> +

    (<%= ts('Approved') %>)

    + <% elsif skin.rejected? %> +

    (<%= ts('Declined:')%> <%= link_to_help 'skins-approval' %> <%= skin.admin_note %>)

    + <% elsif skin.public? %> +

    (<%= ts('Not yet reviewed') %>) <%= link_to_help 'skins-approval' %>

    + <% end %> + <% end %> + +
    <%= skin_preview_display(skin) %>
    +

    <%= set_format_for_date(skin.created_at) %>

    +
    + + +
    <%= ts('Description') %>
    +
    + <%=raw skin.description.blank? ? ts('(No Description Provided)') : strip_images(sanitize_field(skin, :description)) %> +
    + +<%= render "skin_actions", skin: skin %> + diff --git a/app/views/skins/_skin_navigation.html.erb b/app/views/skins/_skin_navigation.html.erb new file mode 100755 index 0000000..fdeb052 --- /dev/null +++ b/app/views/skins/_skin_navigation.html.erb @@ -0,0 +1,36 @@ +<% work_skin = params[:skin_type] && params[:skin_type] == 'WorkSkin' %> + + +

    <%= ts('Navigation') %>

    + + diff --git a/app/views/skins/_skin_parent_fields.html.erb b/app/views/skins/_skin_parent_fields.html.erb new file mode 100755 index 0000000..ed36d1e --- /dev/null +++ b/app/views/skins/_skin_parent_fields.html.erb @@ -0,0 +1,11 @@ +<% index ||= 1 %> +
  • +
    +

    + <%= link_to_remove_section ts('x'), form %> + <%= ts('Parent #') %><%= form.text_field :position, :class => 'number', :value => (form.object.position || index), :title => ts('position of parent as integer') %> +

    + <%= form.text_field :parent_skin_title, autocomplete_options('site_skins', data: { autocomplete_token_limit: 1 }, title: ts('title of parent skin')) %> +
    +
  • + diff --git a/app/views/skins/_skin_style_block.html.erb b/app/views/skins/_skin_style_block.html.erb new file mode 100755 index 0000000..4230b82 --- /dev/null +++ b/app/views/skins/_skin_style_block.html.erb @@ -0,0 +1,4 @@ +<% # expects local "skin" and is cached one level up %> + diff --git a/app/views/skins/_skin_type_navigation.html.erb b/app/views/skins/_skin_type_navigation.html.erb new file mode 100755 index 0000000..b108abb --- /dev/null +++ b/app/views/skins/_skin_type_navigation.html.erb @@ -0,0 +1,14 @@ + +

    <%= ts('Skin Type Navigation') %>

    + + + diff --git a/app/views/skins/_update_skin_form.html.erb b/app/views/skins/_update_skin_form.html.erb new file mode 100755 index 0000000..a255329 --- /dev/null +++ b/app/views/skins/_update_skin_form.html.erb @@ -0,0 +1,10 @@ +<% # expects skin %> +<%= form_for(current_user.preference, url: user_preference_path(current_user, current_user.preference), method: "put") do |f| %> + <% if skin.id == current_user.preference.skin_id %> + <%= f.hidden_field :skin_id, value: AdminSetting.default_skin_id %> + <%= f.submit ts("Stop Using") %> + <% else %> + <%= f.hidden_field :skin_id, value: skin.id %> + <%= f.submit ts("Use") %> + <% end %> +<% end %> diff --git a/app/views/skins/_wizard_form.html.erb b/app/views/skins/_wizard_form.html.erb new file mode 100755 index 0000000..f2060b9 --- /dev/null +++ b/app/views/skins/_wizard_form.html.erb @@ -0,0 +1,132 @@ +

    * <%= ts('Required information') %>

    +
    + <%= ts('About') %> +
    +
    <%= f.label :title, ts('Title') + "*" %>
    +
    <%= f.text_field :title %>
    + +
    <%= f.label :description, ts('Description') %>
    +
    <%= f.text_field :description %>
    +
    +
    + +
    + <%= ts("Fonts and Whitespace") %> +
    +
    + <%= f.label :font, ts('Font') %> + <%= link_to_help('skins-wizard-font') %> +
    +
    + <%= f.text_field :font, "aria-describedby" => "font-field-notes" %> +

    + <%= ts("Comma-separated list of font names.") %> +

    +
    + +
    + <%= f.label :base_em, ts('Percent of browser font size') %> + <%= link_to_help('skins-wizard-font-size') %> +
    +
    + <%= f.text_field :base_em, "aria-describedby" => "base-em-field-notes" %> +

    + <%= ts("Numbers only, treated as a percentage of the browser's default font size. Default: 100").html_safe %> +

    +
    + +
    + <%= f.label :margin, ts('Work margin width') %> +
    +
    + <%= f.text_field :margin, "aria-describedby" => "margin-field-notes" %> +

    + <%= ts("Numbers only, treated as a percentage of the page width.") %> +

    +
    + +
    + <%= f.label :paragraph_margin, ts('Vertical gap between paragraphs') %> + <%= link_to_help('skins-wizard-vertical-gap') %> +
    +
    + <%= f.text_field :paragraph_margin %> +

    + <%= ts("Numbers only, treated as a multipler of the paragraph font size. Default: 1.286").html_safe %> +

    +
    +
    +
    + +
    + <%= ts("Colors") %> +

    + <%= ts('You may wish to refer to this handy list of colors.').html_safe %> +

    +
    +
    + <%= f.label :background_color, ts('Background color') %> +
    +
    + <%= f.text_field :background_color, "aria-describedby" => "background-color-field-notes" %> +

    + <%= ts("Name or hex code. Default: #fff".html_safe) %> +

    +
    + +
    + <%= f.label :foreground_color, ts('Text color') %> +
    +
    + <%= f.text_field :foreground_color, "aria-describedby" => "foreground-color-field-notes" %> +

    + <%= ts("Name or hex code. Default: #2a2a2a".html_safe) %> +

    +
    + +
    + <%= f.label :headercolor, ts('Header color') %> +
    +
    + <%= f.text_field :headercolor, "aria-describedby" => "header-color-field-notes" %> +

    + <%= ts("Name or hex code. Default: #900".html_safe) %> +

    +
    + +
    + <%= f.label :accent_color, ts('Accent color') %> + <%= link_to_help('skins-wizard-accent-color') %> +
    +
    + <%= f.text_field :accent_color, "aria-describedby" => "accent-color-field-notes" %> +

    + <%= ts("Name or hex code. Default: #ddd".html_safe) %> +

    +
    +
    + <%= hidden_field_tag 'wizard', true %> +
    +
    + + <%= ts("Parent Skins") %> + <%= link_to_help "skins-parents" %> + +

    + <%= ts("Parent Skins") %> +

    +
      + <% f.object.skin_parents.each_with_index do |parent, index| %> + <%= f.fields_for :skin_parents, parent do |parent_form| %> + <%= render "skin_parent_fields", form: parent_form, index: index %> + <% end %> + <% end %> + <% if f.object.skin_parents.count == 0 %> + + <% end %> +
    • + <%= link_to_add_section(ts("Add parent skin"), f, :skin_parents, "skin_parent_fields") %> +
    • +
    +
    +<%= submit_fieldset(f) %> diff --git a/app/views/skins/confirm_delete.html.erb b/app/views/skins/confirm_delete.html.erb new file mode 100755 index 0000000..b682638 --- /dev/null +++ b/app/views/skins/confirm_delete.html.erb @@ -0,0 +1,13 @@ + +

    <%= ts("Delete Skin") %>

    + + +<%= form_for(@skin, html: { method: :delete, class: "simple destroy" }) do |f| %> +

    + <%= t(".confirm_html", skin_title: @skin.title) %> +

    +

    + <%= f.submit ts("Yes, Delete Skin") %> +

    +<% end %> + diff --git a/app/views/skins/edit.html.erb b/app/views/skins/edit.html.erb new file mode 100755 index 0000000..9692ee1 --- /dev/null +++ b/app/views/skins/edit.html.erb @@ -0,0 +1,17 @@ +

    <%= ts('Edit Skin') %>

    + +<%= error_messages_for :skin %> + + +<%= render 'skin_navigation' %> + + +

    <%= ts('Edit Skin Form') %>

    +<%= form_for(@skin, html: { multipart: true, class: "skin verbose post" }) do |f| %> + + <% if params[:wizard] %> + <%= render 'wizard_form', f: f %> + <% else %> + <%= render 'form', f: f %> + <% end %> +<% end %> diff --git a/app/views/skins/index.html.erb b/app/views/skins/index.html.erb new file mode 100755 index 0000000..2991aab --- /dev/null +++ b/app/views/skins/index.html.erb @@ -0,0 +1,33 @@ +<% work_skin = params[:skin_type] && params[:skin_type] == 'WorkSkin' %> + + +

    <%= @title %>

    +<%= render 'skin_navigation' %> + +

    + <%= ts('A site skin lets you change the way the Archive is presented when you are logged in to your account. You can use work skins to customize the way your own works are shown to others.') %> + <%= link_to_help 'skins-basics' %> +

    + + + +<%= render 'skin_type_navigation' %> + + + +

    <%= ts('List of Skins') %>

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

    + <%= work_skin ? ts('No work skins here yet!') : ts('No site skins here yet!') %> + <% if logged_in? %><%= link_to ts('Why not try making one?'), new_skin_path(skin_type: work_skin ? 'WorkSkin' : 'Skin') %><% end %> +

    +<% else %> +
      + <% for skin in @skins %> +
    • + <%= render 'skin_module', skin: skin %> +
    • + <% end %> +
    +<% end %> + diff --git a/app/views/skins/new.html.erb b/app/views/skins/new.html.erb new file mode 100755 index 0000000..ffc0382 --- /dev/null +++ b/app/views/skins/new.html.erb @@ -0,0 +1,21 @@ + +

    <%= ts('Create New Skin') %>

    + +<%= error_messages_for :skin %> + + + +<%= render 'skin_navigation' %> + + + +

    + <%= ts('This form allows you to create a new site or work skin. Select "Work Skin" or "Site Skin" in the Type option list to choose which type of skin you are creating.') %> + <%= link_to_help 'skins-basics' %> +

    +

    <%= ts('Create New Skin') %>

    + +<%= form_for @skin, html: { multipart: true, class: "skin verbose post" } do |f| %> + <%= render 'form', f: f %> +<% end %> + diff --git a/app/views/skins/new_wizard.html.erb b/app/views/skins/new_wizard.html.erb new file mode 100755 index 0000000..da04f11 --- /dev/null +++ b/app/views/skins/new_wizard.html.erb @@ -0,0 +1,22 @@ + +

    <%= ts('Site Skin Wizard') %>

    + +<%= error_messages_for :skin %> + + + +<%= render "skin_navigation" %> + + + +

    + <%= ts('This wizard only creates site skins. You can also %{link} which can be used to add styling to works that you post.', link: link_to(ts('create a work skin'), url_for(skin_type: 'WorkSkin'))).html_safe %> + <%= link_to_help 'skins-basics' %> +

    + +

    <%= ts('Site Skin Wizard') %>

    + +<%= form_for @skin, html: { class: "wizard skin verbose post" } do |f| %> + <%= render 'wizard_form', f: f %> +<% end %> + diff --git a/app/views/skins/show.html.erb b/app/views/skins/show.html.erb new file mode 100755 index 0000000..8480ef5 --- /dev/null +++ b/app/views/skins/show.html.erb @@ -0,0 +1,94 @@ + +
    + + <%= render 'header' %> + + + <% if @skin.wizard_settings? %> +
    +

    <%= ts('Wizard Settings') %>

    +

    <%= ts("Can be overridden by custom CSS.").html_safe %>

    + +
    +
    + <% unless @skin.font.blank? %> +
    <%= ts('Font:') %>
    +
    + <%= @skin.font %> +
    + <% end %> + + <% if @skin.base_em %> +
    <%= ts('Percent of browser font size:') %>
    +
    + <%= @skin.base_em %>% +
    + <% end %> + + <% if @skin.margin %> +
    <%= ts('Work margin width:') %>
    +
    + <%= @skin.margin %>% +
    + <% end %> + + <% if @skin.paragraph_margin %> +
    <%= ts('Vertical gap between paragraphs:') %>
    +
    + <%= @skin.paragraph_margin %>em +
    + <% end %> + + <% unless @skin.background_color.blank? %> +
    <%= ts('Background color:') %>
    +
    + <%= @skin.background_color %> +
    + <% end %> + + <% unless @skin.foreground_color.blank? %> +
    <%= ts('Text color:') %>
    +
    + <%= @skin.foreground_color %> +
    + <% end %> + + <% unless @skin.headercolor.blank? %> +
    <%= ts('Header color:') %>
    +
    + <%= @skin.headercolor %> +
    + <% end %> + + <% unless @skin.accent_color.blank? %> +
    <%= ts('Accent color:') %>
    +
    + <%= @skin.accent_color %> +
    + <% end %> +
    +
    +
    + <% end %> + + <% unless @skin.css.blank? && @skin.filename.blank? %> +
    +

    CSS

    +
    <%= @skin.get_css %>
    +
    + <% end %> + + <% unless @skin.parent_skins.empty? %> +
    +

    <%= ts('Parent Skins') %>

    +
      + <% @skin.parent_skins.each do |parent| %> +
    • <%= link_to parent.title, skin_path(parent) %>
    • + <% end %> +
    +
    + <% end %> + + <%= render "skin_actions", skin: @skin %> + +
    diff --git a/app/views/stats/_navigation.html.erb b/app/views/stats/_navigation.html.erb new file mode 100755 index 0000000..05195eb --- /dev/null +++ b/app/views/stats/_navigation.html.erb @@ -0,0 +1,4 @@ + diff --git a/app/views/stats/index.html.erb b/app/views/stats/index.html.erb new file mode 100755 index 0000000..05b1e3c --- /dev/null +++ b/app/views/stats/index.html.erb @@ -0,0 +1,105 @@ + +

    <%= ts("Statistics") %>

    + + + +

    <%= ts('Navigation and Sorting') %>

    +<%= render "stats/navigation" %> + + + +
      + <% @years.each do |year| %> +
    1. + <% if @current_year == year %> + <%= year %> + <% else %> + <%= link_to year, current_path_with(year: year) %> + <% end %> +
    2. + <% end %> +
    + +

    <%= ts("Totals") %>

    +
    + +
    + + + +
    +<%= render_chart(@chart, 'stat_chart') %> + +
    +

    <%= ts('View Sorting and Actions') %>

    + + + +
    + +

    <%= ts('Listing Statistics') %>

    +
      + <% @works.keys.sort.each do |fandom| %> +
    • +
      + <%= fandom %> +
      +
        + <% @works[fandom].each do |work| %> +
      • +
        +
        + <%= link_to work.title, work_path(:id => work.id) %> + <% if params[:flat_view] %>(<%= work.fandom_string %>)<% end %> + (<%= ts("%{wordcount} words", wordcount: number_with_delimiter(work.word_count)) %>) +
        +
        +
        + <% if (work_subscriber_count = Subscription.where(:subscribable_id => work.id, :subscribable_type => 'Work').count) > 0 %> +
        <%= ts("Subscriptions:") %>
        +
        <%= number_with_delimiter(work_subscriber_count) %>
        + <% end %> +
        <%= ts("Hits:") %>
        +
        <%= number_with_delimiter(work.hits) %>
        + <% # dt ts("Downloads:") /dt dd work.downloads /dd %> +
        <%= ts("Kudos:") %>
        +
        <%= number_with_delimiter(work.kudos.count) %>
        +
        <%= ts("Comment Threads:") %>
        +
        <%= number_with_delimiter(work.comment_thread_count) %>
        +
        <%= ts("Bookmarks:") %>
        +
        <%= number_with_delimiter(work.bookmarks.count) %>
        +
        +
        +
        +
      • + <% end %> +
      +
    • + <% end %> +
    + diff --git a/app/views/stats/no_stats.html.erb b/app/views/stats/no_stats.html.erb new file mode 100755 index 0000000..02968b7 --- /dev/null +++ b/app/views/stats/no_stats.html.erb @@ -0,0 +1,3 @@ +

    <%= ts("Statistics") %>

    +

    <%= ts("You currently have no works posted to the Archive. If you add some, you'll find information on this page about hits, kudos, comments, and bookmarks of your works.") %>

    +

    <%= ts("Users can also see how many subscribers they have, but not the names of their subscribers or identifying information about other users who have viewed or downloaded their works.") %>

    \ No newline at end of file diff --git a/app/views/statuses/edit.html.erb b/app/views/statuses/edit.html.erb new file mode 100644 index 0000000..e6f7b88 --- /dev/null +++ b/app/views/statuses/edit.html.erb @@ -0,0 +1,42 @@ +

    Edit Status

    + +<% use_tinymce %> + +<%= form_with(model: [current_user, @status]) do |f| %> +
    + <%= f.label :icon %>
    + <%= f.file_field :icon %> +
    + +
    + <%= f.label :text, "Status Text" %>
    + <%= f.text_area :text, class: "mce-editor observe_textlength", id: "status" %> + + <%= live_validation_for_field( + 'content', + maximum_length: ArchiveConfig.STATUS_MAX, + minimum_length: ArchiveConfig.CONTENT_MIN, + tooLongMessage: ts("Too long lmao"), + tooShortMessage: ts("Too short lmao"), + failureMessage: ts("You need to post some content here.") + ) + %> + + <%= generate_countdown_html("status", 3000) %> +
    + +
    + <%= f.label :mood %>
    + <%= f.text_field :mood %> +
    + +
    + <%= f.label :music %>
    + <%= f.text_field :music %> +
    + +
    + <%= f.submit "Save Status" %> +
    +<% end %> + diff --git a/app/views/statuses/index.html.erb b/app/views/statuses/index.html.erb new file mode 100644 index 0000000..48d1a98 --- /dev/null +++ b/app/views/statuses/index.html.erb @@ -0,0 +1,34 @@ +

    <%= @user&.login || @user&.id || "Statuses" %>

    +All Statuses +
    + +
    + <% if @statuses.present? %> + <% @statuses.each do |status| %> + <% if status.icon.attached? %> + <%= image_tag status.icon %> + <% end %> + + <%= time_ago_in_words(status.created_at) %> | + <% if current_user == status.user %> + <%= link_to 'Edit', edit_user_status_path(status.user, status) %> | + <%= link_to t("Delete"), user_status_path(status.user, status), + data: { confirm: t("Are you sure? All information in this status will be lost.") }, + method: :delete %> + <% end %> + +

    <%= raw sanitize_field(status, :text) %>

    + + <% if status.mood.present? %> +

    Mood: <%= status.mood %>

    + <% end %> + + <% if status.music.present? %> +

    Music: <%= status.music %>

    + <% end %> + +
    + <% end %> + <% end %> +
    + diff --git a/app/views/statuses/new.html.erb b/app/views/statuses/new.html.erb new file mode 100644 index 0000000..25f0c73 --- /dev/null +++ b/app/views/statuses/new.html.erb @@ -0,0 +1,42 @@ +

    New Status

    + +<% use_tinymce %> +<%= form_with(model: [current_user, @status]) do |f| %> + + <%= f.label :icon %>
    + <%= f.file_field :icon %> + + +
    + <%= f.label :text, "Status Text" %>
    + <%= f.text_area :text, class: "mce-editor observe_textlength", id: "status" %> + + <%= live_validation_for_field( + 'status', + maximum_length: ArchiveConfig.STATUS_MAX, + minimum_length: ArchiveConfig.CONTENT_MIN, + tooLongMessage: ts("Too long lmao"), + tooShortMessage: ts("Too short lmao"), + failureMessage: ts("You need to post some content here.") + ) + %> + + <%= generate_countdown_html("status", ArchiveConfig.STATUS_MAX) %> +
    + +
    + <%= f.label :mood %>
    + <%= f.text_field :mood %> +
    + +
    + <%= f.label :music %>
    + <%= f.text_field :music %> +
    + +
    + <%= f.submit "Save Status" %> +
    +<% end %> + + diff --git a/app/views/statuses/show.html.erb b/app/views/statuses/show.html.erb new file mode 100644 index 0000000..ccc4a9b --- /dev/null +++ b/app/views/statuses/show.html.erb @@ -0,0 +1,23 @@ +
    +

    Status

    + + <% if @status.icon.attached? %> + <%= image_tag @status.icon %> + <% end %> + + <%= time_ago_in_words(@status.created_at) %> | + <% if current_user == @status.user %> + <%= link_to 'Edit', edit_user_status_path(@status.user, @status) %> | + <%= link_to t("Delete"), user_status_path(@status.user, @status), + data: { confirm: t("Are you sure? All information in this status will be lost.") }, + method: :delete %> + <% end %> +

    <%= raw sanitize_field(@status, :text) %>

    + <% if @status.mood.present? %> +

    Mood: <%= @status.mood %>

    + <% end %> + + <% if @status.music.present? %> +

    Music: <%= @status.music %>

    +
    <% end %> +
    diff --git a/app/views/statuses/timeline.html.erb b/app/views/statuses/timeline.html.erb new file mode 100644 index 0000000..69091c8 --- /dev/null +++ b/app/views/statuses/timeline.html.erb @@ -0,0 +1,29 @@ +
    +

    Recent Statuses

    +<% @statuses.each do |status| %>

    + <%= link_to "##{status.user.login}", user_path(status.user) %> said... +
    + <% if status.icon.attached? %> + <%= image_tag status.icon.variant(resize_to_limit: [100, 100]), class: "iconimg" %> + <% end %> + + <%= time_ago_in_words(status.created_at) %> | + <% if current_user == status.user %> + <%= link_to 'Edit', edit_user_status_path(status.user, status) %> | + <%= link_to t("Delete"), user_status_path(status.user, status), + data: { confirm: t("Are you sure? All information in this status will be lost.") }, + method: :delete %> + <% end %> +

    <%= raw sanitize_field(status, :text) %>

    + <% if status.mood.present? %> +

    Mood: <%= status.mood %>

    + <% end %> + + <% if status.music.present? %> +

    Music: <%= status.music %>

    +
    <% end %> +
    + <% end %> + +
    + diff --git a/app/views/subscriptions/_form.html.erb b/app/views/subscriptions/_form.html.erb new file mode 100755 index 0000000..4b18ea3 --- /dev/null +++ b/app/views/subscriptions/_form.html.erb @@ -0,0 +1,14 @@ +<% # expects subscription and current_user %> +<%= form_for([current_user, subscription], + method: subscription.new_record? ? 'post' : 'delete', + html: { + class: 'ajax-create-destroy', + data: { + create_value: ts('Subscribe'), + destroy_value: ts('Unsubscribe') + } + }) do |f| %> + <%= f.hidden_field :subscribable_id %> + <%= f.hidden_field :subscribable_type %> + <%= f.submit subscription.new_record? ? ts('Subscribe') : ts('Unsubscribe') %> +<% end %> diff --git a/app/views/subscriptions/confirm_delete_all.erb b/app/views/subscriptions/confirm_delete_all.erb new file mode 100755 index 0000000..2e3e90b --- /dev/null +++ b/app/views/subscriptions/confirm_delete_all.erb @@ -0,0 +1,23 @@ + +

    + <% if @subscribable_type %> + <%= t(".page_heading.#{@subscribable_type}") %> + <% else %> + <%= t(".page_heading.all") %> + <% end %> +

    + + +<%= form_with(model: @user, url: delete_all_user_subscriptions_path(@user, type: @subscribable_type), method: :post, class: "simple destroy") do |f| %> +

    + <%= t(".caution_html") %> +

    +

    + <% if @subscribable_type %> + <%= f.submit t(".submit.#{@subscribable_type}") %> + <% else %> + <%= f.submit t(".submit.all") %> + <% end %> +

    +<% end %> + diff --git a/app/views/subscriptions/index.html.erb b/app/views/subscriptions/index.html.erb new file mode 100755 index 0000000..758dd11 --- /dev/null +++ b/app/views/subscriptions/index.html.erb @@ -0,0 +1,76 @@ + +

    + <% if @subscribable_type %> + <%= t(".page_heading.#{@subscribable_type}") %> + <% else %> + <%= t(".page_heading.all") %> + <% end %> +

    + + + +

    <%= t("a11y.navigation") %>

    + + + + +<%= will_paginate @subscriptions %> + +

    <%= t(".heading.landmark.list") %>

    +
    + <% @subscriptions.each do |subscription| %> +
    + <% if subscription.subscribable %> + <%= link_to(subscription.name, subscription.subscribable) %> + <% case subscription.subscribable_type %> + <% when "Work" %> + <%= t(".work") if @subscribable_type.blank? %> + <%= t(".byline_html", creators: byline(subscription.subscribable)) %> + <% when "Series" %> + <%= t(".series") if @subscribable_type.blank? %> + <%= t(".byline_html", creators: byline(subscription.subscribable)) %> + <% end %> + <% else %> + <%= subscription.name %> + <% end %> +
    +
    + <%= form_for [current_user, subscription], :html => {:method => :delete} do |f| %> + <%= f.submit t(".button_html", name: subscription.name) %> + <% end %> +
    + <% end %> +
    + +<%= will_paginate @subscriptions %> + diff --git a/app/views/tag_set_associations/index.html.erb b/app/views/tag_set_associations/index.html.erb new file mode 100755 index 0000000..cd87d96 --- /dev/null +++ b/app/views/tag_set_associations/index.html.erb @@ -0,0 +1,48 @@ +
    + +

    <%= ts("Review Associations for %{title}", :title => @tag_set.title) %>

    + + + +<%= render "owned_tag_sets/navigation" %> + + + +

    <%= ts("Notes") %>

    +
      +
    • Nominated associations will appear only for tags that have already been added to your set.
    • +
    • If tags have been nominated in fandoms that are not in the archive and not in your set, you must first add the fandom to your set to associate them.
    • +
    + +<%= form_tag update_multiple_tag_set_associations_path(@tag_set), :method => :put, :class => "tagset review" do %> + <%= error_messages_formatted @errors %> + + <% if @tags_to_associate.empty? %> +

    <%= ts("No nominated associations to review!") %>

    + <% else %> +
    + Approve Nominated Associations +

    <%= ts("Approve Nominated Associations") %>

    + <%= check_all_none %> +
      + <% @tags_to_associate.each do |tag| %> + <% # this is necessary or else rails thinks the [] characters represent a sub-model! %> + <% tagname = tag.name.gsub('[', '#LBRACKET').gsub(']', '#RBRACKET') %> + <% parent_tagname = tag.parent_tagname.gsub('[', '#LBRACKET').gsub(']', '#RBRACKET') %> +
    • + <% fieldname = "create_association_#{tag.id}_#{parent_tagname}" %> + +
    • + <% end %> +
    +
    + <% end %> + + <%= submit_fieldset %> + +<% end %> + +
    \ No newline at end of file diff --git a/app/views/tag_set_nominations/_nomination_form.html.erb b/app/views/tag_set_nominations/_nomination_form.html.erb new file mode 100755 index 0000000..c37d165 --- /dev/null +++ b/app/views/tag_set_nominations/_nomination_form.html.erb @@ -0,0 +1,70 @@ + +

    <%= ts("Tag Nominations for %{title}", :title => @tag_set_nomination.owned_tag_set.title) %>

    + + + + + + + +
      +
    • <%= ts('The autocomplete lists canonical tags for you. Please choose the canonical version of your tag if there is one.') %>
    • +
    • <%= ts('The tag set moderators might change or leave out your nominations (sometimes just because a different form of your nomination was included).') %>
    • +
    • <%= ts('Nominations are not forever! Don\'t be confused if you come back in a few months and they are gone: they may have been cleaned up.') %>
    • +
    + +

    <%= ts("Nominate Tags Form") %>

    + +<%= error_messages_for :tag_set_nomination %> + +<%= form_for(@tag_set_nomination, :url => (@tag_set_nomination.new_record? ? tag_set_nominations_path(@tag_set) : tag_set_nomination_path(@tag_set, @tag_set_nomination)), :html => {:method => (@tag_set_nomination.new_record? ? :post : :put), :id => "tag_set_nomination_form", :class => "tagset"}) do |f| %> +
    + Basic Information +
    +
    <%= ts("Nominating For: ") %>
    +
    <%= link_to @tag_set_nomination.owned_tag_set.title, tag_set_path(@tag_set_nomination.owned_tag_set) %>
    + +
    <%= f.label :pseud_id, ts("Pseud: ") %>
    +
    <%= f.select :pseud_id, current_user.pseuds.collect {|p| [p.name, p.id] } %>
    +
    +
    +
    +

    <%= ts("Tag Nominations") %>

    +

    <%= nomination_notes(@limit) %>

    + <% if @limit[:relationship] > 0 && @limit[:fandom] > 1 %> +

    <%= ts("If crossover relationships are allowed, you can enter them under either fandom.") %>

    + <% end %> + + <% if @limit[:fandom] > 0 %> + + <% # char and relationship nominations grouped with fandom %> + <%= render 'tag_nominations_by_fandom', :f => f %> + + <% # freeforms on their own %> + <% if @limit[:freeform] > 0 %> + <%= render 'tag_nominations', :f => f, :tag_type => "freeform" %> + <% end %> + + <% else %> + + <% # nominations all on same level in fieldset/dls %> + <% %w(character relationship freeform).each do |tag_type| %> + <% if @limit[tag_type] > 0 %> + <%= render 'tag_nominations', :f => f, :tag_type => tag_type %> + <% end %> + <% end %> + + <% end %> +
    + +
    + <%= ts('Submit') %> +

    + <%= f.submit ts('Submit') %> +

    +
    +<% end %> + diff --git a/app/views/tag_set_nominations/_review.html.erb b/app/views/tag_set_nominations/_review.html.erb new file mode 100755 index 0000000..caa4729 --- /dev/null +++ b/app/views/tag_set_nominations/_review.html.erb @@ -0,0 +1,78 @@ +
    + + +

    <%= ts("Review Nominations for %{title}", :title => @tag_set.title) %>

    + + + + <%= render "owned_tag_sets/navigation" %> + + + +
      +
    • You can approve (+) or reject (x) nominations, or leave them for later. Once a nomination + has been either approved or rejected, it won't appear on this page again.
    • + +
    • If you reject a fandom nomination, we will automatically reject all character and relationship nominations submitted + for that fandom. We will not automatically approve character nominations.
    • + +
    • If you approve non-canonical fandoms and characters, you will have to set up associations for them.
    • + +
    • Old (several months) nominations are sometimes cleared from the database. Please review + nominations regularly or turn them off.
    • +
    + + <%= form_for :tag_set_nominations, :url => update_multiple_tag_set_nominations_path(@tag_set), :html => { :method => :put, :class => "tagset review" } do |form| %> + + <%= error_messages_formatted @errors %> + + <% @tagnames_seen = {} %> + + <% %w(cast fandom character relationship freeform).each do |tag_type| %> + <% if @nominations[tag_type] && @nominations[tag_type].count > 0 %> +
    + <% heading = tag_type == "cast" ? ts("Already Approved Fandoms") : ts("#{tag_type_label_name(tag_type).pluralize} (%{count} left to review)", :count => @tag_set.send("#{tag_type}_nominations").unreviewed.count) %> + <%= heading %> +

    <%= heading %>

    + <%= check_all_none("Reject All", "Reject None", "reject") %> + <%= check_all_none("Approve All", "Approve None", "approve") %> +
      + <% if tag_type == "fandom" %> + <%= render "review_fandoms", :fandoms => @nominations[:fandom] %> + <% elsif tag_type == "cast" %> + <%= render "review_cast", :cast => @nominations[:cast] %> + <% else %> + <% @nominations[tag_type].each do |nom| %> +
    1. <%= render "review_individual_nom", :nom => nom %>
    2. + <% end %> + <% end %> +
    +
    + <% end %> + <% end %> + +
    +

    <%= submit_tag ts("Submit") %>

    +
    + + <% end %> + + +
    + +<%= content_for :footer_js do %> + <%= javascript_include_tag '/javascripts/jquery.qtip.min.js' %> + <%= javascript_tag do %> + $j(document).ready(function() { + setupTooltips(); + }); + function setupTooltips() { + $j('[data-tooltip]').each(function(){ + $j(this).qtip({ + content: $j(this).attr('data-tooltip'), + position: {corner: {target: 'topMiddle'}} + }); + }); + } + <% end %> +<% end %> diff --git a/app/views/tag_set_nominations/_review_cast.html.erb b/app/views/tag_set_nominations/_review_cast.html.erb new file mode 100755 index 0000000..a77e9ac --- /dev/null +++ b/app/views/tag_set_nominations/_review_cast.html.erb @@ -0,0 +1,25 @@ +<% # this lists extra characters/rels in already-approved fandoms. expects "cast" as a list of nominated chars/rels sorted in order of their parent tagname %> +<% current_fandom = "" %> +<% cast.each do |cast_nom| %> + <% unless @tagnames_seen[cast_nom.tagname] %> + <% if cast_nom.parent_tagname != current_fandom %> + <% unless current_fandom.blank? %> + <% # close the prior fandom listbox %> + + + <% end %> + <% # start a new fandom listbox %> + <% current_fandom = cast_nom.parent_tagname %> +
  • +

    <%= current_fandom %>

    +
      + <% end %> +
    1. + <%= render "review_individual_nom", :nom => cast_nom %> +
    2. + <% end %> +<% end %> + +<% # close the last listbox %> +
    +
  • diff --git a/app/views/tag_set_nominations/_review_fandoms.html.erb b/app/views/tag_set_nominations/_review_fandoms.html.erb new file mode 100755 index 0000000..47eb645 --- /dev/null +++ b/app/views/tag_set_nominations/_review_fandoms.html.erb @@ -0,0 +1,20 @@ +<% # expects fandoms %> +<% fandoms.each do |fandom| %> + <% unless @tagnames_seen[fandom.tagname] %> + <% cast = TagNomination.for_tag_set(@tag_set).where(:parent_tagname => fandom.tagname).unreviewed.order(:type, :tagname) %> +
  • +

    + <%= fandom.tagname %>

    + <%= render "review_individual_nom", :nom => fandom %> + <% if cast.count > 0 %> +
      + <% cast.each do |cast_nom| %> +
    1. + <%= render "review_individual_nom", :nom => cast_nom %> +
    2. + <% end %> +
    + <% end %> +
  • + <% end %> +<% end %> diff --git a/app/views/tag_set_nominations/_review_individual_nom.html.erb b/app/views/tag_set_nominations/_review_individual_nom.html.erb new file mode 100755 index 0000000..0f5e74b --- /dev/null +++ b/app/views/tag_set_nominations/_review_individual_nom.html.erb @@ -0,0 +1,41 @@ +<% # expects nom %> +<% unless @tagnames_seen[nom.tagname] %> + <% @tagnames_seen[nom.tagname] = 1 %> + +
    + <% tag_type = nom.class.name.gsub(/Nomination/, '').downcase %> +
    + <%= nomination_tag_information(nom) %> +
    + <% if (nom_count = nom.times_nominated(@tag_set)) > 1 %> +
    (x<%= nom_count %>)
    + <% end %> + + <% # this is necessary or else rails thinks the [] characters represent a sub-model! %> + <% tagname = nom.tagname.gsub('[', '#LBRACKET').gsub(']', '#RBRACKET') %> + +
    + <%= label_tag "#{tag_type}_approve_#{tagname}", :class => "action" do %> + + + <%= check_box_tag "#{tag_type}_approve_#{tagname}", 1, params["#{tag_type}_approve_#{tagname}"] %> + <% end %> + <%= label_tag "#{tag_type}_reject_#{tagname}", :class => "action" do %> + x + <%= check_box_tag "#{tag_type}_reject_#{tagname}", 1, params["#{tag_type}_reject_#{tagname}"] %> + <% end %> +
    + +
    <%= text_field_tag "#{tag_type}_change_#{tagname}", nil, autocomplete_options("tag?type=#{tag_type}", data: { autocomplete_token_limit: 1 }, title: "change tag name") %>
    + + + <% if nom.synonym %> +
    + <%= label_tag "#{tag_type}_synonym_#{tagname}" do %> + (Choose <%= nom.synonym %> instead + <%= check_box_tag "#{tag_type}_synonym_#{tagname}", nom.synonym, params["#{tag_type}_synonym_#{tagname}"] %>) + <% end %> +
    + <% end %> +
    + +<% end %> diff --git a/app/views/tag_set_nominations/_review_thead.html.erb b/app/views/tag_set_nominations/_review_thead.html.erb new file mode 100755 index 0000000..e9850aa --- /dev/null +++ b/app/views/tag_set_nominations/_review_thead.html.erb @@ -0,0 +1,10 @@ + + + + <%= ts("Nomination") %> + <%= ts("Approve") %> + <%= ts("Reject") %> + <% if section == "existing" %><%= ts("Synonym") %><% end %> + <%= ts("Edit") %> + + diff --git a/app/views/tag_set_nominations/_show_by_tag_type.html.erb b/app/views/tag_set_nominations/_show_by_tag_type.html.erb new file mode 100755 index 0000000..4b374ec --- /dev/null +++ b/app/views/tag_set_nominations/_show_by_tag_type.html.erb @@ -0,0 +1,16 @@ +<% if @limit[tag_type] > 0 %> +
  • +

    + <%= ts("%{tag_type}", tag_type: tag_type_label_name(tag_type).pluralize) %> +

    +
      + <% if @tag_set_nomination.nominated_tags(tag_type).count == 0 %> +
    1. <%= ts("None nominated in this category.") %>
    2. + <% else %> + <% @tag_set_nomination.send("#{tag_type}_nominations").each do |tag| %> +
    3. <%= render "show_tag_status", :tag => tag %>
    4. + <% end %> + <% end %> +
    +
  • +<% end %> diff --git a/app/views/tag_set_nominations/_show_tag_status.html.erb b/app/views/tag_set_nominations/_show_tag_status.html.erb new file mode 100755 index 0000000..4263d39 --- /dev/null +++ b/app/views/tag_set_nominations/_show_tag_status.html.erb @@ -0,0 +1,2 @@ +<%= nomination_status(tag) %> +<%= nomination_tag_information(tag) %> diff --git a/app/views/tag_set_nominations/_tag_nominations.html.erb b/app/views/tag_set_nominations/_tag_nominations.html.erb new file mode 100755 index 0000000..904fd22 --- /dev/null +++ b/app/views/tag_set_nominations/_tag_nominations.html.erb @@ -0,0 +1,31 @@ +
    +
    + <% @tag_set_nomination.send("#{tag_type}_nominations").each_with_index do |nom, index| %> + <%= f.fields_for "#{tag_type}_nominations".to_sym, nom do |nom_form| %> + +
    <%= nom_form.label :tagname, ts("%{tag_type} %{index}", tag_type: tag_type_label_name(tag_type), index: index + 1) %> +
    + <% if nom.approved || nom.rejected %> + <%= nom.tagname %> <%= nomination_status(nom) %> + <% else %> + +
    "> + <%= nom_form.text_field :tagname, autocomplete_options(tag_type, data: { autocomplete_token_limit: 1 }) %> +
    + <% end %> +
    + <% unless tag_type == "freeform" %> +
    + <%= nom_form.label :parent_tagname, ts("Fandom?") %> + <% unless @past_first %> + <%= link_to_help 'tagset-fandom-for-child' %> + <% @past_first = true %> + <% end %> +
    +
    "><%= nom_form.text_field :parent_tagname, autocomplete_options("fandom", data: { autocomplete_token_limit: 1 }) %>
    + <% end %> + + <% end %> + <% end %> +
    +
    diff --git a/app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb b/app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb new file mode 100755 index 0000000..5268ce2 --- /dev/null +++ b/app/views/tag_set_nominations/_tag_nominations_by_fandom.html.erb @@ -0,0 +1,39 @@ +<% @tag_set_nomination.fandom_nominations.each_with_index do |nom, index| %> + <%= f.fields_for :fandom_nominations, nom do |nom_form| %> +
    + <%= ts("Fandom %{index}", index: index + 1) %> +
    +
    <%= nom_form.label :tagname, ts("Fandom %{index}", index: index + 1) %>
    +
    + <% if nom.approved || nom.rejected %> + <%= nom.tagname %> <%= nomination_status(nom) %> + <% else %> +
    "><%= nom_form.text_field :tagname, autocomplete_options("fandom", data: { autocomplete_token_limit: 1 }, class: "autocomplete") %>
    + <% end %> +
    + + <% # if fandoms are being nominated then any character/relationship noms go under fandom %> + <% %w(character relationship).each do |tag_type| %> + <% if @limit[tag_type] > 0 %> + <%= nom_form.fields_for "#{tag_type}_nominations".to_sym do |nom_form2| %> +
    <%= nom_form2.label :tagname, ts("%{tag_type}", tag_type: tag_type_label_name(tag_type)) %> +
    + <% if nom_form2.object.approved || nom_form2.object.rejected %> + <%= nom_form2.object.tagname %> <%= nomination_status(nom_form2.object) %> + <% else %> +
    "> <%= nom_form2.text_field :tagname, + autocomplete_options("#{tag_type}_in_fandom", + data: { + autocomplete_token_limit: 1, + autocomplete_live_params: "fandom=tag_set_nomination_fandom_nominations_attributes_#{index}_tagname" + }) %>
    + <% end %> + <%= nom_form2.hidden_field :from_fandom_nomination, :value => true %> +
    + <% end %> + <% end %> + <% end %> +
    +
    + <% end %> +<% end %> diff --git a/app/views/tag_set_nominations/confirm_delete.html.erb b/app/views/tag_set_nominations/confirm_delete.html.erb new file mode 100755 index 0000000..9b1fbaf --- /dev/null +++ b/app/views/tag_set_nominations/confirm_delete.html.erb @@ -0,0 +1,12 @@ + +

    <%= ts("Delete Tag Set Nomination?") %>

    + + +<%= form_for(@tag_set, :url => tag_set_nomination_path(@tag_set, @tag_set_nomination), :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    <%= ts("Are you certain you want to delete these nominations?") %>

    +

    + <%= f.submit ts("Yes, Delete Tag Set Nominations") %> + <%= link_to ts("Back to the Tag Set Nominations"), tag_set_nomination_path(@tag_set, @tag_set_nomination) %> +

    +<% end %> + diff --git a/app/views/tag_set_nominations/confirm_destroy_multiple.html.erb b/app/views/tag_set_nominations/confirm_destroy_multiple.html.erb new file mode 100755 index 0000000..48b3d5c --- /dev/null +++ b/app/views/tag_set_nominations/confirm_destroy_multiple.html.erb @@ -0,0 +1,12 @@ + +

    <%= ts("Clear all Tag Set Nominations?") %>

    + + +<%= form_for(@tag_set, :url => destroy_multiple_tag_set_nominations_path(@tag_set), :html => {:class => "simple destroy"}, method: :delete) do |f| %> +

    <%= ts("Are you certain you want to clear all Tag Set Nominations?") %>

    +

    + <%= f.submit ts("Yes, Clear Tag Set Nominations") %> + <%= link_to ts("Back to the Tag Set Nominations"), tag_set_path(@tag_set) %> +

    +<% end %> + diff --git a/app/views/tag_set_nominations/edit.html.erb b/app/views/tag_set_nominations/edit.html.erb new file mode 100755 index 0000000..c3a5efc --- /dev/null +++ b/app/views/tag_set_nominations/edit.html.erb @@ -0,0 +1,18 @@ +<%= render 'nomination_form' %> + +<%= content_for :footer_js do %> + <%= javascript_include_tag '/javascripts/jquery.qtip.min.js' %> + <%= javascript_tag do %> + $j(document).ready(function() { + setupTooltips(); + }); + function setupTooltips() { + $j('span[data-tooltip]').each(function(){ + $j(this).qtip({ + content: $j(this).attr('data-tooltip'), + position: {corner: {target: 'topMiddle'}} + }); + }); + } + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/tag_set_nominations/index.html.erb b/app/views/tag_set_nominations/index.html.erb new file mode 100755 index 0000000..d116c5e --- /dev/null +++ b/app/views/tag_set_nominations/index.html.erb @@ -0,0 +1,11 @@ +<% if @user %> +

    <%= ts("My Nominations") %>

    + +
      + <% @tag_set_nominations.each do |tag_set_nomination| %> +
    • <%= link_to ts("Nominations for %{title}", :title => @tag_set.title) %>
    • + <% end %> +
    +<% elsif @tag_set %> + <%= render "review" %> +<% end %> diff --git a/app/views/tag_set_nominations/new.html.erb b/app/views/tag_set_nominations/new.html.erb new file mode 100755 index 0000000..8bccef8 --- /dev/null +++ b/app/views/tag_set_nominations/new.html.erb @@ -0,0 +1 @@ +<%= render 'nomination_form' %> diff --git a/app/views/tag_set_nominations/show.html.erb b/app/views/tag_set_nominations/show.html.erb new file mode 100755 index 0000000..1df1cba --- /dev/null +++ b/app/views/tag_set_nominations/show.html.erb @@ -0,0 +1,104 @@ + +
    + +

    <%= @tag_set.title %>

    + + + + + + +

    <%= ts("My Nominations for %{title}", :title => @tag_set.title) %>

    +
    +
    +
    <%= ts("Created at: ") %>
    +
    <%= l(@tag_set_nomination.created_at.to_date) %>
    +
    <%= ts("Status: ") %>
    +
    + <% if @tag_set_nomination.unreviewed? %> + <%= ts("Not Yet Reviewed") %> + <% if @tag_set.nominated %> + <%= ts("(may be edited or deleted)") %> + <% end %> + <% elsif @tag_set_nomination.reviewed? %> + <%= ts("Reviewed (may not be edited or deleted)") %> + <% else %> + <%= ts("Partially Reviewed") %> + <% if @tag_set.nominated %> + <%= ts("(unreviewed nominations may be edited)") %> + <% end %> + <% end %> +
    +
    +
    + + +

    <%= ts("Nominated Tags") %> <%= link_to_help "tagset-nominated-tags" %>

    + +
      + <% if @limit[:fandom] > 0 && (@limit[:character] > 0 || @limit[:relationship] > 0) %> + <% # group fandom, char, rel together %> + <% @tag_set_nomination.fandom_nominations.each do |fandom_nom| %> +
    1. +

      <%= render "show_tag_status", :tag => fandom_nom %>

      + <% TagSet::TAG_TYPES_RESTRICTED_TO_FANDOM.each do |tag_type| %> + <% if @limit[tag_type] > 0 %> +
      +
      <%= ts("%{tag_type}", tag_type: tag_type_label_name(tag_type).pluralize) %>
      +
        + <% if fandom_nom.send("#{tag_type}_nominations").count == 0 %> +
      • <%= ts("None nominated in this fandom.") %>
      • + <% else %> + <% fandom_nom.send("#{tag_type}_nominations").each do |tag| %> +
      • <%= render "show_tag_status", :tag => tag %>
      • + <% end %> + <% end %> +
      +
      + <% end %> + <% end %> +
    2. + <% end %> + + <% # show freeforms separately %> + <%= render "show_by_tag_type", :tag_type => "freeform" %> + + <% else %> + + <% # list char, rel, freeform individually %> + <% TagSet::TAG_TYPES_INITIALIZABLE.each do |tag_type| %> + <%= render "show_by_tag_type", :tag_type => tag_type %> + <% end %> + <% end %> +
    + + +
    + +<%= content_for :footer_js do %> + <%= javascript_include_tag '/javascripts/jquery.qtip.min.js' %> + <%= javascript_tag do %> + $j(document).ready(function() { + setupTooltips(); + }); + function setupTooltips() { + $j('span[data-tooltip]').each(function(){ + $j(this).qtip({ + content: $j(this).attr('data-tooltip'), + position: {corner: {target: 'topMiddle'}} + }); + }); + } + <% end %> +<% end %> diff --git a/app/views/tag_wranglers/index.html.erb b/app/views/tag_wranglers/index.html.erb new file mode 100755 index 0000000..0f879a7 --- /dev/null +++ b/app/views/tag_wranglers/index.html.erb @@ -0,0 +1,101 @@ +
    + +

    Tag Wrangling Assignments

    + + + + <%= will_paginate(@assignments) %> + + + + <%= form_tag url_for(:controller => 'tag_wranglers', :action => "create"), :id => "tag_wranglers" do %> +
    + Assign fandoms to yourself +

    Assign fandoms to yourself

    +

    + (<%= label_tag "tag_fandom_string", "Enter as many fandoms as you like." %>) +

    +
    + <%= text_field_tag "tag_fandom_string", params[:sign_up_fandoms], autocomplete_options("fandom") %> +
    +

    <%= submit_tag 'Assign' %>

    +
    + + <% redirect_params = { fandom_string: params[:fandom_string], media_id: params[:media_id], wrangler_id: params[:wrangler_id] } %> + +
    + Assign Wranglers to Fandoms +

    Assign Wranglers to Fandoms

    +
    + <% @assignments.group_by(&:name).each do |name, assignments| %> +
    <%= link_to name, {:controller => :tags, :action => :edit, :id => assignments.first} %>
    +       <% wranglers = assignments.collect(&:wrangler).compact %> +       
    + <% unless wranglers.empty? %> + + <% end %> + +

    + <% select_tag_to_add = select_tag("assignments[#{assignments.first.id}][]", options_for_select([''] + @wranglers.collect(&:login))) %> + <%= select_tag_to_add %> + + <%= link_to_function("+", + "$j('#wranglers-for-#{assignments.first.id}').append('

    " + escape_javascript(select_tag_to_add) + "

    ')") %> + +

    +
    + <% end %> +
    +

    + <%= hidden_field_tag :fandom_string, params[:fandom_string] %> + <%= hidden_field_tag :media_id, params[:media_id] %> + <%= hidden_field_tag :wrangler_id, params[:wrangler_id] %> + <%= submit_tag 'Assign' %> +

    +
    + <% end %> + + + + <%= form_tag tag_wranglers_path, :class => 'filters', :method => :get do %> +
    +

    Filters

    + +
    + <% end %> + +
    + <%= will_paginate(@assignments) %> + +
    diff --git a/app/views/tag_wranglers/show.html.erb b/app/views/tag_wranglers/show.html.erb new file mode 100755 index 0000000..0c39cf9 --- /dev/null +++ b/app/views/tag_wranglers/show.html.erb @@ -0,0 +1,70 @@ +
    +
    + +

    <%= ts("%{wrangler_login}'s Wrangling Page", :wrangler_login => @wrangler.login) %>

    +

    <%= icon_display(@wrangler) %>

    + + + <% if policy(:wrangling).report_csv? %> + + <% end %> + +
    + + + +
    +

    <%= ts('Assigned Fandoms') %>

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

    <%= ts("Your lack of fandoms makes the wrangulator sad. Fandoms can be assigned via the") %> <%= link_to ts('tag wranglers page'), tag_wranglers_path %>.

    + <% else %> +

    <%= ts('Fandoms assigned to you via the ') %> <%= link_to ts('tag wranglers page'), tag_wranglers_path %>. <%= ts('The unwrangled count is the number of unwrangled tags which were used on works in the given fandom.') %>

    + <% end %> + <% if (@wrangler == @current_user || logged_in_as_admin?) && @wrangler.last_wrangling_activity %> + <% wrangled_time_html = tag.span(time_in_zone(@wrangler.last_wrangling_activity.updated_at), class: "datetime") %> +

    <%= t(".last_wrangled_html", wrangler_login: @wrangler.login, time: wrangled_time_html) %>

    + <% end %> + <% if @fandoms.any? %> + + + + + + + + + + + + + + + + + + + <% @fandoms.each do |fandom| %> + + + + + + + + + + <% end %> + +
    <%= ts('Unfilterable and Unwrangled Tag Counts for Your Assigned Fandoms') %>
    <%= ts('Fandom') %><%= ts('Unfilterable') %><%= ts('Unwrangled') %>
    <%= ts('Characters') %><%= ts('Relationships') %><%= ts('Freeforms') %><%= ts('Characters') %><%= ts('Relationships') %><%= ts('Freeforms') %>
    <%= link_to fandom.name, {:controller => :tags, :action => :wrangle, :id => fandom} %><%= (tag_count = fandom.characters.unfilterable.size) > 0 ? link_to(tag_count, {:controller => :tags, :action => :wrangle, :id => fandom, :show => :characters, :status => :unfilterable}) : " " %><%= (tag_count = fandom.relationships.unfilterable.size) > 0 ? link_to(tag_count, {:controller => :tags, :action => :wrangle, :id => fandom, :show => :relationships, :status => :unfilterable}) : " " %><%= (tag_count = fandom.freeforms.unfilterable.size) > 0 ? link_to(tag_count, {:controller => :tags, :action => :wrangle, :id => fandom, :show => :freeforms, :status => :unfilterable}) : " " %><%= (tag_count = fandom.unwrangled_tag_count("Character")) > 0 ? link_to(tag_count, {:controller => :tags, :action => :wrangle, :id => fandom, :show => :characters, :status => :unwrangled}) : " " %><%= (tag_count = fandom.unwrangled_tag_count("Relationship")) > 0 ? link_to(tag_count, {:controller => :tags, :action => :wrangle, :id => fandom, :show => :relationships, :status => :unwrangled}) : " " %><%= (tag_count = fandom.unwrangled_tag_count("Freeform")) > 0 ? link_to(tag_count, {:controller => :tags, :action => :wrangle, :id => fandom, :show => :freeforms, :status => :unwrangled}) : " " %>
    + <% end %> +
    +
    + + + + + +
    diff --git a/app/views/tag_wrangling_supervisor_mailer/wrangler_username_change_notification.html.erb b/app/views/tag_wrangling_supervisor_mailer/wrangler_username_change_notification.html.erb new file mode 100755 index 0000000..a144b62 --- /dev/null +++ b/app/views/tag_wrangling_supervisor_mailer/wrangler_username_change_notification.html.erb @@ -0,0 +1,10 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.informal.addressed_html", name: style_bold(t("mailer.general.greeting.tag_wrangler_supervisors"))) %>

    + +

    <%= t(".name_changed.html", old_username: style_bold(@old_username), new_username: style_bold(@new_username)) %>

    + +

    + <%= t("mailer.general.closing.informal") %>
    + <%= t("mailer.general.signature.app_short_name") %> +

    +<% end %> diff --git a/app/views/tag_wrangling_supervisor_mailer/wrangler_username_change_notification.text.erb b/app/views/tag_wrangling_supervisor_mailer/wrangler_username_change_notification.text.erb new file mode 100755 index 0000000..5315e40 --- /dev/null +++ b/app/views/tag_wrangling_supervisor_mailer/wrangler_username_change_notification.text.erb @@ -0,0 +1,8 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.informal.addressed_html", name: t("mailer.general.greeting.tag_wrangler_supervisors")) %> + +<%= t(".name_changed.html", old_username: @old_username, new_username: @new_username) %> + +<%= t("mailer.general.closing.informal") %> +<%= t("mailer.general.signature.app_short_name") %> +<% end %> diff --git a/app/views/tag_wranglings/_wrangler_dashboard.html.erb b/app/views/tag_wranglings/_wrangler_dashboard.html.erb new file mode 100755 index 0000000..a1e0bcd --- /dev/null +++ b/app/views/tag_wranglings/_wrangler_dashboard.html.erb @@ -0,0 +1,62 @@ +<% if (logged_in_as_admin? && policy(:wrangling).read_access?) || current_user.try(:is_tag_wrangler?) || @counts %> +
    + <% if (logged_in_as_admin? && policy(:wrangling).read_access?) || current_user.try(:is_tag_wrangler?) %> + + <% end %> + + <% if @counts %> + + <% end %> +
    +<% end %> diff --git a/app/views/tag_wranglings/index.html.erb b/app/views/tag_wranglings/index.html.erb new file mode 100755 index 0000000..7f07bf6 --- /dev/null +++ b/app/views/tag_wranglings/index.html.erb @@ -0,0 +1,159 @@ +
    + +

    <%= ts('Tag Wrangling') %>

    + <% unless params[:show] %> +

    <%= ts('Notes') %>

    + +

    Additional Resources:

    + + <% end %> + + + + + + + + + <% unless params[:show].blank? %> +

    <%= ts('Mass Wrangle New/Unwrangled Tags') %>

    + <% end %> + + <% if @tags && @tags.empty? %> +

    <%= ts('There are no unwrangled tags in this category at the moment.') %>

    + <% elsif @tags %> + <%= will_paginate @tags %> + + <%= form_tag url_for(controller: 'tag_wranglings', action: 'wrangle'), method: :post, id: 'wrangulator' do %> +
    + <%= ts('Assign and Mass Select') %> + +
    + <% if params[:show] == 'fandoms' %> +
    <%= label_tag :media, ts('Wrangle to Media') %>
    +
    <%= select_tag :media, options_for_select(@media_names) %>
    + <% else %> +
    <%= label_tag :fandom_string, ts('Wrangle to Fandom(s)') %>
    +
    <%= text_field_tag 'fandom_string', params[:fandom_string], autocomplete_options('fandom') %>
    + <% end %> +
    <%= ts('Submit') %>
    +
    <%= submit_tag ts('Wrangle') %>
    +
    +
    + +
    + <%= ts('Choose tags from a table') %> + +

    <%= ts('Individual Selection Table') %>

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + <% @tags.each do |tag| %> + <% if tag.unwrangled? %> + + + + + + + + + + + + <% end %> + <% end %> + +
    <%= @tags.first.class.to_s.pluralize %> <%= ts('to be Wrangled') %>
    + <%= sort_link ts('Tag Name'), :name %> + + + <%= sort_link ts('Created'), :created_at, {sort_default: true} %> + + <%= ts('Canonical') %> + + + <%= sort_link ts('Taggings'), :taggings_count_cache, { desc_default: true } %> + <%= ts('Manage') %>
    <%= ts('Action:') %><%= submit_tag ts('Wrangle') %>
    "> + <%= check_box_tag "selected_tags[]", tag.id, nil, id: "selected_tags_#{tag.id}" %> + <%= label_tag "selected_tags_#{tag.id}", tag.name.to_s %> + "><%= l(tag.created_at.to_date) %>"> + <% if tag.canonical? %> + <%= ts("Yes") %> + <% else %> + <%= check_box_tag "canonicals[]", tag.id, tag.canonical?, id: "canonicals_#{tag.id}" %> + <% end %> + "><%= tag.taggings_count_cache %> + +
    +
    +
    + +
    + <%= hidden_field_tag :show, params[:show] %> + <%= hidden_field_tag :sort_column, params[:sort_column] %> + <%= hidden_field_tag :sort_direction, params[:sort_direction] %> + <%= hidden_field_tag :page, params[:page] %> +
    + <% end %> + +
    + + + <%= will_paginate @tags %> + <% end %> + +
    + +<% content_for :footer_js do %> + <%= javascript_include_tag 'select_all', skip_pipeline: true %> +<% end %> diff --git a/app/views/tags/_search_form.html.erb b/app/views/tags/_search_form.html.erb new file mode 100755 index 0000000..5dcbea1 --- /dev/null +++ b/app/views/tags/_search_form.html.erb @@ -0,0 +1,85 @@ +<%= form_for @search, as: :tag_search, url: search_tags_path, html: { class: "search", method: :get } do |f| %> +
    +
    +
    + <%= f.label :name, t(".tag_name") %> + <%= link_to_help "tag-search-text-help" %> +
    +
    + <%= f.text_field :name %> +
    +
    + <%= f.label :fandoms, t(".fandoms") %> +
    +
    + <%= f.text_field :fandoms, autocomplete_options("fandom", "aria-describedby" => "fandom-field-description") %> +

    + <%= t(".fandoms_footnote") %> +

    +
    +
    <%= t(".type") %>
    +
    +
    +
      + <% types = Tag::USER_DEFINED %> + <% types.each do |type| %> +
    • + <%= f.radio_button :type, type %> + <%= f.label :type, ts("%{type}", type: type), value: type %> +
    • + <% end %> +
    • + <%= f.radio_button :type, "" %> + <%= f.label :type, ts("Any type"), value: "" %> +
    • +
    +
    +
    +
    <%= t(".wrangling_status") %>
    +
    +
    +
      +
    • + <%= f.radio_button :wrangling_status, "canonical" %> + <%= f.label :wrangling_status, t(".status_option.canonical"), value: "canonical" %> +
    • +
    • + <%= f.radio_button :wrangling_status, "noncanonical" %> + <%= f.label :wrangling_status, t(".status_option.noncanonical"), value: "noncanonical" %> +
    • +
    • + <%= f.radio_button :wrangling_status, "synonymous" %> + <%= f.label :wrangling_status, t(".status_option.synonymous"), value: "synonymous" %> +
    • +
    • + <%= f.radio_button :wrangling_status, "canonical_synonymous" %> + <%= f.label :wrangling_status, t(".status_option.canonical_or_synonymous"), value: "canonical_synonymous" %> +
    • +
    • + <%= f.radio_button :wrangling_status, "noncanonical_nonsynonymous" %> + <%= f.label :wrangling_status, t(".status_option.noncanonical_and_nonsynonymous"), value: "noncanonical_nonsynonymous" %> +
    • +
    • + <%= f.radio_button :wrangling_status, "" %> + <%= f.label :wrangling_status, t(".status_option.any_status"), value: "" %> +
    • +
    +
    +
    +
    + <%= f.label :sort_column, t(".sort_by") %> +
    +
    + <%= f.select :sort_column, options_for_select(@search.sort_options, @search.sort_column) %> +
    +
    + <%= f.label :sort_direction, t(".sort_direction") %> +
    +
    + <%= f.select :sort_direction, + options_for_select([["Ascending", "asc"], ["Descending", "desc"]], @search.sort_direction) %> +
    +
    +

    <%= f.submit t(".search_tags") %>

    +
    +<% end %> diff --git a/app/views/tags/edit.html.erb b/app/views/tags/edit.html.erb new file mode 100755 index 0000000..a66c463 --- /dev/null +++ b/app/views/tags/edit.html.erb @@ -0,0 +1,235 @@ + +

    + <%= ts("Edit %{tag_link} Tag", tag_link: link_to_tag(@tag)).html_safe %> +

    +<%= error_messages_for :tag %> + + + + + + + + +<% if logged_in_as_admin? %> +

    <%= ts("Last updated by %{wrangler} on %{date}", wrangler: @tag.last_wrangler.try(:login) || '---', date: @tag.updated_at) %>

    +<% end %> + +<%= form_for @tag, as: :tag, url: { action: "update", id: @tag}, html: { method: :put } do |f| %> +
    + <%= t(".submit_legend") %> +

    + <%= submit_tag t(".save_changes") %> +

    +
    +
    + <%= ts("Tag Info") %> +

    <%= ts("Tag Info") %>

    + +
    +
    <%= f.label :name, ts("Name") %>
    +
    + <% if Tag::USER_DEFINED.include?(@tag.class.name) || (@tag[:type] == "Media" && logged_in_as_admin?) %> + <%= f.text_field :name, size: (@tag.name.length + 5) %> + <% unless logged_in_as_admin? %> +

    + <%= ts("Only changes to capitalization and diacritic marks are permitted.") %> +

    + <% end %> + <% else %> + <%= @tag.name %> + <% end %> +
    + + <% if @tag.type.to_s == "Fandom" %> +
    + <%= f.label :sortable_name, ts("Name To Use For Alphabetical Sorting") %> +
    +
    + <%= f.text_field :sortable_name, size: (@tag.sortable_name.length + 5) %> +
    + <% end %> + +
    <%= ts("Category") %>
    +
    + <% types = logged_in_as_admin? ? (Tag::USER_DEFINED + %w[Media]) : Tag::USER_DEFINED %> + <% if @tag.can_change_type? %> + <%= f.select :type, + options_for_select(types + %w[UnsortedTag], + @tag.type.to_s) %> + <% else %> + <%= ts("%{tag_type}", tag_type: tag_type_label_name(@tag.type.tableize)) %> + <% end %> +
    + + <% if @wranglers %> +
    <%= ts("Wranglers") %>
    +
    <%= wrangler_list(@wranglers, @tag) %>
    + <% end %> + +
    <%= f.label :canonical, ts("Canonical") %>
    +
    + <%= f.check_box("canonical", disabled: !(logged_in_as_admin? || Tag::USER_DEFINED.include?(@tag.class.name)) || !@tag.mergers.empty? || !@tag.children.empty?) %>  +

    + <%= ts("This is the official name for the %{tag_type}", + tag_type: tag_type_label_name(@tag.type.tableize)) %> +

    + <% if logged_in_as_admin? && Tag::USER_DEFINED.include?(@tag.class.name) && @tag.canonical? && (!@tag.mergers.empty? || !@tag.children.empty?) %> + + <% end %> +
    + + <% if @tag.is_a?(Rating)%> +
    <%= f.label :adult, ts("Adult") %>
    +
    + <%= f.check_box("adult", disabled: !logged_in_as_admin? )%>  + <%= ts("This tag indicates adult content.") %> +
    + <% end %> + + <% if Tag::USER_DEFINED.include?(@tag[:type]) && !(@tag.canonical? && !logged_in_as_admin?) %> +
    <%= f.label :syn_string, ts("Synonym of") %>
    +
    + <%= f.text_field :syn_string, + autocomplete_options("tag?type=#{@tag.type.downcase}", + class: "autocomplete tags", + data: { autocomplete_token_limit: 1 }) %> +

    + <%= ts("Choose an existing tag or add a new tag name here to create a new canonical and make this tag its synonym.") %> +

    + <% if @tag.merger %> + + <% elsif @tag.canonical? %> +

    + <%= ts("Adding a synonym to a canonical tag will make it non-canonical and move its associations to the other tag. (Be careful with this!)") %> +

    + <% end %> +
    + <% end %> + +
    <%= f.label :unwrangleable %>
    +
    + <%= f.check_box(:unwrangleable, disabled: (@tag.class.name == "UnsortedTag")) %>  +

    <%= ts("This tag will never be merged or made canonical and should not be included on wrangling pages.") %>

    +
    +
    +
    + + <% if (Tag::USER_DEFINED + ["Media"]).include?(@tag[:type]) %> +
    + <%= ts("Parent Tags") %> +

    <%= ts("Parent Tags") %>

    +
    + <% @tag.parent_types.each do |tag_type| %> + <% if tag_type == "Fandom" && !@suggested_fandoms.blank? %> +
    <%= ts("Suggested Fandoms") %>:
    +
    +
      + <% @suggested_fandoms.each do |tag| %> +
    • <%= link_to_edit_tag(tag) %>
    • + <% end %> +
    +
    + <% end %> +
    <%= tag_category_name(tag_type) %>
    +
    + <% if @parents[tag_type].present? %> +

    <%= ts("Check to remove:") %>

    + <%= check_all_none("All", "None", tag_type) %> + <%= checkbox_section(f, "associations_to_remove", @parents[tag_type], + name_helper_method: "remove_tag_association_label", + extra_info_method: "link_to_edit_tag", + field_id: "parent_#{tag_type}_associations_to_remove", + concise: true) %> +
    + <%= f.label tag_type.underscore + "_string", ts("Add:") %> +
    + <% else %> +

    + <%= f.label tag_type.underscore + "_string", + ts("Add %{catname}:", catname: tag_category_name(tag_type)) %> +

    + <% end %> +
    "> + <%= f.text_field tag_type.underscore + "_string", + autocomplete_options("tag?type=#{(tag_type.downcase == 'metatag' ? @tag.type.downcase : tag_type.downcase)}", + class: "tags autocomplete") %> +
    +
    + <% end %> +
    +
    + + <% if @tag.canonical? %> +
    + <%= ts("Child Tags") %> +

    <%= ts("Child Tags") %>

    + +
    + <% @tag.child_types.each do |tag_type| %> +
    <%= tag_category_name(tag_type) %>
    +
    + <% if @children[tag_type].present? %> +

    <%= ts("Check to remove: ") %>

    + <%= check_all_none("All", "None", tag_type) %> + <%= checkbox_section(f, "associations_to_remove", + @children[tag_type][0..19], + name_helper_method: "remove_tag_association_label", + extra_info_method: "link_to_edit_tag", + field_id: "child_#{tag_type}_associations_to_remove", + concise: true) %> + <% if @children[tag_type].length > 20 %> + + <% end %> +
    + <%= f.label tag_type.underscore + "_string", ts("Add:") %> +
    + <% else %> +

    + <%= f.label tag_type.underscore + "_string", ts("Add %{catname}:", + catname: tag_category_name(tag_type)) %> +

    + <% end %> +
    "> + <%= f.text_field tag_type.underscore + "_string", + autocomplete_options("#{tag_type == 'Merger' ? ('noncanonical_tag?type=' + @tag.type.downcase) : (tag_type == 'SubTag' ? @tag.type.downcase : tag_type.downcase)}", + class: "tags autocomplete") %> +
    +
    + <% end %> +
    +
    + <% end %> + + <% elsif @tag.is_a?(Media) %> + + <% end %> + +
    + <%= t(".submit_legend") %> +

    + <%= submit_tag t(".save_changes") %> +

    +
    +<% end %> + + + + diff --git a/app/views/tags/feed.atom.builder b/app/views/tags/feed.atom.builder new file mode 100755 index 0000000..9f01c5e --- /dev/null +++ b/app/views/tags/feed.atom.builder @@ -0,0 +1,17 @@ +atom_feed do |feed| + feed.title "AO3 works tagged '#{@tag.name}'" + feed.updated @works.first.created_at if @works.respond_to?(:first) && @works.first.present? + + @works.each do |work| + unless work.unrevealed? + feed.entry work do |entry| + entry.title work.title + entry.summary feed_summary(work), :type => 'html' + + entry.author do |author| + author.name text_byline(work, :visibility => 'public') + end + end + end + end +end diff --git a/app/views/tags/index.html.erb b/app/views/tags/index.html.erb new file mode 100755 index 0000000..0658c8b --- /dev/null +++ b/app/views/tags/index.html.erb @@ -0,0 +1,48 @@ + + +

    <%= ts("Tags") %>

    + + + +<% unless @collection %> + +<% end %> + + + +<% unless @collection %> +

    + <% if params[:show] == "random" %> + <%= ts('Browse Random Tags')%> + <% else %> + <%= ts('Browse Popular Tags')%> + <% end %> +

    +<% end %> + +<% if @tags %> + <% if params[:show] == "random" %> + <% if @collection %> +

    <%= t(".about.random_in_collection") %>

    + <% else %> +

    <%= t(".about.random", search_tags_link: (link_to t(".search_tags"), search_tags_path)).html_safe %>

    + <% end %> + <% else %> + <% if @collection %> +

    <%= t(".about.popular_in_collection") %>

    + <% else %> +

    <%= t(".about.popular", search_tags_link: (link_to t(".search_tags"), search_tags_path)).html_safe %>

    + <% end %> + <% end %> +
      + + <% tag_cloud @tags, %w(cloud1 cloud2 cloud3 cloud4 cloud5 cloud6 cloud7 cloud8) do |tag, css_class| %> +
    • <%= link_to_tag_works(tag, class: css_class.dup, collection: @collection) %>
    • + <% end %> +
    +<% end %> + diff --git a/app/views/tags/new.html.erb b/app/views/tags/new.html.erb new file mode 100755 index 0000000..f1eb488 --- /dev/null +++ b/app/views/tags/new.html.erb @@ -0,0 +1,47 @@ + +

    <%= ts('New Tag') %>

    + +<%= error_messages_for :tag %> + +

    <%= ts('Once you have created the tag, the attributes that are particular for that tag category will be available for editing.') %>

    + + + + + + + +<%= form_for @tag, as: :tag, url: { action: "create" } do |f| %> +
    +
    <%= f.label :name, ts('Name') %>
    +
    <%= f.text_field :name, size: ArchiveConfig.TAG_MAX %>
    + +
    <%= f.label :canonical, ts('Canonical') %>
    +
    <%= f.check_box :canonical %>
    + +
    <%= ts('Category') %>
    +
    + <% if logged_in_as_admin? %> + <% types = Tag::TYPES %> + <% else %> + <% types = Tag::USER_DEFINED %> + <% end %> +
      + <% types.each do |type| %> +
    • + <%= f.radio_button("type", type) %> + <%= f.label("type_#{type.downcase}", ts("%{type}", type: tag_type_label_name(type))) %> +
    • + <% end %> +
    +
    +
    + +

    + <%= f.submit %> +

    +<% end %> + + + + diff --git a/app/views/tags/search.html.erb b/app/views/tags/search.html.erb new file mode 100755 index 0000000..b77048d --- /dev/null +++ b/app/views/tags/search.html.erb @@ -0,0 +1,18 @@ +

    <%= ts("Tag Search") %>

    + +<%= render 'shared/search_nav' %> + +<%= render :partial => 'tags/search_form' %> + +<% if @tags %> +

    <%= search_results_found(@tags) %> <%= link_to_help "tag-search-results-help" %>

    +

    Listing Tags

    +
      + <% for tag in @tags %> + <% unless tag.nil? %> +
    1. <%= tag_search_result(tag) %>
    2. + <% end %> + <% end %> +
    + <%= will_paginate @tags %> +<% end %> diff --git a/app/views/tags/show.html.erb b/app/views/tags/show.html.erb new file mode 100755 index 0000000..6334bd7 --- /dev/null +++ b/app/views/tags/show.html.erb @@ -0,0 +1,143 @@ + +
    +
    +

    <%= @tag.name %>

    +
    + <% if @tag.canonical || @tag.merger || can_wrangle? %> + + <% end %> +
    + + <%= error_messages_for :tag %> + + + +

    <%= ts("This tag belongs to the %{tag_class} Category.", :tag_class => @tag.class::NAME) %> + <% if @tag.canonical %> + <%= t(".canonical_html", + canonical_tag_link: link_to(t(".canonical_tag"), archive_faq_path("glossary", anchor: "canonicaldef")), + filter_works_link: link_to(t(".filter_works"), tag_works_path(@tag)), + filter_bookmarks_link: link_to(t(".filter_bookmarks"), tag_bookmarks_path(@tag))) %> + <% if @tag.is_a?(Fandom) %> + <%= t(".list_fandom_tags_html", fandom_relationship_tags_link: link_to(t(".fandom_relationship_tags"), fandom_path(@tag))) %> + <% end %> + <% end %> +

    + + + <% if @tag.is_a?(Rating) && @tag.adult %> +

    <%= ts('This tag indicates adult content.') %>

    + <% end %> + + <% if @tag.is_a?(Fandom) %> +
    +

    <%= ts('Parent tags (more general)') %>:

    +
      + <% (@tag.parents + [@tag.media]).uniq.compact.sort.each do |parent| %> +
    • <%= link_to_tag parent %>
    • + <% end %> +
    +
    + <% else %> + <% unless @tag.parents.blank? %> +
    +

    <%= ts('Parent tags (more general)') %>:

    +
      <%= tag_link_list(@tag.parents.sort) %>
    +
    + <% end %> + <% end %> + + <% if @tag.merger %> +
    +

    <%= ts("Mergers") %>

    +

    <%= ts("%{tag_name} has been made a synonym of %{tag_synonym_link}. Works and bookmarks tagged with %{tag_name} will show up in %{tag_synonym}'s filter.", :tag_name => @tag.name, :tag_synonym_link => (link_to_tag @tag.merger), :tag_synonym => @tag.merger.name).html_safe %>

    +
    + <% end %> + + <% unless @tag_children['Merger'].blank? %> +
    +

    <%= ts('Tags with the same meaning') %>:

    +
      <%= tag_link_list(@tag_children['Merger'].sort) %>
    +
    + <% end %> + + <% unless @tag.direct_meta_tags.blank? %> +
    +

    <%= ts('Metatags') %>:

    + <% cache "tag-#{@tag.cache_key}-metatags-v2", expires_in: 24.hours, skip_digest: true do %> + <%= meta_tag_tree(@tag) %> + <% end %> +
    + <% end %> + + <% unless @tag.direct_sub_tags.blank? %> +
    +

    <%= ts('Subtags') %>:

    + <% cache "tag-#{@tag.cache_key}-subtags-v3", expires_in: 24.hours, skip_digest: true do %> + <%= sub_tag_tree(@tag) %> + <% end %> +
    + <% end %> + + <% unless (@tag_children.keys - ['Merger']).blank? %> + + <% cache("tag-#{@tag.cache_key}-children-v3", skip_digest: true) do %> +
    +

    <%= ts('Child tags (displaying the first %{count} of each type)', :count => ArchiveConfig.TAG_LIST_LIMIT) %>:

    + <% %w(Character Relationship Freeform).each do |type| %> + <% if @tag_children[type].present? %> +
    +

    <%= type.constantize::NAME.pluralize %>:

    +
      + <%= tag_link_list(@tag_children[type].sort) %> + <% if @tag_children[type].length > ArchiveConfig.TAG_LIST_LIMIT %> +
    • <%= ts("and more") %>
    • + <% end %> +
    +
    + <% end %> + <% end %> +
    + <% end %> + <% end %> + + <% if @works %> +

    <%= ts("This tag has not been marked common and can't be filtered on (yet).") %>

    + <% unless @works.blank? %> +
    +

    <%= ts('Works which have used it as a tag') %>:

    + <%= paginated_section @works do %> +
      + <% for work in @works %> + <%= render :partial => 'works/work_blurb', :locals => {:work => work} %> + <% end %> +
    + <% end %> +
    + <% end %> + + <% unless @bookmarks.blank? %> +
    +

    <%= ts('Bookmarks which have used it as a tag') %>:

    + <%= paginated_section @bookmarks, {:previous_label => '« Previous', :next_label => 'Next »'} do %> +
      + <% for bookmark in @bookmarks %> + <%= render 'bookmarks/bookmark_blurb', :bookmark => bookmark %> + <% end %> +
    + <% end %> +
    + <% end %> + <% end %> +
    + diff --git a/app/views/tags/show_hidden.js.erb b/app/views/tags/show_hidden.js.erb new file mode 100755 index 0000000..283d892 --- /dev/null +++ b/app/views/tags/show_hidden.js.erb @@ -0,0 +1,12 @@ +<% +last_tag = @display_tags.last +if @display_category == 'warnings' + open_tags = "
  • " + closing_tags = "
  • " +else + open_tags = "
  • " + closing_tags = "
  • " +end +tag_list = @display_tags.map {|tag| open_tags + link_to_tag_works(tag) + closing_tags } +%> +$j("#<%= "#{@display_creation.class.to_s.underscore}_#{@display_creation.id}_category_#{@display_category}" %>").replaceWith("<%= escape_javascript(tag_list.join(" ").html_safe) %>"); diff --git a/app/views/tags/wrangle.html.erb b/app/views/tags/wrangle.html.erb new file mode 100755 index 0000000..5eef96a --- /dev/null +++ b/app/views/tags/wrangle.html.erb @@ -0,0 +1,177 @@ + +

    <%= ts('Wrangle Tags for') %> <%= link_to_tag(@tag) %>

    + + + + + + +<% + showing_header = '' + if params[:show] && params[:status] + showing_header = ts('Showing %{status} %{tag_type} Tags', status: params[:status].to_s.capitalize, tag_type: params[:show].to_s.titleize.singularize) + elsif params[:show] + showing_header = ts('Showing All %{tag_type} Tags', tag_type: params[:show].to_s.titleize.singularize) + end +%> +<% unless showing_header.blank? %> +

    <%= showing_header %>

    +<% end %> + +<% if params[:show] %> + +<% end %> + +<% if @tags && @tags.empty? %> +

    <%= ts('There are no tags in this category at the moment.') %>

    +<% elsif @tags %> + <%= will_paginate @tags %> + + <%= form_tag url_for(controller: 'tags', action: 'mass_update'), method: :post, id: 'wrangulator' do %> + + <% if @tag.is_a?(Fandom) && !%w(sub_tags mergers).include?(params[:show]) %> +
    + <%= ts('Assign and Mass Select') %> + +
    +
    <%= label_tag :fandom_string, ts('Wrangle to Fandom(s)') %>
    +
    <%= text_field_tag 'fandom_string', params[:fandom_string], autocomplete_options('fandom') %>
    + +
    <%= ts('Submit') %>
    +
    <%= submit_tag ts('Wrangle') %>
    +
    +
    + <% end %> + +

    <%= submit_tag ts('Wrangle') %>

    + + <% sort_url_options = {show: params[:show], status: params[:status], sort_column: params[:sort_column]} %> + + + + + + + + + <% if params[:show] == 'relationships' %> + + <% end %> + + <% if params[:status] == 'canonical' %> + + <% else %> + + <% end %> + + + + + + + + <% @tags.each do |tag| %> + + <% if @tag.is_a?(Fandom) %> + + <% else %> + + <% end %> + + <% if params[:show] == 'relationships' %> + + <% end %> + + + + + + + + + + + + <% end %> + +
    <%= ts('Tags to Wrangle') %>
    + <%= sort_link ts('Tag Name'), :name, {sort_default: true} %> + + <%= ts('Characters') %><%= ts('Canonical') %><%= ts('Metatag') %><%= ts('Synonym') %> + <%= sort_link ts('Created'), :created_at, {desc_default: true} %> + + <%= sort_link ts('Taggings'), :taggings_count_cache, {desc_default: true} %> + <%= ts('Manage') %>
    + <%= check_box_tag 'selected_tags[]', tag.id, nil, id: "selected_tags_#{tag.id}" %> + <%= label_tag "selected_tags_#{tag.id}", "#{tag.name}" %> + + <%= label_tag "canonicals_#{tag.id}", tag.name %> + + <% unless !tag.canonical? || tag.characters.empty? %> +
      <%= tag_link_list(tag.characters) %>
    + <% end %> +
    + <% if tag.canonical? %> + <%= ts('Yes') %> + <% elsif tag.unwrangleable? %> + <%= ts('Unwrangleable') %> + <% else %> + <%= check_box_tag 'canonicals[]', tag.id, tag.canonical?, id: "canonicals_#{tag.id}" %> + <% end %> + + <% if params[:status] == 'canonical' %> + <% unless tag.direct_meta_tags.blank? %><%= tag_link_list(tag.direct_meta_tags) %><% end %> + <% else %> + <% if tag.merger %><%= link_to_tag(tag.merger) %><% end %> + <% end %> + <%= tag.created_at.to_date %>"><%= tag.taggings_count_cache %> + +
    + +
    + <%= hidden_field_tag :show, params[:show] %> + <%= hidden_field_tag :sort_column, params[:sort_column] %> + <%= hidden_field_tag :sort_direction, params[:sort_direction] %> + <%= hidden_field_tag :page, params[:page] %> + <%= hidden_field_tag :status, params[:status] %> +
    + +

    <%= submit_tag ts('Wrangle') %>

    + <% end %> + + + + <%= will_paginate @tags %> +<% end %> + + +<% content_for :footer_js do %> + <%= javascript_include_tag 'select_all', skip_pipeline: true %> +<% end %> diff --git a/app/views/tos_update_mailer/tos_update_notification.html.erb b/app/views/tos_update_mailer/tos_update_notification.html.erb new file mode 100755 index 0000000..502a99e --- /dev/null +++ b/app/views/tos_update_mailer/tos_update_notification.html.erb @@ -0,0 +1,16 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@username)) %>

    + +

    In order to make AO3's rules clearer to our users, we intend to update the AO3 Terms of Service (TOS) later this year. Once this occurs, you will need to agree to the updated TOS in order to continue using AO3.

    + +

    Here are the highlights of the changes in the 2024 version of the TOS:

    + +
    • We've clarified the Content Policy, but we haven't changed what works are or are not allowed. <%= style_bold("If your fanwork was allowed on AO3 before, then it is still allowed.") %>
    • +
    • The TOS has been split into three pages (General Principles, Content Policy, and Privacy Policy). This should make it easier to find what you're looking for when you want to know about a specific part of the TOS.
    • +
    • We've simplified the language throughout the TOS and removed redundant or overly specific phrases and passages. When longer explanations would help to provide clarity, we've added new questions to the TOS FAQ instead.
    • +
    • We've updated the descriptions of how we and our subprocessors collect and process user information (including personal information) in the Privacy Policy.
    • +
    • The Abuse Policy has been generalized to provide the AO3 Policy & Abuse committee with greater flexibility to determine how to address TOS violations, while still providing protections for fanworks in accordance with AO3's mission.
    • +
    • The "Underage" Archive Warning, which is used for works that depict or describe underage sex, will be renamed to "Underage Sex". This does not change the meaning of this warning or how it is enforced. When the TOS update occurs, <%= style_bold('all works with the "Underage" Archive Warning will be recategorized automatically to display the new "Underage Sex" Archive Warning label instead.') %> If you have a work that carries the "Underage" warning and you don't want it to display the "Underage Sex" label, you can replace it with the "Creator Chose Not to Use Archive Warnings" label at any time.
    + +

    You can learn more about the intended changes, access the full draft text, ask questions, and provide public feedback by visiting our <%= style_link(style_bold("news post about the 2024 Terms of Service updates"), admin_post_url(@admin_post)) %>.

    +<% end %> diff --git a/app/views/tos_update_mailer/tos_update_notification.text.erb b/app/views/tos_update_mailer/tos_update_notification.text.erb new file mode 100755 index 0000000..6465639 --- /dev/null +++ b/app/views/tos_update_mailer/tos_update_notification.text.erb @@ -0,0 +1,16 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @username) %> + +In order to make AO3's rules clearer to our users, we intend to update the AO3 Terms of Service (TOS) later this year. Once this occurs, you will need to agree to the updated TOS in order to continue using AO3. + +Here are the highlights of the changes in the 2024 version of the TOS: + + - We've clarified the Content Policy, but we haven't changed what works are or are not allowed. If your fanwork was allowed on AO3 before, then it is still allowed. + - The TOS has been split into three pages (General Principles, Content Policy, and Privacy Policy). This should make it easier to find what you're looking for when you want to know about a specific part of the TOS. + - We've simplified the language throughout the TOS and removed redundant or overly specific phrases and passages. When longer explanations would help to provide clarity, we've added new questions to the TOS FAQ instead. + - We've updated the descriptions of how we and our subprocessors collect and process user information (including personal information) in the Privacy Policy. + - The Abuse Policy has been generalized to provide the AO3 Policy & Abuse committee with greater flexibility to determine how to address TOS violations, while still providing protections for fanworks in accordance with AO3's mission. + - The "Underage" Archive Warning, which is used for works that depict or describe underage sex, will be renamed to "Underage Sex". This does not change the meaning of this warning or how it is enforced. When the TOS update occurs, all works with the "Underage" Archive Warning will be recategorized automatically to display the new "Underage Sex" Archive Warning label instead. If you have a work that carries the "Underage" warning and you don't want it to display the "Underage Sex" label, you can replace it with the "Creator Chose Not to Use Archive Warnings" label at any time. + +You can learn more about the intended changes, access the full draft text, ask questions, and provide public feedback by visiting our news post about the 2024 Terms of Service updates: <%= admin_post_url(@admin_post) %>. +<% end %> diff --git a/app/views/troubleshooting/show.html.erb b/app/views/troubleshooting/show.html.erb new file mode 100755 index 0000000..e86d76c --- /dev/null +++ b/app/views/troubleshooting/show.html.erb @@ -0,0 +1,31 @@ +

    <%= t(".page_title.#{@item_type}") %>

    +

    <%= t(".page_description.#{@item_type}") %>

    + +<% if @item.is_a?(Tag) %> +

    <%= link_to @item.name, tag_path(@item) %> (<%= @item.type %>)

    +<% elsif @item.is_a?(Work) %> +
      + <%= render "works/work_blurb", work: @item %> +
    +<% end %> + +<%= form_tag troubleshooting_path, method: "patch" do %> +
    + <%= collection_check_boxes "", :actions, @allowed_actions, :to_s, :to_s do |builder| %> +
    + <%= builder.label do %> + <%= builder.check_box %> + <%= t(".#{builder.text}.title") %> + <% end %> +
    +
    + <%= t(".#{builder.text}.description") %> +
    + <% end %> +
    +
      +
    • + <%= submit_tag "Troubleshoot" %> +
    • +
    +<% end %> diff --git a/app/views/unsorted_tags/index.html.erb b/app/views/unsorted_tags/index.html.erb new file mode 100755 index 0000000..feb9609 --- /dev/null +++ b/app/views/unsorted_tags/index.html.erb @@ -0,0 +1,43 @@ + +

    <%= ts("Unsorted Tags") %>

    + + +<% if @tags %> + + <%= will_paginate @tags %> + + <%= form_tag mass_update_unsorted_tags_path do %> + +

    <%= submit_tag ts("Update") %>

    + + <%= hidden_field_tag :page, params[:page] %> + + "> + + + + + + + + + + <% @tags.each do |tag| %> + <% cache("unsorted-#{tag.cache_key}", skip_digest: true) do %> + + + + + + <% end %> + <% end %> + +
    <%= ts("Unsorted Tags") %>
    <%= ts("Tag") %><%= ts("Uses") %><%= ts("Category") %>
    <%= link_to tag.name, edit_tag_path(tag) %><%= link_to ts("Bookmarks (%{count})", :count => tag.bookmarks.count), tag_bookmarks_path(tag) %><%= select_tag "tags[#{tag.id}]", options_for_select(["", ts("Fandom"), ts("Character"), ts("Relationship"), ts("Freeform")]) %>
    + +

    <%= submit_tag ts("Update") %>

    + + <%= will_paginate @tags %> + + <% end %> + +<% end %> diff --git a/app/views/user_invite_requests/index.html.erb b/app/views/user_invite_requests/index.html.erb new file mode 100755 index 0000000..144118c --- /dev/null +++ b/app/views/user_invite_requests/index.html.erb @@ -0,0 +1,43 @@ +<% # this page is for administrators only, they cannot navigate to individual user pages %> +
    +

    <%= ts("User Invite Requests") %>

    +

    <%= ts("Enter \"0\" under quantity to deny the request. Clear the box to delay your decision for now.") %>

    +

    <%= ts("To give a user more invitations without a request, visit their individual invitations page.") %>

    + + + <%= will_paginate @user_invite_requests %> + + + + <%= form_tag url_for(:controller => 'user_invite_requests', :action => 'update'), method: :patch do %> + + + + + + + + + + + + + <% @user_invite_requests.each do |request| %> + + + + + + + <% end %> + +
    <%= ts('Allot Invites to Users') %>
    <%= ts('User') %><%= ts('Reason') %><%= ts('Quantity') %><%= ts('Created at') %><%= ts('Previous') %>
    <%= link_to request.user.login, request.user %><%= request.reason %><%= text_field_tag "requests[#{request.id}]", request.quantity, :size => 2, :id => "requests[#{request.user.login}]" %><%= request.created_at %> + <%= link_to_previous_invite_requests(request) %>
    +

    <%= submit_tag ts("Update") %><%= submit_tag ts("Decline All"), :name => 'decline_all', data: {confirm: "This will decline ALL requests. Are you sure?"} %>

    + <% end %> + + + + <%= will_paginate @user_invite_requests %> + +
    diff --git a/app/views/user_invite_requests/new.html.erb b/app/views/user_invite_requests/new.html.erb new file mode 100755 index 0000000..3c86c94 --- /dev/null +++ b/app/views/user_invite_requests/new.html.erb @@ -0,0 +1,26 @@ + +

    <%= ts("Request Invitations") %>

    +

    + <%= ts("We don't normally grant more than 3 invitations at a time for personal use, and the maximum you can request through this form is %{max}. Requests are manually reviewed and may take several days to be approved. Please ", :max => ArchiveConfig.MAX_USER_INVITE_REQUEST.to_s) %> + <%= link_to ts('contact Support'), new_feedback_report_path %> <%= ts("if you need more than 10 invitations for a challenge, or if your challenge or collection is opening soon.") %> +

    + + + +<%= render "invitations/user_invitations_navigation" %> + + + +<%= form_for(@user_invite_request) do |f| %> +

    <%= ts("* Required information") %>

    + <%= error_messages_for @user_invite_request %> +
    +
    <%= f.label :quantity, ts("How many invitations would you like? (max %{max})", :max => ArchiveConfig.MAX_USER_INVITE_REQUEST.to_s) + "*" %>
    +
    <%= f.text_field :quantity, :size => '2', :class => 'number' %>
    +
    <%= f.label :reason, ts("Please specify why you'd like them:") + "*" %>
    +
    <%= f.text_area :reason, :size => '50x5' %>
    +
    Submit
    +
    <%= f.submit ts("Send Request") %>
    +
    +<% end %> + diff --git a/app/views/user_mailer/_work_info.html.erb b/app/views/user_mailer/_work_info.html.erb new file mode 100755 index 0000000..096b7a2 --- /dev/null +++ b/app/views/user_mailer/_work_info.html.erb @@ -0,0 +1,24 @@ +<% # expects work %> +

    + <%= style_metadata_label(Work.human_attribute_name("chapter_total_display")) %><%= chapter_total_display(work) %> +
    <%= style_work_tag_metadata(work.tag_groups["Fandom"]) %> +
    <%= style_work_tag_metadata(work.tag_groups["Rating"]) %> +
    <%= style_work_tag_metadata(work.tag_groups["ArchiveWarning"]) %> + <% unless work.tag_groups["Relationship"].empty? %> +
    <%= style_work_tag_metadata(work.tag_groups["Relationship"]) %> + <% end %> + <% unless work.tag_groups["Character"].empty? %> +
    <%= style_work_tag_metadata(work.tag_groups["Character"]) %> + <% end %> + <% unless work.tag_groups["Freeform"].empty? %> +
    <%= style_work_tag_metadata(work.tag_groups["Freeform"]) %> + <% end %> + <% unless work.series.count.zero? %> +
    <%= style_metadata_label(Series.model_name.human(count: work.series.count)) %><%= series_list_for_feeds(work).html_safe %> + <% end %> +

    + +<% unless work.summary.blank? %> +

    <%= style_metadata_label(Work.human_attribute_name("summary")) %>

    + <%= style_quote(raw sanitize_field(work, :summary)) %> +<% end %> diff --git a/app/views/user_mailer/_work_info.text.erb b/app/views/user_mailer/_work_info.text.erb new file mode 100755 index 0000000..decbb00 --- /dev/null +++ b/app/views/user_mailer/_work_info.text.erb @@ -0,0 +1,22 @@ +<% # expects work %> +<%= metadata_label(Work.human_attribute_name("chapter_total_display"))%><%= chapter_total_display(work) %> +<%= work_tag_metadata(work.tag_groups["Fandom"]) %> +<%= work_tag_metadata(work.tag_groups["Rating"]) %> +<%= work_tag_metadata(work.tag_groups["ArchiveWarning"]) %> +<% unless work.tag_groups["Relationship"].empty? %> +<%= work_tag_metadata(work.tag_groups["Relationship"]) %> +<% end %> +<% unless work.tag_groups["Character"].empty? %> +<%= work_tag_metadata(work.tag_groups["Character"]) %> +<% end %> +<% unless work.tag_groups["Freeform"].empty? %> +<%= work_tag_metadata(work.tag_groups["Freeform"]) %> +<% end %> +<% unless work.series.count.zero? %> +<%= metadata_label(Series.model_name.human(count: work.series.count)) %><%= raw to_plain_text(series_list_for_feeds(work)) %> +<% end %> +<% unless work.summary.blank? %> + +<%= metadata_label(Work.human_attribute_name("summary")) %> + <%= raw to_plain_text(sanitize_field(work, :summary)) %> +<% end %> diff --git a/app/views/user_mailer/abuse_report.html.erb b/app/views/user_mailer/abuse_report.html.erb new file mode 100755 index 0000000..b493d29 --- /dev/null +++ b/app/views/user_mailer/abuse_report.html.erb @@ -0,0 +1,38 @@ +<% content_for :message do %> +

    + <% if @username.present? %> + <%= t("mailer.general.greeting.informal.addressed_html", name: style_bold(@username)) %>

    + <% else %> + <%= t("mailer.general.greeting.informal.unaddressed") %> +

    + <% end %> + +

    <%= t(".report_received") %>

    + +

    <%= t(".resubmission") %>

    + +

    <%= t(".copy.intro") %>

    + +

    + <%= style_metadata_label(t(".copy.url")) %><%= style_link(@url, @url) %> +

    + +

    + <%# TODO: Remove to_plain_text when AO3-6519 is fixed. %> + <%= style_metadata_label(t(".copy.summary")) %><%= to_plain_text(raw(@summary)) %> +

    + +

    <%= style_metadata_label(t(".copy.comment")) %>

    +

    <%= style_quote(raw(strip_images(@comment, keep_src: true))) %>

    + +

    <%= t(".thank_you") %>

    + +

    + <%= t("mailer.general.closing.formal") %>
    + <%= style_bold(t("mailer.general.signature.abuse_team")) %> +

    +<% end %> + +<% content_for :sent_at do %> + <%= l(Time.current) %> +<% end %> diff --git a/app/views/user_mailer/abuse_report.text.erb b/app/views/user_mailer/abuse_report.text.erb new file mode 100755 index 0000000..f42af34 --- /dev/null +++ b/app/views/user_mailer/abuse_report.text.erb @@ -0,0 +1,33 @@ +<% content_for :message do %> +<% if @username.present? %> +<%= t("mailer.general.greeting.informal.addressed_html", name: @username) %> +<% else %> +<%= t("mailer.general.greeting.informal.unaddressed") %> +<% end %> + +<%= t(".report_received") %> + +<%= t(".resubmission") %> + +<%= t(".copy.intro") %> + +<%= text_divider %> + +<%= metadata_label(t(".copy.url")) %> +<%= to_plain_text(@url) %> + +<%= metadata_label(t(".copy.summary")) %> +<%= to_plain_text(raw @summary) %> + +<%= metadata_label(t(".copy.comment")) %> +<%= to_plain_text(raw(strip_images(@comment, keep_src: true))) %> + +<%= text_divider %> + +<%= t(".thank_you") %> + +<%= t("mailer.general.closing.formal") %> +<%= t("mailer.general.signature.abuse_team") %> +<% end %> + +<% content_for :sent_at do %><%= l(Time.current) %><% end %> diff --git a/app/views/user_mailer/admin_deleted_work_notification.html.erb b/app/views/user_mailer/admin_deleted_work_notification.html.erb new file mode 100755 index 0000000..846be04 --- /dev/null +++ b/app/views/user_mailer/admin_deleted_work_notification.html.erb @@ -0,0 +1,11 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + +

    <%= t(".deleted.html", title: style_creation_title(@work.title)) %>

    + +

    <%= t(".import_project.html", opendoors_link: opendoors_link(t(".opendoors"))) %>

    + +

    <%= t(".tos_violation.html", contact_abuse_link: abuse_link(t(".contact_abuse"))) %>

    + +

    <%= t(".bye") %>

    +<% end %> diff --git a/app/views/user_mailer/admin_deleted_work_notification.text.erb b/app/views/user_mailer/admin_deleted_work_notification.text.erb new file mode 100755 index 0000000..0ddc7b1 --- /dev/null +++ b/app/views/user_mailer/admin_deleted_work_notification.text.erb @@ -0,0 +1,11 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<%= t(".deleted.text", title: @work.title) %> + +<%= t(".import_project.text", opendoors_link: "https://opendoors.transformativeworks.org/contact-open-doors/") %> + +<%= t(".tos_violation.text", contact_abuse_url: new_abuse_report_url) %> + +<%= t(".bye") %> +<% end %> diff --git a/app/views/user_mailer/admin_hidden_work_notification.html.erb b/app/views/user_mailer/admin_hidden_work_notification.html.erb new file mode 100755 index 0000000..fab73ff --- /dev/null +++ b/app/views/user_mailer/admin_hidden_work_notification.html.erb @@ -0,0 +1,22 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + + <% if @works.size == 1 %> +

    <%= t(".hidden_one.html", title: style_creation_link(@works.first.title, @works.first)) %>

    + <% else %> +

    <%= t(".hidden_multiple", count: @works.size) %>

    +
      + <% @works.each do |work| %> +
    • <%= style_creation_link(work.title, work) %>
    • + <% end %> +
    + <% end %> + +

    <%= t(".access", count: @works.size) %>

    + +

    <%= t(".check_email", count: @works.size) %>

    + +

    <%= t(".tos_violation.html", count: @works.size, tos_link: tos_link(t(".tos")), content_policy_link: style_link(t(".content_policy"), content_url), tos_faq_link: style_link(t(".tos_faq"), tos_faq_url(anchor: "policy_procedures_faq"))) %>

    + +

    <%= t(".help.html", count: @works.size, contact_abuse_link: abuse_link(t(".contact_abuse"))) %>

    +<% end %> diff --git a/app/views/user_mailer/admin_hidden_work_notification.text.erb b/app/views/user_mailer/admin_hidden_work_notification.text.erb new file mode 100755 index 0000000..d8c971b --- /dev/null +++ b/app/views/user_mailer/admin_hidden_work_notification.text.erb @@ -0,0 +1,20 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<% if @works.size == 1 %> +<%= t(".hidden_one.text", title: @works.first.title, work_url: work_url(@works.first)) %> +<% else %> +<%= t(".hidden_multiple", count: @works.size) %> +<% @works.each do |work| %> +<%= t(".work_info", title: work.title, work_url: work_url(work)) %> +<% end %> +<% end %> + +<%= t(".access", count: @works.size) %> + +<%= t(".check_email", count: @works.size) %> + +<%= t(".tos_violation.text", count: @works.size, tos_url: tos_url, content_policy_url: content_url, tos_faq_url: tos_faq_url(anchor: "policy_procedures_faq")) %> + +<%= t(".help.text", count: @works.size, contact_abuse_url: new_abuse_report_url) %> +<% end %> diff --git a/app/views/user_mailer/admin_spam_work_notification.html.erb b/app/views/user_mailer/admin_spam_work_notification.html.erb new file mode 100755 index 0000000..91616c3 --- /dev/null +++ b/app/views/user_mailer/admin_spam_work_notification.html.erb @@ -0,0 +1,9 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + +

    <%= t(".flagged_as_spam.html", work_link: style_creation_link(@work.title, @work)) %>

    + +

    <%= t(".future") %>

    + +

    <%= t(".questions.html", contact_abuse_link: abuse_link(t(".contact_abuse"))) %>

    +<% end %> diff --git a/app/views/user_mailer/admin_spam_work_notification.text.erb b/app/views/user_mailer/admin_spam_work_notification.text.erb new file mode 100755 index 0000000..4b33211 --- /dev/null +++ b/app/views/user_mailer/admin_spam_work_notification.text.erb @@ -0,0 +1,9 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<%= t(".flagged_as_spam.text", work_title: @work.title, work_url: work_url(@work)) %> + +<%= t(".future") %> + +<%= t(".questions.text", contact_abuse_url: new_abuse_report_url) %> +<% end %> diff --git a/app/views/user_mailer/anonymous_or_unrevealed_notification.html.erb b/app/views/user_mailer/anonymous_or_unrevealed_notification.html.erb new file mode 100755 index 0000000..0d0f582 --- /dev/null +++ b/app/views/user_mailer/anonymous_or_unrevealed_notification.html.erb @@ -0,0 +1,26 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + +

    <%= t(".changed_status.#{@status}.html", + collection_link: style_link(@collection.title, collection_url(@collection)), + work_link: style_creation_link(@work.title, work_url(@work))) %>

    + + <% if @becoming_anonymous && @becoming_unrevealed %> +

    <%= t(".unrevealed_info") %>

    + +

    <%= t(".anonymous_unrevealed_info") %>

    + <% elsif @becoming_anonymous %> +

    <%= t(".anonymous_info") %>

    + <% else %> +

    <%= t(".unrevealed_info") %>

    + <% end %> + +

    <%= t(".do_not_want.#{@status}.html", + collection_items_link: style_link(t(".collection_items_link_text"), + user_collection_items_url(@user, status: "approved"))) %>

    + +

    <%= t(".more_info.html", + faq_link: style_link(t(".faq_link_text"), + archive_faq_url("collections", + anchor: :collectionoptions))) %>

    +<% end %> diff --git a/app/views/user_mailer/anonymous_or_unrevealed_notification.text.erb b/app/views/user_mailer/anonymous_or_unrevealed_notification.text.erb new file mode 100755 index 0000000..5d0545c --- /dev/null +++ b/app/views/user_mailer/anonymous_or_unrevealed_notification.text.erb @@ -0,0 +1,26 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<%= t(".changed_status.#{@status}.text", + collection_title: @collection.title, + collection_url: collection_url(@collection), + work_title: @work.title, + work_url: work_url(@work)) %> + +<% if @becoming_anonymous && @becoming_unrevealed %> +<%= t(".unrevealed_info") %> + +<%= t(".anonymous_unrevealed_info") %> +<% elsif @becoming_anonymous %> +<%= t(".anonymous_info") %> +<% else %> +<%= t(".unrevealed_info") %> +<% end %> + +<%= t(".do_not_want.#{@status}.text", + collection_items_url: user_collection_items_url(@user, status: "approved")) %> + +<%= t(".more_info.text", + faq_url: archive_faq_url("collections", + anchor: :collectionoptions)) %> +<% end %> diff --git a/app/views/user_mailer/archivist_added_to_collection_notification.html.erb b/app/views/user_mailer/archivist_added_to_collection_notification.html.erb new file mode 100755 index 0000000..cf68aaa --- /dev/null +++ b/app/views/user_mailer/archivist_added_to_collection_notification.html.erb @@ -0,0 +1,16 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + +

    + <%= t(".work_added.html", + collection_link: style_link(@collection.title, collection_url(@collection)), + work_link: style_creation_link(@work.title, work_url(@work))) %> +

    + +

    <%= t(".archivist_notice") %>

    + +

    + <%= t(".removal_instructions.html", + approved_items_link: style_link(t(".approved_collection_items_page"), user_collection_items_url(@user, status: "approved"))) %> +

    +<% end %> diff --git a/app/views/user_mailer/archivist_added_to_collection_notification.text.erb b/app/views/user_mailer/archivist_added_to_collection_notification.text.erb new file mode 100755 index 0000000..4ace282 --- /dev/null +++ b/app/views/user_mailer/archivist_added_to_collection_notification.text.erb @@ -0,0 +1,15 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<%= t(".work_added.text", + collection_title: @collection.title, + collection_url: collection_url(@collection), + work_title: @work.title, + work_url: work_url(@work)) %> + +<%= t(".archivist_notice") %> + +<%= t(".removal_instructions.text", + approved_items_url: user_collection_items_url(@user, status: "approved")) %> + +<% end %> diff --git a/app/views/user_mailer/batch_subscription_notification.html.erb b/app/views/user_mailer/batch_subscription_notification.html.erb new file mode 100755 index 0000000..b691420 --- /dev/null +++ b/app/views/user_mailer/batch_subscription_notification.html.erb @@ -0,0 +1,77 @@ +<% content_for :message do %> + <% @seen = {} %> + <% @seen_summary = {} %> + <% @creations.each_with_index do |creation, index| %> + + <% this_work = creation.respond_to?(:work) ? creation.work : creation %> + <% work_link = style_link(this_work.title, work_url(this_work)) %> + + <% cache("subscription-email-preface-#{creation.cache_key}") do %> + <%= creator_links(this_work) %> posted a + <% if creation.is_a?(Work) %> + <%= this_work.backdate ? "backdated" : "new" %> work: + <% else %> + new chapter of <%= work_link %> (<%= this_work.word_count %> words): + <% end %> + <% end %> + +

    + + <%= style_bold(creation.is_a?(Work) ? work_link : + style_link(creation.full_chapter_title.html_safe, work_chapter_url(this_work, creation))) %> + (<%= creation.word_count%> words) + + <% unless @seen[this_work.id] %> +
    + + by <%= creator_links(this_work) %> + <% end %> +

    + + <% if creation.summary.present? && creation.is_a?(Chapter) %> +

    <%= style_bold("Chapter Summary:") %>

    + <%= style_quote(raw sanitize_field(creation, :summary)) %> + <% end %> + + <% unless @seen[this_work.id] %> + <% cache("subscription-email-meta-#{creation.cache_key}") do %> +

    + <%= style_bold("Chapters:") %> <%= chapter_total_display(this_work) %> +
    <%= style_bold("Fandom:") %> <%= this_work.fandoms.map{|f| style_link(f.name, fandom_url(f))}.to_sentence.html_safe %> +
    <%= style_bold("Rating:") %> <%= this_work.rating_string %> +
    <%= style_bold("Warnings:") %> <%= this_work.archive_warning_string %> + <% if this_work.relationship_string && !this_work.relationship_string.blank? %> +
    <%= style_bold("Relationships:") %> <%= this_work.relationship_string %> + <% end %> + <% if this_work.character_string && !this_work.character_string.blank? %> +
    <%= style_bold("Characters:") %> <%= this_work.character_string %> + <% end %> + <% if this_work.freeform_string && !this_work.freeform_string.blank? %> +
    <%= style_bold("Additional Tags:") %> <%= this_work.freeform_string %> + <% end %> + <% if this_work.series.count > 0 %> +
    <%= style_bold("Series:") %> <%= series_list_for_feeds(this_work).html_safe %> + <% end %> +

    + <% end %> + + <% @seen[this_work.id] = true %> + <% end %> + + <% unless @seen_summary[this_work.id] || this_work.summary.blank? %> +

    <%= style_bold("Summary:") %>

    + <%= style_quote(raw sanitize_field(this_work, :summary)) %> + <% @seen_summary[this_work.id] = true %> + <% end %> + + <% if (index < @creations.length-1) %> + <%= styled_divider %> + <% end %> + + <% end %> +<% end %> + + +<% content_for :footer_note do %> + You're receiving this email because you've subscribed to <%= style_footer_link(@subscription.name, polymorphic_url(@subscription.subscribable)) %>. Follow the link to unsubscribe if you no longer wish to receive updates. +<% end %> diff --git a/app/views/user_mailer/batch_subscription_notification.text.erb b/app/views/user_mailer/batch_subscription_notification.text.erb new file mode 100755 index 0000000..fe090aa --- /dev/null +++ b/app/views/user_mailer/batch_subscription_notification.text.erb @@ -0,0 +1,40 @@ +<% content_for :message do %> +<% @seen = {} %> +<% @seen_summary = {} %> +<% @creations.each_with_index do |creation, index| %> +<% this_work = creation.respond_to?(:work) ? creation.work : creation %> +<% cache "subscription-email-txt-preface-#{creation.cache_key}" do %> +<%= creator_text(this_work) %> posted a <% if creation.is_a?(Work) then %><%= this_work.backdate ? "backdated" : "new" %> work:<% else %>new chapter of <%= this_work.title %> (<%= this_work.word_count %> words):<% end %> +<%= creation.is_a?(Work) ? work_url(this_work) : work_chapter_url(this_work, creation) %> +<% end %> + +<%= creation.is_a?(Work) ? this_work.title : creation.full_chapter_title.html_safe %> (<%= creation.word_count%> words)<% unless @seen[this_work.id] %> +by <%= creator_text(this_work) %><% end %> + +<% if !creation.summary.blank? && creation.is_a?(Chapter) %> +Chapter Summary: <%= raw to_plain_text(sanitize_field(creation, :summary)) %> +<% end %> + +<% unless @seen[this_work.id] %> +<% cache "subscription-email-txt-meta-#{creation.cache_key}" do %> +Chapters: <%= chapter_total_display(this_work) %> +Fandom: <%= this_work.fandoms.map{|f| f.name}.to_sentence.html_safe %> +Rating: <%= this_work.rating_string %> +Warnings: <%= this_work.archive_warning_string %> +<% if this_work.relationship_string && !this_work.relationship_string.blank? then %>Relationships: <%= this_work.relationship_string %><% end %> +<% if this_work.character_string && !this_work.character_string.blank? then %>Characters: <%= this_work.character_string %><% end %> +<% if this_work.freeform_string && !this_work.freeform_string.blank? %>Additional Tags: <%= this_work.freeform_string %><% end %> +<% if this_work.series.count > 0 %>Series: <%=raw to_plain_text(series_list_for_feeds(this_work)) %><% end %> +<% end %><% @seen[this_work.id] = true %><% end %> + +<% unless @seen_summary[this_work.id] || this_work.summary.blank? %> +Summary: + <%= raw to_plain_text(sanitize_field(this_work, :summary)) %><% @seen_summary[this_work.id] = true %><% end %><% if (index < @creations.length-1) %> + +<%= text_divider %> + +<% end %><% end %><% end %> + +<% content_for :footer_note do %> +You're receiving this email because you've subscribed to <%= @subscription.name %>. Follow the link to unsubscribe if you no longer wish to receive updates: <%= polymorphic_url(@subscription.subscribable) %> +<% end %> diff --git a/app/views/user_mailer/challenge_assignment_notification.html.erb b/app/views/user_mailer/challenge_assignment_notification.html.erb new file mode 100755 index 0000000..f00e34c --- /dev/null +++ b/app/views/user_mailer/challenge_assignment_notification.html.erb @@ -0,0 +1,93 @@ +<% content_for :message do %> +

    <%= t(".assignment.html", link: style_link(@collection.title, collection_url(@collection))) %>

    + +

    + <%= style_metadata_label(t(".recipient")) %><%= @request.nil? ? t(".recipient_missing") : style_link(@request.pseud.byline, user_pseud_url(@request.pseud.user, @request.pseud)) %> +

    + + <%= style_bold(t(".prompts")) %> + + <% @request.requests.each_with_index do |prompt, index| %> + <% tag_groups = prompt.tag_groups %> + + <% def styled_tag_list(tags) %> + <% return nil if !tags || tags.empty? %> + <% to_sentence(tags.map { |tag| style_link(tag.name, tag_works_url(tag)) }) %> + <% end %> + + <% fandoms = prompt.any_fandom ? t(".any") : styled_tag_list(tag_groups["Fandom"]) %> + <% chars = prompt.any_character ? t(".any") : styled_tag_list(tag_groups["Character"]) %> + <% ships = prompt.any_relationship ? t(".any") : styled_tag_list(tag_groups["Relationship"]) %> + <% ratings = prompt.any_rating ? t(".any") : (tag_groups["Rating"] ? get_title_string(tag_groups["Rating"]) : nil) %> + <% warnings = prompt.any_archive_warning ? t(".any") : (tag_groups["ArchiveWarning"] ? get_title_string(tag_groups["ArchiveWarning"]) : nil) %> + <% categories = prompt.any_category ? t(".any") : (tag_groups["Category"] ? get_title_string(tag_groups["Category"]) : nil) %> + <% atags = prompt.any_freeform ? t(".any") : styled_tag_list(tag_groups["Freeform"]) %> + <% otags = prompt.optional_tag_set ? styled_tag_list(prompt.optional_tag_set.tags) : nil %> + + <%= styled_divider %> + <%= index + 1 %>. <%= style_bold(prompt.title) %> + +

    + <% if fandoms %> + <%= style_metadata_label(t("activerecord.models.fandom", count: prompt.any_fandom ? 1 : tag_groups["Fandom"].count)) %><%= fandoms %> +
    + <% end %> + <% if chars %> + <%= style_metadata_label(t("activerecord.models.character", count: prompt.any_character ? 1 : tag_groups["Character"].count)) %><%= chars %> +
    + <% end %> + <% if ships %> + <%= style_metadata_label(t("activerecord.models.relationship", count: prompt.any_relationship ? 1 : tag_groups["Relationship"].count)) %><%= ships %> +
    + <% end %> + <% if ratings %> + <%= style_metadata_label(t("activerecord.models.rating", count: prompt.any_rating ? 1 : tag_groups["Rating"].count)) %><%= ratings %> +
    + <% end %> + <% if warnings %> + <%= style_metadata_label(t("activerecord.models.archive_warning", count: prompt.any_archive_warning ? 1 : tag_groups["ArchiveWarning"].count)) %><%= warnings %> +
    + <% end %> + <% if categories %> + <%= style_metadata_label(t("activerecord.models.category", count: prompt.any_category ? 1 : tag_groups["Category"].count)) %><%= categories %> +
    + <% end %> + <% if atags %> + <%= style_metadata_label(t("activerecord.models.freeform", count: prompt.any_freeform ? 1 : tag_groups["Freeform"].count)) %><%= atags %> +
    + <% end %> + <% if otags %> + <%= style_metadata_label(t(".optional_tags")) %><%= otags %> +
    + <% end %> + <% if prompt.url && !prompt.url.blank? %> + <%= style_metadata_label(t(".prompt_url")) %><%= style_link(prompt.url, prompt.url) %> +
    + <% end %> + <% if prompt.description && !prompt.description.blank? %> + <%= style_metadata_label(t(".description")) %> + <%= style_quote(prompt.description) %> + <% end %> +

    + <% end %> + + <%= styled_divider %> + +

    + <%= style_metadata_label(t(".due")) %><%= time_in_zone(@collection.challenge.assignments_due_at, (@collection.challenge.time_zone || Time.zone.name), @assigned_user) %>. +

    + +

    <%= t(".look_up.html", your_assignments_link: style_link(t(".look_up.your_assignments"), user_assignments_url(@assigned_user))) %>

    + + <% if @collection && !@collection.assignment_notification.blank? %> +

    <%= escape_html_and_create_linebreaks(@collection.assignment_notification) %>

    + <% end %> +<% end %> + +<% content_for :footer_note do %> + <%= t(".footer.html", title: style_footer_link(@collection.title, collection_url(@collection)), challenge_profile_link: style_footer_link(t(".footer.challenge_profile"), collection_profile_url(@collection))) %> +<% end %> + +<% content_for :sent_at do %> + <%= l(@assignment.sent_at) %> +<% end %> diff --git a/app/views/user_mailer/challenge_assignment_notification.text.erb b/app/views/user_mailer/challenge_assignment_notification.text.erb new file mode 100755 index 0000000..2149651 --- /dev/null +++ b/app/views/user_mailer/challenge_assignment_notification.text.erb @@ -0,0 +1,71 @@ +<% content_for :message do %> +<%= t(".assignment.text", collection_title: @collection.title, collection_url: collection_url(@collection)) %> + +<%= metadata_label(t(".recipient")) %><%= @request.nil? ? t(".recipient_missing") : text_pseud(@request.pseud) %> + +<%= t(".prompts") %> +<% @request.requests.each_with_index do |prompt, index| %> +<% tag_groups = prompt.tag_groups %> +<% def tag_list(tags) %> +<% return nil if !tags || tags.empty? %> +<% tags.map { |tag| tag.name }.to_sentence.html_safe %> +<% end %> +<% fandoms = prompt.any_fandom ? t(".any") : tag_list(tag_groups["Fandom"]) %> +<% chars = prompt.any_character ? t(".any") : tag_list(tag_groups["Character"]) %> +<% ships = prompt.any_relationship ? t(".any") : tag_list(tag_groups["Relationship"]) %> +<% ratings = prompt.any_rating ? t(".any") : (tag_groups["Rating"] ? get_title_string(tag_groups["Rating"]) : nil) %> +<% warnings = prompt.any_archive_warning ? t(".any") : (tag_groups["ArchiveWarning"] ? get_title_string(tag_groups["ArchiveWarning"]) : nil) %> +<% categories = prompt.any_category ? t(".any") : (tag_groups["Category"] ? get_title_string(tag_groups["Category"]) : nil) %> +<% atags = prompt.any_freeform ? t(".any") : tag_list(tag_groups["Freeform"]) %> +<% otags = prompt.optional_tag_set ? tag_list(prompt.optional_tag_set.tags) : nil %> +<%= text_divider %> + +<%= index + 1 %>. <%= prompt.title %> + +<% if fandoms %> +<%= metadata_label(t("activerecord.models.fandom", count: prompt.any_fandom ? 1 : tag_groups["Fandom"].count)) %><%= fandoms %> +<% end %> +<% if chars %> +<%= metadata_label(t("activerecord.models.character", count: prompt.any_character ? 1 : tag_groups["Character"].count)) %><%= chars %> +<% end %> +<% if ships %> +<%= metadata_label(t("activerecord.models.relationship", count: prompt.any_relationship ? 1 : tag_groups["Relationship"].count)) %><%= ships %> +<% end %> +<% if ratings %> +<%= metadata_label(t("activerecord.models.rating", count: prompt.any_rating ? 1 : tag_groups["Rating"].count)) %><%= ratings %> +<% end %> +<% if warnings %> +<%= metadata_label(t("activerecord.models.archive_warning", count: prompt.any_archive_warning ? 1 : tag_groups["ArchiveWarning"].count)) %><%= warnings %> +<% end %> +<% if categories %> +<%= metadata_label(t("activerecord.models.category", count: prompt.any_category ? 1 : tag_groups["Category"].count)) %><%= categories %> +<% end %> +<% if atags %> +<%= metadata_label(t("activerecord.models.freeform", count: prompt.any_freeform ? 1 : tag_groups["Freeform"].count)) %><%= atags %> +<% end %> +<% if otags %> +<%= metadata_label(t(".optional_tags")) %><%= otags %> +<% end %> +<% if prompt.url && !prompt.url.blank? %> +<%= metadata_label(t(".prompt_url")) %><%= prompt.url %> +<% end %> +<% if prompt.description && !prompt.description.blank? %> +<%= metadata_label(t(".description")) %> + <%= to_plain_text(prompt.description) %> +<% end %> + +<% end %><%= text_divider %> + +<%= metadata_label(t(".due")) %><%= to_plain_text(time_in_zone(@collection.challenge.assignments_due_at, (@collection.challenge.time_zone || Time.zone.name), @assigned_user)).gsub(/\n\s*/, "") %>. + +<%= t(".look_up.text", your_assignments_url: user_assignments_url(@assigned_user)) %> +<% if @collection && !@collection.assignment_notification.blank? %> + + +<%= @collection.assignment_notification %><% end %><% end %> +<% content_for :footer_note do %> +<%= t(".footer.text", title: @collection.title, url: collection_url(@collection), challenge_profile_url: collection_profile_url(@collection)) -%> +<% end %> +<% content_for :sent_at do %> +<%= l(@assignment.sent_at) -%> +<% end %> diff --git a/app/views/user_mailer/change_email.html.erb b/app/views/user_mailer/change_email.html.erb new file mode 100755 index 0000000..f95039b --- /dev/null +++ b/app/views/user_mailer/change_email.html.erb @@ -0,0 +1,14 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + +

    <%= t(".made_request", app_name: ArchiveConfig.APP_SHORT_NAME) %>

    + +

    <%= t(".confirm_change.html", unconfirmed_email: style_email(@new_email), count: User.confirm_within.in_days.to_i, contact_support_link: style_link(t(".contact_support"), new_feedback_report_url)) %>

    + +

    <%= t(".wrong_email.html", email_change_form_link: style_link(t(".email_change_form"), change_email_user_url(@user))) %>

    + +

    <%= t(".not_made_request.html", + reset_password_link: style_link(t(".reset_password"), new_user_password_url), + contact_policy_abuse_link: style_link(t(".contact_policy_abuse"), new_abuse_report_url), + app_name: ArchiveConfig.APP_SHORT_NAME) %>

    +<% end %> diff --git a/app/views/user_mailer/change_email.text.erb b/app/views/user_mailer/change_email.text.erb new file mode 100755 index 0000000..0f64121 --- /dev/null +++ b/app/views/user_mailer/change_email.text.erb @@ -0,0 +1,14 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<%= t(".made_request", app_name: ArchiveConfig.APP_SHORT_NAME) %> + +<%= t(".confirm_change.text", unconfirmed_email: @new_email, count: User.confirm_within.in_days.to_i, contact_support_url: new_feedback_report_url) %> + +<%= t(".wrong_email.text", email_change_form_url: change_email_user_url(@user)) %> + +<%= t(".not_made_request.text", + reset_password_url: new_user_password_url, + contact_policy_abuse_url: new_abuse_report_url, + app_name: ArchiveConfig.APP_SHORT_NAME) %> +<% end %> diff --git a/app/views/user_mailer/change_username.html.erb b/app/views/user_mailer/change_username.html.erb new file mode 100755 index 0000000..848a0be --- /dev/null +++ b/app/views/user_mailer/change_username.html.erb @@ -0,0 +1,22 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.unaddressed") %>

    + +

    <%= t(".changed_html", + app_name: ArchiveConfig.APP_SHORT_NAME, + old_username: style_bold(@old_username), + new_username: style_bold(@new_username)) %>

    + +

    <%= t(".effects.html", + refer_faq_link: style_link(t(".refer_faq"), archive_faq_url("your-account", anchor: "changenameaffect")), + contact_support_link: support_link(t(".contact_support"))) %>

    + +

    <%= t(".change_cooldown_html", + app_name: ArchiveConfig.APP_SHORT_NAME, + count: ArchiveConfig.USER_RENAME_LIMIT_DAYS, + date: l(@next_change_time)) %>

    + +

    <%= t(".did_not_make_change.html", + reset_password_link: style_link(t(".reset_password"), new_user_password_url), + contact_policy_abuse_link: abuse_link(t(".contact_policy_abuse")), + app_name: ArchiveConfig.APP_SHORT_NAME) %>

    +<% end %> diff --git a/app/views/user_mailer/change_username.text.erb b/app/views/user_mailer/change_username.text.erb new file mode 100755 index 0000000..af00455 --- /dev/null +++ b/app/views/user_mailer/change_username.text.erb @@ -0,0 +1,22 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.unaddressed") %> + +<%= t(".changed_html", + app_name: ArchiveConfig.APP_SHORT_NAME, + old_username: @old_username, + new_username: @new_username) %> + +<%= t(".effects.text", + refer_faq_url: archive_faq_url("your-account", anchor: "changenameaffect"), + contact_support_url: new_feedback_report_url) %> + +<%= t(".change_cooldown_html", + app_name: ArchiveConfig.APP_SHORT_NAME, + count: ArchiveConfig.USER_RENAME_LIMIT_DAYS, + date: l(@next_change_time)) %> + +<%= t(".did_not_make_change.text", + reset_password_url: new_user_password_url, + contact_policy_abuse_url: new_abuse_report_url, + app_name: ArchiveConfig.APP_SHORT_NAME) %> +<% end %> diff --git a/app/views/user_mailer/claim_notification.html.erb b/app/views/user_mailer/claim_notification.html.erb new file mode 100755 index 0000000..9657568 --- /dev/null +++ b/app/views/user_mailer/claim_notification.html.erb @@ -0,0 +1,41 @@ +<% content_for :message do %> +

    + <%= t("mailer.general.greeting.introductory") %> +

    + +

    <%= t(".introduction.html", open_doors_name_link: style_link(t(".introduction.open_doors_name"), "https://opendoors.transformativeworks.org"), app_link: style_link(t(".introduction.ao3_name"), root_url)) %>

    + +

    <%= t(".more_info.html", ao3_news_link: style_link(t(".more_info.ao3_news"), admin_posts_url(tag: 18)), faq_page_link: style_link(t(".more_info.faq_page"), "https://opendoors.transformativeworks.org/faq"), tutorial_page_link: style_link(t(".more_info.tutorial_page"), "https://opendoors.transformativeworks.org/tutorials"), contact_support_link: support_link(t(".more_info.contact_support"))) %>

    + +

    <%= t(".mistake.html", contact_open_doors_link: opendoors_link(t(".mistake.contact_open_doors"))) %>

    + +

    <%= t(".access.html", contact_support_link: support_link(t(".access.contact_support"))) %>

    + +

    <%= t(".works_by", email: @external_email) %>

    + +
      + <% @claimed_works.each do |work| %> +
    • + <% if work.fandom_string.present? %> + <%= t(".work_info.html", work_link: style_link(work.title, work_url(work)), fandom: work.fandom_string.split(",").to_sentence) %> + <% else %> + <%= style_link(work.title, work_url(work)) %> + <% end %> +
    • + <% end %> +
    + +

    <%= t(".redirects.html", negation: style_bold(t(".redirects.negation"))) %>

    + +

    <%= t(".update_redirect.html", contact_open_doors_link: opendoors_link(t(".update_redirect.contact_open_doors"))) %>

    + +

    <%= t(".other_works.html", contact_open_doors_link: opendoors_link(t(".other_works.contact_open_doors"))) %>

    + +

    <%= t(".questions.html", contact_support_link: support_link(t(".questions.contact_support"))) %>

    + +

    <%= t(".email_tips") %>

    + +

    <%= t("mailer.general.closing.informal") %>
    + <%= style_bold(t("mailer.general.signature.open_doors")) %>
    + <%= style_bold(t("mailer.general.signature.parent_org")) %>

    +<% end %> diff --git a/app/views/user_mailer/claim_notification.text.erb b/app/views/user_mailer/claim_notification.text.erb new file mode 100755 index 0000000..bb876ab --- /dev/null +++ b/app/views/user_mailer/claim_notification.text.erb @@ -0,0 +1,34 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.introductory") %> + +<%= t(".introduction.text", open_doors_url: "https://opendoors.transformativeworks.org", app_url: root_url) %> + +<%= t(".more_info.text", news_url: admin_posts_url(tag: 18), open_doors_faq_url: "https://opendoors.transformativeworks.org/faq", open_doors_tutorial_url: "https://opendoors.transformativeworks.org/tutorials", support_url: new_feedback_report_url) %> + +<%= t(".mistake.text", open_doors_url: "https://opendoors.transformativeworks.org/en/contact-open-doors/") %> + +<%= t(".access.text", support_url: new_feedback_report_url) %> + +<%= t(".works_by", email: @external_email) %> +<% @claimed_works.each do |work| %> + <% if work.fandom_string.present? %> +<%= t(".work_info.text.with_fandom", work_title: work.title, work_url: work_url(work), fandom: work.fandom_string.split(",").to_sentence) %> + <% else %> +<%= t(".work_info.text.no_fandom", work_title: work.title, work_url: work_url(work)) %> + <% end %> +<% end %> + +<%= t(".redirects.html", negation: t(".redirects.negation")) %> + +<%= t(".update_redirect.text", open_doors_url: "https://opendoors.transformativeworks.org/en/contact-open-doors/") %> + +<%= t(".other_works.text") %> + +<%= t(".questions.text", support_url: new_feedback_report_url) %> + +<%= t(".email_tips") %> + +<%= t("mailer.general.closing.informal") %> +<%= t("mailer.general.signature.open_doors") %> +<%= t("mailer.general.signature.parent_org") %> +<% end %> diff --git a/app/views/user_mailer/collection_notification.html.erb b/app/views/user_mailer/collection_notification.html.erb new file mode 100755 index 0000000..d8b6a9f --- /dev/null +++ b/app/views/user_mailer/collection_notification.html.erb @@ -0,0 +1,12 @@ +<% content_for :message do %> + +

    + <%= t(".html.received_message", collection_link: style_link(@collection.title, collection_url(@collection))).html_safe %> +

    + + <%= style_quote(raw @message) %> +<% end %> + +<% content_for :sent_at do %> + <%= l(Time.current) %> +<% end %> diff --git a/app/views/user_mailer/collection_notification.text.erb b/app/views/user_mailer/collection_notification.text.erb new file mode 100755 index 0000000..f8624bb --- /dev/null +++ b/app/views/user_mailer/collection_notification.text.erb @@ -0,0 +1,8 @@ +<% content_for :message do %> +<%= t(".text.received_message", collection_title: @collection.title, collection_url: collection_url(@collection)) %> +<%= text_divider %> + +<%= raw @message %> + +<% end %> +<% content_for :sent_at do %><%= l(Time.current) %><% end %> diff --git a/app/views/user_mailer/creatorship_notification.html.erb b/app/views/user_mailer/creatorship_notification.html.erb new file mode 100755 index 0000000..1f6fcbf --- /dev/null +++ b/app/views/user_mailer/creatorship_notification.html.erb @@ -0,0 +1,26 @@ +<% creation_type = @creation.class.name.underscore %> +<% content_for :message do %> +

    + <%# i18n-tasks-use t('user_mailer.creatorship_notification.intro_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification.intro_series')-%> + <%= t(".intro_#{creation_type}", adding_user: @adding_user.login, pseud: @creatorship.pseud.name) %> +

    + +

    + <%= t(".html.creation", + creation_link: "#{style_link(creation_title(@creation), polymorphic_url(@creation))}".html_safe, + pseud_links: @creation.pseuds.map{ |p| style_pseud_link(p) }.to_sentence.html_safe).html_safe %> +

    + +

    + <%= t ".explanation" %> +

    + +

    + <%# i18n-tasks-use t('user_mailer.creatorship_notification.html.remove_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification.html.remove_series') + i18n-tasks-use t('user_mailer.creatorship_notification.html.edit_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification.html.edit_series')-%> + <%= t(".html.remove_#{creation_type}", "edit_#{creation_type}_link": style_link(t(".html.edit_#{creation_type}"), edit_polymorphic_url(@creation))).html_safe %> +

    +<% end %> diff --git a/app/views/user_mailer/creatorship_notification.text.erb b/app/views/user_mailer/creatorship_notification.text.erb new file mode 100755 index 0000000..153cd53 --- /dev/null +++ b/app/views/user_mailer/creatorship_notification.text.erb @@ -0,0 +1,16 @@ +<% creation_type = @creation.class.name.underscore %> +<% content_for :message do %> +<%# i18n-tasks-use t('user_mailer.creatorship_notification.intro_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification.intro_series')-%> +<%= t(".intro_#{creation_type}", adding_user: @adding_user.login, pseud: @creatorship.pseud.name) %> + +<%= t ".text.creation", title: creation_title(@creation), + url: polymorphic_url(@creation), + pseuds: @creation.pseuds.map(&:byline).to_sentence %> + +<%= t ".explanation" %> + +<%# i18n-tasks-use t('user_mailer.creatorship_notification.text.remove_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification.text.remove_series')-%> +<%= t(".text.remove_#{creation_type}", url: edit_polymorphic_url(@creation)) %> +<% end %> diff --git a/app/views/user_mailer/creatorship_notification_archivist.html.erb b/app/views/user_mailer/creatorship_notification_archivist.html.erb new file mode 100755 index 0000000..9868d6a --- /dev/null +++ b/app/views/user_mailer/creatorship_notification_archivist.html.erb @@ -0,0 +1,27 @@ +<% creation_type = @creation.class.name.underscore %> +<% content_for :message do %> +

    + <%# i18n-tasks-use t('user_mailer.creatorship_notification_archivist.intro_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.intro_series') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.intro_work')-%> + <%= t(".intro_#{creation_type}", archivist: @archivist.login, pseud: @creatorship.pseud.name) %> +

    + +

    + <%= t(".html.creation", + creation_link: "#{style_link(creation_title(@creation), polymorphic_url(@creation))}".html_safe, + pseud_links: @creation.pseuds.map{ |p| style_pseud_link(p) }.to_sentence.html_safe).html_safe %> +

    + +

    <%= t(".explanation") %>

    + +

    + <%# i18n-tasks-use t('user_mailer.creatorship_notification_archivist.html.remove_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.html.remove_series') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.html.remove_work') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.html.edit_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.html.edit_series') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.html.edit_work')-%> + <%= t(".html.remove_#{creation_type}", "edit_#{creation_type}_link": style_link(t(".html.edit_#{creation_type}"), edit_polymorphic_url(@creation))).html_safe %> +

    +<% end %> diff --git a/app/views/user_mailer/creatorship_notification_archivist.text.erb b/app/views/user_mailer/creatorship_notification_archivist.text.erb new file mode 100755 index 0000000..4054525 --- /dev/null +++ b/app/views/user_mailer/creatorship_notification_archivist.text.erb @@ -0,0 +1,18 @@ +<% creation_type = @creation.class.name.underscore %> +<% content_for :message do %> +<%# i18n-tasks-use t('user_mailer.creatorship_notification_archivist.intro_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.intro_series') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.intro_work')-%> +<%= t(".intro_#{creation_type}", archivist: @archivist.login, pseud: @creatorship.pseud.name) %> + +<%= t ".text.creation", title: creation_title(@creation), + url: polymorphic_url(@creation), + pseuds: @creation.pseuds.map(&:byline).to_sentence %> + +<%= t(".explanation") %> + +<%# i18n-tasks-use t('user_mailer.creatorship_notification_archivist.text.remove_chapter') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.text.remove_series') + i18n-tasks-use t('user_mailer.creatorship_notification_archivist.text.remove_work')-%> +<%= t(".text.remove_#{creation_type}", url: edit_polymorphic_url(@creation)) %> +<% end %> diff --git a/app/views/user_mailer/creatorship_request.html.erb b/app/views/user_mailer/creatorship_request.html.erb new file mode 100755 index 0000000..d29cd8e --- /dev/null +++ b/app/views/user_mailer/creatorship_request.html.erb @@ -0,0 +1,20 @@ +<% creation_type = @creation.class.name.underscore %> +<% content_for :message do %> +

    + <%# i18n-tasks-use t('user_mailer.creatorship_request.intro_chapter') + i18n-tasks-use t('user_mailer.creatorship_request.intro_series') + i18n-tasks-use t('user_mailer.creatorship_request.intro_work')-%> + <%= t(".intro_#{creation_type}", inviting_user: @inviting_user.login, pseud: @creatorship.pseud.name) %> +

    + +

    + <%= t(".html.creation", + creation_link: "#{style_link(creation_title(@creation), polymorphic_url(@creation))}".html_safe, + pseud_links: @creation.pseuds.map{ |p| style_pseud_link(p) }.to_sentence.html_safe).html_safe %> +

    + +

    + <%= t(".html.instructions", + page_name: style_link(t(".html.page_name"), user_creatorships_url(@user))).html_safe %> +

    +<% end %> diff --git a/app/views/user_mailer/creatorship_request.text.erb b/app/views/user_mailer/creatorship_request.text.erb new file mode 100755 index 0000000..1e03e97 --- /dev/null +++ b/app/views/user_mailer/creatorship_request.text.erb @@ -0,0 +1,14 @@ +<% creation_type = @creation.class.name.underscore %> +<% content_for :message do %> +<%# i18n-tasks-use t('user_mailer.creatorship_request.intro_chapter') + i18n-tasks-use t('user_mailer.creatorship_request.intro_series') + i18n-tasks-use t('user_mailer.creatorship_request.intro_work')-%> +<%= t(".intro_#{creation_type}", inviting_user: @inviting_user.login, pseud: @creatorship.pseud.name) %> + +<%= t(".text.creation", + title: creation_title(@creation), + url: polymorphic_url(@creation), + pseuds: @creation.pseuds.map(&:byline).to_sentence) %> + +<%= t(".text.instructions", url: user_creatorships_url(@user)) %> +<% end %> diff --git a/app/views/user_mailer/delete_signup_notification.text.erb b/app/views/user_mailer/delete_signup_notification.text.erb new file mode 100755 index 0000000..e69de29 diff --git a/app/views/user_mailer/delete_work_notification.html.erb b/app/views/user_mailer/delete_work_notification.html.erb new file mode 100755 index 0000000..fe54199 --- /dev/null +++ b/app/views/user_mailer/delete_work_notification.html.erb @@ -0,0 +1,10 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + <% if @user == @deleter || !@deleter %> +

    <%= t(".deleted_yourself.html", title: style_creation_title(@work.title)) %>

    + <% else %> +

    <%= t(".deleted_other.html", title: style_creation_title(@work.title), pseud: style_pseud_link(@deleter.default_pseud)) %>

    + <% end %> +

    <%= t(".questions.html", support: support_link(t(".support"))) %>

    +

    <%= t(".attachment") %>

    +<% end %> diff --git a/app/views/user_mailer/delete_work_notification.text.erb b/app/views/user_mailer/delete_work_notification.text.erb new file mode 100755 index 0000000..d411cf9 --- /dev/null +++ b/app/views/user_mailer/delete_work_notification.text.erb @@ -0,0 +1,13 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<% if @user == @deleter || !@deleter %> +<%= t(".deleted_yourself.text", title: @work.title) %> +<% else %> +<%= t(".deleted_other.text", title: @work.title, pseud: text_pseud(@deleter.default_pseud)) %> +<% end %> + +<%= t(".questions.text", support: t(".support"), url: new_feedback_report_url) %> + +<%= t(".attachment") %> +<% end %> diff --git a/app/views/user_mailer/feedback.html.erb b/app/views/user_mailer/feedback.html.erb new file mode 100755 index 0000000..1c2ec1d --- /dev/null +++ b/app/views/user_mailer/feedback.html.erb @@ -0,0 +1,24 @@ +<% content_for :message do %> +

    + <% if @username.present? %> + <%= t("mailer.general.greeting.informal.addressed_html", name: style_bold(@username)) %> + <% else %> + <%= t("mailer.general.greeting.informal.unaddressed") %> + <% end %> +

    + +

    <%= t(".introduction") %>

    + + <%= style_quote("#{raw(strip_images(@summary))} #{raw(strip_images(@comment, keep_src: true))}") %> + +

    <%= t(".additional_ticket") %>

    + +

    + <%= t("mailer.general.closing.formal") %>
    + <%= style_bold(t("mailer.general.signature.support")) %> +

    +<% end %> + +<% content_for :sent_at do %> + <%= l(Time.current) %> +<% end %> diff --git a/app/views/user_mailer/feedback.text.erb b/app/views/user_mailer/feedback.text.erb new file mode 100755 index 0000000..90fbe28 --- /dev/null +++ b/app/views/user_mailer/feedback.text.erb @@ -0,0 +1,24 @@ +<% content_for :message do %> + +<% if @username.present? %> +<%= t("mailer.general.greeting.informal.addressed_html", name: @username) %> +<% else %> +<%= t("mailer.general.greeting.informal.unaddressed") %> +<% end %> + +<%= t(".introduction") %> + +<%= text_divider %> + +* <%= to_plain_text(raw @summary) %> * +<%= to_plain_text(raw(strip_images(@comment, keep_src: true))) %> + +<%= text_divider %> + +<%= t(".additional_ticket") %> + +<%= t("mailer.general.closing.formal") %> +<%= t("mailer.general.signature.support") %> +<% end %> + +<% content_for :sent_at do %><%= l(Time.current) %><% end %> diff --git a/app/views/user_mailer/invalid_signup_notification.html.erb b/app/views/user_mailer/invalid_signup_notification.html.erb new file mode 100755 index 0000000..1809071 --- /dev/null +++ b/app/views/user_mailer/invalid_signup_notification.html.erb @@ -0,0 +1,19 @@ +<% content_for :message do %> +

    <%= t(".found_invalid.html", collection_link: style_link(@collection.title, collection_url(@collection))) %>

    + +

    <%= t(".see_details.html", challenge_matching_help_link: style_link(t(".see_details.challenge_matching_help"), "#{root_url}help/challenge-matching.html#invalid_signups")) %>

    + +

    <%= t(".signups_here") %> +

      + <% @invalid_signups.each do |signup_id| %> +
    • <%= style_link(t(".signup", signup_id: signup_id), collection_signup_url(@collection, signup_id)) %>
    • + <% end %> +
    +

    +<% end %> + +<% content_for :footer_note do %> + <%= collection_footer_note_html(@is_collection_email, @collection) %> +<% end %> + +<% content_for :sent_at do %><%= l(Time.current) %><% end %> diff --git a/app/views/user_mailer/invalid_signup_notification.text.erb b/app/views/user_mailer/invalid_signup_notification.text.erb new file mode 100755 index 0000000..9782118 --- /dev/null +++ b/app/views/user_mailer/invalid_signup_notification.text.erb @@ -0,0 +1,16 @@ +<% content_for :message do %> +<%= t(".found_invalid.text", collection_title: @collection.title, collection_url: collection_url(@collection)) %> + +<%= t(".see_details.text", challenge_matching_help_url: "#{root_url}help/challenge-matching.html#invalid_signups") %> + +<%= t(".signups_here") %> +<% @invalid_signups.each do |signup_id| %> +- <%= collection_signup_url(@collection, signup_id) %> +<% end %> +<% end %> + +<% content_for :footer_note do %> +<%= collection_footer_note_text(@is_collection_email, @collection) -%> +<% end %> + +<% content_for :sent_at do %><%= l(Time.current) %><% end %> diff --git a/app/views/user_mailer/invitation.html.erb b/app/views/user_mailer/invitation.html.erb new file mode 100755 index 0000000..6ba70b0 --- /dev/null +++ b/app/views/user_mailer/invitation.html.erb @@ -0,0 +1,29 @@ +<% content_for :message do %> +

    + <% if !@user_name.blank? %> + <%= t(".has_invited", user_name: style_bold(@user_name)).html_safe %> + <% else %> + <%= t ".been_invited" %> + <% end %> +

    + +

    + <%= t(".html.about", otw_link: style_link(t(".html.otw_link_text"), "https://www.transformativeworks.org")).html_safe %> +

    + +

    + <%= t ".features" %> +

    + +

    + <%= t(".html.join", invitation_link: style_link(t(".html.invitation_link_text"), signup_url(invitation_token: @invitation.token))).html_safe %> +

    + +

    + <%= t(".html.activation_support", support_link: style_link(t(".html.support_link_text"), new_feedback_report_url)).html_safe %> +

    + +

    + <%= t(".html.faq", faq_link: style_link(t(".html.faq_link_text"), archive_faqs_url)).html_safe %> +

    +<% end %> diff --git a/app/views/user_mailer/invitation.text.erb b/app/views/user_mailer/invitation.text.erb new file mode 100755 index 0000000..00fedc6 --- /dev/null +++ b/app/views/user_mailer/invitation.text.erb @@ -0,0 +1,17 @@ +<% content_for :message do %> +<% if !@user_name.blank? %> +<%= t ".has_invited", user_name: @user_name %> +<% else %> +<%= t ".been_invited" %> +<% end %> + +<%= t ".text.about", otw_url: "https://www.transformativeworks.org" %> + +<%= t ".features" %> + +<%= t ".text.join", invitation_url: signup_url(invitation_token: @invitation.token) %> + +<%= t ".text.activation_support", support_url: new_feedback_report_url %> + +<%= t ".text.faq", faq_url: archive_faqs_url %> +<% end %> diff --git a/app/views/user_mailer/invitation_to_claim.html.erb b/app/views/user_mailer/invitation_to_claim.html.erb new file mode 100755 index 0000000..28c581b --- /dev/null +++ b/app/views/user_mailer/invitation_to_claim.html.erb @@ -0,0 +1,40 @@ +<% content_for :message do %> +

    + <%= t("mailer.general.greeting.introductory") %> +

    + +

    <%= t(".introduction.html", open_doors_name_link: style_link(t(".html.open_doors_name"), "https://opendoors.transformativeworks.org"), app_short_name: ArchiveConfig.APP_SHORT_NAME, app_link: style_link(ArchiveConfig.APP_NAME, root_url)) %>

    + +

    <%= t(".more_info.html", ao3_news_link: style_link(t(".html.ao3_news"), "#{admin_posts_url}?tag=18"), faq_page_link: style_link(t(".html.faq_page"), "https://opendoors.transformativeworks.org/faq"), tutorial_page_link: style_link(t(".html.tutorial_page"), "https://opendoors.transformativeworks.org/tutorials"), contact_support_link: support_link(t(".html.contact_support"))) %>

    + +

    <%= t('.mistake.html', contact_open_doors_link: style_link(t('.html.contact_open_doors'), 'https://opendoors.transformativeworks.org/en/contact-open-doors/')) %>

    + +

    <%= t('.access.html', contact_support_link: support_link(t '.html.contact_support')) %>

    + +

    <%= style_link(t('.claim_or_remove.html'), claim_url(:invitation_token => @token)) %>

    + +

    <%= t '.uploaded_list' %>

    + +
      + <% @external_author.works.each do |work| %> +
    • <%= style_link(work.title, work_url(work)) %> + <%= (work.fandom_string.blank? ? "" : " (#{work.fandom_string})") %>
    • + <% end %> +
    + +

    <%= t('.unwanted.html', contact_support_link: support_link(t '.html.contact_support')) %>

    + +

    <%= t '.redirects' %>

    + +

    <%= t('.update_redirect.html', contact_open_doors_link: style_link(t('.html.contact_open_doors'), 'https://opendoors.transformativeworks.org/en/contact-open-doors/')) %>

    + +

    <%= t('.other_works.html', contact_open_doors_link: style_link(t('.html.contact_open_doors'), 'https://opendoors.transformativeworks.org/en/contact-open-doors/')) %>

    + +

    <%= t('.questions.html', contact_support_link: support_link(t '.html.contact_support')) %>

    + +

    <%= t '.email_tips' %>

    + +

    <%= t("mailer.general.closing.informal") %>
    + <%= style_bold(t("mailer.general.signature.open_doors")) %>
    + <%= style_bold(t("mailer.general.signature.parent_org")) %>

    +<% end %> diff --git a/app/views/user_mailer/invitation_to_claim.text.erb b/app/views/user_mailer/invitation_to_claim.text.erb new file mode 100755 index 0000000..d310548 --- /dev/null +++ b/app/views/user_mailer/invitation_to_claim.text.erb @@ -0,0 +1,38 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.introductory") %> + +<%= t(".introduction.text", open_doors_link: "https://opendoors.transformativeworks.org", app_name: ArchiveConfig.APP_NAME, app_short_name: ArchiveConfig.APP_SHORT_NAME, app_url: root_url) %> + +<%= t(".more_info.text", news_link: admin_posts_url + "?tag=18", open_doors_faq_link: "https://opendoors.transformativeworks.org/faq", open_doors_tutorial_link: "https://opendoors.transformativeworks.org/tutorials", support_link: new_feedback_report_url) %> + +<%= t(".mistake.text", open_doors_link: "https://opendoors.transformativeworks.org/en/contact-open-doors/") %> + +<%= t(".access.text") %> + +<%= t(".claim_or_remove.text", claim_url: claim_url(:invitation_token => @token)) %> + +<%= t(".uploaded_list") %> +<% @external_author.works.each do |work| %> +<% if work.fandom_string.present? %> +<%= t(".work_info.with_fandom", work_title: work.title, work_url: work_url(work), fandom: to_sentence(work.fandom_string.split(","))) %> +<% else %> +<%= t(".work_info.no_fandom", work_title: work.title, work_url: work_url(work)) %> +<% end %> +<% end %> + +<%= t(".unwanted.text", support_link: new_feedback_report_url) %> + +<%= t(".redirects") %> + +<%= t(".update_redirect.text", open_doors_link: "https://opendoors.transformativeworks.org/en/contact-open-doors/") %> + +<%= t(".other_works.text") %> + +<%= t(".questions.text", support_link: new_feedback_report_url) %> + +<%= t(".email_tips") %> + +<%= t("mailer.general.closing.informal") %> +<%= t("mailer.general.signature.open_doors") %> +<%= t("mailer.general.signature.parent_org") %> +<% end %> diff --git a/app/views/user_mailer/invite_increase_notification.html.erb b/app/views/user_mailer/invite_increase_notification.html.erb new file mode 100755 index 0000000..eb5036e --- /dev/null +++ b/app/views/user_mailer/invite_increase_notification.html.erb @@ -0,0 +1,10 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.informal.addressed_html", name: style_bold(@user.login)) %>

    + +

    <%= t(".body.html", count: @total, invitation_page_link: style_link(t(".invitation_page_link_text"), user_invitations_url(@user))) %>

    + +

    + <%= t("mailer.general.closing.informal") %>
    + <%= t("mailer.general.signature.app_short_name") %> +

    +<% end %> diff --git a/app/views/user_mailer/invite_increase_notification.text.erb b/app/views/user_mailer/invite_increase_notification.text.erb new file mode 100755 index 0000000..499d6c0 --- /dev/null +++ b/app/views/user_mailer/invite_increase_notification.text.erb @@ -0,0 +1,8 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.informal.addressed_html", name: @user.login) %> + +<%= t(".body.text", count: @total, invitation_page_url: user_invitations_url(@user)) %> + +<%= t("mailer.general.closing.informal") %> +<%= t("mailer.general.signature.app_short_name") %> +<% end %> diff --git a/app/views/user_mailer/invite_request_declined.html.erb b/app/views/user_mailer/invite_request_declined.html.erb new file mode 100755 index 0000000..e608b75 --- /dev/null +++ b/app/views/user_mailer/invite_request_declined.html.erb @@ -0,0 +1,10 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + +

    <%= t(".main", count: @total) %>

    +

    <%= t(".reason") %>

    +

    <%= style_quote(@reason) %>

    + +

    <%= t("mailer.general.closing.formal") %>
    + <%= t("mailer.general.signature.app_short_name") %>

    +<% end %> diff --git a/app/views/user_mailer/invite_request_declined.text.erb b/app/views/user_mailer/invite_request_declined.text.erb new file mode 100755 index 0000000..d8181e2 --- /dev/null +++ b/app/views/user_mailer/invite_request_declined.text.erb @@ -0,0 +1,12 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<%= t(".main", count: @total) %> + +<%= t(".reason") %> + +<%= to_plain_text(raw @reason) %> + +<%= t("mailer.general.closing.formal") %> +<%= t("mailer.general.signature.app_short_name") %> +<% end %> diff --git a/app/views/user_mailer/invited_to_collection_notification.html.erb b/app/views/user_mailer/invited_to_collection_notification.html.erb new file mode 100755 index 0000000..dc78d80 --- /dev/null +++ b/app/views/user_mailer/invited_to_collection_notification.html.erb @@ -0,0 +1,10 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@user.login)) %>

    + +

    <%= t(".would_like_to_include.html", + collection_link: style_link(@collection.title, collection_url(@collection)), + work_link: style_creation_link(@work.title, work_url(@work))) %>

    + +

    <%= t(".approve.html", collection_items_page_link: style_link(t(".approve.collection_items_page"), user_collection_items_url(@user))) %>

    + +<% end %> diff --git a/app/views/user_mailer/invited_to_collection_notification.text.erb b/app/views/user_mailer/invited_to_collection_notification.text.erb new file mode 100755 index 0000000..5ec17bc --- /dev/null +++ b/app/views/user_mailer/invited_to_collection_notification.text.erb @@ -0,0 +1,12 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @user.login) %> + +<%= t(".would_like_to_include.text", + collection_title: @collection.title, + collection_url: collection_url(@collection), + work_title: @work.title, + work_url: work_url(@work)) %> + +<%= t(".approve.text", collection_items_page_url: user_collection_items_url(@user)) %> + +<% end %> diff --git a/app/views/user_mailer/potential_match_generation_notification.html.erb b/app/views/user_mailer/potential_match_generation_notification.html.erb new file mode 100755 index 0000000..cca750f --- /dev/null +++ b/app/views/user_mailer/potential_match_generation_notification.html.erb @@ -0,0 +1,13 @@ +<% content_for :message do %> +

    <%= t(".finished_generating.html", collection_link: style_link(@collection.title, collection_url(@collection))) %>

    + +

    <%= t(".matches_available.html", matching_page_link: style_link(t(".matches_available.matching_page"), collection_potential_matches_url(@collection))) %>

    +<% end %> + +<% content_for :footer_note do %> + <%= collection_footer_note_html(@is_collection_email, @collection) %> +<% end %> + +<% content_for :sent_at do %> + <%= l(Time.current) %> +<% end %> diff --git a/app/views/user_mailer/potential_match_generation_notification.text.erb b/app/views/user_mailer/potential_match_generation_notification.text.erb new file mode 100755 index 0000000..61d66eb --- /dev/null +++ b/app/views/user_mailer/potential_match_generation_notification.text.erb @@ -0,0 +1,11 @@ +<% content_for :message do %> +<%= t(".finished_generating.text", collection_title: @collection.title, collection_url: collection_url(@collection)) %> + +<%= t(".matches_available.text", matching_page_url: collection_potential_matches_url(@collection)) %> +<% end %> + +<% content_for :footer_note do %> +<%= collection_footer_note_text(@is_collection_email, @collection) -%> +<% end %> + +<% content_for :sent_at do %><%= l(Time.current) %><% end %> diff --git a/app/views/user_mailer/prompter_notification.html.erb b/app/views/user_mailer/prompter_notification.html.erb new file mode 100755 index 0000000..aad32cf --- /dev/null +++ b/app/views/user_mailer/prompter_notification.html.erb @@ -0,0 +1,29 @@ +<% content_for :message do %> +

    + A response to your prompt has been posted <% if @collection %>in the <%= style_link(@collection.title, collection_url(@collection)) %> collection <% end %>at the Archive of Our Own! +

    + +

    + <% if @collection.nil? %> + <%= style_creation_link(@work.title, work_url(@work)) %> (<%= @work.word_count %> words) + <% else %> + <%= style_creation_link(@work.title, collection_work_url(@collection, @work)) %> (<%= @work.word_count %> words) + <% end %> +
    + by <%= @work.anonymous? ? style_bold("an anonymous responder") : (@work.pseuds.map{|p| style_pseud_link(p)}.to_sentence.html_safe) %> +
    + <% unless @work.fandom_string.blank? %> + <%= style_bold("Fandom:") %> <%= @work.fandom_string %> + <% end %> +

    + + <% unless @work.summary.blank? %> + <%= style_bold("Summary:") %> + <%= style_quote(raw sanitize_field(@work, :summary)) %> + <% end %> + + <% if @collection && !@collection.gift_notification.blank? %> +

    <%= @collection.gift_notification %>

    + <% end %> + +<% end %> diff --git a/app/views/user_mailer/prompter_notification.text.erb b/app/views/user_mailer/prompter_notification.text.erb new file mode 100755 index 0000000..78cae08 --- /dev/null +++ b/app/views/user_mailer/prompter_notification.text.erb @@ -0,0 +1,14 @@ +<% content_for :message do %> +A response to your prompt has been posted<% if @collection %> in the "<%= @collection.title %>" collection (<%= collection_url(@collection) %>)<% end %> at the Archive of Our Own! + +"<%= @work.title %>" (<%= @work.word_count %> words) +<%= @collection ? collection_work_url(@collection, @work) : work_url(@work) %> + +by <%= @work.anonymous? ? "an anonymous responder" : (@work.pseuds.map{|p| text_pseud(p)}.to_sentence) %> + +<% unless @work.fandom_string.blank? %>Fandom: <%= @work.fandom_string %><% end %> + +<% unless @work.summary.blank? %>Summary: +<%= to_plain_text(raw sanitize_field(@work, :summary)) %><% end %> + +<% if @collection && !@collection.gift_notification.blank? %><%= @collection.gift_notification %><% end %><% end %> diff --git a/app/views/user_mailer/recipient_notification.html.erb b/app/views/user_mailer/recipient_notification.html.erb new file mode 100755 index 0000000..e43576e --- /dev/null +++ b/app/views/user_mailer/recipient_notification.html.erb @@ -0,0 +1,26 @@ +<% content_for :message do %> + +

    <%= t("mailer.general.greeting.informal.addressed_html", name: style_bold(@user.login)) %>

    + +

    + <% if @collection %> + <%= t(".collection.html", collection_link: style_link(@collection.title, collection_url(@collection))) %> + <% else %> + <%= t(".no_collection") %> + <% end %> +

    + +

    + <% url = @collection ? collection_work_url(@collection, @work) : work_url(@work) %> + <%= creation_link_with_word_count(@work, url) %> +
    + by <%= creator_links(@work) %> +

    + + <%= render "work_info", work: @work %> + + <% if @collection && !@collection.gift_notification.blank? %> +

    <%= @collection.gift_notification %>

    + <% end %> + +<% end %> diff --git a/app/views/user_mailer/recipient_notification.text.erb b/app/views/user_mailer/recipient_notification.text.erb new file mode 100755 index 0000000..46e94ff --- /dev/null +++ b/app/views/user_mailer/recipient_notification.text.erb @@ -0,0 +1,17 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.informal.addressed_html", name: @user.login) %> + +<% if @collection %> +<%= t(".collection.text", collection_title: @collection.title, collection_url: collection_url(@collection)) %> +<% else %> +<%= t(".no_collection") %> +<% end %> + +<%= creation_title_with_word_count(@work) %> +<%= @collection ? collection_work_url(@collection, @work) : work_url(@work) %> + +by <%= creator_text(@work) %> + +<%= render "work_info", work: @work %> + +<% if @collection && !@collection.gift_notification.blank? %><%= @collection.gift_notification %><% end %><% end %> diff --git a/app/views/user_mailer/related_work_notification.html.erb b/app/views/user_mailer/related_work_notification.html.erb new file mode 100755 index 0000000..bedbef2 --- /dev/null +++ b/app/views/user_mailer/related_work_notification.html.erb @@ -0,0 +1,18 @@ +<% content_for :message do %> +

    + <%= t(".work_listed.html", + work_link: style_creation_link(@related_work.parent.title, @related_parent_link), + related_work_link: style_creation_link(@related_work.work.title, @related_child_link), + work_creators: if @related_work.work.anonymous? + t(".anonymous") + else + to_sentence(@related_work.work.pseuds.map { |p| style_pseud_link(p) }) + end) %> +

    + +

    + <%= style_link(t(".approve.html"), related_work_url(@related_work)) %> +

    + +

    <%= t(".can_come_back") %>

    +<% end %> diff --git a/app/views/user_mailer/related_work_notification.text.erb b/app/views/user_mailer/related_work_notification.text.erb new file mode 100755 index 0000000..c4fafc5 --- /dev/null +++ b/app/views/user_mailer/related_work_notification.text.erb @@ -0,0 +1,15 @@ +<% content_for :message do %> +<%= t(".work_listed.text", work_title: @related_work.parent.title, + work_url: @related_parent_link, + related_work_title: @related_work.work.title, + related_work_url: @related_child_link, + work_creators: if @related_work.work.anonymous? + t(".anonymous") + else + to_sentence(@related_work.work.pseuds.map { |p| text_pseud(p) }) + end) %> + +<%= t(".approve.text", related_work_url: related_work_url(@related_work)) %> + +<%= t(".can_come_back") %> +<% end %> diff --git a/app/views/user_mailer/signup_notification.html.erb b/app/views/user_mailer/signup_notification.html.erb new file mode 100755 index 0000000..cd76a1d --- /dev/null +++ b/app/views/user_mailer/signup_notification.html.erb @@ -0,0 +1,12 @@ +<% content_for :message do %> +

    <%= t('.welcome', + login: style_bold(@user.login)).html_safe %>

    +

    <%= t('.activate.html', + activate_account_link: style_link(t('.activate_your_account'), activate_url(id: @user.confirmation_token))) %>

    +

    <%= t('.features.html') %>

    +

    <%= t('.information.html', + faq_link: style_link(t('.faq'), archive_faqs_url), + admin_posts_link: style_link(t('.admin_posts'), admin_posts_url), + contact_support_link: support_link(t '.contact_support')) %>

    +

    <%= t('.bye') %>

    +<% end %> diff --git a/app/views/user_mailer/signup_notification.text.erb b/app/views/user_mailer/signup_notification.text.erb new file mode 100755 index 0000000..239596f --- /dev/null +++ b/app/views/user_mailer/signup_notification.text.erb @@ -0,0 +1,16 @@ +<% content_for :message do %> +<%= t('.welcome', + login: @user.login) %> + +<%= t('.activate.text', + activate_account_url: activate_url(id: @user.confirmation_token)) %> + +<%= t('.features.text') %> + +<%= t('.information.text', + faq_url: archive_faqs_url, + admin_posts_url: admin_posts_url, + contact_support_url: new_feedback_report_url) %> + +<%= t('.bye') %> +<% end %> diff --git a/app/views/users/_admin_change_username.html.erb b/app/views/users/_admin_change_username.html.erb new file mode 100755 index 0000000..6b23fda --- /dev/null +++ b/app/views/users/_admin_change_username.html.erb @@ -0,0 +1,29 @@ +

    <%= t(".page_heading") %>

    +<%= error_messages_for :user %> +

    <%= t(".description") %>

    + + + +<%= form_tag changed_username_user_path(@user), autocomplete: "off" do %> + <%= t("users.change_username.legend") %> +

    <%= t("users.change_username.heading") %>

    +
    +
    <%= t("users.change_username.current_username") %>
    +

    <%= @user.login %>

    +
    <%= label_tag :new_login, t("users.change_username.new_username") %>
    +
    + <%= text_field_tag :new_login, "user#{@user.id}", readonly: true, "aria-describedby": "new-login-field-description" %> +

    + <%= t(".new_username_footnote") %> +

    +
    +
    <%= label_tag :ticket_number, t(".ticket_id") %>
    +
    <%= text_field_tag :ticket_number %>
    +
    <%= t("users.change_username.submit_landmark") %>
    +
    + <%= submit_tag t("users.change_username.submit") %> +
    +
    +<% end %> diff --git a/app/views/users/_contents.html.erb b/app/views/users/_contents.html.erb new file mode 100755 index 0000000..a652064 --- /dev/null +++ b/app/views/users/_contents.html.erb @@ -0,0 +1,144 @@ + + +<% if @status.present? %> +
    +

    Current Status...

    +<%= link_to t("All My Statuses"), user_statuses_path(@status.user) %>
    +<%= image_tag @status.icon if @status.icon.attached? %> | <%= time_ago_in_words(@status.created_at) %> | <% if current_user == @status.user %> + <%= link_to 'Edit', edit_user_status_path(@status.user, @status) %> | + <%= link_to t("Delete"), user_status_path(@status.user, @status), + data: { confirm: t("Are you sure? All information in this status will be lost.") }, + method: :delete %> + <% end %> +
    +

    <%= raw sanitize_field(@status, :text) %>

    +<% if @status.mood.present? %> +

    Mood: <%= @status.mood %> +<% end %> +<% if @status.music.present? %> +

    Music: <%= @status.music %>

    +<% end %> +
    +<% end %> + <% unless @fandoms.empty? %> +
    +

    <%= ts("Fandoms") %>

    +
      + <% @fandoms.each_with_index do |fandom, i| %> + <% if i>= ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD && !params[:expand_fandoms] %> +
    1. + <% end %> + <% if fandom.merger %> + <%= link_to fandom.name, {:controller => :works, :user_id => @user, :pseud_id => @pseud, :fandom_id => fandom.merger.id} %> (<%= fandom.work_count %>) + <% else %> + <%= link_to fandom.name, {:controller => :works, :user_id => @user, :pseud_id => @pseud, :fandom_id => fandom.id} %> (<%= fandom.work_count %>) + <% end %> +
    2. + <% end %> +
    + <% if @fandoms.length > ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD %> +

    + + + +

    + <% end %> +
    + <% end %> + + <% unless @works.blank? %> +
    +

    <%= ts("Recent works") %>

    +
      + <%= render partial: 'works/work_blurb', collection: @works, as: :work %> +
    + <% if @pseud %> + <% if @pseud.works.count > ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD %> +
    + <% end %> + + <% unless @series.blank? %> +
    +

    <%= ts("Recent series") %>

    +
      + <%= render partial: 'series/series_blurb', collection: @series, as: :series %> +
    + <% if @pseud %> + <% if @pseud.series.count > ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD %> + + <% end %> + <% else %> + <% if @user.series.size > ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD %> + + <% end %> + <% end %> +
    + <% end %> + + <% unless @bookmarks.blank? %> +
    +

    <%= ts("Recent bookmarks") %>

    +
      + <%= render partial: 'bookmarks/bookmark_blurb', collection: @bookmarks, as: :bookmark %> +
    + <% unless @user == User.orphan_account %> + <% if @pseud %> + <% if @pseud.bookmarks.visible.size > ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD %> + + <% end %> + <% else %> + <% if @user.bookmarks.visible.size > ArchiveConfig.NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD %> + + <% end %> + <% end %> + <% end %> +
    + <% end %> + +<% if @works.blank? && @series.blank? && @bookmarks.blank? %> + <% if current_user == @user %> +

    + <%= ts("You don't have anything posted under this name yet. ") %> + <%= ts("Would you like to ")%> + <%= link_to ts("post a new work"), new_work_path %> + <%= ts("or maybe")%> + <%= link_to ts("a new bookmark"), new_external_work_path %>? +

    + <% else %> +

    <%= ts("There are no works or bookmarks under this name yet.") %>

    + <% end %> +<% end %> + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(document).ready(function() { + $j("#expand-fandoms").removeClass("hidden").click(function(e) { + e.preventDefault(); + $j(".more").toggleClass("hidden"); + $j("#collapse-fandoms").toggleClass("hidden"); + $j(this).toggleClass("hidden"); + }); + $j("#collapse-fandoms").click(function(e) { + e.preventDefault(); + $j(".more").toggleClass("hidden"); + $j("#expand-fandoms").toggleClass("hidden"); + $j(this).toggleClass("hidden"); + }); + }); + <% end %> +<% end %> diff --git a/app/views/users/_edit_header_navigation.html.erb b/app/views/users/_edit_header_navigation.html.erb new file mode 100755 index 0000000..643714f --- /dev/null +++ b/app/views/users/_edit_header_navigation.html.erb @@ -0,0 +1,7 @@ + diff --git a/app/views/users/_edit_user_navigation.html.erb b/app/views/users/_edit_user_navigation.html.erb new file mode 100755 index 0000000..77e872c --- /dev/null +++ b/app/views/users/_edit_user_navigation.html.erb @@ -0,0 +1,7 @@ + diff --git a/app/views/users/_header.html.erb b/app/views/users/_header.html.erb new file mode 100755 index 0000000..12e5f37 --- /dev/null +++ b/app/views/users/_header.html.erb @@ -0,0 +1,15 @@ + +
    +

    + <%= @pseud ? @pseud.byline : @user.login %> +

    +

    <%= icon_display(@user, @pseud) %>

    + + + + <% if logged_in? || policy(User).can_manage_users? %> + <%= render "users/header_navigation" %> + <% end %> + + +
    diff --git a/app/views/users/_header_navigation.html.erb b/app/views/users/_header_navigation.html.erb new file mode 100755 index 0000000..e8d0105 --- /dev/null +++ b/app/views/users/_header_navigation.html.erb @@ -0,0 +1,25 @@ +<% # expects @user to be set %> + + diff --git a/app/views/users/_sidebar.html.erb b/app/views/users/_sidebar.html.erb new file mode 100755 index 0000000..a6a8a02 --- /dev/null +++ b/app/views/users/_sidebar.html.erb @@ -0,0 +1,66 @@ +
    " role="navigation region"> +

    <%= t(".landmark.choices") %>

    + + + +

    <%= t(".landmark.pitch") %>

    + + +<% if @user == current_user || policy(:inbox_comment).show? %> +

    <%= t(".landmark.catch") %>

    + +<% end %> + +

    <%= t(".landmark.switch") %>

    + + +
    diff --git a/app/views/users/change_email.html.erb b/app/views/users/change_email.html.erb new file mode 100755 index 0000000..78db45b --- /dev/null +++ b/app/views/users/change_email.html.erb @@ -0,0 +1,47 @@ + +

    <%= t(".heading") %>

    +<%= error_messages_for :user %> + + + +<%= render "edit_header_navigation" %> + + +<% reconfirmation_date = @user.confirmation_sent_at + User.confirm_within if @user.pending_reconfirmation? %> +<% if reconfirmation_date && (Time.current < reconfirmation_date) %> +
    +

    <%= t(".caution.requested_change_html", unconfirmed_email: tag.strong(@user.unconfirmed_email)) %>

    +

    <%= t(".caution.check_spam_html", must_confirm_bold: tag.strong(t(".caution.must_confirm")), contact_support_link: link_to(t(".caution.contact_support"), new_feedback_report_path)) %>

    +

    <%= t(".caution.confirm_by", date: l(reconfirmation_date)) %>

    +
    +<% end %> + +
    +

    <%= t(".request_for_confirmation") %>

    +

    <%= t(".must_confirm", count: User.confirm_within.in_days.to_i) %>

    +

    <%= t(".resubmission_html", invalidate_bold: tag.strong(t(".invalidate"))) %>

    +
    + + +<%= form_with model: @user, url: confirm_change_email_user_path(@user), method: :put do %> +
    +
    <%= t(".form.current_email") %>
    +
    <%= @user.email %>
    + +
    <%= label_tag :new_email, t(".form.new_email") %>
    +
    <%= email_field_tag :new_email, nil, autocomplete: "off" %>
    + +
    <%= label_tag :email_confirmation, t(".form.email_again") %>
    +
    <%= email_field_tag :email_confirmation, nil, autocomplete: "off" %>
    + +
    <%= label_tag :password_check, t(".form.password") %>
    +
    <%= password_field_tag :password_check %>
    + +
    <%= label_tag :submit, t(".form.submit_landmark") %>
    +
    + <%= submit_tag t(".form.confirm") %> +
    +
    +<% end %> + + diff --git a/app/views/users/change_password.html.erb b/app/views/users/change_password.html.erb new file mode 100755 index 0000000..db107e7 --- /dev/null +++ b/app/views/users/change_password.html.erb @@ -0,0 +1,33 @@ + +

    <%= ts("Change My Password") %>

    +<%= error_messages_for :user %> + + + +<%= render 'edit_header_navigation' %> + + + +<%= form_tag changed_password_user_path(@user) do %> +
    +
    <%= label_tag :password, ts("New password") %>
    +
    + <%= password_field_tag :password, nil, "aria-describedby" => "password-field-description" %> +

    + <%= ts("%{minimum} to %{maximum} characters", + minimum: ArchiveConfig.PASSWORD_LENGTH_MIN, + maximum: ArchiveConfig.PASSWORD_LENGTH_MAX) %> +

    +
    +
    <%= label_tag :password_confirmation, ts("Confirm new password") %>
    +
    <%= password_field_tag :password_confirmation %>
    +
    <%= label_tag :password_check, ts("Old password") %>
    +
    <%= password_field_tag :password_check%>
    +
    <%= label_tag :submit, ts("Submit") %>
    +
    + <%= submit_tag ts("Change Password") %> +
    +
    +<% end %> + + diff --git a/app/views/users/change_username.html.erb b/app/views/users/change_username.html.erb new file mode 100755 index 0000000..25e3895 --- /dev/null +++ b/app/views/users/change_username.html.erb @@ -0,0 +1,55 @@ +<% if policy(@user).change_username? %> + <%= render "admin_change_username" %> +<% else %> + +

    <%= t(".page_heading") %>

    + <%= error_messages_for :user %> +
    +

    + <%= t(".caution") %> + <%= t(".change_window", count: ArchiveConfig.USER_RENAME_LIMIT_DAYS) %> + <% if @user.renamed_at %> + <%= t(".last_renamed", renamed_at: l(@user.renamed_at)) %> + <% end %> +

    +

    + <%= t(".more_info_html", + account_faq_link: link_to(t(".account_faq"), archive_faq_path("your-account", anchor: "namechange")), + contact_support_link: link_to(t(".contact_support"), new_feedback_report_path)) %> +

    +
    +

    + <%= t(".new_pseud_instead_html", create_a_new_pseud_link: link_to(t(".create_a_new_pseud"), new_user_pseud_path(@user))) %> +

    + + + + <%= render "edit_header_navigation" %> + + + + + <%= form_tag changed_username_user_path(@user), autocomplete: "off" do %> + <%= t(".legend") %> +

    <%= t(".heading") %>

    +
    +
    <%= t(".current_username") %>
    +

    <%= @user.login %>

    +
    <%= label_tag :new_login, t(".new_username") %>
    +
    + <%= text_field_tag :new_login, @new_login, "aria-describedby": "new-login-field-description" %> +

    + <%= t(".username_requirements", + minimum: ArchiveConfig.LOGIN_LENGTH_MIN, + maximum: ArchiveConfig.LOGIN_LENGTH_MAX) %> +

    +
    +
    <%= label_tag :password, t(".password") %>
    +
    <%= password_field_tag :password, nil %>
    +
    <%= t(".submit_landmark") %>
    +
    + <%= submit_tag t(".submit"), data: { confirm: t(".confirm") } %> +
    +
    + <% end %> +<% end %> diff --git a/app/views/users/confirm_change_email.html.erb b/app/views/users/confirm_change_email.html.erb new file mode 100755 index 0000000..aa2efd3 --- /dev/null +++ b/app/views/users/confirm_change_email.html.erb @@ -0,0 +1,24 @@ + +

    <%= t(".heading") %>

    + + + +<%= render "edit_header_navigation" %> + + + +<%= form_with model: @user, url: changed_email_user_path(@user), method: :post do %> + <%= hidden_field_tag :new_email, @new_email %> + +
    +

    <%= t(".are_you_sure_html", unconfirmed_email: tag.strong(@new_email)) %>

    +

    <%= t(".confirm_via_link_html", if_not_confirm_bold: tag.strong(t(".if_not_confirm", count: User.confirm_within.in_days.to_i))) %>

    +
    + +

    + <%= link_to t(".cancel"), change_email_user_path(@user) %> + <%= submit_tag t(".confirm") %> +

    +<% end %> + + diff --git a/app/views/users/confirmation.html.erb b/app/views/users/confirmation.html.erb new file mode 100755 index 0000000..81bcaa8 --- /dev/null +++ b/app/views/users/confirmation.html.erb @@ -0,0 +1,21 @@ + +

    <%= t(".page_heading") %>

    + + +
    +

    + <%= t(".receive_email_html", return_address: tag.strong(ArchiveConfig.RETURN_ADDRESS)) %> +

    +

    + <%= t(".no_email_html", contact_support_link: link_to(t(".contact_support"), new_feedback_report_path)) %> +

    +

    + <%# We do days_to_purge_unactivated * 7 because it's actually weeks %> + <%= t(".important")%> + <%= t(".must_activate", count: AdminSetting.current.days_to_purge_unactivated * 7) %> +

    +

    + <%= link_to t(".go_back"), root_path %> +

    +
    + diff --git a/app/views/users/delete_confirmation.html.erb b/app/views/users/delete_confirmation.html.erb new file mode 100755 index 0000000..903c0bd --- /dev/null +++ b/app/views/users/delete_confirmation.html.erb @@ -0,0 +1,4 @@ +

    <%= ts("Account deleted!") %>

    +

    <%= ts('Your account has been deleted.') %> <%= ts('Thank you for using the Archive, and we hope to see you again someday.') %>

    + +

    <%= ts("If you orphaned your works, thank you for your generosity.") %>

    \ No newline at end of file diff --git a/app/views/users/delete_preview.html.erb b/app/views/users/delete_preview.html.erb new file mode 100755 index 0000000..07d6a8f --- /dev/null +++ b/app/views/users/delete_preview.html.erb @@ -0,0 +1,74 @@ +

    <%= t(".heading") %>

    + +<%= form_tag(@user, method: :delete) do %> + <% unless @user.coauthors.blank? %> +
    + <%= t(".co_creations.legend") %> +

    + <%= t(".co_creations.summary", + work_count: @coauthored_works.size, + co_creators: print_coauthors(@user)) %> +

    +

    + <%= t(".co_creations.orphan_info", + orphan_link: link_to(t(".orphan"), archive_faq_path("orphaning")) + ).html_safe %> +

    +

    + <%= radio_button_tag :coauthor, :keep_pseud, true %> + <%= label_tag :coauthor_keep_pseud, t(".options.keep_pseud") %> +

    +

    + <%= radio_button_tag :coauthor, :orphan_pseud %> + <%= label_tag :coauthor_orphan_pseud, t(".options.orphan_pseud") %> +

    +

    + <%= radio_button_tag :coauthor, :remove %> + <%= label_tag :coauthor_remove, t(".options.remove") %> +

    +
    + <% end %> + + <% unless @sole_authored_works.empty? && @sole_owned_collections.empty? %> +
    + <%= t(".sole_creations.legend") %> +

    + <% unless @sole_authored_works.empty? %> + <%= t(".sole_creations.works_summary", + work_count: @sole_authored_works.size, + pseuds: print_pseuds(@user)) %> + <% end %> + <% unless @sole_owned_collections.empty? %> + <% unless @sole_authored_works.empty? %>
    <% end %> + <%= t(".sole_creations.collections_summary", + collection_count: @sole_owned_collections.size, + pseuds: @sole_owned_collections.collect(&:all_owners).flatten.uniq.collect(&:name).join(", ")) %> + <% end %> +

    +

    + <%= t(".sole_creations.options_info", + orphaning_link: link_to(t(".orphaning"), archive_faq_path("orphaning")) + ).html_safe %> +

    +

    + <%= radio_button_tag :sole_author, :keep_pseud, true %> + <%= label_tag :sole_author_keep_pseud, t(".options.keep_pseud") %> +

    +

    + <%= radio_button_tag :sole_author, :orphan_pseud %> + <%= label_tag :sole_author_orphan_pseud, t(".options.orphan_pseud") %> +

    +

    + <%= radio_button_tag :sole_author, :delete %> + <%= label_tag :sole_author_delete, t(".options.delete") %> +

    +
    + <% end %> + +
    +

    + <%= submit_tag t(".submit"), data: { confirm: t(".confirm") } %> + <%= submit_tag t(".cancel"), name: "cancel_button", class: "cancel" %> +

    +
    +<% end %> diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb new file mode 100755 index 0000000..3c0bb73 --- /dev/null +++ b/app/views/users/edit.html.erb @@ -0,0 +1,48 @@ + +

    <%= t(".page_heading") %>

    +<%= error_messages_for :user %> +<%= error_messages_for @user.profile %> + + + +<%= render "edit_header_navigation" %> + + + +

    + <%= t(".public_information_notice_html", privacy_policy_link: link_to(t(".privacy_policy"), privacy_path)) %> +

    + +

    <%= t(".change_profile_landmark") %>

    +<%= form_for(@user) do |f| %> +
    + <%= fields_for :profile_attributes, @user.profile do |p| %> +
    <%= p.label :title, t(".title") %>
    +
    + <%= p.text_field :title, class: "observe_textlength" %> + <%= live_validation_for_field("profile_attributes_title", presence: false, maximum_length: Profile::PROFILE_TITLE_MAX) %> + <%= generate_countdown_html("profile_attributes_title", Profile::PROFILE_TITLE_MAX) %> +
    + +
    <%= p.label :about_me, t(".about_me") %>
    +
    +

    <%= allowed_html_instructions %>

    + <%= p.text_area :about_me, class: "observe_textlength" %> + <%= live_validation_for_field("profile_attributes_about_me", presence: false, maximum_length: Profile::ABOUT_ME_MAX) %> + <%= generate_countdown_html("profile_attributes_about_me", Profile::ABOUT_ME_MAX) %> +
    + + <% if policy(@user.profile).can_edit_profile? %> +
    <%= p.label :ticket_number, class: "required" %>
    +
    + <%= p.text_field :ticket_number, class: "required" %> +
    + <% end %> + +
    <%= p.label :update, t(".update") %>
    +
    <%= f.submit t(".update") %>
    + <% end %> +
    +<% end %> + + diff --git a/app/views/users/end_banner.js.erb b/app/views/users/end_banner.js.erb new file mode 100755 index 0000000..b834c33 --- /dev/null +++ b/app/views/users/end_banner.js.erb @@ -0,0 +1 @@ +$j('#admin-banner').hide(); diff --git a/app/views/users/end_first_login.js.erb b/app/views/users/end_first_login.js.erb new file mode 100755 index 0000000..eeb290e --- /dev/null +++ b/app/views/users/end_first_login.js.erb @@ -0,0 +1,2 @@ +$j('#first-login-help-banner').hide(); +ao3modal.hide(); diff --git a/app/views/users/mailer/confirmation_instructions.html.erb b/app/views/users/mailer/confirmation_instructions.html.erb new file mode 100755 index 0000000..7ca4914 --- /dev/null +++ b/app/views/users/mailer/confirmation_instructions.html.erb @@ -0,0 +1,11 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.unaddressed") %>

    + +

    <%= t(".request_to_change_email_html", username: style_bold(@resource.login), app_name: ArchiveConfig.APP_SHORT_NAME) %>

    + +

    <%= t(".made_request.html", count: @resource.class.confirm_within.in_days.to_i, confirm_email_change_link: style_link(t(".confirm_email_change"), reconfirm_email_user_url(@resource, confirmation_token: @token))) %>

    + +

    <%= t(".confirm_by.html", date: l(@resource.confirmation_sent_at + @resource.class.confirm_within), email_change_form_link: style_link(t(".email_change_form"), change_email_user_url(@user))) %>

    + +

    <%= t(".did_not_make_request") %>

    +<% end %> diff --git a/app/views/users/mailer/confirmation_instructions.text.erb b/app/views/users/mailer/confirmation_instructions.text.erb new file mode 100755 index 0000000..12b6c46 --- /dev/null +++ b/app/views/users/mailer/confirmation_instructions.text.erb @@ -0,0 +1,11 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.unaddressed") %> + +<%= t(".request_to_change_email_html", username: @resource.login, app_name: ArchiveConfig.APP_SHORT_NAME) %> + +<%= t(".made_request.text", count: @resource.class.confirm_within.in_days.to_i, confirm_email_change_url: reconfirm_email_user_url(@resource, confirmation_token: @token)) %> + +<%= t(".confirm_by.text", date: l(@resource.confirmation_sent_at + @resource.class.confirm_within), email_change_form_url: change_email_user_url(@user)) %> + +<%= t(".did_not_make_request") %> +<% end %> diff --git a/app/views/users/mailer/password_change.html.erb b/app/views/users/mailer/password_change.html.erb new file mode 100755 index 0000000..7bcdfaa --- /dev/null +++ b/app/views/users/mailer/password_change.html.erb @@ -0,0 +1,15 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@resource.login)) %>

    + +

    <%= t(".changed", date: l(Time.current), app_name: ArchiveConfig.APP_SHORT_NAME) %>

    + +

    <%= t(".made_change.html", + login_link: style_link(t(".made_change.login"), new_user_session_url), + reset_password_link: style_link(t(".made_change.reset_password"), new_user_password_url), + contact_support_link: support_link(t(".made_change.contact_support"))) %>

    + +

    <%= t(".did_not_make_change.html", + reset_password_link: style_link(t(".did_not_make_change.reset_password"), new_user_password_url), + contact_policy_abuse_link: style_link(t(".did_not_make_change.contact_policy_abuse"), new_abuse_report_url), + app_name: ArchiveConfig.APP_SHORT_NAME) %>

    +<% end %> diff --git a/app/views/users/mailer/password_change.text.erb b/app/views/users/mailer/password_change.text.erb new file mode 100755 index 0000000..2cd7601 --- /dev/null +++ b/app/views/users/mailer/password_change.text.erb @@ -0,0 +1,15 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @resource.login) %> + +<%= t(".changed", date: l(Time.current), app_name: ArchiveConfig.APP_SHORT_NAME) %> + +<%= t(".made_change.text", + login_url: new_user_session_url, + reset_password_url: new_user_password_url, + contact_support_url: new_feedback_report_url) %> + +<%= t(".did_not_make_change.text", + reset_password_url: new_user_password_url, + contact_policy_abuse_url: new_abuse_report_url, + app_name: ArchiveConfig.APP_SHORT_NAME) %> +<% end %> diff --git a/app/views/users/mailer/reset_password_instructions.html.erb b/app/views/users/mailer/reset_password_instructions.html.erb new file mode 100755 index 0000000..bce2e17 --- /dev/null +++ b/app/views/users/mailer/reset_password_instructions.html.erb @@ -0,0 +1,7 @@ +<% content_for :message do %> +

    <%= t("mailer.general.greeting.formal.addressed_html", name: style_bold(@resource.login)) %>

    +

    <%= t(".intro") %>

    +

    <%= style_link t(".link_title"), edit_user_password_url(reset_password_token: @token) %>

    +

    <%= t(".expiration") %>

    +

    <%= t(".unrequested") %>

    +<% end %> diff --git a/app/views/users/mailer/reset_password_instructions.text.erb b/app/views/users/mailer/reset_password_instructions.text.erb new file mode 100755 index 0000000..0e320d1 --- /dev/null +++ b/app/views/users/mailer/reset_password_instructions.text.erb @@ -0,0 +1,12 @@ +<% content_for :message do %> +<%= t("mailer.general.greeting.formal.addressed_html", name: @resource.login) %> + +<%= t(".intro") %> + +<%= edit_user_password_url(reset_password_token: @token) %> + +<%= t(".expiration") %> + +<%= t(".unrequested") %> + +<% end %> diff --git a/app/views/users/passwords/edit.html.erb b/app/views/users/passwords/edit.html.erb new file mode 100755 index 0000000..f7ea8e7 --- /dev/null +++ b/app/views/users/passwords/edit.html.erb @@ -0,0 +1,28 @@ + +

    <%= ts("Change My Password") %>

    +<%= error_messages_for resource %> + + + +<%= form_for resource, url: users_password_reset_path, html: { method: :put, class: "reset password post" } do |f| %> + <%= f.hidden_field :reset_password_token %> +
    +
    <%= label_tag :edit_password, ts("New password") %>
    +
    + <%= f.password_field(:password, id: :edit_password, + "aria-describedby" => "password-field-description") %> +

    + <%= ts("%{minimum} to %{maximum} characters", + minimum: ArchiveConfig.PASSWORD_LENGTH_MIN, + maximum: ArchiveConfig.PASSWORD_LENGTH_MAX) %> +

    +
    +
    <%= label_tag :edit_password_confirmation, ts("Confirm new password") %>
    +
    <%= f.password_field :password_confirmation, id: :edit_password_confirmation %>
    +
    <%= ts("Submit") %>
    +
    + <%= f.submit ts("Change Password") %> +
    +
    +<% end %> + diff --git a/app/views/users/passwords/new.html.erb b/app/views/users/passwords/new.html.erb new file mode 100755 index 0000000..15fa21c --- /dev/null +++ b/app/views/users/passwords/new.html.erb @@ -0,0 +1,15 @@ + +

    <%= t(".page_heading") %>

    +

    <%= t(".instructions") %>

    + + + +<%= form_for resource, url: user_password_path, html: { method: :post, html: "reset password simple post" } do |f| %> + <%= error_messages_for resource %> +

    + <%= label_tag :reset_login, t(".email_or_username_html", or: tag.strong(t(".or"))) %> + <%= f.text_field :login, id: :reset_login %> + <%= f.submit t(".reset_password") %> +

    +<% end %> + diff --git a/app/views/users/registrations/_legal.html.erb b/app/views/users/registrations/_legal.html.erb new file mode 100755 index 0000000..65db354 --- /dev/null +++ b/app/views/users/registrations/_legal.html.erb @@ -0,0 +1,33 @@ + +

    <%= t(".over_thirteen_required") %>

    +

    + <%= f.check_box :age_over_13 %> + <%= f.label :age_over_13, t(".over_thirteen_confirm") %> +

    + +

    + <%= t(".agreement_required_html", + terms_of_service_link: link_to(t(".terms_of_service"), tos_path, target: "_blank", rel: "noopener"), + content_policy_link: link_to(t(".content_policy"), content_path, target: "_blank", rel: "noopener"), + privacy_policy_link: link_to(t(".privacy_policy"), privacy_path, target: "_blank", rel: "noopener")) %> +

    +
    +
    +
    +

    <%= t("home.tos.page_heading") %>

    + <%= render "home/tos", suppress_footer: true %> +

    <%= t("home.content.page_heading") %>

    + <%= render "home/content", suppress_toc: true, suppress_footer: true %> +

    <%= t("home.privacy.page_heading") %>

    + <%= render "home/privacy", suppress_toc: true %> +
    +
    +
    +

    + <%= f.check_box :terms_of_service %> + <%= f.label :terms_of_service, t(".agreement_confirm"), class: "important" %> +

    +

    + <%= f.check_box :data_processing %> + <%= f.label :data_processing, t(".data_processing_confirm"), class: "important" %> +

    diff --git a/app/views/users/registrations/_passwd.html.erb b/app/views/users/registrations/_passwd.html.erb new file mode 100755 index 0000000..68f5a38 --- /dev/null +++ b/app/views/users/registrations/_passwd.html.erb @@ -0,0 +1,44 @@ +
    +
    + <%= f.label :login, t(".username") %> +
    +
    + <%= f.text_field :login, "aria-describedby" => "login-field-description" %> + <%= live_validation_for_field("user_registration_login", + maximum_length: ArchiveConfig.LOGIN_LENGTH_MAX, + minimum_length: ArchiveConfig.LOGIN_LENGTH_MIN, + failureMessage: t(".username_validation", minimum: ArchiveConfig.LOGIN_LENGTH_MIN)) %> +

    + <%= t(".username_requirements", + minimum: ArchiveConfig.LOGIN_LENGTH_MIN, + maximum: ArchiveConfig.LOGIN_LENGTH_MAX) %> +

    +
    +
    + <%= f.label :password, t(".password") %> +
    +
    + <%= f.password_field :password, "aria-describedby" => "password-field-description" %> + <%= live_validation_for_field("user_registration_password", + minimum_length: ArchiveConfig.PASSWORD_LENGTH_MIN, + maximum_length: ArchiveConfig.PASSWORD_LENGTH_MAX, + failureMessage: t(".password_validation", minimum: ArchiveConfig.PASSWORD_LENGTH_MIN)) %> +

    + <%= t(".password_requirements", + minimum: ArchiveConfig.PASSWORD_LENGTH_MIN, + maximum: ArchiveConfig.PASSWORD_LENGTH_MAX) %> +

    +
    +
    <%= f.label :password_confirmation, t(".confirm_password") %>
    +
    + <%= f.password_field :password_confirmation %> + <%= live_validation_for_field("user_registration_password_confirmation", + minimum_length: ArchiveConfig.PASSWORD_LENGTH_MIN, + maximum_length: ArchiveConfig.PASSWORD_LENGTH_MAX, + failureMessage: t(".confirm_password_validation")) %> +
    +
    + <%= f.label :email, t(".valid_email") %> +
    +
    <%= f.text_field :email %>
    +
    diff --git a/app/views/users/registrations/new.html.erb b/app/views/users/registrations/new.html.erb new file mode 100755 index 0000000..56184ce --- /dev/null +++ b/app/views/users/registrations/new.html.erb @@ -0,0 +1,29 @@ + +

    <%= t(".heading") %>

    +<%= error_messages_for :user %> + + + + +<%= form_for resource, as: :user_registration, url: registration_path(resource_name), :html => {:id => "user_registration_form"} do |f| %> + <%= hidden_field_tag :invitation_token, resource.invitation_token %> + +
    + <%= t(".legend.user") %> + <%= render :partial => "passwd", :locals => {:f => f} %> +
    + +
    + <%= t(".legend.legal") %> + <%= render :partial => "legal", :locals => {:f => f} %> +
    + +
    + <%= t(".submit") %> +

    + <%= link_to t(".cancel"), root_path %> + <%= submit_tag t(".submit"), data: { disable_with: t(".wait") } %> +

    +
    +<% end %> + diff --git a/app/views/users/sessions/_greeting.html.erb b/app/views/users/sessions/_greeting.html.erb new file mode 100755 index 0000000..e5688cd --- /dev/null +++ b/app/views/users/sessions/_greeting.html.erb @@ -0,0 +1,60 @@ + + diff --git a/app/views/users/sessions/_login.html.erb b/app/views/users/sessions/_login.html.erb new file mode 100755 index 0000000..3342ba1 --- /dev/null +++ b/app/views/users/sessions/_login.html.erb @@ -0,0 +1,3 @@ + diff --git a/app/views/users/sessions/_passwd.html.erb b/app/views/users/sessions/_passwd.html.erb new file mode 100755 index 0000000..db6eeb1 --- /dev/null +++ b/app/views/users/sessions/_passwd.html.erb @@ -0,0 +1,14 @@ +<%= form_for(User.new, url: new_user_session_path) do |f| %> +
    +
    <%= f.label :login, t(".username_or_email") %>
    +
    <%= f.text_field :login %>
    +
    <%= f.label :password, t(".password") %>
    +
    <%= f.password_field :password %>
    +
    <%= f.label :remember_me, t(".remember_me") %>
    +
    <%= f.check_box :remember_me %>
    +
    <%= t(".landmark_submit") %>
    +
    + <%= f.submit t(".log_in"), class: "submit" %> +
    +
    +<% end %> diff --git a/app/views/users/sessions/_passwd_small.html.erb b/app/views/users/sessions/_passwd_small.html.erb new file mode 100755 index 0000000..3ebcdeb --- /dev/null +++ b/app/views/users/sessions/_passwd_small.html.erb @@ -0,0 +1,29 @@ +<%# We need to override the ids to avoid accessibility issues on the new user session page, +which has a second user session form %> +<%= form_for(User.new, url: user_session_path, html: { id: "new_user_session_small" }) do |f| %> +
    +
    <%= f.label :login, t(".username_or_email"), for: "user_session_login_small" %>
    +
    <%= f.text_field :login, autocomplete: "on", id: "user_session_login_small" %>
    +
    <%= f.label :password, t(".password"), for: "user_session_password_small" %>
    +
    <%= f.password_field :password, id: "user_session_password_small" %>
    +
    +

    + + <%= f.submit t(".log_in") %> +

    +<% end %> + +
      +
    • <%= link_to t(".forgot_password"), new_user_password_path %>
    • + <% if AdminSetting.current.account_creation_enabled? && !AdminSetting.current.creation_requires_invite? %> +
    • + <%= link_to t(".create_an_account"), signup_path %> +
    • + <% elsif AdminSetting.current.invite_from_queue_enabled? %> +
    • + <%= link_to t(".get_an_invitation"), invite_requests_path %> +
    • + <% end %> +
    diff --git a/app/views/users/sessions/confirm_logout.html.erb b/app/views/users/sessions/confirm_logout.html.erb new file mode 100755 index 0000000..10bb0b1 --- /dev/null +++ b/app/views/users/sessions/confirm_logout.html.erb @@ -0,0 +1,8 @@ +

    <%= ts("Log Out") %>

    + +<%= form_tag destroy_user_session_path, method: :delete, class: "simple destroy" do %> +

    <%= ts("Are you sure you want to log out?") %>

    +

    + <%= submit_tag ts("Yes, Log Out") %> +

    +<% end %> diff --git a/app/views/users/sessions/new.html.erb b/app/views/users/sessions/new.html.erb new file mode 100755 index 0000000..85215f8 --- /dev/null +++ b/app/views/users/sessions/new.html.erb @@ -0,0 +1,43 @@ +<% if params[:restricted] %> +

    <%= t(".restricted.sorry") %>

    +

    + <%= t(".restricted.work_unavailable") %> + <%= t(".restricted.account_exists") %> + <% if AdminSetting.current.invite_from_queue_enabled? && AdminSetting.current.creation_requires_invite? %> + <%= t(".restricted.no_account", request_invite_link: link_to(t(".restricted.request_invite"), invite_requests_path)).html_safe %> + <% elsif AdminSetting.current.account_creation_enabled? && !AdminSetting.current.creation_requires_invite? %> + <%= link_to t(".restricted.signup"), signup_path %> + <% end %> +

    +<% elsif params[:restricted_commenting] %> +

    <%= t(".restricted.sorry") %>

    +

    + <%= t(".restricted.commenting_unavailable") %> + <%= t(".restricted.account_exists") %> + <% if AdminSetting.current.invite_from_queue_enabled? && AdminSetting.current.creation_requires_invite? %> + <%= t(".restricted.no_account", request_invite_link: link_to(t(".restricted.request_invite"), invite_requests_path)).html_safe %> + <% elsif AdminSetting.current.account_creation_enabled? && !AdminSetting.current.creation_requires_invite? %> + <%= link_to t(".restricted.signup"), signup_path %> + <% end %> +

    +<% else %> +

    <%= t(".login.log_in") %>

    +

    + <%= t(".beta_reminder.reminder") %> + <%= t(".beta_reminder.warning") %> + <%= t(".beta_reminder.report_bugs", give_feedback_link: link_to(t(".beta_reminder.give_feedback"), feedbacks_path)).html_safe %> +

    +<% end %> + +
    + <%= render "users/sessions/passwd" %> +
    + +

    + <%= t(".login.forgot", reset_password_link: link_to(t(".login.reset_password"), new_user_password_path)).html_safe %> + <% if AdminSetting.current.invite_from_queue_enabled? && AdminSetting.current.creation_requires_invite? %> +
    <%= t(".login.no_account", join_link: link_to(t(".login.request_invite"), invite_requests_path)).html_safe %> + <% elsif AdminSetting.current.account_creation_enabled? && !AdminSetting.current.creation_requires_invite? %> +
    <%= t(".login.no_account", join_link: link_to(t(".login.create_account"), signup_path)).html_safe %> + <% end %> +

    diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb new file mode 100755 index 0000000..5f21f81 --- /dev/null +++ b/app/views/users/show.html.erb @@ -0,0 +1,37 @@ +<% if @user == current_user && @user.preference.try(:first_login) %> + +
    +

    + <%= t(".login_banner.welcome_html", + new_user_tips_link: link_to(t(".login_banner.new_user_tips"), first_login_help_path), + our_faqs_link: link_to(t(".login_banner.our_faqs"), archive_faqs_path)) %> +

    +

    + <%= t(".login_banner.help_html", + contact_support_link: link_to(t(".login_banner.contact_support"), new_feedback_report_path), + tos_link: link_to(t(".login_banner.tos"), tos_path), + content_policy_link: link_to(t(".login_banner.content_policy"), content_path), + privacy_policy_link: link_to(t(".login_banner.privacy_policy"), privacy_path), + contact_abuse_link: link_to(t(".login_banner.contact_abuse"), new_abuse_report_path)) %> +

    + <%= form_tag end_first_login_user_path(current_user), method: :post, remote: true do %> +

    + <%= submit_tag t(".login_banner.dismiss") %> + <%= link_to "×".html_safe, nil, remote: true, id: "hide-first-login-help", title: t(".login_banner.hide") %> +

    + <% end %> +
    +<% end %> + +
    + <%= render "users/header" %> + <%= render "users/contents" %> +
    + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j("#hide-first-login-help").click(function() { + $j("#first-login-help-banner").hide(); + }) + <% end %> +<% end %> diff --git a/app/views/works/_adult.html.erb b/app/views/works/_adult.html.erb new file mode 100755 index 0000000..9d6b41d --- /dev/null +++ b/app/views/works/_adult.html.erb @@ -0,0 +1,29 @@ +

    <%= t(".page_title") %>

    + +

    + <%= t(".caution") %> +

    + +
      +
    • + <%= link_to t(".navigation.continue"), current_path_with(view_adult: true) %> +
    • +
    • + <%= link_to t(".navigation.back"), :back %> +
    • + <% if logged_in? %> +
    • + <%= link_to t(".navigation.preferences"), user_preferences_path(current_user) %> +
    • + <% end %> +
    + +

    + <%= t(".footnote") %> +

    + +
    + +
      + <%= render "works/work_blurb", work: @work %> +
    diff --git a/app/views/works/_collection_filters.html.erb b/app/views/works/_collection_filters.html.erb new file mode 100755 index 0000000..e939239 --- /dev/null +++ b/app/views/works/_collection_filters.html.erb @@ -0,0 +1,57 @@ +<%= form_for @search, as: :work_search, + url: collected_user_works_path(@user), + html: { + method: :get, + class: 'narrow-hidden filters', + id: 'works-in-collections-filters' + } do |f| %> +

    <%= ts("Filters") %>

    + <%= field_set_tag (ts('Filter results:') + link_to_help("filters")).html_safe do %> + +

    + <%= link_to ts("Clear Filters"), collected_user_works_path(@user) %> +

    +
    + <%= hidden_field_tag("user_id", @user.login) if @user %> +
    + <% end %> + <% # On narrow screens, link jumps to top of index when JavaScript is disabled and closes filters when JavaScript is enabled %> + +<% end %> + diff --git a/app/views/works/_filters.html.erb b/app/views/works/_filters.html.erb new file mode 100755 index 0000000..62f6121 --- /dev/null +++ b/app/views/works/_filters.html.erb @@ -0,0 +1,199 @@ +<%= form_for @search, as: :work_search, + url: (@collection ? collection_works_path(@collection) : works_path), + html: { + method: :get, + class: "narrow-hidden filters", + id: "work-filters" + } do |f| %> +

    <%= ts("Filters") %>

    + <%= field_set_tag ts("Filter results:") do %> +
    +
    <%= ts("Submit") %>
    +
    <%= f.submit ts("Sort and Filter") %>
    +
    + <%= f.label :sort_column, ts("Sort by") %> +
    +
    + <%= f.select :sort_column, options_for_select(@search.sort_options, @search.sort_column) %> +
    + + <% %w(include exclude).each do |filter_action| %> +
    +

    + <%= ts("%{filter_action}", filter_action: filter_action.titleize) %> +

    + <%= link_to_help "work-filters-#{filter_action}-tags" %> +
    +
    +
    + <% %w(rating archive_warning category fandom character relationship freeform).each do |tag_type| %> +
    + <% # For accessibility, include filter action (e.g. Include) as landmark text %> + <% # The space needs to be in the landmark to keep the text aligned %> + <%= ts("%{filter_action} %{tag_type}", + filter_action: filter_action.titleize, + tag_type: tag_type_label_name(tag_type).pluralize + ).html_safe %> +
    + + <% end %> + <% field_name = filter_action == "include" ? "other_tag_names" : "excluded_tag_names" %> + + +
    +
    + <% end %> + +
    +

    <%= ts("More Options") %>

    +
    + +
    +
    +
    <%= ts("Crossovers") %>
    + +
    <%= ts("Completion Status") %>
    + +
    <%= ts("Word Count") %>
    + +
    <%= ts("Date Updated") %>
    + + + + + + <% unless @language %> +
    + <%= f.label :language_id, ts("Language") %> +
    +
    + <%= f.select(:language_id, language_options_for_select(Language.default_order, "short"), include_blank: true) %> +
    + <% end %> +
    +
    +
    <%= ts("Submit") %>
    +
    <%= f.submit ts("Sort and Filter") %>
    +
    + + <% if @owner %> +

    + <%= link_to ts("Clear Filters"), works_original_path %> +

    + <% end %> + +
    + <%= hidden_field_tag("collection_id", @collection.id) if @collection %> + <%= hidden_field_tag("tag_id", @tag.to_param) if @tag %> + <%= hidden_field_tag("fandom_id", @fandom.id) if @fandom %> + <%= hidden_field_tag("pseud_id", @pseud.name) if @pseud %> + <%= hidden_field_tag("user_id", @user.login) if @user %> + <%= hidden_field_tag("language_id", @language.short) if @language %> +
    + + <% end %> + + <% # On narrow screens, link jumps to top of index when JavaScript is disabled and closes filters when JavaScript is enabled %> + + +<% end %> + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(".datepicker").datepicker({ + dateFormat: "yy-mm-dd" + }); + <% end %> +<% end %> diff --git a/app/views/works/_hidden_fields.html.erb b/app/views/works/_hidden_fields.html.erb new file mode 100755 index 0000000..a028c2e --- /dev/null +++ b/app/views/works/_hidden_fields.html.erb @@ -0,0 +1,55 @@ + + + +
    + <%= form.fields_for :author_attributes do |creator_form| %> + <% (@work.current_user_pseuds || []).each do |pseud| %> + <%= creator_form.hidden_field :ids, value: pseud.id, multiple: true %> + <% end %> + + <% @work.creatorships.each do |creatorship| %> + <% if creatorship.new_record? %> + <%= creator_form.hidden_field :coauthors, value: creatorship.pseud_id, multiple: true %> + <% end %> + <% end %> + <% end %> + +<%= form.hidden_field :rating_string, :value => "#{@work.rating_string}" %> +<%= form.hidden_field :archive_warning_string, :value => "#{@work.archive_warning_string}" %> +<%= form.hidden_field :category_string, :value => "#{@work.category_string}" %> +<%= form.hidden_field :fandom_string, :value => "#{@work.fandom_string}" %> +<%= form.hidden_field :relationship_string, :value => "#{@work.relationship_string}" %> +<%= form.hidden_field :character_string, :value => "#{@work.character_string}" %> +<%= form.hidden_field :freeform_string, :value => "#{@work.freeform_string}" %> + +<%= form.hidden_field :title, :value => "#{@work.title}" %> +<%= form.hidden_field :summary, :value => "#{@work.summary}" %> +<%= form.hidden_field :collection_names, :value => "#{@work.collection_names}" %> +<%= form.hidden_field :recipients, :value => "#{@work.recipients}" %> +<%= form.hidden_field :notes, :value => "#{@work.notes}" %> +<%= form.hidden_field :endnotes, :value => "#{@work.endnotes}" %> +<%= fields_for "work[chapter_attributes]", @chapter do |c| %> + <%= c.hidden_field :content, :value => "#{@chapter.content}" %> + <%= c.hidden_field :title, :value => "#{@chapter.title}" %> + <%= c.hidden_field :published_at, :value => "#{@chapter.published_at}" %> +<% end %> +<%= fields_for "work[series_attributes]" do |s| %> + <%= s.hidden_field :id, value: "#{work_series_value(:id)}" %> + <%= s.hidden_field :title, value: "#{work_series_value(:title)}" %> +<% end %> + +<%= form.fields_for :parent_work_relationships, @work.parent_work_relationships.select(&:new_record?) do |p| %> + <%= p.hidden_field :url %> + <%= p.hidden_field :title %> + <%= p.hidden_field :author %> + <%= p.hidden_field :language_id %> + <%= p.hidden_field :translation %> +<% end %> + +<%= form.hidden_field :backdate, :value => "#{@work.backdate}" %> +<%= form.hidden_field :wip_length, :value => "#{@work.wip_length}" %> +<%= form.hidden_field :restricted, :value => "#{@work.restricted}" %> +<%= form.hidden_field :comment_permissions, :value => "#{@work.comment_permissions}" %> +<%= form.hidden_field :language_id, :value => "#{@work.language_id}" %> +<%= form.hidden_field :work_skin_id, :value => "#{@work.work_skin_id}" %> +
    diff --git a/app/views/works/_meta.html.erb b/app/views/works/_meta.html.erb new file mode 100755 index 0000000..a122e89 --- /dev/null +++ b/app/views/works/_meta.html.erb @@ -0,0 +1,117 @@ +<% cache_unless(@preview_mode, "/v4/#{work.cache_key}-#{Work.work_blurb_version(work.id)}-meta-#{hide_warnings?(work) ? 'nowarn' : 'showwarn'}-#{hide_freeform?(work) ? 'nofreeform' : 'showfreeform'}", skip_digest: true) do %> +

    <%= ts("Work Header") %>

    + +
    + +
    + <% tag_group = work.tag_groups + Tag::VISIBLE.each do |type| %> + <% tags = tag_group[type] %> + <% unless tags.blank? %> +
    + + <% if type == "ArchiveWarning" %> + <%= link_to( tags.size == 1 ? type.constantize::NAME : type.constantize::NAME.pluralize, tos_faq_path(:anchor => "tags") ) %>: + <% elsif type.constantize::NAME == ArchiveConfig.FREEFORM_CATEGORY_NAME %> + <%= type.constantize::NAME %>: + <% else %> + <%= tags.size == 1 ? type.constantize::NAME : type.constantize::NAME.pluralize %>: + <% end %> +
    + +
    +
      + <% if (type == "ArchiveWarning" && hide_warnings?(work)) || (type == "Freeform" && hide_freeform?(work)) %> + <%= show_hidden_tag_link_list_item(work, type, { suppress_toggle_class: true }) %> + <% else %> + <%= tag_link_list(tags, link_to_works=true) %> + <% end %> +
    +
    + <% end %> + <% end %> + + <% unless @work.language.blank? %> +
    + <%= ts("Language:") %> +
    +
    + <%= @work.language.name %> +
    + <% end %> + + <% unless @work.serial_works.blank? %> +
    + <%= ts("Series:") %> +
    +
    + <%= show_series_data(@work) %> +
    + <% end %> + + <% unless @work.approved_collections.empty? %> +
    + <%= ts('Collections:') %> +
    +
    + <%= show_collections_data(@work.approved_collections) %> +
    + <% end %> + +
    <%= ts("Stats:") %>
    +
    +<% end %> + + <%= work_meta_list(@work, @chapter) %> +
    + <% if policy(:user_creation).show_original_creators? %> + <% if @work.original_creators.any? %> + <% original_creators = @work.original_creators.map(&:display) %> +
    + <%= t('.original_creators', count: original_creators.count) %> +
    +
    + <%= original_creators.join(", ") %> +
    + <% end %> + <% end %> + <% if policy(:user_creation).show_ip_address? %> +
    + <%= ts('IP Address:') %> +
    +
    + <% if @work.ip_address.nil? %> + <%= ts('No address recorded') %> + <% else %> + <%= @work.ip_address %> + <% end %> +
    + <% end %> + <% if logged_in_as_admin? %> +
    + <%= ts('Akismet Reported As Spam:') %> +
    +
    + <% if !@work.spam_checked? %> + <%= ts('No result recorded') %> + <% else %> + <%= @work.spam? %> + <% end %> +
    +
    + <%= ts("Over Tag Limit:") %> +
    +
    + <%= @work.user_defined_tags_count > ArchiveConfig.USER_DEFINED_TAGS_MAX ? ts("Yes") : ts("No") %> +
    + <% if @work.gifts.are_rejected.exists? %> +
    + <%= ts('Refused As Gift:') %> +
    +
    + <%= @work.gifts.are_rejected.map { |g| g.recipient }.join(", ") %> +
    + <% end %> + <% end %> +
    +
    diff --git a/app/views/works/_mystery_blurb.html.erb b/app/views/works/_mystery_blurb.html.erb new file mode 100755 index 0000000..9b7cb6b --- /dev/null +++ b/app/views/works/_mystery_blurb.html.erb @@ -0,0 +1,11 @@ +
    +

    <%= ts("Mystery Work") %>

    + <% if item.approved_collections.unrevealed.present? %> +
    <%= h(ts("Part of ")) + show_collections_data(item.approved_collections.unrevealed) %>
    + <% end %> +
    +
    +
    <%= ts("Summary") %>
    +
    +

    <%= ts("This is part of an ongoing challenge and will be revealed soon!") %>

    +
    diff --git a/app/views/works/_notes_form.html.erb b/app/views/works/_notes_form.html.erb new file mode 100755 index 0000000..eb39ecc --- /dev/null +++ b/app/views/works/_notes_form.html.erb @@ -0,0 +1,40 @@ +
    <%= type == "chapter" ? ts("Chapter Notes") : ts("Notes") %>
    +
    +
      +
    • + <% if !params[:claim_id].blank? %> + <%= check_box_tag "front-notes-options-show", "1", true, :class => "toggle_formfield" %> + <%= label_tag 'front-notes-options-show', ts("at the beginning") %> + <% else %> + <%= check_box_tag "front-notes-options-show", "1", !f.object.notes.blank?, :class => "toggle_formfield" %> + <%= label_tag 'front-notes-options-show', ts("at the beginning") %> + <% end %> + + <%= ts("Warning: Unchecking this box will delete the existing beginning note.") %> + +
      + <%= f.label :notes, ts("Notes") %> + <% if @posting_claim && @posting_claim.prompt_description.present? %> + <%= f.text_area :notes, :class => "observe_textlength", :value => "Prompt: #{@posting_claim.prompt_description}" %> + <%= generate_countdown_html("#{type}_notes", ArchiveConfig.NOTES_MAX) %> + <% else %> + <%= f.text_area :notes, :class => "observe_textlength" %> + <%= generate_countdown_html("#{type}_notes", ArchiveConfig.NOTES_MAX) %> + <% end %> +
      +
    • + +
    • + <%= check_box_tag "end-notes-options-show", "1", !f.object.endnotes.blank?, :class => "toggle_formfield" %> + <%= label_tag 'end-notes-options-show', ts("at the end") %> + + <%= ts("Warning: Unchecking this box will delete the existing end note.") %> + +
      + <%= f.label :endnotes, ts("End Notes") %> + <%= f.text_area :endnotes, :class => "observe_textlength" %> + <%= generate_countdown_html("#{type}_endnotes", ArchiveConfig.NOTES_MAX) %> +
      +
    • +
    +
    diff --git a/app/views/works/_search_box.html.erb b/app/views/works/_search_box.html.erb new file mode 100755 index 0000000..fb18011 --- /dev/null +++ b/app/views/works/_search_box.html.erb @@ -0,0 +1,10 @@ +<%= form_for WorkSearchForm.new, as: :work_search, url: search_works_path, html: { class: "search", id: "search", role: "search", "aria-label": t(".a11y_label"), method: :get } do |f| %> +
    +

    + <%= label_tag :site_search, t(".label"), class: "landmark" %> + <%= f.text_field :query, class: "text", id: "site_search", "aria-describedby": "site_search_tooltip" %> + <%= t(".tooltip_label") %> <%= random_search_tip %> + <%= submit_tag t(".submit"), class: "button", name: nil %> +

    +
    +<% end %> diff --git a/app/views/works/_search_form.html.erb b/app/views/works/_search_form.html.erb new file mode 100755 index 0000000..d1908bd --- /dev/null +++ b/app/views/works/_search_form.html.erb @@ -0,0 +1,212 @@ +<%= form_for @search, as: :work_search, url: search_works_path, html: { method: :get, class: "verbose search" } do |f| %> +
    + <%= ts("Work Info") %> +

    <%= ts("Work Info") %>

    +

    <%= f.submit ts("Search") %>

    +
    +
    + <%= f.label :query, ts("Any Field") %> + <%= link_to_help "work-search-text-help" %> +
    +
    + <%= f.text_field :query %> +
    +
    + <%= f.label :title, ts("Title") %> +
    +
    + <%= f.text_field :title %> +
    +
    + <%= f.label :creators, t(".creator") %> +
    +
    + <%= f.text_field :creators %> +
    +
    + <%= f.label :revised_at, ts("Date") %> + <%= link_to_help "work-search-date-help" %> +
    +
    + <%= f.text_field :revised_at %> +
    +
    <%= ts("Completion status") %>
    +
    +
      +
    • + <%= f.radio_button :complete, "" %> + <%= f.label :complete, ts("All works"), value: "" %> +
    • +
    • + <%= f.radio_button :complete, "T" %> + <%= f.label :complete, ts("Complete works only"), value: "T" %> +
    • +
    • + <%= f.radio_button :complete, "F" %> + <%= f.label :complete, ts("Works in progress only"), value: "F" %> +
    • +
    +
    +
    + <%= ts("Crossovers") %> + <%= link_to_help "work-search-crossover-help" %> +
    +
    +
      +
    • + <%= f.radio_button :crossover, "" %> + <%= f.label :crossover, ts("Include crossovers"), value: "" %> +
    • +
    • + <%= f.radio_button :crossover, "F" %> + <%= f.label :crossover, ts("Exclude crossovers"), value: "F" %> +
    • +
    • + <%= f.radio_button :crossover, "T" %> + <%= f.label :crossover, ts("Only crossovers"), value: "T" %> +
    • +
    +
    +
    + <%= f.label :single_chapter, ts("Single Chapter") %> +
    +
    + <%= f.check_box :single_chapter %> +
    +
    + <%= f.label :word_count, ts("Word Count") %> + <%= link_to_help "work-search-numerical-help" %> +
    +
    + <%= f.text_field :word_count %> +
    +
    + <%= f.label :language_id, ts("Language") %> + <%= link_to_help "work-search-language-help" %> +
    +
    + <%= f.select(:language_id, language_options_for_select(@languages, "short"), include_blank: true) %> +
    +
    +
    + +
    + <%= ts("Work Tags") %> <%= link_to_help "work-search-tags-help" %> +

    <%= ts("Work Tags") %>

    +
    +
    + <%= f.label :fandom_names, ts("Fandoms") %> +
    +
    + <%= f.text_field :fandom_names, autocomplete_options("fandom") %> +
    +
    + <%= f.label :rating_ids, ts("Rating") %> +
    +
    + <%= f.collection_select :rating_ids, + Rating.defaults_by_severity, + :id, + :name, + include_blank: true %> +
    +
    + <%= ts("Warnings") %> +
    +
    +
      + <% for tag in ArchiveWarning.canonical.by_name %> +
    • + <%= check_box_tag "work_search[archive_warning_ids][]", tag.id, @search.archive_warning_ids.present? && @search.archive_warning_ids.include?(tag.id.to_s), :id => "warning_#{tag.id}" %> + <%= label_tag "warning_#{tag.id}", warning_display_name(tag.name) %> +
    • + <% end %> +
    +
    +
    + <%= ts("Categories") %> +
    +
    +
      + <% for tag in Category.canonical.by_name.sort %> +
    • + <%= check_box_tag "work_search[category_ids][]", tag.id, @search.category_ids.present? && @search.category_ids.include?(tag.id.to_s), :id => "category_#{tag.id}" %> + <%= label_tag "category_#{tag.id}", tag.name %> +
    • + <% end %> +
    +
    +
    + <%= f.label :character_names, ts("Characters") %> +
    +
    + <%= f.text_field :character_names, autocomplete_options("character") %> +
    +
    + <%= f.label :relationship_names, ts("Relationships") %> +
    +
    + <%= f.text_field :relationship_names, autocomplete_options("relationship") %> +
    +
    + <%= f.label :freeform_names, ts("Additional Tags") %> +
    +
    + <%= f.text_field :freeform_names, autocomplete_options("freeform") %> +
    +
    +
    + +
    + <%= ts("Work Stats") %> <%= link_to_help "work-search-numerical-help" %> +

    <%= ts("Work Stats") %>

    +
    +
    + <%= f.label :hits, ts("Hits") %> +
    +
    + <%= f.text_field :hits %> +
    +
    + <%= f.label :kudos_count, ts("Kudos") %> +
    +
    + <%= f.text_field :kudos_count %> +
    +
    + <%= f.label :comments_count, ts("Comments") %> +
    +
    + <%= f.text_field :comments_count %> +
    +
    + <%= f.label :bookmarks_count, ts("Bookmarks") %> +
    +
    + <%= f.text_field :bookmarks_count %> +
    +
    +
    + +
    + <%= ts("Search") %> +

    <%= ts("Search") %>

    +
    +
    + <%= f.label :sort_column, ts("Sort by") %> +
    +
    + <%= f.select :sort_column, options_for_select(@search.sort_options, @search.sort_column) %> +
    +
    + <%= f.label :sort_direction, ts("Sort direction") %> +
    +
    + <%= f.select :sort_direction, + options_for_select([["Ascending", "asc"], ["Descending", "desc"]], @search.sort_direction) %> +
    +
    +

    <%= f.submit ts("Search") %>

    +
    + +<% end %> diff --git a/app/views/works/_standard_form.html.erb b/app/views/works/_standard_form.html.erb new file mode 100755 index 0000000..32ac453 --- /dev/null +++ b/app/views/works/_standard_form.html.erb @@ -0,0 +1,378 @@ + +<%= form_for(@work, html: { id: "work-form", class: "verbose post work" }) do |f| %> + +

    * <%= ts("Required information") %>

    + + <%= render "work_form_tags", include_blank: false %> + +
    + <%= t("works.preface.title") %> +

    <%= t("works.preface.title") %>

    +
    +
    + <%= f.label :title, ts("Work Title") + "*" %> +
    +
    + <%= f.text_field :title, class: "observe_textlength text" %> + <%= live_validation_for_field("work_title", + maximum_length: ArchiveConfig.TITLE_MAX, + minimum_length: ArchiveConfig.TITLE_MIN, + failureMessage: ts("We need a title! (At least %{min_length} character long, please.)", + min_length: ArchiveConfig.TITLE_MIN.to_s)) + %> + <%= generate_countdown_html("work_title", ArchiveConfig.TITLE_MAX) %> +
    + + + <%= render "pseuds/byline", form: f, object: @work %> + +
    + <%= f.label :summary, ts("Summary", max: ArchiveConfig.SUMMARY_MAX.to_s) %> +
    +
    + <%= f.text_area :summary, class: "observe_textlength" %> + <%= live_validation_for_field("work_summary", presence: false, + maximum_length: ArchiveConfig.SUMMARY_MAX) %> + <%= generate_countdown_html("work_summary", ArchiveConfig.SUMMARY_MAX) %> +
    + + + <%= render "notes_form", f: f, type: "work" %> + +
    +
    + +
    + <%= t("works.associations.title") %> +

    <%= t("works.associations.title") %>

    +
    + <% @assignments = get_open_assignments(current_user) %> + <% if @assignments.any? || @work.challenge_assignments.any? %> + +
    + <%= f.label "challenge_assignment_ids[]", ts("Does this fulfill a challenge assignment") %> + <%= link_to_help "add-work-to-assignment" %> +
    +
    +

    <%= ts("Open Assignments") %>

    + <%= checkbox_section f, :challenge_assignment_ids, (@work.challenge_assignments + @assignments).uniq, + :checked_method => "challenge_assignments", :name_method => "title" %> +
    + <% end %> + + <% if !(@claims = current_user.request_claims.unstarted).empty? || !@work.challenge_claims.empty? %> + +
    + <%= f.label "challenge_claim_ids[]", ts("Fulfill a Claim") %> + <%= link_to_help "add-work-to-assignment" %> +
    +
    +

    <%= ts("Open Claims") %>

    + <%= checkbox_section f, :challenge_claim_ids, (@work.challenge_claims + @claims).uniq, + :checked_method => "challenge_claims", :name_helper_method => "claim_title" %> +
    + <% end %> + + +
    "> + <%= f.label :collection_names, ts("Post to Collections / Challenges") %> + <%= link_to_help "add-collectible-to-collection" %> +
    +
    "> + <%= f.text_field :collection_names, autocomplete_options("open_collection_names") %> +
    + +
    "> + <%= f.label :recipients, ts("Gift this work to") %> + <%= link_to_help "recipients" %> +
    +
    "> + <%= f.text_field :recipients, autocomplete_options("pseud", value: @work.recipients(for_form = true)) %> +
    + + +
    + <%= check_box_tag "parent-options-show", "1", check_parent_box(@work), class: "toggle_formfield" %> +
    +
    + <%= label_tag "parent-options-show", ts("This work is a remix, a translation, a podfic, or was inspired by another work") %> + <%= link_to_help "parent-works-help" %> + + +
    +
    + <% new_parent, existing_parents = @work.parent_work_relationships.partition(&:new_record?) %> + <% new_parent << @work.parent_work_relationships.build if new_parent.empty? %> + + <%= f.fields_for :parent_work_relationships, new_parent do |p| %> +
    <%= p.label :url, ts("URL") %>
    +
    + <%= p.text_field :url, + "aria-describedby" => "parent-attributes-url-field-description" %> +

    + <%= ts("For a work in the Archive, only the URL is required.") %> +

    +
    + +
    <%= p.label :title %>
    +
    <%= p.text_field :title %>
    + +
    <%= p.label :author %>
    +
    <%= p.text_field :author %>
    + +
    + <%= p.label :language_id, ts("Language") %> + <%= link_to_help "languages-help" %> +
    +
    + <%= p.select(:language_id, language_options_for_select(sorted_languages, "id"), prompt: " ") %> +
    + +
    <%= p.check_box :translation %>
    +
    + <%= p.label :translation, ts("This is a translation") %> + <%= link_to_help "translation-link" %> +
    + <% end %> + + <% unless existing_parents.blank? %> +
    <%= ts("Current parent works") %>
    + <% existing_parents.each do |related_work| %> + <% if related_work.parent %> +
    + +
    + <% end %> + <% end %> + <% end %> +
    +
    +
    + + + +
    + <%= check_box_tag "series-options-show", "1", check_series_box(@work), class: "toggle_formfield" %> +
    +
    + <%= label_tag "series-options-show", ts("This work is part of a series") %> + <%= link_to_help "choosing-series" %> + + +
    +
    + <%= fields_for "work[series_attributes]" do |s| %> +
    <%= s.label "id", ts("Choose one of your existing series:") %>
    +
    + <%= s.collection_select(:id, @series, :id, :title, { selected: work_series_value(:id), prompt: true }) %> +
    + +
    <%= s.label :title, ts("Or create and use a new one:") %>
    +
    <%= s.text_field :title, value: work_series_value(:title) %>
    + <% end %> + + <% unless @serial_works.blank? || @work.new_record? %> +
    <%= ts("Current Series") %>
    + <% for serial in @serial_works %> + <% unless serial.new_record? %> +
    + +
    + <% end %> + <% end %> + <% end %> +
    +
    +
    + + <%= fields_for "work[chapter_attributes]", @chapter do |c| %> + + +
    + <%= check_box_tag "chapters-options-show", "1", @work.chaptered?, class: "toggle_formfield" %> +
    +
    + <%= label_tag "chapters-options-show", ts("This work has multiple chapters") %> + +
    +
    +
    <%= f.label :wip_length, ts("Chapter 1 of") %>
    +
    <%= f.text_field :wip_length, class: "number" %>
    +
    <%= c.label :title, ts("Chapter Title:") %>
    +
    <%= c.text_field :title, value: @chapter.title %>
    +
    +
    +
    + + +
    + <%= f.check_box :backdate, { id: "backdate-options-show", class: "toggle_formfield" } %> +
    +
    + <%= label_tag "backdate-options-show", ts("Set a different publication date") %> + <%= link_to_help "backdating-help" %> + +
    +
    +
    <%= label_tag "published_at", ts("Set publication date") %>
    +
    "> + + <%= c.date_select("published_at", :start_year => Date.current.year, :end_year => 1950, :default => Date.current, :value => @chapter.published_at, :order => [:day, :month, :year]) %> +
    +
    +
    +
    + + <%= render "work_form_associations_language", f: f %> + +
    + <%= f.label :work_skin_id, t("works.skin.select") %> + <%= link_to_help "work-skins" %> +
    +
    + <%= f.collection_select :work_skin_id, all_coauthor_skins, :id, :title, + { :selected => (@work.work_skin ? @work.work_skin.id.to_s : nil), include_blank: true } %> + +
    +
    + +
    + + +
    + <%= t("works.permissions.privacy") %> +

    <%= t("works.permissions.privacy") %>

    +
    + +
    + <%= f.check_box :restricted %> +
    + +
    + <%= f.label :restricted, t("works.permissions.visibility.restricted") %> + <%= link_to_help "registered-users" %> +
    + +
    + <%= f.check_box :moderated_commenting_enabled %> +
    +
    + <%= f.label :moderated_commenting_enabled, t("comments.commentable.permissions.moderated_commenting.enable") %> + <%= link_to_help "comments-moderated" %> +
    + +
    + <%= t("comments.commentable.permissions.options.label") %> + <%= link_to_help "who-can-comment-on-this-work" %> +
    +
    +
    + <%= + radio_button_list(f, :comment_permissions, [ + [:enable_all, t("comments.commentable.permissions.options.enable_all")], + [:disable_anon, t("comments.commentable.permissions.options.disable_anon")], + [:disable_all, t("comments.commentable.permissions.options.disable_all")] + ]) + %> +
    +
    + +
    +
    + <% unless @chapters %> + +
    + <%= ts("Work Text") %>* + +

    + <%= allowed_html_instructions %> + +

    +

    + <%= ts("Note: Text entered in the posting form is not automatically saved. Always keep a backup copy of your work.").html_safe %> +

    + + <% use_tinymce %> +
    +

    <%= ts("Work Text") %>*

    + <%= c.text_area :content, value: @chapter.content, + class: "mce-editor observe_textlength large", id: "content" %> + <%= live_validation_for_field("content", + maximum_length: ArchiveConfig.CONTENT_MAX_DISPLAYED, + minimum_length: ArchiveConfig.CONTENT_MIN, + tooLongMessage: ts("We salute your ambition! But sadly the content must be less than %{max} characters long. (Maybe you want to create a multi-chaptered work?)", + max: ArchiveConfig.CONTENT_MAX_DISPLAYED.to_s), + tooShortMessage: ts("Brevity is the soul of wit, but your content does have to be at least %{min} characters long.", + min: ArchiveConfig.CONTENT_MIN.to_s), + failureMessage: ts("Brevity is the soul of wit, but your content does have to be at least %{min} characters long.", + min: ArchiveConfig.CONTENT_MIN.to_s)) + %> + + <%= generate_countdown_html("content", ArchiveConfig.CONTENT_MAX_DISPLAYED) %> +
    +
    + <% end %> + + <% end %> + +
    + <%= ts("Post") %> +

    + <%= t(".post_notice_html", + content_policy_link: link_to(t(".content_policy"), content_path), + tos_faq_link: link_to(t(".tos_faq"), tos_faq_path(anchor: "content_faq"))) %> +

    +
      + <% unless @work.new_record? || @work.posted? %> +
    • + <%= submit_tag ts("Save As Draft"), name: "save_button" %> +
    • + <% end %> +
    • + <%= submit_tag ts("Preview"), name: "preview_button" %> +
    • +
    • + <%= submit_tag ts("Post"), name: "post_button", + data: { disable_with: ts("Please wait...") } %> +
    • +
    • + <%= submit_tag ts("Cancel"), name: "cancel_button" %> +
    • +
    +
    +<% end %> + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(document).ready(function(){ + $j(".toggle_formfield").click(function() { + var targetId = $j(this).attr("id").replace("-show", ""); + toggleFormField(targetId); + }); + }) + <% end %> +<% end %> diff --git a/app/views/works/_work_abbreviated_list.html.erb b/app/views/works/_work_abbreviated_list.html.erb new file mode 100755 index 0000000..40c236e --- /dev/null +++ b/app/views/works/_work_abbreviated_list.html.erb @@ -0,0 +1,17 @@ +<% # this partial is intended to be used wherever an abbreviated list of works is desired instead of the full listing with blurbs %> +<% # expects local "works" %> + +
    + <% works.each do |work| tag_groups = work.tag_groups %> +
    + <%= link_to work.title, work %> + (<%= tag_groups["Fandom"].collect {|tag| link_to_tag_works(tag) }.join(', ').html_safe %>) +
    +
    +
      + <%= blurb_tag_block(work) %> +
    +
    + <% end %> +
    + diff --git a/app/views/works/_work_approved_children.html.erb b/app/views/works/_work_approved_children.html.erb new file mode 100755 index 0000000..9f7ee8f --- /dev/null +++ b/app/views/works/_work_approved_children.html.erb @@ -0,0 +1,15 @@ + + +
    +

    <%= t(".inspired_by.title") %>:

    +
      + <%# i18n-tasks-use t("works.work_approved_children.inspired_by.restricted_html") %> + <%# i18n-tasks-use t("works.work_approved_children.inspired_by.revealed_html") %> + <%# i18n-tasks-use t("works.work_approved_children.inspired_by.unrevealed") %> + <% for child_work in inspired_by %> +
    • + <%= related_work_note(child_work.work, "inspired_by") %> +
    • + <% end %> +
    +
    diff --git a/app/views/works/_work_blurb.html.erb b/app/views/works/_work_blurb.html.erb new file mode 100755 index 0000000..74ff518 --- /dev/null +++ b/app/views/works/_work_blurb.html.erb @@ -0,0 +1,22 @@ +<% # expects "work" %> +
  • + <%= render "works/work_module", work: work %> + <% if is_author_of?(work) %> +
    <%= ts("Author Actions") %>
    + + <% end %> +
  • diff --git a/app/views/works/_work_endnotes.html.erb b/app/views/works/_work_endnotes.html.erb new file mode 100755 index 0000000..835d60d --- /dev/null +++ b/app/views/works/_work_endnotes.html.erb @@ -0,0 +1,6 @@ + +
    +

    <%= ts("Notes:") %>

    +
    <%=raw sanitize_field(@work, :endnotes) %>
    +
    + \ No newline at end of file diff --git a/app/views/works/_work_form_associations_language.html.erb b/app/views/works/_work_form_associations_language.html.erb new file mode 100755 index 0000000..ae20bac --- /dev/null +++ b/app/views/works/_work_form_associations_language.html.erb @@ -0,0 +1,11 @@ +<% # expects local variable f %> +
    + <%= f.label :language_id, "#{t('works.associations.language.choose')} *" %> + <%= link_to_help "languages-help" %> +
    +
    + +
    diff --git a/app/views/works/_work_form_pseuds.html.erb b/app/views/works/_work_form_pseuds.html.erb new file mode 100755 index 0000000..872ef30 --- /dev/null +++ b/app/views/works/_work_form_pseuds.html.erb @@ -0,0 +1,23 @@ +<% # expects 'form' and 'works' which can be 1 or more works %> +<% # used exclusively for the edit_multiple works view %> + + +<% has_cocreators = (works.flat_map(&:pseuds).uniq - current_user.pseuds).any? %> +<% has_multiple_pseuds = current_user.pseuds.length > 1 %> +<% if has_multiple_pseuds || has_cocreators %> +
    <%= form.label :current_user_pseud_ids, ts("Creator/Pseud(s)") %>
    +
    + <% if has_multiple_pseuds %> + <%= form.collection_select :current_user_pseud_ids, current_user.pseuds, :id, :name, { include_hidden: false }, { multiple: true } %> + <% end %> + <% if has_cocreators %> + <%= label_tag :remove_me, class: "action" do %> + <%= check_box_tag :remove_me, "1", false %> + <%= ts("Remove me as co-creator") %> + <% end %> + <% end %> +
    +<% end %> + +
    <%= form.label :pseuds_to_add, t("works.byline.add_co-creators") %>
    +
    <%= form.text_field :pseuds_to_add, autocomplete_options("pseud", data: { autocomplete_min_chars: 0 }) %>
    diff --git a/app/views/works/_work_form_tags.html.erb b/app/views/works/_work_form_tags.html.erb new file mode 100755 index 0000000..cd8f003 --- /dev/null +++ b/app/views/works/_work_form_tags.html.erb @@ -0,0 +1,120 @@ +
    + <%= ts('Tags') %> +

    <%= ts('Tags') %>

    + +

    + <%= ts("Tags are comma separated, %{max} characters per tag. Fandom, relationship, character, and additional tags must not add up to more than %{limit}. Archive warning, category, and rating tags do not count toward this limit.", + limit: ArchiveConfig.USER_DEFINED_TAGS_MAX, + max: ArchiveConfig.TAG_MAX) %> +

    + +
    +
    + + <%= link_to_help "rating-help" %> +
    +
    + <%= collection_select :work, + :rating_string, + Rating.defaults_by_severity, + :name, + :name, + include_blank: include_blank, + selected: include_blank ? nil : + rating_selected(@work) %> +
    + +
    + + <%= link_to_help "warning-help" %> +
    +
    +
    + +
      + <%= collection_check_boxes( + :work, :archive_warning_strings, + ArchiveWarning.canonical.by_name, + :name, :name, + include_hidden: !include_blank + ) do |builder| %> +
    • + <%= builder.check_box %> + <%= builder.label %> +
    • + <% end %> +
    +
    +
    + +
    + + <%= link_to_help "fandom-help" %> +
    +
    + <%= text_field_tag "work[fandom_string]", include_blank ? "" : @work.fandom_string, + autocomplete_options('fandom', + :id => "work_fandom", + :title => ts('fandoms')) %> +

    <%= ts('If this is the first work for a fandom, it may not show up in the fandoms page for a day or two.') %>

    +
    + +
    + + <%= link_to_help "categories-help" %> +
    +
    +
    + +
      + <%= collection_check_boxes( + :work, :category_strings, + Category.canonical.by_name.sort, + :name, :name, + include_hidden: !include_blank + ) do |builder| %> +
    • + <%= builder.check_box %> + <%= builder.label %> +
    • + <% end %> +
    +
    +
    + +
    + + <%= link_to_help "relationships-help" %> +
    +
    + <%= text_field_tag "work[relationship_string]", include_blank ? "" : @work.relationship_string, + autocomplete_options("relationship_in_fandom", + id: "work_relationship", + title: ts('relationships'), + data: { autocomplete_live_params: "fandom=work_fandom" }) %> +
    + +
    + + <%= link_to_help "characters-help" %> +
    +
    + <%= text_field_tag "work[character_string]", include_blank ? "" : @work.character_string, + autocomplete_options('character_in_fandom', + id: "work_character", + title: ts('characters'), + data: { autocomplete_live_params: "fandom=work_fandom" }) %> +
    + +
    + + <%= link_to_help "additional-tags-help" %> +
    +
    + <%= text_field_tag "work[freeform_string]", include_blank ? "" : @work.freeform_string, autocomplete_options('freeform', + :id => "work_freeform", + :title => ts('additional tags')) %> +
    + +
    +
    diff --git a/app/views/works/_work_header.html.erb b/app/views/works/_work_header.html.erb new file mode 100755 index 0000000..73d38e2 --- /dev/null +++ b/app/views/works/_work_header.html.erb @@ -0,0 +1,55 @@ +<% unless @preview_mode %> + <%= render "works/work_header_navigation" %> +<% end %> + +<%= render "works/meta", work: @work %> + +<% if @work.work_skin && !Preference.disable_work_skin?(params[:style]) %> + <% cache("#{@work.work_skin.id}-#{@work.work_skin.updated_at}-work-skin", skip_digest: true) do %> + <%= render "skins/skin_style_block", skin: @work.work_skin %> + <% end %> +<% end %> + + +
    +
    +

    + <% if @work.restricted %> + <%= image_tag("lockblue.png", size: "15x15", + alt: ts("(Restricted)"), + title: ts("Restricted"), + skip_pipeline: true) %> + <% end %> + <% if @work.hidden_by_admin %> + <%= image_tag("lockred.png", size: "15x15", + alt: ts("(Hidden by Admin)"), + title: ts("Hidden by Administrator"), + skip_pipeline: true) %> + <% end %> + <%= @work.title %> +

    + + + <% if @chapter == @work.first_chapter %> + + <% unless @work.summary.blank? %> +
    +

    <%= ts("Summary:") %>

    + <% unless @work.summary.blank? %> +
    + <%=raw sanitize_field(@work, :summary) %> +
    + <% end %> +
    + <% end %> + + <% if show_work_notes?(@work) %> + <%= render "works/work_header_notes" %> + <% end %> + + <% end %> +
    + + <% # NOTE: the div id="workskin" is DELIBERATELY not closed in this file! %> diff --git a/app/views/works/_work_header_navigation.html.erb b/app/views/works/_work_header_navigation.html.erb new file mode 100755 index 0000000..454d442 --- /dev/null +++ b/app/views/works/_work_header_navigation.html.erb @@ -0,0 +1,122 @@ + +

    <%= ts("Actions") %>

    + + diff --git a/app/views/works/_work_header_notes.html.erb b/app/views/works/_work_header_notes.html.erb new file mode 100755 index 0000000..a81d38d --- /dev/null +++ b/app/views/works/_work_header_notes.html.erb @@ -0,0 +1,79 @@ +
    +

    <%= ts("Notes:") %>

    + + <%# We don't want the ul tag hanging around when it's empty (i.e. when there are no recipients, parent works, or claims) but we can't skip this entire section because line 25 generates the link to child works that appear under any notes. We repeat this logic on line 63 to close the ul. %> + <% if show_associations?(@work) %> +
      + <% end %> + <%# dedication %> + <% if @work.gifts.not_rejected.exists? %> +
    • <%= ts("For") %> <%= recipients_link(@work) %>.
    • + <% end %> + + <%# translations %> + <%# i18n-tasks-use t("works.work_header_notes.translated_to.restricted_html") %> + <%# i18n-tasks-use t("works.work_header_notes.translated_to.revealed_html") %> + <%# i18n-tasks-use t("works.work_header_notes.translated_to.unrevealed_html") %> + <% for related_work in @work.approved_related_works %> + <% if related_work.translation %> +
    • + <%= related_work_note(related_work.work, "translated_to") %> +
    • + <% else %> + <% related_works_link ||= link_to t(".inspired_by.other_works_inspired_by_this_one"), get_related_works_url %> + <% end %> + <% end %> + + <%# parent works %> + <%# i18n-tasks-use t("works.work_header_notes.translation_of.restricted_html") %> + <%# i18n-tasks-use t("works.work_header_notes.translation_of.revealed_html") %> + <%# i18n-tasks-use t("works.work_header_notes.translation_of.unrevealed") %> + <%# i18n-tasks-use t("works.work_header_notes.inspired_by.restricted_html") %> + <%# i18n-tasks-use t("works.work_header_notes.inspired_by.revealed_html") %> + <%# i18n-tasks-use t("works.work_header_notes.inspired_by.unrevealed") %> + <% for related_work in @work.parents_after_saving %> + <% if related_work.parent %> +
    • + <% relation = related_work.translation ? "translation_of" : "inspired_by" %> + <%= related_work_note(related_work.parent, relation) %> +
    • + <% end %> + <% end %> + + <%# prompts %> + <% @work.challenge_claims.each do |claim| %> + <% unless claim.request_prompt.nil? %> +
    • <%= ts("In response to a ") %><%= link_to("prompt", collection_prompt_path(claim.collection, claim.request_prompt)) %> <%= ts("by") %> + <% if claim.request_prompt.anonymous? %> + <%= ts("Anonymous in the ") %><%= link_to(claim.collection.title, collection_path(claim.collection)) %> + <% else %> + <%= link_to(claim.request_signup.pseud.byline, user_pseud_path(claim.request_signup.user, claim.request_signup.pseud)) %> <%= ts(" in the ") %> <%= link_to(claim.collection.title, collection_path(claim.collection)) %> + <% end %> + <%= ts("collection.") %> +
    • + <% end %> + <% end %> + <% if show_associations?(@work) %> +
    + <% end %> + + <%# notes %> + <% unless @work.notes.blank? %> +
    + <%=raw sanitize_field(@work, :notes) %> +
    + <% end %> + + <% if @work.endnotes.present? || related_works_link %> + <% endnotes_link = link_to (@work.notes.blank? ? t(".jump.notes") : t(".jump.more_notes")), get_endnotes_link(@work) %> +

    + <% if @work.endnotes.present? && related_works_link %> + <%= t(".jump.endnotes_and_related_works_html", endnotes_link: endnotes_link, related_works_link: related_works_link) %> + <% elsif @work.endnotes.present? %> + <%= t(".jump.endnotes_html", endnotes_link: endnotes_link) %> + <% elsif related_works_link %> + <%= t(".jump.related_works_html", related_works_link: related_works_link) %> + <% end %> +

    + <% end %> +
    diff --git a/app/views/works/_work_module.html.erb b/app/views/works/_work_module.html.erb new file mode 100755 index 0000000..88762ca --- /dev/null +++ b/app/views/works/_work_module.html.erb @@ -0,0 +1,121 @@ +<% # expects "work" %> + +<% if work.unrevealed? && !is_author_of?(work) %> + <%= render "works/mystery_blurb", item: work %> +<% else %> + +
    + +

    + <% if (work.unrevealed? || work.anonymous?) && is_author_of?(work) %> + + <% if work.unrevealed? %> + <%= ts("Unrevealed:") %> + <% elsif work.anonymous? %> + <%= ts("Anonymous:") %> + <% end %> + + <% end %> + <%= link_to work.title, @collection ? collection_work_path(@collection, work) : work %> + <%= ts('by') %> + + + <%= byline(work, visibility: "public") %> + +<% #### CACHE show/hide ####, if you update the key edit lib/tasks/memcached.rake %> +<% cache("#{work.cache_key}-#{Work.work_blurb_version(work.id)}-#{hide_warnings?(work) ? 'nowarn' : 'showwarn'}-#{hide_freeform?(work) ? 'nofreeform' : 'showfreeform'}-v11", skip_digest: true) do %> + + <% tag_groups = work.tag_groups %> + + <% if work.gifts.not_rejected.exists? %> + <%= ts("for") %> <%= recipients_link(work) %> + <% end %> + <% if work.restricted %><%= image_tag("lockblue.png", :size => "15x15", :alt => "(Restricted)", :title => "Restricted", skip_pipeline: true) %><% end %> + <% if work.hidden_by_admin %><%= image_tag("lockred.png", :size => "15x15", :alt => "(Hidden by Admin)", :title => "Hidden by Administrator", skip_pipeline: true) %><% end %> +

    + +
    + <%= ts("Fandoms") %>: + <% fandoms = tag_groups['Fandom'] %> + <%= fandoms.collect{|tag| link_to_tag_works(tag) }.join(', ').html_safe if fandoms %> +   +
    + + + <%= get_symbols_for(work, tag_groups) %> +

    <%= set_format_for_date(work.revised_at) %>

    +
    + + <% if !work.posted? %> +

    <%= t('.draft_deletion_notice_html', deletion_date: date_in_zone(work.created_at + 29.days)) %>

    + <% end %> + +
    <%= ts("Tags") %>
    +
      + <%= blurb_tag_block(work, tag_groups) %> +
    + + + <% unless work.summary.blank? %> +
    <%= ts("Summary") %>
    +
    + <%=raw strip_images(sanitize_field(work, :summary)) %> +
    + <% end %> + + <% unless work.series.empty? %> +
    <%= ts("Series") %>
    +
      + <% work.series.each do |series| %> +
    • + <%= work_series_description(work, series) %> +
    • + <% end %> +
    + <% end %> + + + +
    + <% if work.language.present? %> +
    <%= ts("Language") %>:
    +
    <%= work.language.name %>
    + <% end %> +
    <%= ts('Words') %>:
    +
    <%= number_with_delimiter(work.word_count) %>
    +
    <%= ts('Chapters') %>:
    +
    <%= chapter_total_display_with_link(work) %>
    + +<% end %> +<% #### END CACHE show/hide %> + +<% #### CACHE stats #### %> +<% cache("#{work.cache_key}/stats-v4", expires_in: 1.hour, skip_digest: true) do %> + <% unless work.approved_collections.empty? %> +
    <%= ts('Collections') %>:
    +
    <%= link_to number_with_delimiter(work.approved_collections.length), work_collections_path(work) %>
    + <% end %> + + <% if work.count_visible_comments > 0 %> +
    <%= ts('Comments') %>:
    +
    <%= link_to number_with_delimiter(work.count_visible_comments), work.number_of_posted_chapters > 1 ? work_path(work, anchor: "comments", show_comments: true, view_full_work: "true") : work_path(work, anchor: "comments", show_comments: true) %>
    + <% end %> + + <% if work.all_kudos_count > 0 %> +
    <%= ts('Kudos') %>:
    +
    <%= link_to number_with_delimiter(work.all_kudos_count), work.number_of_posted_chapters > 1 ? work_path(work, anchor: "kudos", view_full_work: "true") : work_path(work, anchor: "kudos") %>
    + + <% end %> + <% if (bookmark_count = work.public_bookmarks_count) > 0 %> +
    <%= ts('Bookmarks') %>:
    +
    <%= link_to_bookmarkable_bookmarks(work, number_with_delimiter(bookmark_count)) %>
    + <% end %> + +
    <%= ts("Hits") %>:
    +
    <%= number_with_delimiter(work.hits) %>
    +<% end %> +<% #### END CACHE stats #### %> + +
    + +<% end %> diff --git a/app/views/works/_work_series_links.html.erb b/app/views/works/_work_series_links.html.erb new file mode 100755 index 0000000..85145ac --- /dev/null +++ b/app/views/works/_work_series_links.html.erb @@ -0,0 +1,10 @@ + +
    +

    <%= ts('Series this work belongs to:') %>

    +
      + <% series_data_for_work(@work).each do |series_info| %> +
    • <%= series_info %>
    • + <% end %> +
    +
    + \ No newline at end of file diff --git a/app/views/works/_work_unrevealed_notice.erb b/app/views/works/_work_unrevealed_notice.erb new file mode 100755 index 0000000..f61799e --- /dev/null +++ b/app/views/works/_work_unrevealed_notice.erb @@ -0,0 +1,12 @@ +

    + <%= ts("This work is part of an ongoing challenge and will be revealed soon!") %> + <% if @work.user_is_owner_or_invited?(current_user) %> + <%= ts("You can find details here: ") %> + <%= show_collections_data(@work.collections.unrevealed) %> + <% else %> + <% if @work.approved_collections.unrevealed.present? %> + <%= ts("You can find details here: ") %> + <%= show_collections_data(@work.approved_collections.unrevealed) %> + <% end %> + <% end %> +

    diff --git a/app/views/works/collected.html.erb b/app/views/works/collected.html.erb new file mode 100755 index 0000000..bab2507 --- /dev/null +++ b/app/views/works/collected.html.erb @@ -0,0 +1,43 @@ + +

    + <%= ts("Works in Challenges/Collections") %> +

    + + + + + + +<% if @works.respond_to?(:total_pages) %> + <%= will_paginate @full_results %> +<% end %> + + +

    <%= ts("Listing Works") %>

    +
      + <% for work in @works %> + <% if work %><%= render 'work_blurb', :work => work %><% end %> + <% end %> +
    + + + + +<% if @facets.present? %> + <%= render 'collection_filters' %> +<% end %> + + +<% if @works.respond_to?(:total_pages) %> + <%= will_paginate @full_results %> +<% end %> diff --git a/app/views/works/confirm_delete.html.erb b/app/views/works/confirm_delete.html.erb new file mode 100755 index 0000000..7e6c55b --- /dev/null +++ b/app/views/works/confirm_delete.html.erb @@ -0,0 +1,19 @@ + +

    <%= @work.posted? ? ts("Delete Work") : ts("Delete Draft") %>

    + + +<%= form_for(@work, :html => {:method => :delete, :class => "simple destroy"}) do |f| %> +

    + <%= ts('Are you sure you want to delete "%{work_title}" permanently? This cannot be undone.', :work_title => @work.title).html_safe %> + <% if @work.posted? %> + <%= ts("All bookmarks, comments, and kudos will be lost. If you just want to remove your association with the work, you could Orphan it instead.") %> + <% end %> +

    +

    + <%= f.submit (@work.posted? ? ts("Yes, Delete Work") : ts("Yes, Delete Draft")) %> + <% if @work.posted? %> + <%= link_to ts("Orphan Work Instead"), new_orphan_path(:work_id => @work.id) %> + <% end %> +

    +<% end %> + diff --git a/app/views/works/confirm_delete_multiple.html.erb b/app/views/works/confirm_delete_multiple.html.erb new file mode 100755 index 0000000..1bddd2c --- /dev/null +++ b/app/views/works/confirm_delete_multiple.html.erb @@ -0,0 +1,26 @@ + +

    <%= ts("Delete Works?") %>

    + +

    + You are about to delete all of the following works PERMANENTLY. This CANNOT BE UNDONE and all bookmarks, comments, and kudos will be lost. +

    + +<%= render "works/work_abbreviated_list", :works => @works %> + +<%= form_tag delete_multiple_user_works_path(@user) do %> + +

    + <%= ts("Are you sure you want to delete these works PERMANENTLY? + If you just want to remove your association with the work, you could orphan it instead.") %> + <% @works.each_with_index do |work, index| %><%= hidden_field_tag "work_ids[]", work.id, :id => "work_ids_#{index}" %><% end %> +

    + +
      +
    • <%= submit_tag ts("Yes, Delete Works") %>
    • +
    • <%= link_to ts("Orphan Works Instead"), new_orphan_path(:work_ids => @works.collect(&:id)) %>
    • +
    • <%= link_to ts("Cancel"), show_multiple_user_works_path(@user) %>
    • +
    + +<% end %> + + diff --git a/app/views/works/drafts.html.erb b/app/views/works/drafts.html.erb new file mode 100755 index 0000000..03a650a --- /dev/null +++ b/app/views/works/drafts.html.erb @@ -0,0 +1,24 @@ + +

    <%= search_header @works, nil, ts("Unposted Draft") %>

    + +

    + <%= ts("Please note:") %> + <%= ts("Unposted drafts are only saved for a month from the day they are first created, and then deleted from the Archive.") %> +

    + + + +<%= will_paginate @works %> + + + +
      + <% for work in @works %> + <%= render 'work_blurb', :work => work %> + <% end %> +
    + + + +<%= will_paginate @works %> + diff --git a/app/views/works/edit.html.erb b/app/views/works/edit.html.erb new file mode 100755 index 0000000..785e573 --- /dev/null +++ b/app/views/works/edit.html.erb @@ -0,0 +1,36 @@ + +

    <%= ts('Edit Work') %>

    + +<%= error_messages_for :work %> + + + + + + + +<%= render :partial => 'standard_form' %> + diff --git a/app/views/works/edit_multiple.html.erb b/app/views/works/edit_multiple.html.erb new file mode 100755 index 0000000..1dca1cd --- /dev/null +++ b/app/views/works/edit_multiple.html.erb @@ -0,0 +1,105 @@ + +

    <%= ts("Edit Multiple Works") %>

    + + + +<%= render "users/header_navigation" %> + + + +

    + <%= ts("Your edits will be applied to") %> <%= ts("all") %> <%= ts("of the following works:") %> +

    + +<%= render "works/work_abbreviated_list", works: @works %> + +<%= form_for :work, url: update_multiple_user_works_path(@user), method: :patch, html: { class: "verbose post" } do |form| %> +

    + <%= ts("* Required information") %> + <% @works.each do |work| %> + <%= hidden_field_tag "work_ids[]", work.id %> + <% end %> +

    + + <%= render "work_form_tags", include_blank: true %> +
    + <%= t("works.preface.title") %> +

    <%= t("works.preface.title") %>

    +
    + <%= render "works/work_form_pseuds", form: form, works: @works %> +
    +
    + +
    + <%= t("works.associations.title") %> +

    <%= t("works.associations.title") %>

    +
    + <%= render "collectibles/collectible_form", form: form, collectibles: @works %> +
    <%= form.label :language_id, t("works.associations.language.choose") %> <%= link_to_help "languages-help" %>
    +
    + <%= form.select :language_id, language_options_for_select(sorted_languages, "id"), { include_blank: true } %> +
    + +
    <%= form.label :work_skin_id, t("works.skin.select") %> <%= link_to_help "work-skins" %>
    +
    + <%= form.collection_select :work_skin_id, WorkSkin.approved_or_owned_by(current_user).order(:title), :id, :title, + { include_blank: true } %> +
    +
    +
    + +
    + <%= t("works.permissions.privacy") %> +

    <%= t("works.permissions.privacy") %>

    +
    + +
    <%= t("works.permissions.visibility.label") %> <%= link_to_help "registered-users" %>
    +
    +
    + <%= radio_button_list(form, :restricted, [ + ["", t("works.permissions.visibility.keep_current")], + ["1", t("works.permissions.visibility.multiple_works_restricted")], + ["0", t("works.permissions.visibility.unrestricted")] + ]) + %> +
    +
    + +
    <%= t("comments.commentable.permissions.moderated_commenting.label") %><%= link_to_help "comments-moderated" %>
    +
    +
    + <%= radio_button_list(form, :moderated_commenting_enabled, [ + ["", t("comments.commentable.permissions.moderated_commenting.keep_current")], + ["1", t("comments.commentable.permissions.moderated_commenting.enable")], + ["0", t("comments.commentable.permissions.moderated_commenting.disable")] + ]) + %> +
    +
    + +
    + <%= t("comments.commentable.permissions.options.multiple_works_label") %> + <%= link_to_help "who-can-comment-on-this-work" %> +
    +
    +
    + <%= radio_button_list(form, :comment_permissions, [ + ["", t("comments.commentable.permissions.options.keep_current")], + [:enable_all, t("comments.commentable.permissions.options.enable_all")], + [:disable_anon, t("comments.commentable.permissions.options.disable_anon")], + [:disable_all, t("comments.commentable.permissions.options.disable_all")] + ]) %> +
    +
    +
    +
    + +

    + <%= ts("Your edits will") %> <%= ts("replace") %> <%= ts("the existing values! + (If you leave a field blank it will remain unchanged.)") %> +

    + +

    <%= submit_tag ts("Update All Works"), data: { confirm: ts("Are you sure? Remember this will replace all existing values!") } %>

    + +<% end %> + diff --git a/app/views/works/edit_tags.html.erb b/app/views/works/edit_tags.html.erb new file mode 100755 index 0000000..5fd622d --- /dev/null +++ b/app/views/works/edit_tags.html.erb @@ -0,0 +1,46 @@ + +

    + <% if logged_in_as_admin? %> + <%= ts('Edit Work Tags and Language for %{title}', title: @work.title).html_safe %> + <% else %> + <%= ts('Edit Work Tags for %{title}', title: @work.title).html_safe %> + <% end %> +

    + +<%= error_messages_for :work %> + + + +<%= form_for(@work, html: { id: "work-form", class: "verbose work post" }, url: { action: "update_tags" }) do |f| %> +

    * <%= ts('Required information') %>

    + + <%= render 'work_form_tags', include_blank: false %> + + <% if logged_in_as_admin? %> +
    + <%= t("works.associations.title") %> +

    <%= t("works.associations.title") %>

    +
    + <%= render 'work_form_associations_language', f: f %> +
    +
    + <% end %> + +
    + <%= ts('Post Work') %> +

    + <%= t(".post_notice_html", + content_policy_link: link_to(t(".content_policy"), content_path), + tos_faq_link: link_to(t(".tos_faq"), tos_faq_path(anchor: "content_faq"))) %> +

    +
      + <% unless @work.posted? %> +
    • <%= submit_tag ts('Save As Draft'), name: 'save_button' %>
    • + <% end %> +
    • <%= submit_tag ts('Preview'), name: 'preview_button' %>
    • +
    • <%= submit_tag ts('Post'), name: 'update_button' %>
    • +
    • <%= submit_tag ts('Cancel'), name: 'cancel_button' %>
    • +
    +
    +<% end %> + diff --git a/app/views/works/import.html.erb b/app/views/works/import.html.erb new file mode 100755 index 0000000..5049f3c --- /dev/null +++ b/app/views/works/import.html.erb @@ -0,0 +1,19 @@ +

    <%= t(".page_heading") %>

    + +<% if @works && !@works.empty? %> +

    + <%= t(".success") %> +

    +
      + <% for work in @works %> + <% if work.posted? %> +
    • <%= link_to(work.title, work_path(work)) %>
    • + <% else %> +
    • <%= t(".draft_work_title_html", work_link: link_to(work.title, preview_work_path(work))) %>
    • + <% end %> + <% end %> +
    + +<% end %> + + diff --git a/app/views/works/index.html.erb b/app/views/works/index.html.erb new file mode 100755 index 0000000..db80ac9 --- /dev/null +++ b/app/views/works/index.html.erb @@ -0,0 +1,65 @@ + +<%= render "muted/muted_items_notice" %> + +

    + <%= search_header @works, @search, "Work", @owner %> +

    + + + +<% if @collection || @tag || @user || @language %> + +<% end %> + + +<% unless @owner.present? %> +

    <%= t(".recent_works_html", choose_fandom_link: link_to(t(".choose_fandom"), media_index_path), advanced_search_link: link_to(t(".advanced_search"), search_works_path)) %> +<% end %> + +<%== pagy_nav @pagy %> + + +

    <%= ts("Listing Works") %>

    +
      + <%= render partial: "work_blurb", collection: @works, as: :work %> +
    + + + + +<% if @facets.present? %> + <%= render "filters" %> +<% end %> + + +<%== pagy_nav @pagy %> diff --git a/app/views/works/navigate.html.erb b/app/views/works/navigate.html.erb new file mode 100755 index 0000000..084a790 --- /dev/null +++ b/app/views/works/navigate.html.erb @@ -0,0 +1,8 @@ +

    <%= t(".page_heading_html", work_link: link_to(@work.title, @work), creators: byline(@work)) %>

    + + + diff --git a/app/views/works/new.html.erb b/app/views/works/new.html.erb new file mode 100755 index 0000000..672955f --- /dev/null +++ b/app/views/works/new.html.erb @@ -0,0 +1,24 @@ + +

    <%= ts('Post New Work') %>

    + +<%= error_messages_for @work %> + + + + + + + +<%= render :partial => "standard_form" %> + diff --git a/app/views/works/new_import.html.erb b/app/views/works/new_import.html.erb new file mode 100755 index 0000000..c4b239d --- /dev/null +++ b/app/views/works/new_import.html.erb @@ -0,0 +1,206 @@ + +

    <%= ts("Import New Work") %> <%= link_to_help 'work-import'%>

    +<% import = true %> + +<%= error_messages_for :work %> +
    +

    + <%= ts("Please note! Fanfiction.net, Wattpad.com, and Quotev.com do not allow imports from their sites.") %> +

    +

    <%= ts("You might find the #{ link_to(ts("Import FAQ"), archive_faqs_path + "/posting-and-editing#importwork") } useful.").html_safe %>

    +
    + + + + + + + + + +<%= form_tag url_for(controller: :works, action: :import), :class => "import work verbose post" do %> +
    + <%= ts("Works URLs") %> +
    +
    <%= label_tag "urls", ts("URLs") + "*" %>
    +
    <%= text_area_tag "urls", @urls ? @urls.join("\n") : "", rows: 20, cols: 90, "aria-describedby" => "url-field-description" %> +

    + <%= ts("URLs for existing work(s) or for the chapters of a single work; one URL per line.").html_safe %> +

    +
    +
    + <%= label_tag :language_id, ts("Choose a language") + "*" %> + <%= link_to_help "languages-help" %> +
    +
    + +
    +
    <%= label_tag "encoding", ts("Set custom encoding") %> <%= link_to_help "encoding-help" %>
    +
    <%= select_tag "encoding", options_for_select([''] + Encoding.name_list.sort) %>
    +
    <%= ts("Import as") %>
    +
    +
      +
    • + <%= radio_button_tag "import_multiple", "works", true %> + <%= label_tag "import_multiple_works", + ts("Works (limit of %{max})", + max: current_user.archivist ? ArchiveConfig.IMPORT_MAX_WORKS_BY_ARCHIVIST : ArchiveConfig.IMPORT_MAX_WORKS) %> +
    • +
    • + <%= radio_button_tag "import_multiple", "chapters" %> + <%= label_tag "import_multiple_chapters", + ts("Chapters in a single work (limit of %{max})", + max: ArchiveConfig.IMPORT_MAX_CHAPTERS) %> +
    • +
    +
    + <% if current_user.archivist %> +
    <%= label_tag ts("Archiving for others") %>
    +
    +
    +
    +
    <%= check_box_tag "importing_for_others" %>
    +
    <%= label_tag "importing_for_others", ts("Import for others ONLY with permission") %>
    +
    <%= label_tag "external_author_name", ts("Author Name") + "*" %>
    +
    <%= text_field_tag_original "external_author_name" %>
    +
    <%= label_tag "external_author_email", ts("Author Email Address") + "*" %>
    +
    <%= text_field_tag_original "external_author_email" %>
    +
    <%= label_tag "external_coauthor_name", ts("Co-Author Name") %>
    +
    <%= text_field_tag_original "external_coauthor_name" %>
    +
    <%= label_tag "external_coauthor_email", ts("Co-Author Email Address") %>
    +
    <%= text_field_tag_original "external_coauthor_email" %>
    +
    +
    +
    + <% end %> + +
    <%= ts("Preferences") %>
    +
    +
      +
    • + <%= check_box_tag "post_without_preview" %> + <%= label_tag "post_without_preview", ts("Post without previewing.") %> +
    • +
    +
    +
    <%= ts("Override tags and notes") %>
    +
    +
      +
    • + <%= check_box_tag "override_tags", 1, false, class: "toggle_formfield", id: "override_tags-options-show" %> + <%= label_tag "override_tags-options-show", + ts("Set the following tags and/or notes on all works, overriding whatever the importer finds in the content.") %> +
        +
      • + <%= radio_button_tag "detect_tags", true, true, id: "detect_tags_true" %> + <%= label_tag "detect_tags_true", + ts("Use values extracted from the content for blank fields if possible") %> +
      • +
      • + <%= radio_button_tag "detect_tags", false, false, id: "detect_tags_false" %> + <%= label_tag "detect_tags_false", + ts("Do not use values extracted from the content at all; use Archive defaults for blank fields") %> +
      • +
      +
    • +
    +
    +
    +
    + +
    + <%= t("works.permissions.privacy") %> +

    <%= t("works.permissions.privacy") %>

    +
    +
    + <%= check_box_tag "restricted" %> +
    +
    + <%= label_tag "restricted", t("works.permissions.visibility.import_works_restricted") %> + <%= link_to_help "registered-users" %> +
    + +
    + <%= check_box_tag "moderated_commenting_enabled" %> +
    +
    + <%= label_tag :moderated_commenting_enabled, t("comments.commentable.permissions.moderated_commenting.enable") %> + <%= link_to_help "comments-moderated" %> +
    + +
    + <%= t("comments.commentable.permissions.options.multiple_works_label") %> + <%= link_to_help "who-can-comment-on-this-work" %> +
    +
    +
    +
      +
    • + <%= radio_button_tag "comment_permissions", "enable_all" %> + <%= label_tag "comment_permissions_enable_all", t("comments.commentable.permissions.options.enable_all") %> +
    • +
    • + <%= radio_button_tag "comment_permissions", "disable_anon", true %> + <%= label_tag "comment_permissions_disable_anon", t("comments.commentable.permissions.options.disable_anon") %> +
    • +
    • + <%= radio_button_tag "comment_permissions", "disable_all" %> + <%= label_tag "comment_permissions_disable_all", t("comments.commentable.permissions.options.disable_all") %> +
    • +
    +
    +
    +
    +
    + + <%= render :partial => 'work_form_tags', locals: { include_blank: true, import: true } %> + +
    + <%= label_tag :notes, ts("Notes") %> +
    +
    <%= label_tag :notes, ts("Notes at the beginning") %>
    +
    + <%= text_area_tag :notes, nil, class: "observe_textlength" %> + <%= generate_countdown_html(".notes", ArchiveConfig.NOTES_MAX) %> +
    +
    +
    + +
    + <%= ts("Submit") %> +

    + <%= t(".post_notice_html", + content_policy_link: link_to(t(".content_policy"), content_path), + tos_faq_link: link_to(t(".tos_faq"), tos_faq_path(anchor: "content_faq"))) %> +

    +

    + <%= submit_tag ts("Import") %> +

    +
    + +<% end %> + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j(document).ready(function(){ + $j(".toggle_formfield").click(function() { + var targetId = $j(this).attr("id").replace("-show", ""); + toggleFormField(targetId); + }); + }) + <% end %> +<% end %> diff --git a/app/views/works/preview.html.erb b/app/views/works/preview.html.erb new file mode 100755 index 0000000..9534b08 --- /dev/null +++ b/app/views/works/preview.html.erb @@ -0,0 +1,73 @@ + +

    <%= ts("Preview") %>

    +<%= error_messages_for :work %> + + + +
    +
    + <%= render "works/work_header" %> +
    + <% if @chapters %> + <% @chapters.each do |chapter| %> + <%= render "chapters/chapter", chapter: chapter %> + <% end %> + <% else %> +
    <%=raw sanitize_field(@chapter, :content) %>
    + <% end %> +
    + + <% inspired_by = get_inspired_by(@work) %> + <% if !@work.endnotes.blank? || !@work.serial_works.blank? || !inspired_by.empty? %> + +
    + <% unless @work.endnotes.blank? %> + <%= render "works/work_endnotes" %> + <% end %> + <% unless @work.serial_works.blank? %> + <%= render "works/work_series_links" %> + <% end %> + <% unless inspired_by.empty? %> + <%= render "works/work_approved_children", inspired_by: inspired_by %> + <% end %> +
    + + <% end %> + +
    +
    + +
    + +<%= form_for(@work) do |f| %> + + <%= render "hidden_fields", form: f %> + +
    + <%= ts("Post Work") %> +

    + <%= t(".post_notice_html", + content_policy_link: link_to(t(".content_policy"), content_path), + tos_faq_link: link_to(t(".tos_faq"), tos_faq_path(anchor: "content_faq"))) %> +

    +
      + <% if @work.posted? %> +
    • <%= submit_tag ts("Update"), name: "update_button" %>
    • + <% else %> +
    • + <%= submit_tag ts("Post"), + name: "post_button", + data: { disable_with: ts("Please wait...") } %> +
    • +
    • + <%= submit_tag ts("Save As Draft"), name: "save_button" %> +
    • + <% end %> +
    • <%= submit_tag ts("Edit"), name: "edit_button" %>
    • +
    • <%= submit_tag ts("Cancel"), name: "cancel_button" %>
    • +
    +
    + +<% end %> +
    + diff --git a/app/views/works/preview_tags.html.erb b/app/views/works/preview_tags.html.erb new file mode 100755 index 0000000..e94257b --- /dev/null +++ b/app/views/works/preview_tags.html.erb @@ -0,0 +1,46 @@ + +

    + <% if logged_in_as_admin? %> + <%= ts("Preview Tags and Language") %> + <% else %> + <%= ts("Preview Tags") %> + <% end %> +

    +<%= error_messages_for :work %> + + + +
    +
    + <%= render 'works/meta', work: @work %> +
    +
    + + +<%= form_for(@work, url: { action: :update_tags }) do |form| %> + <%= form.hidden_field :rating_string, value: "#{@work.rating_string}" %> + <%= form.hidden_field :archive_warning_string, value: "#{@work.archive_warning_string}" %> + <%= form.hidden_field :category_string, value: "#{@work.category_string}" %> + <%= form.hidden_field :fandom_string, value: "#{@work.fandom_string}" %> + <%= form.hidden_field :relationship_string, value: "#{@work.relationship_string}" %> + <%= form.hidden_field :character_string, value: "#{@work.character_string}" %> + <%= form.hidden_field :freeform_string, value: "#{@work.freeform_string}" %> + <% if logged_in_as_admin? %> + <%= form.hidden_field :language_id, value: "#{@work.language.id}" %> + <% end %> + +
    + <%= ts('Post Work') %> +

    + <% if @work.posted? %> + <%= submit_tag ts('Update'), name: 'update_button' %> + <% else %> + <%= submit_tag ts('Post'), name: 'post_button' %> + <%= submit_tag ts('Save As Draft'), name: 'save_button' %> + <% end %> + <%= submit_tag ts('Edit'), name: 'edit_button' %> + <%= submit_tag ts('Cancel'), name: 'cancel_button' %> +

    +
    + +<% end %> diff --git a/app/views/works/search.html.erb b/app/views/works/search.html.erb new file mode 100755 index 0000000..66ab610 --- /dev/null +++ b/app/views/works/search.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts('Work Search') %>

    + + + +<%= render 'shared/search_nav' %> + + + +<%= render 'search_form' %> + \ No newline at end of file diff --git a/app/views/works/search_results.html.erb b/app/views/works/search_results.html.erb new file mode 100755 index 0000000..5330293 --- /dev/null +++ b/app/views/works/search_results.html.erb @@ -0,0 +1,36 @@ + +<%= render "muted/muted_items_notice" %> + +

    <%= ts('Search Results') %>

    + +

    + <%= ts("You searched for:") %> + <%= (sanitize @search.summary, tags: %w[span], attributes: %w[lang]).html_safe %> +

    + + + + + + + + +<% if @works.blank? %> +

    <%= ts("No results found. You may want to edit your search to make it less specific.") %>

    +<% else %> +

    <%= search_results_found(@works) %> <%= link_to_help "work-search-results-help" %>

    + +

    Works List

    +
      + <% @works.each do |work| %> + <% unless work.nil? %> + <%= render :partial => 'work_blurb', :locals => {:work => work} %> + <% end %> + <% end %> +
    + + <%= will_paginate @works %> +<% end %> + diff --git a/app/views/works/share.html.erb b/app/views/works/share.html.erb new file mode 100755 index 0000000..6bc24a2 --- /dev/null +++ b/app/views/works/share.html.erb @@ -0,0 +1 @@ +<%= render 'share/share', shareable: @work %> diff --git a/app/views/works/show.html.erb b/app/views/works/show.html.erb new file mode 100755 index 0000000..cb49e25 --- /dev/null +++ b/app/views/works/show.html.erb @@ -0,0 +1,76 @@ + + +<% if !@work.posted? %> +

    <%= t(".unposted_deletion_notice_html", deletion_date: date_in_zone(@work.created_at + 29.days)) %>

    +<% end %> +<% if @work.unrevealed? %> + <%= render "works/work_unrevealed_notice" %> +<% end %> +<% if @work.user_has_creator_invite?(current_user) %> +

    + <%= ts("You've been invited to become a co-creator of this work. To accept or reject the request, visit your %{creator_requests_page}.", + creator_requests_page: link_to(ts("Co-Creator Requests page"), user_creatorships_path(current_user))).html_safe %> +

    +<% end %> + + + + +<% if policy(@work).show_admin_options? %> + <%= render "admin/admin_options", item: @work %> +<% end %> + + + +<% if !@work.unrevealed? || logged_in_as_admin? || can_access_unrevealed_work(@work, current_user) %> + + + <%= render partial: 'works/work_header' %> + + + +
    + <% if @chapters %> + <% for chapter in @chapters %> + <%= render 'chapters/chapter', chapter: chapter %> + <% end %> + <% else %> +

    <%= ts("Work Text:") %>

    + <% cache("#{@chapter.cache_key}-show-content", skip_digest: true) do %> +
    <%=raw sanitize_field(@chapter, :content) %>
    + <% end %> + <% end %> +
    + + + <% inspired_by = get_inspired_by(@work) %> + <% if !@work.endnotes.blank? || !@work.series.blank? || !inspired_by.empty? %> + +
    + <% unless @work.endnotes.blank? %> + <%= render :partial => 'works/work_endnotes' %> + <% end %> + <% unless @work.series.blank? %> + <%= render :partial => 'works/work_series_links' %> + <% end %> + <% unless inspired_by.empty? %> + <%= render :partial => 'works/work_approved_children', :locals => {:inspired_by => inspired_by} %> + <% end %> +
    + + <% end %> + +
    + + + + +<%= render 'comments/commentable', :commentable => @work %> + +<% end %> + + +<%= render "hit_count/include" %> diff --git a/app/views/works/show_multiple.html.erb b/app/views/works/show_multiple.html.erb new file mode 100755 index 0000000..6055eaf --- /dev/null +++ b/app/views/works/show_multiple.html.erb @@ -0,0 +1,67 @@ + +

    Edit Multiple Works

    + + + +<%= render "users/header_navigation" %> + + + +<% if @works.empty? %> +

    + <%= t(".no_works") %> +

    +<% else %> + <%= form_tag edit_multiple_user_works_path(@user), id: "edit-multiple-works" do %> + +
    + <%= check_all_none %> + +
    + Actions +

    + + + +

    +
    + +
      + <% @works_by_fandom.keys.sort.each do |fandom| %> +
    • +
      + Select <%= fandom %> works +
      + <%= fandom %> + <%= check_all_none %> +
      +
        + <% @works_by_fandom[fandom].each do |work| %> +
      • + <% work_title_with_status = work.title + (work.posted? ? "" : t(".draft")) %> + + <%= link_to work_title_with_status, work_path(id: work.id) %> +
      • + <% end %> +
      +
      +
    • + <% end %> +
    + +
    + Actions +

    + + + +

    +
    + +
    + + <% end %> +<% end %> + diff --git a/app/views/wrangling_guidelines/_admin_index.html.erb b/app/views/wrangling_guidelines/_admin_index.html.erb new file mode 100755 index 0000000..cdb309c --- /dev/null +++ b/app/views/wrangling_guidelines/_admin_index.html.erb @@ -0,0 +1,29 @@ +
    + +

    <%= ts('Wrangling Guidelines') %>

    + + + + <%= render 'admin/admin_nav' %> + + + + +

    <%= ts("Manage Wrangling Guidelines") %>

    +
    + <% @wrangling_guidelines.each do |wrangling_guideline| %> +
    <%= link_to wrangling_guideline.title, wrangling_guideline %>
    +
    +

    <%= ts('Created at') %> <%= wrangling_guideline.created_at %> <%= ts('and updated at') %> <%= wrangling_guideline.updated_at %>

    +
    + <% end %> +
    + +
    diff --git a/app/views/wrangling_guidelines/_wrangling_guideline_form.html.erb b/app/views/wrangling_guidelines/_wrangling_guideline_form.html.erb new file mode 100755 index 0000000..f0fa89e --- /dev/null +++ b/app/views/wrangling_guidelines/_wrangling_guideline_form.html.erb @@ -0,0 +1,43 @@ +<%= form_for(@wrangling_guideline, html: { class: "post" }) do |f| %> + + <%= error_messages_for @wrangling_guideline %> + +

    <%= "* #{t('.required_information')}" %>

    +
    + +
    <%= f.label :title, "#{t('.title')}*" %>
    +
    + <%= f.text_field :title %> + <%= live_validation_for_field("wrangling_guideline_title", failureMessage: t(".title_failure")) %> +
    + +
    <%= f.label :content, "#{t('.guideline_text')}*", for: "content" %>
    +
    + +

    + <%= allowed_html_instructions %> + +

    + <% use_tinymce %> +
    + <%= f.text_area :content, class: "mce-editor observe_textlength", id: "content" %> + <%= live_validation_for_field("content", + maximum_length: ArchiveConfig.CONTENT_MAX, + minimum_length: ArchiveConfig.CONTENT_MIN, + tooLongMessage: t(".content_too_long", count: ArchiveConfig.CONTENT_MAX), + tooShortMessage: t(".content_too_short", count: ArchiveConfig.CONTENT_MIN), + failureMessage: t(".content_required")) %> + <%= generate_countdown_html("content", ArchiveConfig.CONTENT_MAX) %> +
    +
    + +
    <%= t(".landmark.post") %>
    +
    + <%= submit_tag t(".post"), name: "post_button" %> +
    + +
    +<% end %> diff --git a/app/views/wrangling_guidelines/_wrangling_guideline_order.html.erb b/app/views/wrangling_guidelines/_wrangling_guideline_order.html.erb new file mode 100755 index 0000000..ab2c7ba --- /dev/null +++ b/app/views/wrangling_guidelines/_wrangling_guideline_order.html.erb @@ -0,0 +1,33 @@ +
    + <%= form_tag url_for(:action => 'update_positions') do %> +
      + <% for wrangling_guideline in @wrangling_guidelines %> +
    • + <%= text_field_tag "wrangling_guidelines[]", nil, :size => 3, :maxlength => 3, :id => "wrangling_guidelines_#{wrangling_guideline.id}", :class => "number" %> + <%= wrangling_guideline.position %>. +

      <%=h wrangling_guideline.title %>

      +
    • + <% end %> +
    +

    <%= submit_tag ts('Update Positions') %>

    + <% end %> +
    + +<%= content_for :footer_js do %> + <%= javascript_tag do %> + $j("#sortable_wrangling_guideline_list").sortable({ + delay: 300, + update: function(event, ui) { + $j(".wrangling_guideline-position-list").each(function(index, li){ + var faqId = $j(li).attr("id").replace("wrangling_guideline_",""); + $j("#position-for-"+faqId).html(index+1); + }); + $j.ajax({ + type: 'post', + data: $j("#sortable_wrangling_guideline_list").sortable("serialize"), + dataType: 'script', + url: "<%= url_for(:action => :update_positions) %>"}) + } + }) + <% end %> +<% end %> diff --git a/app/views/wrangling_guidelines/edit.html.erb b/app/views/wrangling_guidelines/edit.html.erb new file mode 100755 index 0000000..8d23d43 --- /dev/null +++ b/app/views/wrangling_guidelines/edit.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts('Edit Wrangling Guideline') %>

    + + + +<%= render 'admin/admin_nav' %> + + + +<%= render 'wrangling_guideline_form' %> + \ No newline at end of file diff --git a/app/views/wrangling_guidelines/index.html.erb b/app/views/wrangling_guidelines/index.html.erb new file mode 100755 index 0000000..0b29d89 --- /dev/null +++ b/app/views/wrangling_guidelines/index.html.erb @@ -0,0 +1,19 @@ + +<% if policy(:wrangling).new? %> + <%= render 'admin_index' %> +<% else %> +

    <%= ts('Wrangling Guidelines') %>

    + + + +
    + <% unless @wrangling_guidelines.blank? %> +

    <%= ts('Wrangling Guideline Sections') %>

    +
      + <% for wrangling_guideline in @wrangling_guidelines %> +
    1. <%= link_to wrangling_guideline.title, wrangling_guideline %>
    2. + <% end %> +
    + <% end %> +
    +<% end %> \ No newline at end of file diff --git a/app/views/wrangling_guidelines/manage.html.erb b/app/views/wrangling_guidelines/manage.html.erb new file mode 100755 index 0000000..7a9b1a8 --- /dev/null +++ b/app/views/wrangling_guidelines/manage.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts('Manage Wrangling Guidelines') %>

    + + + +<%= render 'admin/admin_nav' %> + + + +<%= render 'wrangling_guideline_order' %> + \ No newline at end of file diff --git a/app/views/wrangling_guidelines/new.html.erb b/app/views/wrangling_guidelines/new.html.erb new file mode 100755 index 0000000..9710f14 --- /dev/null +++ b/app/views/wrangling_guidelines/new.html.erb @@ -0,0 +1,11 @@ + +

    <%= ts('Create New Wrangling Guideline Section') %>

    + + + +<%= render 'admin/admin_nav' %> + + + +<%= render 'wrangling_guideline_form' %> + \ No newline at end of file diff --git a/app/views/wrangling_guidelines/show.html.erb b/app/views/wrangling_guidelines/show.html.erb new file mode 100755 index 0000000..8288367 --- /dev/null +++ b/app/views/wrangling_guidelines/show.html.erb @@ -0,0 +1,22 @@ + +

    <%= link_to t(".heading"), wrangling_guidelines_path %> > <%= @wrangling_guideline.title %>

    + + + + + + + +
    + <% if policy(:wrangling).edit? %> +
    +

    + Updated: <%= h @wrangling_guideline.updated_at %> | <%= link_to t(".edit"), edit_wrangling_guideline_path(@wrangling_guideline) %> +

    +
    + <% end %> +
    + <%= raw sanitize_field(@wrangling_guideline, :content) %> +
    +
    + diff --git a/bin/brakeman b/bin/brakeman new file mode 100755 index 0000000..ace1c9b --- /dev/null +++ b/bin/brakeman @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +ARGV.unshift("--ensure-latest") + +load Gem.bin_path("brakeman", "brakeman") diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 0000000..66e9889 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 0000000..efc0377 --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/bin/rake b/bin/rake new file mode 100755 index 0000000..4fbf10b --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative "../config/boot" +require "rake" +Rake.application.run diff --git a/bin/reload_elastic b/bin/reload_elastic new file mode 100755 index 0000000..10f728b --- /dev/null +++ b/bin/reload_elastic @@ -0,0 +1,8 @@ +#!/bin/bash + export RAILS_ENV=production + + bundle exec rake environment search:index_bookmarks + bundle exec rake environment search:index_pseuds + bundle exec rake environment search:index_tags + bundle exec rake environment search:index_works + diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 0000000..40330c0 --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +require "rubygems" +require "bundler/setup" + +# explicit rubocop config increases performance slightly while avoiding config confusion. +ARGV.unshift("--config", File.expand_path("../.rubocop.yml", __dir__)) + +load Gem.bin_path("rubocop", "rubocop") diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..84cd631 --- /dev/null +++ b/bin/setup @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby +require "fileutils" + +APP_ROOT = File.expand_path("..", __dir__) +APP_NAME = "otwarchive" + +def system!(*args) + system(*args, exception: true) +end + +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. + # Add necessary setup steps to this file. + + puts "== Installing dependencies ==" + system! "gem install bundler --conservative" + system("bundle check") || system!("bundle install") + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" + # end + + puts "\n== Preparing database ==" + system! "bin/rails db:prepare" + + puts "\n== Removing old logs and tempfiles ==" + system! "bin/rails log:clear tmp:clear" + + puts "\n== Restarting application server ==" + system! "bin/rails restart" + + # puts "\n== Configuring puma-dev ==" + # system "ln -nfs #{APP_ROOT} ~/.puma-dev/#{APP_NAME}" + # system "curl -Is https://#{APP_NAME}.test/up | head -n 1" +end diff --git a/bin/update b/bin/update new file mode 100755 index 0000000..a8e4462 --- /dev/null +++ b/bin/update @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/config.ru b/config.ru new file mode 100755 index 0000000..610a678 --- /dev/null +++ b/config.ru @@ -0,0 +1,17 @@ +# This file is used by Rack-based servers to start the application. + +require_relative "config/environment" +require "resque/server" +require "resque/scheduler/server" + +# Set the AUTH env variable to your basic auth password to protect Resque. +AUTH_PASSWORD = ENV['AUTH'] +if AUTH_PASSWORD + Resque::Server.use Rack::Auth::Basic do |username, password| + password == AUTH_PASSWORD + end +end + +run Rack::URLMap.new \ + "/" => Otwarchive::Application, + "/resque" => Resque::Server diff --git a/config/application.rb b/config/application.rb new file mode 100755 index 0000000..6144a86 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,153 @@ +require_relative "boot" + +require "rails/all" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module Otwarchive + class Application < Rails::Application + app_config = YAML.load_file(Rails.root.join("config/config.yml")) + app_config.merge!(YAML.load_file(Rails.root.join("config/local.yml"))) if File.exist?(Rails.root.join("config/local.yml")) + ::ArchiveConfig = OpenStruct.new(app_config) + + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib(ignore: %w[assets tasks]) + + # Configuration for the application, engines, and railties goes here. + # + # These settings can be overridden in specific environments using the files + # in config/environments, which are processed later. + + config.load_defaults 7.2 + + %w[ + app/models/challenge_models + app/models/feedback_reporters + app/models/indexing + app/models/potential_matcher + app/models/search + app/models/tagset_models + ].each do |dir| + config.eager_load_paths << Rails.root.join(dir) + end + + # I18n validation deprecation warning fix + + I18n.config.enforce_available_locales = false + I18n.config.available_locales = [ + :en, :af, :ar, :bg, :bn, :ca, :cs, :cy, :da, :de, :el, :es, :fa, :fi, + :fil, :fr, :he, :hi, :hr, :hu, :id, :it, :ja, :ko, :lt, :lv, :mk, + :mr, :ms, :nb, :nl, :pl, :"pt-BR", :"pt-PT", :ro, :ru, :scr, :sk, :sl, + :sv, :th, :tr, :uk, :vi, :"zh-CN" + ] + + # 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 = "UTC" + + # The default locale is :en. + config.i18n.default_locale = ArchiveConfig.DEFAULT_LOCALE_ISO.to_sym + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation can not be found) + config.i18n.fallbacks = true + + # JavaScript files you want as :defaults (application.js is always included). + # config.action_view.javascript_expansions[:defaults] = %w(jquery rails) + + # Configure the default encoding used in templates for Ruby 1.9. + config.encoding = "utf-8" + + config.action_view.automatically_disable_submit_tag = false + + # Disable dumping schemas after migrations. + # This can cause problems since we don't always update versions on merge. + # Ideally this would be enabled in dev, but we're not quite ready for that. + config.active_record.dump_schema_after_migration = false + + # Allows belongs_to associations to be optional + config.active_record.belongs_to_required_by_default = false + + # Keeps updated_at in cache keys + config.active_record.cache_versioning = false + + # Setting this to true (the default) breaks series orphaning + config.active_record.before_committed_on_all_records = false + + # This class is not allowed by default when upgrading Rails to 6.0.5.1 patch + config.active_record.yaml_column_permitted_classes = [ + ActiveSupport::TimeWithZone, + Time, + ActiveSupport::TimeZone, + BCrypt::Password + ] + + # handle errors with custom error pages: + config.exceptions_app = self.routes + + # Bring the log under control + config.lograge.enabled = true + + # Only send referrer information to ourselves + config.action_dispatch.default_headers = { + "Content-Security-Policy" => "frame-ancestors 'self'", + "Referrer-Policy" => "strict-origin-when-cross-origin", + "X-Frame-Options" => "SAMEORIGIN", + "X-XSS-Protection" => "1; mode=block", + "X-Content-Type-Options" => "nosniff", + "X-Permitted-Cross-Domain-Policies" => "none" + } + + # Use Resque to run ActiveJobs (including sending delayed mail): + config.active_job.queue_adapter = :resque + + # TODO: Remove with Rails 8.0 where this option will be deprecated + config.active_job.enqueue_after_transaction_commit = :always + + config.active_model.i18n_customize_full_message = true + + config.action_mailer.default_url_options = { host: ArchiveConfig.APP_HOST, protocol: "https" } + + # Use "mailer" instead of "mailers" as the Resque queue for emails: + config.action_mailer.deliver_later_queue_name = :mailer + + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = { + address: ArchiveConfig.SMTP_SERVER, + domain: ArchiveConfig.SMTP_DOMAIN, + port: ArchiveConfig.SMTP_PORT, + enable_starttls_auto: ArchiveConfig.SMTP_ENABLE_STARTTLS_AUTO, + enable_starttls: ArchiveConfig.SMTP_ENABLE_STARTTLS, + openssl_verify_mode: ArchiveConfig.SMTP_OPENSSL_VERIFY_MODE + } + if ArchiveConfig.SMTP_AUTHENTICATION + config.action_mailer.smtp_settings.merge!({ + user_name: ArchiveConfig.SMTP_USER, + password: ArchiveConfig.SMTP_PASSWORD, + authentication: ArchiveConfig.SMTP_AUTHENTICATION + }) + end + + # Disable ActiveStorage things that we don't need and can hit the DB hard + config.active_storage.analyzers = [] + config.active_storage.previewers = [] + + # Set ActiveStorage queue name + config.active_storage.queues.mirror = :active_storage + config.active_storage.queues.preview_image = :active_storage + config.active_storage.queues.purge = :active_storage + config.active_storage.queues.transform = :active_storage + + config.active_storage.web_image_content_types = %w[image/png image/jpeg image/gif] + + # Do not enable YJIT automatically once we upgrade to Ruby 3.3 + config.yjit = false + + # Use secret from archive config + config.secret_key_base = ArchiveConfig.SESSION_SECRET + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100755 index 0000000..2820116 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" # Set up gems listed in the Gemfile. diff --git a/config/brakeman.yml b/config/brakeman.yml new file mode 100755 index 0000000..28e6a3b --- /dev/null +++ b/config/brakeman.yml @@ -0,0 +1,4 @@ +--- +:safe_methods: +- :pagy_nav +- :sanitize_field diff --git a/config/cable.yml b/config/cable.yml new file mode 100755 index 0000000..f53bb96 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: test + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: otwarchive_production diff --git a/config/config.yml b/config/config.yml new file mode 100755 index 0000000..7adcf98 --- /dev/null +++ b/config/config.yml @@ -0,0 +1,773 @@ +# WARNING: DO NOT EDIT THIS FILE (unless you are changing the underlying code) +# Instead, create a file called local.yml in the same place, +# copy any sections you want to change to it, and edit them there. + +# 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. + +# do not use the defaults in production! +SESSION_KEY: '_otwarchive_session' +SESSION_SECRET: '898f6d0363863ec79d782238cd1c5767636d712cc0d138238bcd5bfc9d2672fb852380050e52c03a0401175d909c09dba48512a119d46b126a84c2dd05716eb5' + +DEFAULT_SESSION_LENGTH_IN_WEEKS: 2 +REMEMBERED_SESSION_LENGTH_IN_MONTHS: 3 + +# This length is hardcoded into the reset_password_instructions email message, +# defined in config/locales/mailers/en.yml. If you change this value, you should +# also change the message (and vice versa). +DAYS_UNTIL_RESET_PASSWORD_LINK_EXPIRES: 7 + +# This also affects the link included in the admin account creation email. +DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES: 5 + +# If more than PASSWORD_RESET_LIMIT password reset emails are sent within +# PASSWORD_RESET_COOLDOWN_HOURS time, then password resets for that user +# will be prevented until PASSWORD_RESET_COOLDOWN_HOURS after the last +# password reset. +PASSWORD_RESET_LIMIT: 3 +PASSWORD_RESET_COOLDOWN_HOURS: 12 + +# email addresses +RETURN_ADDRESS: 'do-not-reply@example.org' +SPAM_ALERT_ADDRESS: 'abuse-discuss@example.org' +SPAM_THRESHOLD: 15 +ADMIN_ADDRESS: 'admin@example.org' +TAG_WRANGLER_SUPERVISORS_ADDRESS: 'tagwranglers-personnel@example.org' + +# Because the default email addresses are fake, +# email delivery is turned off by default, even for production. +# The log file will nonetheless show "Sent mail:" +# +# Note that this is independent from whether the scheduled email-sending +# tasks will be run -- to make changes to that, please see schedule.rb +# and your deploy file. +PERFORM_DELIVERIES: false + +# email server +SMTP_SERVER: localhost +SMTP_PORT: 25 +SMTP_DOMAIN: localhost +SMTP_OPENSSL_VERIFY_MODE: none +SMTP_ENABLE_STARTTLS_AUTO: false +SMTP_ENABLE_STARTTLS: false +# if required for email authentication +#SMTP_USER: +#SMTP_PASSWORD: +#SMTP_AUTHENTICATION: # :plain, :login or :cram_md5 + +# Branding +APP_URL: 'http://www.example.org' +APP_NAME: 'Example Archive' +APP_HOST: 'archiveofourown.org' +APP_SHORT_NAME: 'AO3' +LOGO: 'logo.png' +ALT_LOGO: 'Archive of Our Own' +OTWLOGO: 'OTWLogo.png' +OTWALT_LOGO: 'OTW Logo:closing the circle of the copyright symbol, it symbolizes our creative engagement with media: participating and not just consuming.' +REVISION: '' +ES_URL: 'http://127.0.0.1:9400' +MEMCACHED_SERVERS: '127.0.0.1:11211' +ZOHO_URL: 'https://desk.zoho.com' + +# tag settings +DELIMITER_FOR_INPUT: ',' # if you change this, you will need to change +# validates_format_of :name, in app/models/tag.rb +DELIMITER_FOR_OUTPUT: ', ' + +# accounts and invitations +# these can be overridden in the admin controller +INVITE_FROM_QUEUE_ENABLED: true +INVITE_FROM_QUEUE_NUMBER: 10 +# How often INVITE_FROM_QUEUE_NUMBER of invites are sent from the queue, in hours +INVITE_FROM_QUEUE_FREQUENCY: 12 + +HOURS_BEFORE_RESEND_INVITATION: 24 +# this is whether or not people without invitations can create accounts +ACCOUNT_CREATION_ENABLED: false +DAYS_TO_CONFIRM_EMAIL_CHANGE: 7 +# number of invites users can request +MAX_USER_INVITE_REQUEST: 10 +# number of accounts users can block +MAX_BLOCKED_USERS: 2000 +# number of accounts users can mute +MAX_MUTED_USERS: 2000 + +# this determines how long we keep processed results like tag set nominations in redis +DAYS_TO_SAVE_PROCESSED: 56 + +# validation values -- max/min lengths +TITLE_MAX: 255 +TITLE_MIN: 1 +SUMMARY_MAX: 1250 +NOTES_MAX: 5000 +COMMENT_MAX: 10000 +TAG_MAX: 150 +CONTENT_MIN: 10 +CONTENT_MAX: 510000 +CONTENT_MAX_DISPLAYED: 500000 +LOGNOTE_MIN: 5 +LOGNOTE_MAX: 1250 +FEEDBACK_SUMMARY_MAX_DISPLAYED: 100 +FEEDBACK_SUMMARY_MAX: 107 +INFO_MAX: 100000 +FAQ_MAX: 200000 +ICON_ALT_MAX: 250 +ICON_COMMENT_MAX: 50 +ICON_SIZE_KB_MAX: 500 +LOGIN_LENGTH_MIN: 3 +LOGIN_LENGTH_MAX: 40 +PASSWORD_LENGTH_MIN: 6 +PASSWORD_LENGTH_MAX: 40 +ADMIN_PASSWORD_LENGTH_MIN: 10 +ADMIN_PASSWORD_LENGTH_MAX: 40 + +# The maximum number of tags you can add to a collection +COLLECTION_TAGS_MAX: 10 + +# The maximum number of user-defined tags you can add to a work or external work +USER_DEFINED_TAGS_MAX: 75 + +# max number of tags of each type allowed in challenge prompts (requests/offers) +# increasing this number can lead to slower automated matching +PROMPT_TAGS_MAX: 20 + +# max number of potential matches to generate +POTENTIAL_MATCHES_MAX: 50 +# min number of potential matches to allow +POTENTIAL_MATCHES_MIN: 10 +# max percentage of participants to match +POTENTIAL_MATCHES_PERCENT: 10 + +# These options control the number of tags we'd ideally like to see in each tag +# type in a gift exchange, in order to ensure that indexing on that type (to +# speed up matching) will yield good results. The number scales with the number +# of signups (using the divisor), but is capped at the maximum. Increasing the +# maximum (and decreasing the divisor) will cause the preprocessing step to +# take somewhat longer. +PREPROCESS_COUNT_TAGS_DIVISOR: 10 +PREPROCESS_COUNT_TAGS_MAX: 10 + +# These options control how many prompts with "any_#{type}" an exchange can +# have before we consider that tag type to be difficult to index on. +PREPROCESS_COUNT_ANY_DIVISOR: 10 +PREPROCESS_COUNT_ANY_MIN: 10 + +# max number of prompts of each type (offer, request) allowed +PROMPTS_MAX: 10 +# max for prompt memes (can be much higher than for gift exchanges, as there is no matching) +PROMPT_MEME_PROMPTS_MAX: 50 + + +# max number of works/chapters that can be imported +IMPORT_MAX_WORKS: 25 +IMPORT_MAX_CHAPTERS: 200 +IMPORT_MAX_WORKS_BY_ARCHIVIST: 200 + +# max number of abuse reports to accept for a given user profile URL +ABUSE_REPORTS_PER_USER_MAX: 5 +# max number of abuse reports to accept for a given work URL +ABUSE_REPORTS_PER_WORK_MAX: 5 +# max number of abuse reports to accept from a given email +ABUSE_REPORTS_PER_EMAIL_MAX: 5 + +# number of items in various displays +ITEMS_PER_PAGE: 25 +# must be less than ITEMS_PER_PAGE above +NUMBER_OF_ITEMS_VISIBLE_IN_DASHBOARD: 5 +NUMBER_OF_ITEMS_VISIBLE_ON_HOMEPAGE: 3 +COMMENT_THREAD_MAX_DEPTH: 5 +TAGS_IN_CLOUD: 200 +TAG_LIST_LIMIT: 300 +# how many options there should be before we show a scrollable window, and how many there +# can be before we just use an autocomplete instead +OPTIONS_TO_SHOW: 3 +MAX_OPTIONS_TO_SHOW: 20 +MAX_KUDOS_TO_SHOW: 50 +MAX_FAVORITE_TAGS: 20 + +# Used by Rack Attack, periods are measured in seconds +RATE_LIMIT_NUMBER: 300 +RATE_LIMIT_PERIOD: 300 +RATE_LIMIT_LOGIN_ATTEMPTS: 5 +RATE_LIMIT_LOGIN_PERIOD: 20 +RATE_LIMIT_ADMIN_LOGIN_ATTEMPTS: 10 +RATE_LIMIT_ADMIN_LOGIN_PERIOD: 300 +RATE_LIMIT_PER_NGINX_UPSTREAM: + unicorn_elastic: + limit: 300 + period: 300 + unicorn_elastic_bookmarks: + limit: 300 + period: 300 +RATE_LIMIT_PER_NGINX_UPSTREAM_USER: + unicorn_elastic: + limit: 300 + period: 300 +RATE_LIMIT_SAFELIST: ["127.0.0.0/8", "10.0.0.0/8"] + +# The number of tags to show on the search page: +TAGS_PER_SEARCH_PAGE: 50 + +# When updating tag counts, how many to do in one TagCountUpdateJob: +TAG_UPDATE_JOB_SIZE: 1000 + +# When updating tag counts, how many to do in one transaction: +TAG_UPDATE_BATCH_SIZE: 100 + +# We only start caching tag counts for tags used more than a certain number of times +TAGGINGS_COUNT_MIN_CACHE_COUNT: 1000 + +# For tagging changes, we only reindex tags used less than a certain number of times +TAGGINGS_COUNT_REINDEX_LIMIT: 1000 + +# how many signups in a challenge before we move to static summaries generated hourly +MAX_SIGNUPS_FOR_LIVE_SUMMARY: 20 + +DOWNLOAD_FORMATS: ['azw3', 'epub', 'mobi', 'pdf', 'html'] + +# Tag kinds and default tags +WARNING_CATEGORY_NAME: 'Archive Warning' +WARNING_DEFAULT_TAG_NAME: 'Choose Not To Use Archive Warnings' +WARNING_DEFAULT_TAG_DISPLAY_NAME: 'Creator Chose Not To Use Archive Warnings' +WARNING_NONE_TAG_NAME: 'No Archive Warnings Apply' +WARNING_NONE_TAG_DISPLAY_NAME: 'No Archive Warnings Apply' +WARNING_VIOLENCE_TAG_NAME: 'Graphic Depictions Of Violence' +WARNING_DEATH_TAG_NAME: 'Major Character Death' +WARNING_NONCON_TAG_NAME: 'Rape/Non-Con' +WARNING_CHAN_TAG_NAME: 'Underage Sex' + +RATING_CATEGORY_NAME: 'Rating' +RATING_DEFAULT_TAG_NAME: 'Not Rated' +RATING_EXPLICIT_TAG_NAME: 'Explicit' +RATING_MATURE_TAG_NAME: 'Mature' +RATING_TEEN_TAG_NAME: 'Teen And Up Audiences' +RATING_GENERAL_TAG_NAME: 'General Audiences' + +CATEGORY_CATEGORY_NAME: 'Category' +CATEGORY_GEN_TAG_NAME: 'Gen' +CATEGORY_HET_TAG_NAME: 'F/M' +CATEGORY_SLASH_TAG_NAME: 'M/M' +CATEGORY_FEMSLASH_TAG_NAME: 'F/F' +CATEGORY_MULTI_TAG_NAME: 'Multi' +CATEGORY_OTHER_TAG_NAME: 'Other' + +MEDIA_CATEGORY_NAME: 'Media' +MEDIA_NO_TAG_NAME: 'No Media' +MEDIA_UNCATEGORIZED_NAME: 'Uncategorized Fandoms' +FANDOM_CATEGORY_NAME: 'Fandom' +FANDOM_NO_TAG_NAME: 'No Fandom' +RELATIONSHIP_CATEGORY_NAME: 'Relationship' +CHARACTER_CATEGORY_NAME: 'Character' +FREEFORM_CATEGORY_NAME: 'Additional Tags' +COMMON_CATEGORY_NAME: 'Common' +BANNED_CATEGORY_NAME: 'Banned' + +# DATE TIME FORMAT see http://ruby-doc.org/core/classes/Time.html#M000392 +DEFAULT_DATETIME_FORMAT: '%Y-%m-%d %I:%M%p' + +# SEARCH TIPS +SEARCH_TIPS: ['arthur merlin words>1000 sort:hits', 'words:100', 'buffy gen teen AND "no archive warnings apply"', 'lex m/m (mature OR explicit)', + 'hetalia f/f sort:kudos', '"sherlock (tv)" m/m NOT "sherlock holmes/john watson"', 'austen words:10000-50000 sort:title', + 'katekyou "alternate universe" sort:>words', '"uchiha sasuke/uzumaki naruto" angst kudos>10' +] + +# This is used to determine how many recent items +# to cache for recent lookups -- eg if we want to +# provide a "ten most recent" items to browse. +# used in CacheFinds module -- include CacheFinds in a model +# and the methods Model.recent and Model.last(#) will be +# enabled, cached on production/test environments. +MAX_RECENT: 20 + +# This determines the maximum value of (from + size) for searches +# to all indices (Elasticsearch index setting max_result_window). +# If a search has more results than this limit, the last page of +# search results will include a message advising the user to narrow +# their search or change their sorting options. +MAX_SEARCH_RESULTS: 100000 + +# This is used to determine how many works or how many authors have to be +# present in order for anonymous or mystery works to begin being displayed +ANONYMOUS_THRESHOLD_COUNT: 10 + +# This is used to determine how tolerant of changes to be when determining +# whether a comment should go back into moderation after editing or not +COMMENT_MODERATION_THRESHOLD: 10 + +# This is used to determine how tolerant of changes to be when determining +# whether a comment should be spam checked again when edited +EDITED_COMMENT_SPAM_CHECK_THRESHOLD: 10 + +# SANITIZER VERSION +SANITIZER_VERSION: 4 + +# parameters that must be natural integers and their default values +NONZERO_INTEGER_PARAMETERS: + page: 1 + per_page: 25 + +# Enable image safety mode when sanitizing comments on the following parents for +# display. This is the parent_type of the comment, not the ultimate_parent, +# so if you want to add extra sanitization to work comments, use Chapter here. +# Options: AdminPost, Chapter, Tag. +PARENTS_WITH_IMAGE_SAFETY_MODE: [] + +# These fields are encrypted and should not have characters escaped or be treated as HTML +FIELDS_WITHOUT_SANITIZATION: ["password", "password_check", "password_confirmation"] + +# These fields are query fields and are allowed to contain "less than" values +FIELDS_ALLOWING_LESS_THAN: ["query", "words", "kudos", "hits", "date", "bookmarkable_date", "word_count", "bookmarks_count", "comments_count", "kudos_count", "revised_at"] + +# Only the following fields are allowed to have HTML. In others, all HTML tags +# will be stripped by the "sanitize_ac_params" filter. +# +# The exact HTML tags and attributes and protocols allowed are defined in: +# - config/initializers/gem-plugin_config/sanitizer_config.rb +# - lib/html_cleaner.rb +# +# If you add a new field to this list, you need to: +# +# - make sure every model containing the field also has a matching field "[fieldname]_sanitizer_version", e.g. +# add_column :chapters, :content_sanitizer_version, :integer, default: 0, null: false, limit: 2 +# +# - make sure the field is NOT permitted for mass updating (by not including it in params.permit calls) +# +# - display the field in views using the HtmlCleaner helper, e.g. +# <%=raw sanitize_field(object, :fieldname) %> +# +# This will ensure that the field has been sanitized with the latest version of the sanitizer. +FIELDS_ALLOWING_HTML: ["about_me", "bookmarker_notes", "comment", "comment_content", "content", "description", "disabled_support_form_text", "endnotes", "faq", "intro", "notes", + "rules", "series_notes", "signup_instructions_general", "signup_instructions_offers", "signup_instructions_requests", "summary"] + +FIELDS_ALLOWING_HTML_ENTITIES: ["title"] + +FIELDS_ALLOWING_MEDIA_EMBEDS: ["content"] + +FIELDS_ALLOWING_CSS: ["content", "endnotes", "notes"] + +# Domains that are not allowed be used as the src for audio and video HTML tags. +# Format: ["google.com", "archiveofourown.org"] +BANNED_MULTIMEDIA_SRCS: [] + +# Allowed CSS +# +# *** IMPORTANT: if you edit these values please also update the +# skins-creating.html file in public/help *** +# +# the following properties and keywords will be ADDED to the default set allowed +# in user-submitted CSS code, along with: +# - hex and rgb color values +# - numeric values specified with percentages or cm|em|ex|in|mm|pc|pt|px|% +# - image files specified with url(http://image.url/blahblah/whatever.(jpg|png|gif)) +# + +# We use this list for properties which can take shorthand values and also have +# subproperties or variants (ie, because "border" is in here, we allow through: +# border-right, border-bottom-left-radius, -moz-border-foo, etc) +# It is slightly less secure so do NOT put any property in here if you aren't +# sure all variations on it are okay! +SUPPORTED_CSS_SHORTHAND_PROPERTIES: +- background +- border +- column +- cue +- flex +- font +- layer-background +- layout-grid +- list-style +- margin +- marker +- outline +- overflow +- padding +- page-break +- pause +- scrollbar +- text +- transform +- transition + +SUPPORTED_CSS_PROPERTIES: +- -replace +- -use-link-source +- accelerator +- accent-color +- align-content +- align-items +- align-self +- alignment-adjust +- alignment-baseline +- appearance +- azimuth +- baseline-shift +- behavior +- binding +- bookmark-label +- bookmark-level +- bookmark-target +- bottom +- box-align +- box-direction +- box-flex +- box-flex-group +- box-lines +- box-orient +- box-pack +- box-shadow +- box-sizing +- caption-side +- clear +- clip +- color +- color-profile +- color-scheme +- content +- counter-increment +- counter-reset +- crop +- cue +- cue-after +- cue-before +- cursor +- direction +- display +- dominant-baseline +- drop-initial-after-adjust +- drop-initial-after-align +- drop-initial-before-adjust +- drop-initial-before-align +- drop-initial-size +- drop-initial-value +- elevation +- empty-cells +- filter +- fit +- fit-position +- float +- float-offset +- font +- font-effect +- font-emphasize +- font-emphasize-position +- font-emphasize-style +- font-family +- font-size +- font-size-adjust +- font-smooth +- font-stretch +- font-style +- font-variant +- font-weight +- grid-columns +- grid-rows +- hanging-punctuation +- height +- hyphenate-after +- hyphenate-before +- hyphenate-character +- hyphenate-lines +- hyphenate-resource +- hyphens +- icon +- image-orientation +- image-resolution +- ime-mode +- include-source +- inline-box-align +- justify-content +- layout-flow +- left +- letter-spacing +- line-break +- line-height +- line-stacking +- line-stacking-ruby +- line-stacking-shift +- line-stacking-strategy +- mark +- mark-after +- mark-before +- marks +- marquee-direction +- marquee-play-count +- marquee-speed +- marquee-style +- max-height +- max-width +- min-height +- min-width +- move-to +- nav-down +- nav-index +- nav-left +- nav-right +- nav-up +- opacity +- order +- orphans +- page +- page-policy +- phonemes +- pitch +- pitch-range +- play-during +- position +- presentation-level +- punctuation-trim +- quotes +- rendering-intent +- resize +- rest +- rest-after +- rest-before +- richness +- right +- rotation +- rotation-point +- ruby-align +- ruby-overhang +- ruby-position +- ruby-span +- size +- speak +- speak-header +- speak-numeral +- speak-punctuation +- speech-rate +- stress +- string-set +- tab-side +- table-layout +- target +- target-name +- target-new +- target-position +- top +- unicode-bibi +- unicode-bidi +- user-select +- vertical-align +- visibility +- voice-balance +- voice-duration +- voice-family +- voice-pitch +- voice-pitch-range +- voice-rate +- voice-stress +- voice-volume +- volume +- white-space +- white-space-collapse +- widows +- width +- word-break +- word-spacing +- word-wrap +- writing-mode +- z-index + +# We allow the !important keyword as well as any string that is just a-z plus +# dashes, as well as space- or comma-separated lists of such strings. The only +# keywords you need to specify are keywords that contain other characters. +# +# We have the URL_FUNCTION_REGEX in lib/css_cleaner.rb, but including "url" here +# is necessary to prevent the url() function from being stripped before any +# value containing it is sanitized. Allowing images in skins should be moved to +# its own config variable in the future. +# +# Do not add other functions here; they are not keywords and are controlled by +# regular expressions in lib/css_cleaner.rb. +SUPPORTED_CSS_KEYWORDS: ["!important", "url"] + +# if you include "url" in the SUPPORTED_CSS_KEYWORDS, only urls pointing to this +# kind of resource will be allowed +SUPPORTED_EXTERNAL_URLS: ["jpg", "jpeg", "png", "gif"] + +# variables for Askimet http://akismet.com/ +AKISMET_KEY: '6833ee7298cf' +AKISMET_NAME: 'http://transformativeworks.org' + +# Abuse and Support ticket trackers; you may need to change +# feedbacks_controller.rb and abuse_reports_controller.rb +# to properly send to your own ticket tracker. +# +# - Register a new client at Zoho's Developer Console, whatever you fill into "Authorized redirect URIs" +# is ZOHO_REDIRECT_URI. +# - Upon registering, you receive ZOHO_CLIENT_ID and ZOHO_CLIENT_SECRET. +# - Upon requesting an "offline" authorization grant, you receive ZOHO_REFRESH_TOKEN. +ZOHO_CLIENT_ID: "" +ZOHO_CLIENT_SECRET: "" +ZOHO_REDIRECT_URI: "" +ZOHO_REFRESH_TOKEN: "" +ZOHO_ORG_ID: "" +ABUSE_ZOHO_DEPARTMENT_ID: "" +SUPPORT_ZOHO_DEPARTMENT_ID: "" + +DEFAULT_LANGUAGE_SHORT: 'en' +DEFAULT_LANGUAGE_NAME: 'English' +DEFAULT_LOCALE_ISO: 'en' +DEFAULT_LOCALE_NAME: 'English (US)' + +# Allow orphaninig +ORPHANING_ALLOWED: true + +# Help directory, must be in the public folder. +# Create subfolders for each supported language +# (eg, /help/fr/ contains the French versions of the help) +HELP_DIRECTORY: '/help' + +# production caching +#PRODUCTION_CACHE: "memory" +PRODUCTION_CACHE: "memcache" + +# TTL in seconds for cached work and bookmark counts on user/pseud dashboards. +# Default to 20 minutes. +SECONDS_UNTIL_DASHBOARD_COUNTS_EXPIRE: 1200 + +# how many cache pages to expire for a tag/collection/pseud when a work is updated or deleted +PAGES_TO_CACHE: 5 + +# Turn this off in local.yml to keep the development footer/profiling code from running +DEVELOPMENT_PROFILING_ENABLED: true + + +# These are the actions logged in the user history - the log_items table +ACTION_ACTIVATE: 0 +ACTION_ADD_ROLE: 1 +ACTION_REMOVE_ROLE: 2 +ACTION_SUSPEND: 3 +ACTION_UNSUSPEND: 4 +ACTION_BAN: 5 +ACTION_WARN: 6 +ACTION_RENAME: 7 +ACTION_PASSWORD_CHANGE: 8 +ACTION_NEW_EMAIL: 9 +ACTION_TROUBLESHOOT: 10 +ACTION_NOTE: 11 +ACTION_ADD_FNOK: 12 +ACTION_REMOVE_FNOK: 13 +ACTION_ADDED_AS_FNOK: 14 +ACTION_REMOVED_AS_FNOK: 15 +ACTION_PASSWORD_RESET: 16 + + +# Elasticsearch index prefix +# If you're using webdev or another shared environment, change this to include +# your username (e.g. ao3_testy) to ensure all users have separate search +# indexes +ELASTICSEARCH_PREFIX: 'ao3' + + +# List of Unicode scripts where spaces are not used as separators, and +# character counts should be used for word counts. +# Check if a script is supported by the version of Ruby we use: +# https://ruby-doc.org/core/Regexp.html#class-Regexp-label-Character+Properties +CHARACTER_COUNT_SCRIPTS: ["Han", "Hiragana", "Katakana", "Thai"] + + +# Cache durations for work and bookmark searches (in seconds) +SECONDS_UNTIL_WORK_INDEX_EXPIRE: 1800 +SECONDS_UNTIL_BOOKMARK_INDEX_EXPIRE: 1800 + +# Cache duration for commentable kudos list of names +MINUTES_UNTIL_COMMENTABLE_KUDOS_LISTS_EXPIRE: 60 + +# Cache duration for comment counts: +SECONDS_UNTIL_COMMENT_COUNTS_EXPIRE: 3600 + +# Cache duration for various collection-related counts (# of works, # of +# bookmarks, # of fandoms): +SECONDS_UNTIL_COLLECTION_COUNTS_EXPIRE: 300 + +# Cache durations for work and bookmark searches (in minutes) +MINUTES_UNTIL_COLLECTION_BLURBS_EXPIRE: 120 + +# Job size used for the HitCountUpdateJob class: +HIT_COUNT_JOB_SIZE: 1000 + +# Batch size used for the HitCountUpdateJob class: +HIT_COUNT_BATCH_SIZE: 100 + +# The hour (in UTC time) that we want the hit counts to rollover at. If someone +# views the work shortly before this hour and shortly after, it should count as +# two hits. Used by the RedisHitCounter class. +HIT_COUNT_ROLLOVER_HOUR: 3 + +# The batch size for calculating a work's filters from its tags: +FILTER_UPDATE_BATCH_SIZE: 100 + +# URLs for which we should not display the proxy notice. URLs from these hosts +# are allowed in Abuse reports and disallowed in Work imports. Alphabetical by +# environment. +PERMITTED_HOSTS: [ + # Production + "104.153.64.122", + "208.85.241.152", + "208.85.241.157", + "ao3.org", + "archiveofourown.com", + "archiveofourown.net", + "archiveofourown.org", + "download.archiveofourown.org", + "insecure.archiveofourown.org", + "secure.archiveofourown.org", + "www.ao3.org", + "www.archiveofourown.com", + "www.archiveofourown.net", + "www.archiveofourown.org", + # Staging + "insecure-test.archiveofourown.org", + "test.archiveofourown.org", + "testdownload.archiveofourown.org" +] + +USER_RENAME_LIMIT_DAYS: 7 + +# The number of readings to include in a single ReadingsJob: +READING_JOB_SIZE: 5000 + +# The number of readings to change in a single transaction: +READING_BATCH_SIZE: 100 + +# The number of work IDs to include in a single StatCounterJob: +STAT_COUNTER_JOB_SIZE: 1000 + +# The number of works to fetch from the database in one query when updating stat counters: +STAT_COUNTER_BATCH_SIZE: 100 + +# Number of hours to retain the original creator for works that have been +# orphaned. +ORIGINAL_CREATOR_TTL_HOURS: 72 + +# The maximum number of tags to provide in a tag wrangling report. +WRANGLING_REPORT_LIMIT: 1000 + +# The number of days after which an Admin Post should allow comments. +# After this window, all comments are disabled. Setting this value to +# something below 1 -- or commenting it out -- will turn off comment disabling. +ADMIN_POST_COMMENTING_EXPIRATION_DAYS: 14 + +# Usernames in this list are not allowed to avoid potential confusion (like +# a user who has the username 'admin', for example). +FORBIDDEN_USERNAMES: [] + +# The arguments to pass to pt-online-schema-change: +PERCONA_ARGS: > + --chunk-size=5k + --max-flow-ctl 0 + --pause-file /tmp/pauseme + --max-load Threads_running=15 + --critical-load Threads_running=100 + --set-vars innodb_lock_wait_timeout=2 + --alter-foreign-keys-method=rebuild_constraints + --no-check-unique-key-change + +# How many shards to have in elastic indexes. +# Production may have more than 5 for these +BOOKMARKABLE_SHARDS: 5 +WORKS_SHARDS: 5 +USER_SHARDS: 5 diff --git a/config/cucumber.yml b/config/cucumber.yml new file mode 100755 index 0000000..ef879fe --- /dev/null +++ b/config/cucumber.yml @@ -0,0 +1,11 @@ +<% +rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" +rerun = rerun.strip.gsub /\s/, ' ' +rerun_opts = rerun.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" +retry_opts = "--retry #{ENV['CUCUMBER_RETRY'] || '0'} --no-strict-flaky" +std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags 'not @wip' #{retry_opts} --color" +%> +default: <%= std_opts %> features +wip: --tags @wip:3 --wip features +rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags 'not @wip' +html_report: --format progress --format html --out=features/features_report.html diff --git a/config/database.example b/config/database.example new file mode 100755 index 0000000..7681ef5 --- /dev/null +++ b/config/database.example @@ -0,0 +1,45 @@ +defaults: &defaults + adapter: mysql2 + encoding: utf8mb4 + collation: utf8mb4_unicode_ci + username: root + password: + +development: + database: otwarchive_development + <<: *defaults + +# 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: + database: otwarchive_test + <<: *defaults + +production: + database: otwarchive_production + <<: *defaults + +# +# The following is an example of how to set up the db for sqlite3 +# +# +## SQLite version 3.x +## gem install sqlite3-ruby (not necessary on OS X Leopard) +#development: +# adapter: sqlite3 +# database: db/development.sqlite3 +# timeout: 5000 + +## 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: sqlite3 +# database: db/test.sqlite3 +# timeout: 5000 + +#production: +# adapter: sqlite3 +# database: db/production.sqlite3 +# timeout: 5000 diff --git a/config/deploy.rb b/config/deploy.rb new file mode 100755 index 0000000..f164ec9 --- /dev/null +++ b/config/deploy.rb @@ -0,0 +1,140 @@ +# BACKGROUND: +# To describe the idea here -- these are capistrano "recipes" which are a bit like rake tasks +# You wrap all the fiddly systems scripts and things that you need to do for a deploy into these nice neat little individual tasks +# and then you can chain the tasks together +# +# when you run "cap deploy:migrate" let's say, all the things you've told to run before or after it go automatically +# eg this line in deploy/production.rb: +# before "deploy:migrate", "production_only:backup_db" +# says, if I run "cap deploy:migrate production" then before doing any of the actual work of the deploy, +# run the task called "production_only:backup_db" which is defined in deploy.rb +# +# namespace :production_only do +# # Back up the production database +# task :backup_db, roles: :db do +# run "/static/bin/backup_database.sh &" +# end +# end +# +# which says, run this script backup_database.sh +# and run it on the machine that has the ":db" role +# +# The roles are defined in each of deploy/production.rb and deploy/staging.rb, +# and can be set differently for whichever system you are deploying to. +# +# Several tasks run automatically based on behind-the-scenes magic +# +require "./config/boot" +require "active_support/core_ext/hash/keys" + +# takes care of the bundle install tasks +require 'bundler/capistrano' + +# deploy to different environments with tags +require 'capistrano/ext/multistage' +set :stages, %w[staging production] +set :default_stage, "staging" +#require 'capistrano/gitflow_version' + +# use rvm +require "rvm/capistrano" +set :rvm_ruby_string, ENV['GEM_HOME'].gsub(/.*\//, "") +set :rvm_type, :user + +# user settings +set :user, "ao3app" +set :auth_methods, "publickey" +#ssh_options[:verbose] = :debug +ssh_options[:auth_methods] = %w(publickey) +set :use_sudo, false +default_run_options[:shell] = '/bin/bash' + +# basic settings +set :application, "otwarchive" +set :deploy_to, "/home/ao3app/app" +set :keep_releases, 4 + +set :mail_to, "otw-coders@transformativeworks.org otw-testers@transformativeworks.org" + +# git settings +set :scm, :git +set :repository, "https://github.com/otwcode/otwarchive.git" +set :deploy_via, :remote_cache + +set :servers, -> { YAML.load_file(File.join(__dir__, "servers.yml")).deep_symbolize_keys[fetch(:stage)] } + +# overwrite default capistrano deploy tasks +namespace :deploy do + desc "Restart the unicorns" + task :restart do + find_servers(roles: [:app, :web]).each do |server| + puts "restart on #{server.host}" + run "cd ~/app/current ; bundle exec rake skins:cache_chooser_skins RAILS_ENV=#{rails_env}", hosts: server.host + run "/home/ao3app/bin/unicorns_reload", hosts: server.host + end + end + + desc "Restart the resque workers" + task :restart_workers, roles: :workers do + run "/home/ao3app/bin/workers_reload" + end + + desc "Restart the schedulers" + task :restart_schedulers, roles: :schedulers do + run "/home/ao3app/bin/scheduler_reload" + end + + desc "Get the config files" + task :update_configs, roles: [:app, :web, :workers, :schedulers] do + run "/home/ao3app/bin/create_links_on_install" + end + + desc "Update the web-related whenever tasks" + task :update_cron_web, roles: :web do + # run "bundle exec whenever --update-crontab web -f config/schedule_web.rb" + run "echo cron entries are currently managed by hand" + end + + # This should only be one machine + desc "update the crontab for whatever machine should run the scheduled tasks" + task :update_cron, roles: :app, only: {primary: true} do + # run "bundle exec whenever --update-crontab #{application}" + run "echo cron entries are currently managed by hand" + end + + # Needs to run on web (front-end) servers, but they must also have rails installed + desc "Re-caches the site skins" + task :reload_site_skins do + find_servers(roles: :web).each do |server| + puts "Caching skins on #{server.host}" + run "cd ~/app/current ; bundle exec rake skins:cache_chooser_skins RAILS_ENV=#{rails_env} ; cd ~/app ; rm web_old ; ln -f -s `readlink -f current` web_new ; mv web web_old ; mv web_new web", hosts: server.host + sleep (10) + end + end +end + +# ORDER OF EVENTS +# Calling "cap deploy" runs: +# deploy:update which runs: +# deploy:update_code +# deploy:symlink +# deploy:restart +# +# Calling "cap deploy:migrations" inserts the task "deploy:migrate" before deploy:symlink +# + +# after and before task triggers that should run on both staging and production +#before "deploy:migrate", "deploy:web:disable" +#after "deploy:migrate", "extras:run_after_tasks" + +#before "deploy:symlink", "deploy:web:enable_new" +#after "deploy:symlink", "extras:update_revision" + +after "deploy:restart", "deploy:update_cron" +after "deploy:restart", "deploy:update_cron_web" +#after "deploy:restart", "extras:restart_delayed_jobs" +#after "deploy:restart", "deploy:cleanup" + +after "deploy:restart", "deploy:restart_workers" +after "deploy:restart", "deploy:restart_schedulers" +after "deploy:symlink", "deploy:update_configs" diff --git a/config/deploy/production.rb b/config/deploy/production.rb new file mode 100755 index 0000000..bd6a52d --- /dev/null +++ b/config/deploy/production.rb @@ -0,0 +1,56 @@ +# ORDER OF EVENTS +# Calling "cap deploy" runs: +# deploy:update which runs: +# deploy:update_code +# deploy:symlink +# deploy:restart +# +# Calling "cap deploy:migrations" inserts the task "deploy:migrate" before deploy:symlink + +require "capistrano/gitflow_version" + +fetch(:servers).each do |s| + server s[:host], *s[:roles], s[:options] || {} +end + +# our tasks which are production specific +namespace :production_only do + desc "Set up production robots.txt file" + task :update_robots, roles: :web do + run "cp #{release_path}/public/robots.public.txt #{release_path}/public/robots.txt" + end + + desc "Send out 'Archive deployed' notification" + task :notify_testers do + system "echo 'Archive deployed' | mail -s 'Archive deployed' #{mail_to}" + end + + desc "Rebalance nginx and squid" + task :rebalance_unicorns, roles: :web do + logger.info "Rebalancing in a minute" + sleep(60) + run "/usr/bin/sudo /var/cfengine/files/scripts/rebalance" + logger.info "Rebalancing complete" + end + + desc "Update the crontab on the primary app machine" + task :update_cron_email, roles: :app, only: {primary: true} do + # run "bundle exec whenever --update-crontab production -f config/schedule_production.rb" + end +end + +#before "deploy:update_code", "production_only:git_in_home" +#after "deploy:update_code", "production_only:update_public", "production_only:update_tag_feeds", "production_only:update_configs" + +#before "deploy:migrate", "production_only:backup_db" + +after "deploy:restart", "production_only:update_cron_email" + +after "deploy:update_code", "production_only:update_robots" +after "deploy:restart", "production_only:notify_testers" +after "deploy:restart", "production_only:rebalance_unicorns" + + +# deploy from clean branch +set :branch, "deploy" +set :rails_env, 'production' diff --git a/config/deploy/staging.rb b/config/deploy/staging.rb new file mode 100755 index 0000000..f626e45 --- /dev/null +++ b/config/deploy/staging.rb @@ -0,0 +1,41 @@ +# ORDER OF EVENTS +# Calling "cap deploy" runs: +# deploy:update which runs: +# deploy:update_code +# deploy:symlink +# deploy:restart +# +# Calling "cap deploy:migrations" inserts the task "deploy:migrate" before deploy:symlink + +require "capistrano/gitflow_version" + +fetch(:servers).each do |s| + server s[:host], *s[:roles], s[:options] || {} +end + +set :rails_env, 'staging' + +# our tasks which are staging specific +namespace :stage_only do + desc "Set up staging robots.txt file" + task :update_robots, roles: :web do + run "cp #{release_path}/public/robots.private.txt #{release_path}/public/robots.txt" + end + + desc "Send out 'Testarchive deployed' notification" + task :notify_testers do + system "echo 'Testarchive deployed' | mail -s 'Testarchive deployed' #{mail_to}" + end +end + +#before "deploy:update_code", "stage_only:git_in_home" +after "deploy:update_code", "stage_only:update_robots" + +#before "db:reset_on_stage", "deploy:web:disable" +# reset the database and clear subscriptions and emails out of it +#after "db:reset_on_stage", "stage_only:reset_db", "stage_only:clear_subscriptions", "stage_only:clear_emails" +#after "db:reset_on_stage", "stage_only:reindex_elasticsearch" +#after "db:reset_on_stage", "deploy:web:enable" + +# reload the site skins after each deploy since there may have been CSS changes +after "deploy:restart", "stage_only:notify_testers" diff --git a/config/docker/Dockerfile b/config/docker/Dockerfile new file mode 100755 index 0000000..3a986b8 --- /dev/null +++ b/config/docker/Dockerfile @@ -0,0 +1,24 @@ +FROM ruby:3.2.7 + +# Install additional packages +RUN apt-get update && \ + apt-get install -y \ + calibre \ + default-mysql-client \ + libvips \ + shared-mime-info \ + zip + +# Clean and mount repository at /otwa +RUN rm -rf /otwa && mkdir -p /otwa +WORKDIR /otwa +VOLUME /otwa + +# Install ruby packages +COPY Gemfile . +COPY Gemfile.lock . +RUN gem install bundler -v 2.6.3 && bundle install + +# Default command to run in a new container +EXPOSE 3000 +CMD bundle exec rails s -p 3000 diff --git a/config/docker/local.yml b/config/docker/local.yml new file mode 100755 index 0000000..27e3fcf --- /dev/null +++ b/config/docker/local.yml @@ -0,0 +1,2 @@ +ES_URL: es:9200 +MEMCACHED_SERVERS: mc:11211 diff --git a/config/docker/redis.yml b/config/docker/redis.yml new file mode 100755 index 0000000..63fef41 --- /dev/null +++ b/config/docker/redis.yml @@ -0,0 +1,18 @@ +redis_resque: + test: redis:6379 + development: redis:6379 +redis_kudos: + test: redis:6379 + development: redis:6379 +redis_general: + test: redis:6379 + development: redis:6379 +redis_rollout: + test: redis:6379 + development: redis:6379 +redis_autocomplete: + test: redis:6379 + development: redis:6379 +redis_hits: + test: redis:6379 + development: redis:6379 diff --git a/config/environment.rb b/config/environment.rb new file mode 100755 index 0000000..cac5315 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative "application" + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100755 index 0000000..28e4e66 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,119 @@ +require "active_support/core_ext/integer/time" + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + config.hosts = ArchiveConfig.PERMITTED_HOSTS + + # Code is not reloaded between requests. + config.enable_reloading = false + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + + # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead. + # config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + + + + config.serve_static_files = true + + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.asset_host = "http://assets.example.com" + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache + # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX + + + + # Use a different cache store in production + config.cache_store = :mem_cache_store, ArchiveConfig.MEMCACHED_SERVERS, + { namespace: "ao3-v#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}", + compress: true, pool: { size: 10 } } + + # Mount Action Cable outside main process or domain. + # config.action_cable.mount_path = nil + # config.action_cable.url = "wss://example.com/cable" + # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] + + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. + # config.assume_ssl = true + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + config.force_ssl = false + + # Skip http-to-https redirect for the default health check endpoint. + # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } } + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + if ENV["RAILS_LOG_TO_STDOUT"].present? + config.logger = ActiveSupport::Logger.new($stdout) + .tap { |logger| logger.formatter = config.log_formatter } + .then { |logger| ActiveSupport::TaggedLogging.new(logger) } + end + + # Prepend all log lines with the following tags. + config.log_tags = [:request_id] + + # "info" includes generic and useful information about system operation, but avoids logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). If you + # want to log everything, set the level to "debug". + # config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "debug") + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment). + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "otwarchive_production" + + # Disable caching for Action Mailer templates even if Action Controller + # caching is enabled. + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Don't log any deprecations. + config.active_support.report_deprecations = false + + config.middleware.use Rack::Attack + + config.active_storage.service = :local + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + # Only use :id for inspections in production. + # config.active_record.attributes_for_inspect = [:id] + + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } +end diff --git a/config/environments/staging.rb b/config/environments/staging.rb new file mode 100755 index 0000000..e92b4ad --- /dev/null +++ b/config/environments/staging.rb @@ -0,0 +1,80 @@ +Otwarchive::Application.configure do + # Settings specified here will take precedence over those in config/environment.rb + + config.hosts = ArchiveConfig.PERMITTED_HOSTS + + # The production environment is meant for finished, "live" apps. + # Code is not reloaded between requests + config.cache_classes = true + config.eager_load = true + + # Full error reports are disabled and caching is turned on + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + config.action_mailer.perform_caching = true + + # Specifies the header that your server uses for sending files + # config.action_dispatch.x_sendfile_header = "X-Sendfile" + + # For nginx: + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' + + # If you have no front-end server that supports something like X-Sendfile, + # just comment this out and Rails will serve the files + + # Disable IP spoofing protection + config.action_dispatch.ip_spoofing_check = false + + # See everything in the log (default is now :debug) + # config.log_level = :debug + config.log_level = :info + + # Use a different logger for distributed setups + # config.logger = SyslogLogger.new + + # Use a different cache store in production + config.cache_store = :mem_cache_store, ArchiveConfig.MEMCACHED_SERVERS, + { namespace: "ao3-v#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}", + compress: true, pool: { size: 5 } } + + # Disable Rails's static asset server + # In production, Apache or nginx will already do this + config.serve_static_files = false + + # Enable serving of images, stylesheets, and javascripts from an asset server + # config.action_controller.asset_host = "http://assets.example.com" + + # Disable delivery errors, bad email addresses will be ignored + # config.action_mailer.raise_delivery_errors = false + + # Enable mailer previews. + config.action_mailer.show_previews = true + + # Enable threaded mode + # config.threadsafe! + + # Send deprecation notices to registered listeners + config.active_support.deprecation = :notify + + # Make it clear we are on staging + config.rack_dev_mark.enable = true + config.rack_dev_mark.theme = [:title, Rack::DevMark::Theme::GithubForkRibbon.new(position: "left", fixed: "true", color: "orange")] + + config.after_initialize do + Bullet.enable = true + Bullet.bullet_logger = true + Bullet.add_footer = false + Bullet.console = true + Bullet.rails_logger = true + Bullet.counter_cache_enable = false + end + + # Store uploaded files in AWS S3, proxied so we can cache them. + config.active_storage.service = :s3 + config.active_storage.resolve_model_to_route = :rails_storage_proxy + + config.middleware.use Rack::Attack + + # Disable dumping schemas after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100755 index 0000000..b7395ff --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,74 @@ +require "active_support/core_ext/integer/time" + +# 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! + +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false + + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. + config.eager_load = ENV["CI"].present? + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{1.hour.to_i}" } + + # Show full error reports and enable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = true + config.action_controller.page_cache_directory = Rails.root.join("public/test_cache") + + config.action_mailer.perform_caching = true + + config.cache_store = :mem_cache_store, ArchiveConfig.MEMCACHED_SERVERS, + { namespace: "ao3-v2-test", compress: true, pool: { size: 10 }, raise_errors: true } + + # Render exception templates for rescuable exceptions and raise for other exceptions. + config.action_dispatch.show_exceptions = :rescuable + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + + # 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 + + # Inline ActiveJob when testing: + config.active_job.queue_adapter = :inline + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Configure strong parameters to raise an exception if an unpermitted attribute is used + config.action_controller.action_on_unpermitted_parameters = :raise + + # Make sure that we don't have a host mismatch: + config.action_controller.default_url_options = { host: "www.example.com", port: nil } + config.action_mailer.default_url_options = config.action_controller.default_url_options.merge(protocol: "https") + + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + # Raise error when a before_action's only/except options reference missing actions. + config.action_controller.raise_on_missing_callback_actions = true +end diff --git a/config/gh-actions/database.yml b/config/gh-actions/database.yml new file mode 100755 index 0000000..af5a14b --- /dev/null +++ b/config/gh-actions/database.yml @@ -0,0 +1,11 @@ +test: + host: 127.0.0.1 + port: 3306 + adapter: mysql2 + database: otwarchive_test + username: root + password: password + encoding: utf8mb4 + collation: utf8mb4_unicode_ci + variables: + sql_mode: STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION diff --git a/config/gh-actions/local.yml b/config/gh-actions/local.yml new file mode 100755 index 0000000..8990cb0 --- /dev/null +++ b/config/gh-actions/local.yml @@ -0,0 +1,2 @@ +ES_URL: 'http://127.0.0.1:9200' +BCRYPT_COST: 4 diff --git a/config/gh-actions/redis.yml b/config/gh-actions/redis.yml new file mode 100755 index 0000000..fd21268 --- /dev/null +++ b/config/gh-actions/redis.yml @@ -0,0 +1,12 @@ +redis_autocomplete: + test: localhost:6379 +redis_general: + test: localhost:6380 +redis_hits: + test: localhost:6381 +redis_kudos: + test: localhost:6382 +redis_resque: + test: localhost:6383 +redis_rollout: + test: localhost:6384 diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml new file mode 100755 index 0000000..4e82ccc --- /dev/null +++ b/config/i18n-tasks.yml @@ -0,0 +1,277 @@ +# i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks + +# The "main" locale. +base_locale: en +## All available locales are inferred from the data by default. Alternatively, specify them explicitly: +# locales: [es, fr] +## Reporting locale, default: en. Available: en, ru. +# internal_locale: en + +# Read and write translations. +data: + ## Translations are read from the file system. Supported format: YAML, JSON. + ## Provide a custom adapter: + # adapter: I18n::Tasks::Data::FileSystem + + # Locale files or `Find.find` patterns where translations are read from: + read: + - config/locales/**/en.yml + - config/locales/phrase-exports/%{locale}.yml + # - locales/views/zh-CN.yml # These are also in the phrase exports + + # Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom: + # `i18n-tasks normalize -p` will force move the keys according to these rules + write: + # - 'config/locales/phrase-exports/%{locale}.yml' # Cannot route by language, 'en' files end up in the wrong place + ## For example, write devise and simple form keys to their respective files: + # - ['{devise, simple_form}.*', 'config/locales/\1.%{locale}.yml'] + ## Catch-all default: + # - config/locales/%{locale}.yml + + # External locale data (e.g. gems). + # This data is not considered unused and is never written to. + external: + - <%= %x[bundle info rails-i18n --path].chomp %>/rails/locale/%{locale}.yml + + ## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class. + # router: conservative_router + + yaml: + write: + # do not wrap lines at 80 characters + line_width: -1 + + ## Pretty-print JSON: + # json: + # write: + # indent: ' ' + # space: ' ' + # object_nl: "\n" + # array_nl: "\n" + +# Find translate calls +search: + ## Paths or `Find.find` patterns to search in: + # paths: + # - app/ + + ## Root directories for relative keys resolution. + # relative_roots: + # - app/controllers + # - app/helpers + # - app/mailers + # - app/presenters + # - app/views + + ## Directories where method names which should not be part of a relative key resolution. + # By default, if a relative translation is used inside a method, the name of the method will be considered part of the resolved key. + # Directories listed here will not consider the name of the method part of the resolved key + # + # relative_exclude_method_name_paths: + # - + + ## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting: + ## *.jpg *.jpeg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less + ## *.yml *.json *.zip *.tar.gz *.swf *.flv *.mp3 *.wav *.flac *.webm *.mp4 *.ogg *.opus *.webp *.map *.xlsx + # exclude: + # - app/assets/images + # - app/assets/fonts + # - app/assets/videos + # - app/assets/builds + + ## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`: + ## If specified, this settings takes priority over `exclude`, but `exclude` still applies. + # only: ["*.rb", "*.html.slim"] + + ## If `strict` is `false`, guess usages such as t("categories.#{category}.title"). The default is `true`. + # strict: true + + ## Allows adding ast_matchers for finding translations using the AST-scanners + ## The available matchers are: + ## - RailsModelMatcher + ## Matches ActiveRecord translations like + ## User.human_attribute_name(:email) and User.model_name.human + ## - DefaultI18nSubjectMatcher + ## Matches ActionMailer's default_i18n_subject method + ## + ## To implement your own, please see `I18n::Tasks::Scanners::AstMatchers::BaseMatcher`. + ast_matchers: + - 'I18n::Tasks::Scanners::AstMatchers::RailsModelMatcher' + - 'I18n::Tasks::Scanners::AstMatchers::DefaultI18nSubjectMatcher' + + ## Multiple scanners can be used. Their results are merged. + ## The options specified above are passed down to each scanner. Per-scanner options can be specified as well. + ## See this example of a custom scanner: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example + +## Translation Services +# translation: +# # Google Translate +# # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate +# google_translate_api_key: "AbC-dEf5" +# # DeepL Pro Translate +# # Get an API key and subscription at https://www.deepl.com/pro to use DeepL Pro +# deepl_api_key: "48E92789-57A3-466A-9959-1A1A1A1A1A1A" +# # deepl_host: "https://api.deepl.com" +# # deepl_version: "v2" + +## Do not consider these keys missing: +ignore_missing: + # File: app/helpers/mailer_helper.rb + - comment_mailer.subject_for_commentable.subject.{chapter,other,tag} + # File: app/mailers/comment_mailer.rb + - mailer_helper.content_for_commentable_html.chapter.{titled,untitled} + - mailer_helper.content_for_commentable_html.content.{chapter,other,tag}.html + - mailer_helper.content_for_commentable_text.content.{other,tag}.text + - mailer_helper.content_for_commentable_text.content.chapter.{titled_text,untitled_text} + ## All of the following keys are using default values defined in the respective .rb files + ## TODO: Move the default values to the .yml files + # File: app/controllers/admin/admin_invitations_controller.rb + - invites_created # should be admin.admin_invitations.grant_invites_to_users.invites_created + - no_email # should be admin.admin_invitations.create.no_email + - sent # should be admin.admin_invitations.create.sent + - user_not_found # should be admin.admin_invitations.find.user_not_found + # File: app/controllers/challenge_assignments_controller.rb + - challenge_assignments.assignments_not_sent + - challenge_assignments.assignments_sent + - challenge_assignments.no_challenge + - challenge_assignments.signup_open + # File: app/controllers/challenges_controller.rb + - challenge.no_collection # should be challenges.no_collection + - challenges.no_challenge + # File: app/controllers/collection_items_controller.rb + - collection_items.create.invitation_not_sent # should not be using lazy lookup + # File: app/controllers/collection_participants_controller.rb + - applied_to_join_collection # should be collection_participants.applied_to_join_collection + - no_collection # should be collection_participants.no_collection + - collection_participants.accepted_invite + - collection_participants.destroy + - collection_participants.no_invitation + - collection_participants.update_success + # File: app/controllers/external_authors_controller.rb + - external_author_claimed # should be external_authors.complete_claim.external_author_claimed + # Files: app/controllers/external_works_controller.rb and app/controllers/languages_controller.rb + - successfully_updated # should be languages.update.successfully_updated + # File: app/controllers/feedbacks_controller.rb + - failure_send # should be feedbacks.create.failure_send + - successfully_sent # should be feedbacks.create.successfully_sent + # Files: app/controllers/languages_controller.rb and app/controllers/locales_controller.rb + - successfully_added # should be languages.create.successfully_added and locales.create.successfully_added + # File: app/views/admin/admin_invitations/find.html.erb + - admin.admin_invitations.find.find_email + - admin.admin_invitations.find.find_token + - admin.admin_invitations.find.find_user_name + # File: app/views/admin/admin_invitations/new.html.erb + - admin.admin_invitations.new.email_address + - admin.admin_invitations.new.invite_user + - admin.admin_invitations.new.submit + # File: app/views/admin/skins/_navigation.html.erb + - skins.approval_queue + - skins.approved_skins + - skins.rejected_skins + # File: app/views/comments/show.html.erb + - comments.show.comment_on + # File: app/views/external_authors/_external_author_name.html.erb + - external_authors.external_author_name.label_external_author_name + # File: app/views/external_authors/edit.html.erb + - external_authors.edit.back + - external_authors.edit.edit_external_author + # File: app/views/gifts/_gift_search.html.erb + - gifts.gift_search.forms.gift_search + - gifts.gift_search.gifts.recipient_field + # File: app/views/invitations/index.html.erb + - invitations.index.choose_invite + - invitations.index.email address # should be invitations.index.email_address + - invitations.index.submit_invite + # File: app/views/languages/_form.html.erb + - languages.form.abuse_support_available + - languages.form.create + - languages.form.name + - languages.form.required_notice + - languages.form.short + - languages.form.sortable_name + - languages.form.support_available + - languages.form.update + # File: app/views/languages/edit.html.erb + - languages.edit.edit_language + # File: app/views/languages/new.html.erb + - languages.new.new_language + # File: app/views/languages/show.html.erb + - languages.show.work_count + # File: app/views/locales/_locale_form.html.erb + - locales.locale_form.actions_heading + - locales.locale_form.actions_legend + - locales.locale_form.create_button + - locales.locale_form.edit_button + - locales.locale_form.enable_email + - locales.locale_form.enable_interface + - locales.locale_form.iso + - locales.locale_form.language + - locales.locale_form.locale_heading + - locales.locale_form.locale_legend + - locales.locale_form.name + - locales.locale_form.required_notice + # File: app/views/locales/_navigation.html.erb + - locales.navigation.link_to_index + - locales.navigation.link_to_new + # File: app/views/locales/edit.html.erb + - locales.edit.edit_locale + # File: app/views/locales/index.html.erb + - locales.index.locale_table_caption + - locales.index.locale_table_summary + - locales.index.supported_locales + # File: app/views/locales/new.html.erb + - locales.new.add_new_locale + # File: app/views/orphans/index.html.erb + - orphans.index.orphaned_works + # File: app/views/orphans/new.html.erb + - orphans.new.links.cancel + - orphans.new.orphans_about + # File: app/views/pseuds/edit.html.erb + - pseuds.edit.forms.update + # File: app/views/pseuds/show.html.erb + - pseuds.show.edit_link + - pseuds.show.index_link + # File: app/views/series/manage.html.erb + - series.manage.manage_series + +## Consider these keys used: +ignore_unused: + - activerecord.attributes.* + - activerecord.errors.models.* + - activerecord.models.* + - devise.* + - errors.messages.* + - errors.attributes.ticket_number.{closed_ticket,invalid_department,required} + - attributes.ticket_number + +## Exclude these keys from the `i18n-tasks eq-base' report: +# ignore_eq_base: +# all: +# - common.ok +# fr,es: +# - common.brand + +## Exclude these keys from the `i18n-tasks check-consistent-interpolations` report: +# ignore_inconsistent_interpolations: +# - 'activerecord.attributes.*' + +## Exclude these keys from the newlines test task: +# ignore_newlines: +# - user_mailer.signup_notification.* + +## Ignore these keys completely: +# ignore: +# - kaminari.* + +## Sometimes, it isn't possible for i18n-tasks to match the key correctly, +## e.g. in case of a relative key defined in a helper method. +## In these cases you can use the built-in PatternMapper to map patterns to keys, e.g.: +# +# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper', +# only: %w(*.html.haml *.html.slim), +# patterns: [['= title\b', '.page_title']] %> +# +# The PatternMapper can also match key literals via a special %{key} interpolation, e.g.: +# +# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper', +# patterns: [['\bSpree\.t[( ]\s*%{key}', 'spree.%{key}']] %> diff --git a/config/initializers/active_record_log_subscriber.rb b/config/initializers/active_record_log_subscriber.rb new file mode 100755 index 0000000..6b07081 --- /dev/null +++ b/config/initializers/active_record_log_subscriber.rb @@ -0,0 +1,16 @@ +module LogQuerySource + def debug(*args, &block) + return unless super + + backtrace = Rails.backtrace_cleaner.clean caller + + relevant_caller_line = backtrace.detect do |caller_line| + !caller_line.include?('/initializers/') + end + + if relevant_caller_line + logger.debug(" ↳ #{ relevant_caller_line.sub("#{ Rails.root }/", '') }") + end + end +end +ActiveRecord::LogSubscriber.send :prepend, LogQuerySource diff --git a/config/initializers/active_record_query_trace.rb b/config/initializers/active_record_query_trace.rb new file mode 100755 index 0000000..04f0e0a --- /dev/null +++ b/config/initializers/active_record_query_trace.rb @@ -0,0 +1,5 @@ +if Rails.env.development? + ActiveRecordQueryTrace.enabled = true + ActiveRecordQueryTrace.ignore_cached_queries = true + ActiveRecordQueryTrace.colorize = :light_purple +end diff --git a/config/initializers/active_record_schema_ignore_tables.rb b/config/initializers/active_record_schema_ignore_tables.rb new file mode 100755 index 0000000..60e89a7 --- /dev/null +++ b/config/initializers/active_record_schema_ignore_tables.rb @@ -0,0 +1,4 @@ +ActiveRecord::SchemaDumper.ignore_tables += [ + # MySQL/MariaDB internals + "innodb_monitor" +] diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb new file mode 100755 index 0000000..89d2efa --- /dev/null +++ b/config/initializers/application_controller_renderer.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/config/initializers/archive_config/locale.rb b/config/initializers/archive_config/locale.rb new file mode 100755 index 0000000..8508c0e --- /dev/null +++ b/config/initializers/archive_config/locale.rb @@ -0,0 +1,16 @@ +Rails.application.config.after_initialize do + ActiveRecord::Base.connection + # try to set language and locale using models (which use Archive Config) + Language.default + Locale.default +rescue ActiveRecord::NoDatabaseError + # No database, this happens when we run rake db:create +rescue ActiveRecord::ConnectionNotEstablished + # no database connection +rescue + # ArchiveConfig didn't work, try to set it manually + if Language.table_exists? && Locale.table_exists? + language = Language.find_or_create_by(short: "en", name: "English") + Locale.set_base_locale(iso: "en", name: "English (US)", language_id: language.id) + end +end diff --git a/config/initializers/archive_config/settings_for_admin.rb b/config/initializers/archive_config/settings_for_admin.rb new file mode 100755 index 0000000..f5f9e29 --- /dev/null +++ b/config/initializers/archive_config/settings_for_admin.rb @@ -0,0 +1,8 @@ +Rails.application.config.after_initialize do + # If we have no database, fall through to rescue + ActiveRecord::Base.connection + AdminSetting.default if AdminSetting.table_exists? +rescue ActiveRecord::ConnectionNotEstablished +rescue ActiveRecord::NoDatabaseError + # This happens if we are running rake db:create +end diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb new file mode 100755 index 0000000..68fd3a0 --- /dev/null +++ b/config/initializers/assets.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +# Rails.application.config.assets.version = "1.0" + +# Add additional assets to the asset load path. +# Rails.application.config.assets.paths << Emoji.images_path diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100755 index 0000000..33699c3 --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,8 @@ +# 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| /my_noisy_library/.match?(line) } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code +# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". +Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb new file mode 100755 index 0000000..b3076b3 --- /dev/null +++ b/config/initializers/content_security_policy.rb @@ -0,0 +1,25 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide content security policy. +# See the Securing Rails Applications Guide for more information: +# https://guides.rubyonrails.org/security.html#content-security-policy-header + +# Rails.application.configure do +# config.content_security_policy do |policy| +# policy.default_src :self, :https +# policy.font_src :self, :https, :data +# policy.img_src :self, :https, :data +# policy.object_src :none +# policy.script_src :self, :https +# policy.style_src :self, :https +# # Specify URI for violation reports +# # policy.report_uri "/csp-violation-report-endpoint" +# end +# +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. +# config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } +# config.content_security_policy_nonce_directives = %w(script-src style-src) +# +# # Report violations without enforcing the policy. +# # config.content_security_policy_report_only = true +# end diff --git a/config/initializers/cookies_serializer.rb b/config/initializers/cookies_serializer.rb new file mode 100755 index 0000000..f51a497 --- /dev/null +++ b/config/initializers/cookies_serializer.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. + +# Specify a serializer for the signed and encrypted cookie jars. +# Valid options are :json, :marshal, and :hybrid. +Rails.application.config.action_dispatch.cookies_serializer = :hybrid diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb new file mode 100755 index 0000000..0c5dd99 --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Avoid CORS issues when API is called from the frontend app. +# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin Ajax requests. + +# Read more: https://github.com/cyu/rack-cors + +# Rails.application.config.middleware.insert_before 0, Rack::Cors do +# allow do +# origins "example.com" +# +# resource "*", +# headers: :any, +# methods: [:get, :post, :put, :patch, :delete, :options, :head] +# end +# end diff --git a/config/initializers/departure.rb b/config/initializers/departure.rb new file mode 100755 index 0000000..f201a56 --- /dev/null +++ b/config/initializers/departure.rb @@ -0,0 +1,10 @@ +Departure.configure do |config| + # Disable departure by default. To use pt-online-schema-change for a + # migration, call + # uses_departure! if Rails.env.staging? || Rails.env.production? + # in the migration file. + config.enabled_by_default = false + + # Set the arguments based on the config file: + config.global_percona_args = ArchiveConfig.PERCONA_ARGS.squish +end diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb new file mode 100755 index 0000000..194b760 --- /dev/null +++ b/config/initializers/devise.rb @@ -0,0 +1,272 @@ +# Use this hook to configure devise mailer, warden hooks and so forth. +# Many of these configuration options can be set straight in your model. +Devise.setup do |config| + # The secret key used by Devise. Devise uses this key to generate + # random tokens. Changing this key will render invalid all existing + # confirmation, reset password and unlock tokens in the database. + # Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key` + # by default. You can change it below and use your own secret key. + config.secret_key = ArchiveConfig.SESSION_SECRET + + # ==> Mailer Configuration + # Configure the e-mail address which will be shown in Devise::Mailer, + # note that it will be overwritten if you use your own mailer class + # with default "from" parameter. + config.mailer_sender = "Archive of Our Own <#{ArchiveConfig.RETURN_ADDRESS}>" + + # Configure the class responsible to send e-mails. + config.mailer = 'ArchiveDeviseMailer' + + # ==> ORM configuration + # Load and configure the ORM. Supports :active_record (default) and + # :mongoid (bson_ext recommended) by default. Other ORMs may be + # available as additional gems. + require 'devise/orm/active_record' + + # ==> Configuration for any authentication mechanism + # Configure which keys are used when authenticating a user. The default is + # just :email. You can configure it to use [:username, :subdomain], so for + # authenticating a user, both parameters are required. Remember that those + # parameters are used only when authenticating and not when retrieving from + # session. If you need permissions, you should implement that in a before filter. + # You can also supply a hash where the value is a boolean determining whether + # or not authentication should be aborted when the value is not present. + config.authentication_keys = [:login] + + # Configure parameters from the request object used for authentication. Each entry + # given should be a request method and it will automatically be passed to the + # find_for_authentication method and considered in your model lookup. For instance, + # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. + # The same considerations mentioned for authentication_keys also apply to request_keys. + # config.request_keys = [] + + # Configure which authentication keys should be case-insensitive. + # These keys will be downcased upon creating or modifying a user and when used + # to authenticate or find a user. Default is :email. + config.case_insensitive_keys = [] + + # Configure which authentication keys should have whitespace stripped. + # These keys will have whitespace before and after removed upon creating or + # modifying a user and when used to authenticate or find a user. Default is :email. + config.strip_whitespace_keys = [:login] + + # Tell if authentication through request.params is enabled. True by default. + # It can be set to an array that will enable params authentication only for the + # given strategies, for example, `config.params_authenticatable = [:database]` will + # enable it only for database (email + password) authentication. + # config.params_authenticatable = true + + # Tell if authentication through HTTP Auth is enabled. False by default. + # It can be set to an array that will enable http authentication only for the + # given strategies, for example, `config.http_authenticatable = [:database]` will + # enable it only for database authentication. The supported strategies are: + # :database = Support basic authentication with authentication key + password + # config.http_authenticatable = false + + # If 401 status code should be returned for AJAX requests. True by default. + # config.http_authenticatable_on_xhr = true + + # The realm used in Http Basic Authentication. 'Application' by default. + # config.http_authentication_realm = 'Application' + + # It will change confirmation, password recovery and other workflows + # to behave the same regardless if the e-mail provided was right or wrong. + # Does not affect registerable. + # config.paranoid = true + + # By default Devise will store the user in session. You can skip storage for + # particular strategies by setting this option. + # Notice that if you are skipping storage for all authentication paths, you + # may want to disable generating routes to Devise's sessions controller by + # passing skip: :sessions to `devise_for` in your config/routes.rb + config.skip_session_storage = [:http_auth] + + # By default, Devise cleans up the CSRF token on authentication to + # avoid CSRF token fixation attacks. This means that, when using AJAX + # requests for sign in and sign up, you need to get a new CSRF token + # from the server. You can disable this option at your own risk. + # config.clean_up_csrf_token_on_authentication = true + + # ==> Configuration for :database_authenticatable + # For bcrypt, this is the cost for hashing the password and defaults to 10. If + # using other encryptors, it sets how many times you want the password re-encrypted. + # + # Limiting the stretches to just one in testing will increase the performance of + # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use + # a value less than 10 in other environments. Note that, for bcrypt (the default + # encryptor), the cost increases exponentially with the number of stretches (e.g. + # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). + config.stretches = Rails.env.test? ? 1 : 14 + + # Setup a pepper to generate the encrypted password. + # config.pepper = '70ca884cc885f6ea790b81e61162e634afadc5121775443df4cb3d1e3d76d74b5c226af89d64b69c000ad9b42f1998c49ef2758ddbbab01483eded4723d7ef97' + + # Send a notification email when the user's password is changed + config.send_password_change_notification = true + + # ==> Configuration for :confirmable + # A period that the user is allowed to access the website even without + # confirming their account. For instance, if set to 2.days, the user will be + # able to access the website for two days without confirming their account, + # access will be blocked just in the third day. Default is 0.days, meaning + # the user cannot access the website without confirming their account. + # config.allow_unconfirmed_access_for = 2.days + + # A period that the user is allowed to confirm their account before their + # token becomes invalid. For example, if set to 3.days, the user can confirm + # their account within 3 days after the mail was sent, but on the fourth day + # their account can't be confirmed with the token any more. + # Default is nil, meaning there is no restriction on how long a user can take + # before confirming their account. + config.confirm_within = ArchiveConfig.DAYS_TO_CONFIRM_EMAIL_CHANGE.days + + # If true, requires any email changes to be confirmed (exactly the same way as + # initial account confirmation) to be applied. Requires additional unconfirmed_email + # db field (see migrations). Until confirmed, new email is stored in + # unconfirmed_email column, and copied to email column on successful confirmation. + config.reconfirmable = true + + # Defines which key will be used when confirming an account + # config.confirmation_keys = [:email] + + # ==> Configuration for :rememberable + # The time the user will be remembered without asking for credentials again. + config.remember_for = ArchiveConfig.REMEMBERED_SESSION_LENGTH_IN_MONTHS.months + + # Invalidates all the remember me tokens when the user signs out. + config.expire_all_remember_me_on_sign_out = true + + # If true, extends the user's remember period when remembered via cookie. + # config.extend_remember_period = false + + # Options to be passed to the created cookie. For instance, you can set + # secure: true in order to force SSL only cookies. + # config.rememberable_options = {} + + # ==> Configuration for :validatable + # Range for password length. + config.password_length = ArchiveConfig.PASSWORD_LENGTH_MIN..ArchiveConfig.PASSWORD_LENGTH_MAX + + # Email regex used to validate email formats. It simply asserts that + # one (and only one) @ exists in the given string. This is mainly + # to give user feedback and not to assert the e-mail validity. + # config.email_regexp = /\A[^@]+@[^@]+\z/ + + # ==> Configuration for :timeoutable + # The time you want to timeout the user session without activity. After this + # time the user will be asked for credentials again. Default is 30 minutes. + # config.timeout_in = 30.minutes + + # ==> Configuration for :lockable + # Defines which strategy will be used to lock an account. + # :failed_attempts = Locks an account after a number of failed attempts to sign in. + # :none = No lock strategy. You should handle locking by yourself. + # config.lock_strategy = :failed_attempts + + # Defines which key will be used when locking and unlocking an account + # config.unlock_keys = [:login] + + # Defines which strategy will be used to unlock an account. + # :email = Sends an unlock link to the user email + # :time = Re-enables login after a certain amount of time (see :unlock_in below) + # :both = Enables both strategies + # :none = No unlock strategy. You should handle unlocking by yourself. + # config.unlock_strategy = :both + config.unlock_strategy = :time + + # Number of authentication tries before locking an account if lock_strategy + # is failed attempts. + # config.maximum_attempts = 20 + config.maximum_attempts = 50 + + # Time interval to unlock the account if :time is enabled as unlock_strategy. + # config.unlock_in = 1.hour + config.unlock_in = 5.minutes + + # Warn on the last attempt before the account is locked. + # config.last_attempt_warning = true + + # ==> Configuration for :recoverable + # + # Defines which key will be used when recovering the password for an account + config.reset_password_keys = [:login] + + # Time interval you can reset your password with a reset password key. + # Don't put a too small interval or your users won't have the time to + # change their passwords. + config.reset_password_within = ArchiveConfig.DAYS_UNTIL_RESET_PASSWORD_LINK_EXPIRES.days + + # When set to false, does not sign a user in automatically after their password is + # reset. Defaults to true, so a user is signed in automatically after a reset. + # config.sign_in_after_reset_password = true + + # ==> Configuration for :encryptable + # Allow you to use another encryption algorithm besides bcrypt (default). You can use + # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, + # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) + # and :restful_authentication_sha1 (then you should set stretches to 10, and copy + # REST_AUTH_SITE_KEY to pepper). + # + # Require the `devise-encryptable` gem when using anything other than bcrypt + # config.encryptor = :sha512 + #config.encryptor = :authlogic_sha512 + + # ==> Scopes configuration + # Turn scoped views on. Before rendering "sessions/new", it will first check for + # "users/sessions/new". It's turned off by default because it's slower if you + # are using only default views. + # config.scoped_views = false + config.scoped_views = true # We use scoped views because we have 2 devise models + + # Configure the default scope given to Warden. By default it's the first + # devise role declared in your routes (usually :user). + # config.default_scope = :user + config.default_scope = :admin + + # Set this configuration to false if you want /users/sign_out to sign out + # only the current scope. By default, Devise signs out all scopes. + config.sign_out_all_scopes = true + + # ==> Navigation configuration + # Lists the formats that should be treated as navigational. Formats like + # :html, should redirect to the sign in page when the user does not have + # access, but formats like :xml or :json, should return 401. + # + # If you have any extra navigational formats, like :iphone or :mobile, you + # should add them to the navigational formats lists. + # + # The "*/*" below is required to match Internet Explorer requests. + # config.navigational_formats = ['*/*', :html] + + # The default HTTP method used to sign out a resource. Default is :delete. + config.sign_out_via = :delete + + # ==> OmniAuth + # Add a new OmniAuth provider. Check the wiki for more information on setting + # up on your models and hooks. + # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' + + # ==> Warden configuration + # If you want to use other strategies, that are not supported by Devise, or + # change the failure app, you can configure them inside the config.warden block. + # + config.warden do |manager| + manager.failure_app = DeviseFailureMessageOptions + # manager.intercept_401 = false + # manager.default_strategies(scope: :user).unshift :some_external_strategy + end + + # ==> Mountable engine configurations + # When using Devise inside an engine, let's call it `MyEngine`, and this engine + # is mountable, there are some extra configurations to be taken into account. + # The following options are available, assuming the engine is mounted as: + # + # mount MyEngine, at: '/my_engine' + # + # The router that invoked `devise_for`, in the example above, would be: + # config.router_name = :my_engine + # + # When using OmniAuth, Devise cannot automatically set OmniAuth path, + # so you need to do it manually. For the users scope, it would be: + # config.omniauth_path_prefix = '/my_engine/users/auth' +end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100755 index 0000000..63b1295 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,13 @@ +# Be sure to restart your server when you modify this file. + +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. +Rails.application.config.filter_parameters += [ + :content, :passw, :terms_of_service_non_production, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn +] + +# IMPORTANT! Rails.application.config.filter_parameters must be set *above* in this file +# Ensure filter_attributes is always set. Without this, it is brittle. +# See https://github.com/rails/rails/issues/48704 +ActiveRecord::Base.filter_attributes += Rails.application.config.filter_parameters diff --git a/config/initializers/gem-plugin_config/acts_as_commentable.rb b/config/initializers/gem-plugin_config/acts_as_commentable.rb new file mode 100755 index 0000000..c68da0e --- /dev/null +++ b/config/initializers/gem-plugin_config/acts_as_commentable.rb @@ -0,0 +1,3 @@ +require "acts_as_commentable/commentable" + +ActiveRecord::Base.include ActsAsCommentable::Commentable diff --git a/config/initializers/gem-plugin_config/elasticsearch.rb b/config/initializers/gem-plugin_config/elasticsearch.rb new file mode 100755 index 0000000..524ea7c --- /dev/null +++ b/config/initializers/gem-plugin_config/elasticsearch.rb @@ -0,0 +1 @@ +$elasticsearch = Elasticsearch::Client.new host: ArchiveConfig.ES_URL diff --git a/config/initializers/gem-plugin_config/escape_utils_config.rb b/config/initializers/gem-plugin_config/escape_utils_config.rb new file mode 100755 index 0000000..6c23695 --- /dev/null +++ b/config/initializers/gem-plugin_config/escape_utils_config.rb @@ -0,0 +1,16 @@ +# This will apparently speed up our html escaping by a LOT and also get rid of pesky UTF-8 error messages in cucumber tests +# See http://openhood.com/rack/ruby/2010/07/15/rack-test-warning/ +# and also http://github.com/brianmario/escape_utils +require "escape_utils/html/rack" + +# don't escape erb files - it creates hideous html and doesn't parse properly in URI during testing +#require "escape_utils/html/erb" + +module Rack + module Utils + def escape(s) + EscapeUtils.escape_url(s) + end + end +end + diff --git a/config/initializers/gem-plugin_config/pagy.rb b/config/initializers/gem-plugin_config/pagy.rb new file mode 100755 index 0000000..62acb36 --- /dev/null +++ b/config/initializers/gem-plugin_config/pagy.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# https://ddnexus.github.io/pagy/docs/extras/i18n/ +require "pagy/extras/i18n" + +# See https://ddnexus.github.io/pagy/docs/api/pagy#variables +Pagy::DEFAULT[:limit] = ArchiveConfig.ITEMS_PER_PAGE +Pagy::DEFAULT[:size] = 9 + +Pagy::DEFAULT.freeze diff --git a/config/initializers/gem-plugin_config/permit_yo_config.rb b/config/initializers/gem-plugin_config/permit_yo_config.rb new file mode 100755 index 0000000..4e984b2 --- /dev/null +++ b/config/initializers/gem-plugin_config/permit_yo_config.rb @@ -0,0 +1,34 @@ +# Authorization plugin configuration goes here +# +# See http://github.com/ianterrell/permityo/tree/ Settings section for details on what can be configured, +# although most defaults are sensible. + +module Otwarchive + class Application < Rails::Application + + # Which flash key we stick error messages into + config.permit_yo.require_user_flash = :error + config.permit_yo.permission_denied_flash = :error + + # Where users get redirected if they are not currently logged in + config.permit_yo.require_user_redirection = {controller: :user_sessions, action: :new} + end +end + +module PermitYo + module Default + module UserExtensions + module InstanceMethods + + # Determine if the current model has a particular role + # depends on the model having a relationship with roles! (eg, has_and_belongs_to_many :roles) + def has_role?(role_name) + return self.roles.any? { |role| role.name == role_name.to_s } if self.roles.loaded? + + role = Role.find_by(name: role_name) + self.roles.include?(role) + end + end + end + end +end diff --git a/config/initializers/gem-plugin_config/redis.rb b/config/initializers/gem-plugin_config/redis.rb new file mode 100755 index 0000000..a373aa0 --- /dev/null +++ b/config/initializers/gem-plugin_config/redis.rb @@ -0,0 +1,35 @@ +require "redis_test_setup" +include RedisTestSetup # rubocop:disable Style/MixinUsage + +rails_root = ENV["RAILS_ROOT"] || "#{File.dirname(__FILE__)}/../../.." +rails_env = (ENV["RAILS_ENV"] || "development").to_sym + +# https://gist.github.com/441072 +start_redis!(rails_root, :cucumber) if rails_env == :test && !(ENV["CI"] || ENV["DOCKER"]) + +redis_configs = YAML.load_file("#{rails_root}/config/redis.yml", symbolize_names: true) +redis_configs.each_pair do |name, redis_config| + redis_options = {} + if redis_config[rails_env].is_a?(Hash) + # example: + # redis_kudos: + # development + # name: redis_kudos + # sentinels: + # - host: 127.0.0.1 + # port: 26379 + # - host: 127.0.0.1 + # port: 26380 + redis_options = redis_config[rails_env] + else + redis_host, redis_port = redis_config[rails_env].split(":") + redis_options[:host] = redis_host + redis_options[:port] = redis_port + end + redis_connection = Redis.new(redis_options) + if ENV["DEV_USER"] + namespaced_redis = Redis::Namespace.new(ENV["DEV_USER"], redis: redis_connection) + redis_connection = namespaced_redis + end + Object.const_set(name.upcase, redis_connection) +end diff --git a/config/initializers/gem-plugin_config/resque.rb b/config/initializers/gem-plugin_config/resque.rb new file mode 100755 index 0000000..6506289 --- /dev/null +++ b/config/initializers/gem-plugin_config/resque.rb @@ -0,0 +1,14 @@ +require "resque" + +rails_root = ENV["RAILS_ROOT"] || "#{File.dirname(__FILE__)}/../../.." +rails_env = (ENV["RAILS_ENV"] || "development").to_sym + +redis_configs = YAML.load_file("#{rails_root}/config/redis.yml", symbolize_names: true) +Resque.redis = redis_configs[:redis_resque][rails_env] + +# in-process performing of jobs (for testing) doesn't require a redis server +Resque.inline = ENV["RAILS_ENV"] == "test" + +Resque.after_fork do + Resque.redis.client.reconnect +end diff --git a/config/initializers/gem-plugin_config/sanitizer_config.rb b/config/initializers/gem-plugin_config/sanitizer_config.rb new file mode 100755 index 0000000..5f94296 --- /dev/null +++ b/config/initializers/gem-plugin_config/sanitizer_config.rb @@ -0,0 +1,71 @@ +# Sanitize: http://github.com/rgrove/sanitize.git +class Sanitize + # This defines the configuration we use for HTML tags and attributes allowed in the archive. + module Config + ARCHIVE = freeze_config( + elements: %w[ + a abbr acronym address b big blockquote br caption center cite code col + colgroup details figcaption figure dd del dfn div dl dt em h1 h2 h3 h4 h5 h6 hr + i img ins kbd li ol p pre q rp rt ruby s samp small span strike strong + sub summary sup table tbody td tfoot th thead tr tt u ul var + ], + attributes: { + all: %w[align title dir], + "a" => %w[href name], + "blockquote" => %w[cite], + "col" => %w[span width], + "colgroup" => %w[span width], + "details" => %w[open], + "hr" => %w[align width], + "img" => %w[align alt border height src width], + "ol" => %w[start type], + "q" => %w[cite], + "table" => %w[border summary width], + "td" => %w[abbr axis colspan height rowspan width], + "th" => %w[abbr axis colspan height rowspan scope width], + "ul" => %w[type] + }, + + add_attributes: { + "a" => { "rel" => "nofollow" } + }, + + protocols: { + "a" => { "href" => ["ftp", "http", "https", "mailto", :relative] }, + "blockquote" => { "cite" => ["http", "https", :relative] }, + "img" => { "src" => ["http", "https"] }, + "q" => { "cite" => ["http", "https", :relative] } + }, + + # TODO: This can be removed once we upgrade sanitizer gem, AO3-5801 + # I would leave the tests we added in AO3-5974 though. + remove_contents: %w[iframe math noembed noframes noscript plaintext script style svg xmp] + ) + + CLASS_ATTRIBUTE = freeze_config( + # see in the Transformers section for what classes we strip + attributes: { + all: ARCHIVE[:attributes][:all] + ["class"] + } + ) + + CSS_ALLOWED = freeze_config(merge(ARCHIVE, CLASS_ATTRIBUTE)) + + # On details elements, force boolean attribute "open" to have + # value "open", if it exists + OPEN_ATTRIBUTE_TRANSFORMER = lambda do |env| + return unless env[:node_name] == "details" + + env[:node]["open"] = "open" if env[:node].has_attribute?("open") + end + + # On img elements, convert relative paths to absolute: + RELATIVE_IMAGE_PATH_TRANSFORMER = lambda do |env| + return unless env[:node_name] == "img" && env[:node]["src"] + + env[:node]["src"] = URI.join(ArchiveConfig.APP_URL, env[:node]["src"]) + rescue URI::InvalidURIError + # do nothing, the sanitizer will handle it + end + end +end diff --git a/config/initializers/gem-plugin_config/webmock.rb b/config/initializers/gem-plugin_config/webmock.rb new file mode 100755 index 0000000..2b2f493 --- /dev/null +++ b/config/initializers/gem-plugin_config/webmock.rb @@ -0,0 +1,6 @@ +if Rails.env.test? + # net_http_connect_on_start: https://stackoverflow.com/questions/59632283/chromedriver-capybara-too-many-open-files-socket2-for-127-0-0-1-port-951 + # limited to localhost: https://github.com/bblimke/webmock/issues/955#issuecomment-1373962511 + WebMock.allow_net_connect!(net_http_connect_on_start: %w[127.0.0.1 localhost]) + WebMock.enable! +end diff --git a/config/initializers/gem-plugin_config/will_paginate_config.rb b/config/initializers/gem-plugin_config/will_paginate_config.rb new file mode 100755 index 0000000..a24be48 --- /dev/null +++ b/config/initializers/gem-plugin_config/will_paginate_config.rb @@ -0,0 +1,2 @@ +require 'will_paginate/array' +WillPaginate.per_page = ArchiveConfig.ITEMS_PER_PAGE diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100755 index 0000000..1674594 --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,17 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +ActiveSupport::Inflector.inflections(:en) do |inflect| + inflect.irregular "Media", "Media" +# inflect.plural /^(ox)$/i, "\\1en" +# inflect.singular /^(ox)en/i, "\\1" +# inflect.irregular "person", "people" +# inflect.uncountable %w( fish sheep ) +end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym "RESTful" +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100755 index 0000000..4fac756 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,9 @@ +# for azw3 files +Marcel::MimeType.extend "application/x-mobi8-ebook", extensions: %w[azw3] +Mime::Type.register "application/x-mobi8-ebook", :azw3 +# for epub files +Marcel::MimeType.extend "application/epub", extensions: %w[epub] +Mime::Type.register "application/epub", :epub + +# for mobi type (already present in marcel types) +Mime::Type.register "application/x-mobipocket-ebook", :mobi diff --git a/config/initializers/monkeypatches/akismetor.rb b/config/initializers/monkeypatches/akismetor.rb new file mode 100755 index 0000000..0dae9c8 --- /dev/null +++ b/config/initializers/monkeypatches/akismetor.rb @@ -0,0 +1,10 @@ +# Patch Akismetor, which is not Ruby 3 compatible, as it uses URI.escape: +# https://github.com/freerobby/akismetor/blob/1cef6c0e237dd69b3f6ae1ee8d719c0862cd77e4/lib/akismetor.rb#L53-L56 +# +# TODO: AO3-6454 Remove this gem and handle the API calls ourselves. + +class Akismetor + def attributes_for_post + URI.encode_www_form(attributes) + end +end diff --git a/config/initializers/monkeypatches/deliver_after_commit.rb b/config/initializers/monkeypatches/deliver_after_commit.rb new file mode 100755 index 0000000..d289ce0 --- /dev/null +++ b/config/initializers/monkeypatches/deliver_after_commit.rb @@ -0,0 +1,9 @@ +module ActionMailer + class MessageDelivery + include AfterCommitEverywhere + + def deliver_after_commit + after_commit { deliver_later } + end + end +end diff --git a/config/initializers/monkeypatches/fix_phraseapp.rb b/config/initializers/monkeypatches/fix_phraseapp.rb new file mode 100755 index 0000000..8f68902 --- /dev/null +++ b/config/initializers/monkeypatches/fix_phraseapp.rb @@ -0,0 +1,16 @@ +module FixPhraseapp + def translate(*args) + if to_be_translated_without_phraseapp?(args) + kw_args = args.last.is_a?(Hash) ? args.pop : {} + I18n.translate_without_phraseapp(*args, **kw_args) + else + phraseapp_delegate_for(args) + end + end +end + +if PhraseApp::VERSION == "1.6.0" + PhraseApp::InContextEditor::BackendService.prepend(FixPhraseapp) +else + puts "WARNING: The monkeypatch #{__FILE__} was written for version 1.6.0 of the phraseapp-in-context-editor-ruby gem, but you are running #{PhraseApp::VERSION}. Please update or remove the monkeypatch." +end diff --git a/config/initializers/monkeypatches/mailers_controller.rb b/config/initializers/monkeypatches/mailers_controller.rb new file mode 100755 index 0000000..ca8f941 --- /dev/null +++ b/config/initializers/monkeypatches/mailers_controller.rb @@ -0,0 +1,11 @@ +module MailersController + extend ActiveSupport::Concern + + included do + # Hide the dev mark in mailer previews. + skip_rack_dev_mark + end +end +Rails.application.config.after_initialize do + ::Rails::MailersController.include MailersController +end diff --git a/config/initializers/monkeypatches/override_default_form_field_sizes.rb b/config/initializers/monkeypatches/override_default_form_field_sizes.rb new file mode 100755 index 0000000..6142e53 --- /dev/null +++ b/config/initializers/monkeypatches/override_default_form_field_sizes.rb @@ -0,0 +1,24 @@ +# Rails default form helpers text_field etc use default sizes. Rails default form helpers text_field_tag etc do NOT. WHY. +# Here we trash all the default options. +# +# We also add the css class "text" to all text input fields because we need a class on them to be +# able to target them in ie6, alas. + +# InstanceTag no longer exists in Rails 4 +# module ActionView::Helpers +# class InstanceTag +# remove_const :DEFAULT_TEXT_AREA_OPTIONS +# DEFAULT_TEXT_AREA_OPTIONS = { } +# +# remove_const :DEFAULT_FIELD_OPTIONS +# DEFAULT_FIELD_OPTIONS = { "class" => "text" } +# end +# end + + +module ActionView::Helpers::FormTagHelper + alias_method :text_field_tag_original, :text_field_tag + def text_field_tag(name, value = nil, options = {}) + text_field_tag_original(name, value, {"class" => "text"}.merge(options)) + end +end diff --git a/config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb b/config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb new file mode 100755 index 0000000..e74fbf5 --- /dev/null +++ b/config/initializers/monkeypatches/textarea_convert_html_to_newlines.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +# modifying to_text_area_tag and text_area_tag to strip paragraph/br tags +# and convert them back into newlines for editing purposes +module ActionView + module Helpers + module Tags + class TextArea + # added method to yank

    and
    tags and replace with newlines + # this needs to reverse "add_paragraph_tags_to_text" from our html_cleaner library + # TODO: this is not fully working as of 2025 (probably for years) + def strip_html_breaks(content, name="") + return "" if content.blank? + if name =~ /content/ + # might be using RTE, preserve all paragraphs as they are + content.gsub(/\s*
    \s*/, "
    \n"). + gsub(/\s*]*>\s* \s*<\/p>\s*/, "\n\n\n"). + gsub(/\s*(]*>.*?<\/p>)\s*/m, "\n\n" + '\1'). + strip + else + # no RTE, so clean up paragraphs unless they have qualifiers + content = content.gsub(/\s*
    \s*/, "
    \n"). + gsub(/\s*]*>\s* \s*<\/p>\s*/, "\n\n\n") + + if content.match(/\s*(]+>)(.*?)(<\/p>)\s*/m) + content.gsub(/\s*(]*>.*?<\/p>)\s*/m, "\n\n" + '\1'). + strip + else + content.gsub(/\s*]*>(.*?)<\/p>\s*/m, "\n\n" + '\1'). + strip + end + end + end + + def render + options = @options.stringify_keys + add_default_name_and_id(options) + + if size = options.delete("size") + options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split) + end + + content = options.delete("value") { value_before_type_cast } + content = strip_html_breaks(content, options['name']) + + content_tag("textarea", content, options) + end + end + end + end +end diff --git a/config/initializers/monkeypatches/translate_string.rb b/config/initializers/monkeypatches/translate_string.rb new file mode 100755 index 0000000..fbd81a6 --- /dev/null +++ b/config/initializers/monkeypatches/translate_string.rb @@ -0,0 +1,78 @@ +module I18n + class << self + # Formats a string. Used to mark strings that should eventually be + # translated with I18n, but aren't at the moment. + # + # Deprecated. + def translate_string(str, **options) + str % options + end + + alias :ts :translate_string + end +end + +module AbstractController + module Translation + def translate_string(str, **options) + I18n.translate_string(str, **options) + end + alias :ts :translate_string + end +end + + +module ActiveRecord #:nodoc: + class Base + def translate_string(str, **options) + begin + ActiveRecord::Base.connection + I18n.translate_string(str, **options) + rescue StandardError + str || "" + end + end + + alias :ts :translate_string + + class << Base + def translate_string(str, **options) + begin + ActiveRecord::Base.connection + I18n.translate_string(str, **options) + rescue StandardError + str || "" + end + end + + alias :ts :translate_string + end + end +end + +module ActionMailer #:nodoc: + class Base + def translate_string(str, **options) + begin + ActiveRecord::Base.connection + I18n.translate_string(str, **options) + rescue StandardError + str || "" + end + end + + alias :ts :translate_string + end +end + +module ActionView + module Helpers + module TranslationHelper + def translate_string(str, **options) + str % options + end + + alias :ts :translate_string + end + end +end diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb new file mode 100755 index 0000000..7db3b95 --- /dev/null +++ b/config/initializers/permissions_policy.rb @@ -0,0 +1,13 @@ +# Be sure to restart your server when you modify this file. + +# Define an application-wide HTTP permissions policy. For further +# information see: https://developers.google.com/web/updates/2018/06/feature-policy + +# Rails.application.config.permissions_policy do |policy| +# policy.camera :none +# policy.gyroscope :none +# policy.microphone :none +# policy.usb :none +# policy.fullscreen :self +# policy.payment :self, "https://secure.example.com" +# end diff --git a/config/initializers/phraseapp_in_context_editor.rb b/config/initializers/phraseapp_in_context_editor.rb new file mode 100755 index 0000000..96163b8 --- /dev/null +++ b/config/initializers/phraseapp_in_context_editor.rb @@ -0,0 +1,31 @@ +PhraseApp::InContextEditor.configure do |config| + # Enable or disable the In-Context-Editor in general + if ENV['AO3_PHRASE_APP'] == 'true' || ArchiveConfig.PHRASEAPP_ENABLE == 'true' then + config.enabled = true + else + config.enabled = false + end + + # Fetch your project id after creating your first project + # in Translation Center. + # You can find the project id in your project settings + # page (https://phraseapp.com/projects) + config.project_id = "47f2a1b0cf81df327878c6d89cee7af3" + + # You can create and manage access tokens in your profile settings + # in Translation Center or via the Authorizations API + # (http://docs.phraseapp.com/api/v2/authorizations/). + config.access_token = ArchiveConfig.PHRASEAPP_TOKEN + + # Configure an array of key names that should not be handled + # by the In-Context-Editor. + config.ignored_keys = ["number.*", "breadcrumb.*"] + + # PhraseApp uses decorators to generate a unique identification key + # in context of your document. However, this might result in conflicts + # with other libraries (e.g. client-side template engines) that use a similar syntax. + # If you encounter this problem, you might want to change this decorator pattern. + # More information: http://docs.phraseapp.com/guides/in-context-editor/configure/ + # config.prefix = "{{__" + # config.suffix = "__}}" +end diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb new file mode 100755 index 0000000..8ed35d5 --- /dev/null +++ b/config/initializers/rack_attack.rb @@ -0,0 +1,127 @@ +class Rack::Attack + + # The following is a useful resource. + # https://www.driftingruby.com/episodes/rails-api-throttling-with-rack-attack + # + ### Configure Cache ### + + # If you don't want to use Rails.cache (Rack::Attack's default), then + # configure it here. + # + # Note: The store is only used for throttling (not blocklisting and + # safelisting). It must implement .increment and .write like + # ActiveSupport::Cache::Store + + # Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new + + ### Throttle Spammy Clients ### + + # If we fail to unmask the remote IP for a request, the + # frontends will pass the internal network (10.0.0.0/8) to the + # unicorns. We need to ensure that we don't block these requests. + + ArchiveConfig.RATE_LIMIT_SAFELIST.each do |ip| + Rack::Attack.safelist_ip(ip) + end + + # If any single client IP is making tons of requests, then they're + # probably malicious or a poorly-configured scraper. Either way, they + # don't deserve to hog all of the app server's CPU. Cut them off! + # + # Note: If you're serving assets through rack, those requests may be + # counted by rack-attack and this throttle may be activated too + # quickly. If so, enable the condition to exclude them from tracking. + # + + # This stanza allows us to limit by user which backend is selected by nginx. + + ArchiveConfig.RATE_LIMIT_PER_NGINX_UPSTREAM_USER.each do |k, v| + throttle("req/#{k}/user", limit: v["limit"], period: v["period"]) do |req| + req.env["HTTP_X_AO3_SESSION_USER"] if req.env["HTTP_X_UNICORNS"] == k && req.env["HTTP_X_AO3_SESSION_USER"].present? + end + end + + # This stanza allows us to limit by ip which backend is selected by nginx. + + ArchiveConfig.RATE_LIMIT_PER_NGINX_UPSTREAM.each do |k, v| + throttle("req/#{k}/ip", limit: v["limit"], period: v["period"]) do |req| + req.ip if req.env["HTTP_X_UNICORNS"] == k + end + end + + # Throttle all requests by IP (60rpm) + # + # Key: "rack::attack:#{Time.now.to_i/:period}:req/ip:#{req.ip}" + limit = ArchiveConfig.RATE_LIMIT_NUMBER + period = ArchiveConfig.RATE_LIMIT_PERIOD + throttle('req/ip', limit: limit, period: period) do |req| + req.ip + end + + ### Prevent Brute-Force Login Attacks ### + + # The most common brute-force login attack is a brute-force password + # attack where an attacker simply tries a large number of emails and + # passwords to see if any credentials match. + # + # Another common method of attack is to use a swarm of computers with + # different IPs to try brute-forcing a password for a specific account. + + login_limit = ArchiveConfig.RATE_LIMIT_LOGIN_ATTEMPTS + login_period = ArchiveConfig.RATE_LIMIT_LOGIN_PERIOD + + # Throttle POST requests to /users/login by IP address + # + # Key: "rack::attack:#{Time.now.to_i/:period}:logins/ip:#{req.ip}" + throttle("logins/ip", limit: login_limit, period: login_period) do |req| + req.ip if req.path == "/users/login" && req.post? + end + + # Throttle POST requests to /users/login by login param (username or email) + # + # Key: "rack::attack:#{Time.now.to_i/:period}:logins/email:#{login}" + # + # Note: This creates a problem where a malicious user could intentionally + # throttle logins for another user and force their login requests to be + # denied, but that's not very common and shouldn't happen to you. (Knock + # on wood!) + throttle("logins/email", limit: login_limit, period: login_period) do |req| + req.params.dig("user", "login").presence if req.path == "/users/login" && req.post? + end + + ### Add Rate Limits for Admin Login ### + admin_login_limit = ArchiveConfig.RATE_LIMIT_ADMIN_LOGIN_ATTEMPTS + admin_login_period = ArchiveConfig.RATE_LIMIT_ADMIN_LOGIN_PERIOD + + # Throttle POST requests to /admin/login by IP address + # + # Key: "rack::attack:#{Time.now.to_i/:period}:admin_logins/ip:#{req.ip}" + throttle("admin_logins/ip", limit: admin_login_limit, period: admin_login_period) do |req| + req.ip if req.path == "/admin/login" && req.post? + end + + # Throttle POST requests to /admin/login by login param (user name or email) + # + # Key: "rack::attack:#{Time.now.to_i/:period}:admin_logins/email:#{login}" + throttle("admin_logins/email", limit: admin_login_limit, period: admin_login_period) do |req| + req.params.dig("admin", "login").presence if req.path == "/admin/login" && req.post? + end + + # Add Retry-After response header to let polite clients know + # how many seconds they should wait before trying again + Rack::Attack.throttled_response_retry_after_header = true + + ### Custom Throttle Response ### + + # By default, Rack::Attack returns an HTTP 429 for throttled responses, + # which is just fine. + # + # If you want to return 503 so that the attacker might be fooled into + # believing that they've successfully broken your app (or you just want to + # customize the response), then uncomment these lines. + # self.throttled_response = lambda do |env| + # [ 503, # status + # {}, # headers + # ['']] # body + # end +end diff --git a/config/initializers/rollout_init.rb b/config/initializers/rollout_init.rb new file mode 100755 index 0000000..ab2451b --- /dev/null +++ b/config/initializers/rollout_init.rb @@ -0,0 +1 @@ +$rollout = Rollout.new(REDIS_ROLLOUT) diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb new file mode 100755 index 0000000..fb597dc --- /dev/null +++ b/config/initializers/sentry.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +if Rails.env.production? || Rails.env.staging? + Sentry.init do |config| + # get breadcrumbs from logs + config.breadcrumbs_logger = [:active_support_logger, :http_logger] + + # enable tracing + config.traces_sampler = lambda do |sampling_context| + next sampling_context[:parent_sampled] unless sampling_context[:parent_sampled].nil? + + rack_env = sampling_context[:env] || {} + rate_from_nginx = Float(rack_env["HTTP_X_SENTRY_RATE"], exception: false) + return rate_from_nginx if rate_from_nginx + return 0.01 if Rails.env.production? + return 1.00 if Rails.env.staging? + + # Default to off for other environments when no override is present + 0.0 + end + + # enable profiling + # this is relative to traces_sample_rate + config.profiles_sample_rate = 1.0 + + config.environment = Rails.env + config.release = ArchiveConfig.REVISION.to_s + end +end diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100755 index 0000000..9f523a0 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,18 @@ +class ActionDispatch::Session::ForceSignedCookieStore < ActionDispatch::Session::CookieStore + private + + # Override the cookie_jar method to use signed cookies + # regardless of whether a secret_key_base has been set + def cookie_jar(request) + request.cookie_jar.signed + end +end + +# Be sure to restart your server when you modify this file. + +Otwarchive::Application.config.session_store :force_signed_cookie_store, key: '_otwarchive_session', expire_after: ArchiveConfig.DEFAULT_SESSION_LENGTH_IN_WEEKS.weeks + +# Use the database for sessions instead of the cookie-based default, +# which shouldn't be used to store highly confidential information +# (create the session table with "rake db:sessions:create") +# Otwarchive::Application.config.session_store :active_record_store diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100755 index 0000000..bbfc396 --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/README.md b/config/locales/README.md new file mode 100755 index 0000000..bd1ddf2 --- /dev/null +++ b/config/locales/README.md @@ -0,0 +1,17 @@ +## `phrase-exports/` + +These files are updated by Phrase and should not be edited. Refer to `.phrase.yml`. + +## `rails-i18n/` + +We use locale files, pluralization and transliteration rules from the installed +gem [rails-i18n](https://github.com/svenfuchs/rails-i18n). + +This folder contains patches to rails-i18n. + +We [manually install](https://github.com/svenfuchs/rails-i18n#manual-installation) +the following locales from rails-i18n version 7.0.3 in order to rename them. +Aside from the locale name, the files should not be edited. + +- "mr-IN" to "mr" +- "tl" to "fil" diff --git a/config/locales/controllers/en.yml b/config/locales/controllers/en.yml new file mode 100755 index 0000000..cf246d3 --- /dev/null +++ b/config/locales/controllers/en.yml @@ -0,0 +1,283 @@ +--- +en: + admin: + access: + action_access_denied: Sorry, only an authorized admin can do that. + not_admin_denied: Please log in as admin + page_access_denied: Sorry, only an authorized admin can access the page you were trying to reach. + admin_invitations: + find: + user_not_found: No results were found. Try another search. + invite_from_queue: + success: + one: "%{count} person from the invite queue is being invited." + other: "%{count} people from the invite queue are being invited." + admin_users: + confirm_delete_user_creations: + page_title: "%{login} - Confirm Deletion of User Creations" + destroy_user_creations: + success: All creations by user %{login} have been deleted. + user_creations: + confirm_remove_pseud: + must_have_orphan_pseuds: Sorry, this action is only available for works by orphan_account pseuds. + remove_pseud: + must_select_pseud: You must select which orphan_account pseud to remove. + success: + one: Successfully removed pseud %{pseuds} from this work. + other: Successfully removed pseuds %{pseuds} from this work. + application: + access_denied: + access_denied: + logged_in: Sorry, you don't have permission to access the page you were trying to reach. + archive_faqs: + create: + success: Archive FAQ was successfully created. + default_locale_only: Sorry, this action is only available for English FAQs. + update: + success: Archive FAQ was successfully updated. + update_positions: + success: Archive FAQs order was successfully updated. + blocked: + users: + create: + blocked: You have blocked the user %{name}. + destroy: + unblocked: You have unblocked the user %{name}. + challenge_assignments: + validation: + not_owner: You aren't the owner of that assignment. + chapters: + destroy: + only_chapter: You can't delete the only chapter in your work. If you want to delete the work, choose "Delete Work". + draft_flash: + posted_work: This is a draft chapter in a posted work. It will be kept unless the work is deleted. + unposted_work_html: This is a draft chapter in an unposted work. The work will be scheduled for deletion on %{deletion_date}. + show: + anonymous: Anonymous + chapter_position: " - Chapter %{position}" + multifandom: Multifandom + unrevealed: Mystery Work + unspecified_fandom: No fandom specified + collection_items: + create: + invited: invited + invited_to_collections_html: This work has been %{invited_link} to your collection (%{collection_title}). + collection_participants: + update: + failure: Couldn't update %{participant}. + validation: + owners_required: You can't remove the only owner! + collection_profile: + show: + page_title: "%{collection_title} - Profile" + collections: + index: + subcollections_page_title: "%{collection_title} - Subcollections" + comments: + check_blocked: + parent: Sorry, you have been blocked by one or more of this work's creators. + reply: Sorry, you have been blocked by that user. + check_frozen: + error: Sorry, you cannot reply to a frozen comment. + check_guest_replies_preference: + error: Sorry, this user doesn't allow non-Archive users to reply to their comments. + check_hidden_by_admin: + error: Sorry, you cannot reply to a hidden comment. + check_not_replying_to_spam: + error: Sorry, you can't reply to a comment that has been marked as spam. + check_permission_to_edit: + error: + frozen: Frozen comments cannot be edited. + create: + success: + moderated: + admin_post: Your comment was received! It will appear publicly after it has been approved. + work: Your comment was received! It will appear publicly after the work creator has approved it. + not_moderated: Comment created! + freeze: + error: Sorry, that comment thread could not be frozen. + permission_denied: Sorry, you don't have permission to freeze that comment thread. + success: Comment thread successfully frozen! + hide: + error: Sorry, that comment could not be hidden. + permission_denied: Sorry, you don't have permission to hide that comment. + success: Comment successfully hidden! + unfreeze: + error: Sorry, that comment thread could not be unfrozen. + permission_denied: Sorry, you don't have permission to unfreeze that comment thread. + success: Comment thread successfully unfrozen! + unhide: + error: Sorry, that comment could not be unhidden. + permission_denied: Sorry, you don't have permission to unhide that comment. + success: Comment successfully unhidden! + errors: + auth_error: + browser_title: Auth Error + timeout_error: + browser_title: Timeout Error + external_works: + update: + successfully_updated: External work was successfully updated. + fandoms: + index: + choose_media: Please choose a media category to start browsing fandoms. + collection_page_title: "%{collection_title} - Fandoms" + home: + content: + page_title: Content Policy + privacy: + page_title: Privacy Policy + tos: + page_title: Terms of Service + tos_faq: + page_title: Terms of Service FAQ + inbox: + show: + page_title: "%{user} - Inbox" + update: + must_select_item: Please select at least one comment first. + success: Inbox successfully updated. + invite_requests: + create: + queue_disabled: + closed: New invitation requests are currently closed. + html: "%{closed_bold} For more information, please check the %{news_link}." + news: '"Invitations" tag on AO3 News' + success: You've been added to our queue! Yay! We estimate that you'll receive an invitation around %{date}. We strongly recommend that you add %{return_address} to your address book to prevent the invitation email from getting blocked as spam by your email provider. + index: + page_title: Invitation Requests + resend: + not_found: Could not find an invitation associated with that email. + not_yet: You cannot resend an invitation that was sent in the last %{count} hours. + success: Invitation resent to %{email}. + status: + browser_title: Invitation Request Status + kudos: + create: + success: Thank you for leaving kudos! + languages: + cannot_edit_default: Sorry, you can't edit the default language. + successfully_added: Language was successfully added. + successfully_updated: Language was successfully updated. + media: + index: + browser_title: Fandoms + muted: + users: + create: + muted: You have muted the user %{name}. + destroy: + unmuted: You have unmuted the user %{name}. + people: + index: + collection_page_title: "%{collection_title} - People" + profile: + show: + page_title: "%{username} - Profile" + pseuds: + create: + already_have_pseud_with_name: You already have a pseud with that name. + successfully_created: Pseud was successfully created. + destroy: + cannot_delete_default: You cannot delete your default pseudonym, sorry! + cannot_delete_matching_username: You cannot delete the pseud matching your username, sorry! + not_deleted: The pseud was not deleted. + successfully_deleted: The pseud was successfully deleted. + update: + successfully_updated: Pseud was successfully updated. + questions: + not_found: Sorry, we couldn't find the FAQ you were looking for. + update_positions: + success: Question order has been successfully updated. + readings: + clear: + error: There were problems deleting your history. Please try again later. + success: Your history is now cleared. + index: + history_page_title: History + marked_for_later_page_title: Marked for Later + related_works: + index: + page_title: "%{login} - Related Works" + series: + index: + page_title: "%{username} - Series" + show: + anonymous: Anonymous + unrevealed_series: Mystery Series + subscriptions: + delete_all: + error: There were problems deleting your subscriptions. + success: Your subscriptions have been deleted. + index: + page_title: "%{username} - Subscriptions" + subscription_type_page_title: "%{username} - %{subscription_type} Subscriptions" + tag_wranglings: + index: + page_subtitle: fandoms + tags: + index: + collection_page_title: "%{collection_title} - Tags" + users: + change_email: + page_title: Change Email + change_password: + page_title: Change Password + change_username: + page_title: Change Username + changed_password: + blank_password: You must enter your old password. + wrong_password: Your old password was incorrect. + changed_username: + admin: + successfully_updated: Username has been successfully updated. + new_username_must_be_different: Your new username must be different from your current username. + user: + incorrect_password: Your password was incorrect + successfully_updated: Your username has been successfully updated. + confirm_change_email: + blank_email: You must enter a new email address. + blank_password: You must enter your password. + browser_title: Confirm New Email + contact_support: contact Support + nonmatching_email: The email addresses you entered do not match. Please try again. + same_as_current: Your new email address must be different from your current email. + wrong_password_html: Your password was incorrect. Please try again or log out and reset your password via the link on the login form. If you are still having trouble, %{contact_support_link} for help. + contact_abuse: contact our Policy & Abuse team + passwords: + create: + contact_abuse: contact our Policy & Abuse team + reset_blocked_html: Password resets are disabled for that user. For more information, please %{contact_abuse_link}. + reset_cooldown_html: You cannot reset your password at this time. Please try again after %{reset_available_time}. + send_cooldown_period: + one: After that, you will need to wait %{count} hour before requesting another reset. + other: After that, you will need to wait %{count} hours before requesting another reset. + send_instructions: Check your email for instructions on how to reset your password. %{send_times_remaining} %{send_cooldown_period} + send_times_remaining: + one: You may reset your password %{count} more time. + other: You may reset your password %{count} more times. + user_not_found: We couldn't find an account with that email address or username. Please try again. + reconfirm_email: + access_denied: + logged_in: You are not logged in to the account whose email you are trying to change. Please log out and try again. + invalid_token: This email confirmation link is invalid or expired. Please check your email for the correct link or submit the email change form again. + success: Your email has been successfully updated. + registrations: + create: + page_title: Account Created + new: + page_title: Create Account + status: + ban_notice_html: Your account has been banned. You are not permitted to post or edit content on Sunset. Please check your email or %{contact_abuse_link} for more information. + suspension_notice_html: Your account has been suspended until %{suspended_until}. You cannot post, edit, or delete content until your suspension has ended. Please check your email or %{contact_abuse_link} for more information. + works: + drafts: + page_title: "%{username} - Drafts" + show: + page_title: + unrevealed: Mystery Work + wrangling_guidelines: + create: Wrangling Guideline was successfully created. + delete: Wrangling Guideline was successfully deleted. + reorder: Wrangling Guidelines order was successfully updated. + update: Wrangling Guideline was successfully updated. diff --git a/config/locales/devise/en.yml b/config/locales/devise/en.yml new file mode 100755 index 0000000..745f8e8 --- /dev/null +++ b/config/locales/devise/en.yml @@ -0,0 +1,73 @@ +--- +en: + devise: + confirmations: + confirmed: Your email address has been successfully confirmed. + send_instructions: You will receive an email with instructions for how to confirm your email address in a few minutes. + send_paranoid_instructions: If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes. + failure: + admin: + already_authenticated: You are already signed in. + inactive: Your account is not activated yet. + invalid: The password or admin username you entered doesn't match our records. + last_attempt: You have one more attempt before your account is locked. + locked: Your account is locked. + not_found_in_database: The password or admin username you entered doesn't match our records. + timeout: Your session expired. Please sign in again to continue. + unauthenticated: You need to sign in or sign up before continuing. + unconfirmed: You have to confirm your email address before continuing. + user: + already_authenticated: You are already signed in. + inactive: You'll need to activate your account before you can log in. Please check your email or contact support. + invalid: The password or username you entered doesn't match our records. Please try again or reset your password. If you still can't log in, please visit Problems When Logging In for help. + last_attempt: You have one more attempt before your account is locked. + locked: Your account has been locked for 5 minutes due to too many failed login attempts. + not_found_in_database: The password or username you entered doesn't match our records. Please try again or reset your password. If you still can't log in, please visit Problems When Logging In for help. + timeout: Your session expired. Please sign in again to continue. + unauthenticated: You need to sign in or sign up before continuing. + unconfirmed: You have to activate your account before continuing. Please check your email for the activation link. + mailer: + confirmation_instructions: + subject: Confirmation instructions + password_change: + subject: Password Changed + reset_password_instructions: + subject: "[%{app_name}] Generated reset password link" + unlock_instructions: + subject: Unlock instructions + omniauth_callbacks: + failure: Could not authenticate you from %{kind} because "%{reason}". + success: Successfully authenticated from %{kind} account. + passwords: + no_token: You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided. + send_instructions: Check your email for instructions on how to reset your password. + send_paranoid_instructions: If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes. + updated: Your password has been changed successfully. You are now signed in. + updated_not_active: Your password has been changed successfully. + registrations: + destroyed: Bye! Your account has been successfully cancelled. We hope to see you again soon. + signed_up: Welcome! You have signed up successfully. + signed_up_but_inactive: You have signed up successfully. However, we could not sign you in because your account is not yet activated. + signed_up_but_locked: You have signed up successfully. However, we could not sign you in because your account is locked. + signed_up_but_unconfirmed: A message with a confirmation link has been sent to your email address. Please follow the link to activate your account. + update_needs_confirmation: You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address. + updated: Your account has been updated successfully. + sessions: + already_signed_out: Successfully logged out. + signed_in: Successfully logged in. + signed_out: Successfully logged out. + unlocks: + send_instructions: You will receive an email with instructions for how to unlock your account in a few minutes. + send_paranoid_instructions: If your account exists, you will receive an email with instructions for how to unlock it in a few minutes. + unlocked: Your account has been unlocked successfully. Please sign in to continue. + errors: + messages: + already_confirmed: was already confirmed, please try signing in + confirmation_period_expired: needs to be confirmed within %{period}, please request a new one + expired: has expired, please request a new one + not_found: not found + not_locked: was not locked + not_saved: + one: '1 error prohibited this %{resource} from being saved:' + other: "%{count} errors prohibited this %{resource} from being saved:" + pwned_password: appears in data breaches from other sites and is no longer secure. For your protection, please select a stronger, unique password. diff --git a/config/locales/helpers/en.yml b/config/locales/helpers/en.yml new file mode 100755 index 0000000..21aa667 --- /dev/null +++ b/config/locales/helpers/en.yml @@ -0,0 +1,54 @@ +--- +en: + collections_helper: + collection_item_approval_options: + collection: + approved: Approved by collection moderators + rejected: Rejected by collection moderators + unreviewed: Unreviewed by collection moderators + user: + bookmark: + approved: Approved by bookmarker + rejected: Rejected by bookmarker + unreviewed: Unreviewed by bookmarker + work: + approved: Approved by creator + rejected: Rejected by creator + unreviewed: Unreviewed by creator + collection_item_approval_options_label: + collection: Collection approval status + user: + bookmark: Bookmarker approval status + work: Creator approval status + comments_helper: + chapter_link_html: Chapter %{position} + comment_link_with_commentable_name: + on_admin_post_html: Comment on the news post %{title} + on_tag_html: Comment on the tag %{name} + on_unknown: Comment on unknown item + on_work_html: Comment on the work %{title} + inbox_helper: + comment_link_with_chapter_number: Chapter %{position} of %{title} + users_helper: + log: + ban: Suspended Permanently + email_change: Email Changed + fnok: + has_added: 'Fannish Next of Kin Added: %{user_id}' + has_removed: 'Fannish Next of Kin Removed: %{user_id}' + was_added: 'Added as Fannish Next of Kin for: %{user_id}' + was_removed: 'Removed as Fannish Next of Kin for: %{user_id}' + lift_suspension: Suspension Lifted + note: Note Added + password_change: Password Changed + password_reset: Password Reset + rename: Username Changed + role_added: 'Role Added: ' + role_removed: 'Role Removed: ' + suspended: 'Suspended until ' + troubleshot: Account Troubleshot + validated: Account Validated + warn: Warned + works_helper: + mark_as_read_button: Mark as Read + mark_for_later_button: Mark for Later diff --git a/config/locales/mailers/en.yml b/config/locales/mailers/en.yml new file mode 100755 index 0000000..7dd6e00 --- /dev/null +++ b/config/locales/mailers/en.yml @@ -0,0 +1,700 @@ +--- +en: + admin: + mailer: + password_change: + changed: The password for your %{app_name} admin account was changed on %{date}. + did_not_make_change: If you did not make this change, someone else may have access to your %{app_name} admin account or your OTW email. Please let AD&T and VolCom know immediately so they can take steps to secure your accounts. + made_change: + html: If you made this change, you can %{login_link} or %{reset_password_link} if you've forgotten it. + login: log in with your new password + reset_password: reset your password + text: If you made this change, you can log in with your new password (%{login_url}) or reset your password if you've forgotten it (%{reset_password_url}). + secure_again: + html: When your accounts are secure again, please %{reset_password_link}. + reset_password: reset your admin password + text: 'When your accounts are secure again, please reset your admin password: %{reset_password_url}.' + subject: "[%{app_name}] Your admin password has been changed" + reset_password_instructions: + expiration: + one: If you do not use this link to reset your password within %{count} day, it will expire, and you will have to request a new one. + other: If you do not use this link to reset your password within %{count} days, it will expire, and you will have to request a new one. + intro: 'Someone has requested a password reset for your account. You can change your account password by following the link below and entering your new password:' + link_title_html: Change my password. + subject: "[%{app_name}] Reset your admin password" + unrequested: If you did not request this password reset, you may ignore this email and your previous password will continue to work. + admin_mailer: + set_password_notification: + created: Your AO3 admin account has been created. + expiration: + one: 'The link to set your password is good for %{count} day. If it no longer works, you can request a password reset and use the link that will be emailed to you instead: %{request_reset_url}.' + other: 'The link to set your password is good for %{count} days. If it no longer works, you can request a password reset and use the link that will be emailed to you instead: %{request_reset_url}.' + expiration_html: + one: The link to set your password is good for %{count} day. If it no longer works, you can %{request_reset_link} and use the link that will be emailed to you instead. + other: The link to set your password is good for %{count} days. If it no longer works, you can %{request_reset_link} and use the link that will be emailed to you instead. + finish: 'Please follow this link to set your password so you can log in: %{set_password_url}.' + finish_html: Please %{set_password_link} so you can log in. + request_reset: request a password reset + set_password: follow this link to set your password + subject: "[%{app_name}] Your AO3 admin account" + url: Admin login URL + username: Admin username + comment_mailer: + comment_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: "%{pseud_link} left the following comment on %{chapter_link} of %{work_link}:" + titled_text: "%{pseud} left the following comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):" + untitled_text: "%{pseud} left the following comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):" + other: + html: "%{pseud_link} left the following comment on %{commentable_link}:" + text: "%{pseud} left the following comment on %{title} (%{commentable_url}):" + tag: + html: "%{pseud_link} left the following comment on the tag %{tag_link}:" + text: "%{pseud} left the following comment on the tag %{tag} (%{tag_url}):" + subject: + chapter: "[%{app_name}] Comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Comment on %{title}" + tag: "[%{app_name}] Comment on the tag %{name}" + comment_reply_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: "%{pseud_link} replied to your comment on %{chapter_link} of %{work_link}:" + titled_text: "%{pseud} replied to your comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):" + untitled_text: "%{pseud} replied to your comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):" + other: + html: "%{pseud_link} replied to your comment on %{commentable_link}:" + text: "%{pseud} replied to your comment on %{title} (%{commentable_url}):" + tag: + html: "%{pseud_link} replied to your comment on the tag %{tag_link}:" + text: "%{pseud} replied to your comment on the tag %{tag} (%{tag_url}):" + subject: + chapter: "[%{app_name}] Reply to your comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Reply to your comment on %{title}" + tag: "[%{app_name}] Reply to your comment on the tag %{name}" + comment_reply_sent_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: 'You replied to a comment on %{chapter_link} of %{work_link}:' + titled_text: 'You replied to a comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):' + untitled_text: 'You replied to a comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):' + other: + html: 'You replied to a comment on %{commentable_link}:' + text: 'You replied to a comment on %{title} (%{commentable_url}):' + tag: + html: 'You replied to a comment on the tag %{tag_link}:' + text: 'You replied to a comment on the tag %{tag} (%{tag_url}):' + subject: + chapter: "[%{app_name}] Reply you left to a comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Reply you left to a comment on %{title}" + tag: "[%{app_name}] Reply you left to a comment on the tag %{name}" + comment_sent_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: 'You left the following comment on %{chapter_link} of %{work_link}:' + titled_text: 'You left the following comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):' + untitled_text: 'You left the following comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):' + other: + html: 'You left the following comment on %{commentable_link}:' + text: 'You left the following comment on %{title} (%{commentable_url}):' + tag: + html: 'You left the following comment on the tag %{tag_link}:' + text: 'You left the following comment on the tag %{tag} (%{tag_url}):' + subject: + chapter: "[%{app_name}] Comment you left on Chapter %{position} of %{title}" + other: "[%{app_name}] Comment you left on %{title}" + tag: "[%{app_name}] Comment you left on the tag %{name}" + edited_comment_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: "%{pseud_link} edited the following comment on %{chapter_link} of %{work_link}:" + titled_text: "%{pseud} edited the following comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):" + untitled_text: "%{pseud} edited the following comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):" + other: + html: "%{pseud_link} edited the following comment on %{commentable_link}:" + text: "%{pseud} edited the following comment on %{title} (%{commentable_url}):" + tag: + html: "%{pseud_link} edited the following comment on the tag %{tag_link}:" + text: "%{pseud} edited the following comment on the tag %{tag} (%{tag_url}):" + subject: + chapter: "[%{app_name}] Edited comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Edited comment on %{title}" + tag: "[%{app_name}] Edited comment on the tag %{name}" + edited_comment_reply_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: "%{pseud_link} edited their reply to your comment on %{chapter_link} of %{work_link}:" + titled_text: "%{pseud} edited their reply to your comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):" + untitled_text: "%{pseud} edited their reply to your comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):" + other: + html: "%{pseud_link} edited their reply to your comment on %{commentable_link}:" + text: "%{pseud} edited their reply to your comment on %{title} (%{commentable_url}):" + tag: + html: "%{pseud_link} edited their reply to your comment on the tag %{tag_link}:" + text: "%{pseud} edited their reply to your comment on the tag %{tag} (%{tag_url}):" + subject: + chapter: "[%{app_name}] Edited reply to your comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Edited reply to your comment on %{title}" + tag: "[%{app_name}] Edited reply to your comment on the tag %{name}" + kudo_mailer: + batch_kudo_notification: + guest: + one: a guest + other: "%{count} guests" + left_kudos: + html: + one: "%{givers_list} left kudos on %{commentable_link}." + other: "%{givers_list} left kudos on %{commentable_link}." + text: + one: '%{givers_list} left kudos on "%{commentable_title}" (%{commentable_url}).' + other: '%{givers_list} left kudos on "%{commentable_title}" (%{commentable_url}).' + single_guest: + giver: A guest + html: "%{giver} left kudos on %{commentable_link}." + text: A guest left kudos on "%{commentable_title}" (%{commentable_url}). + subject: "[%{app_name}] You've got kudos!" + mailer: + collections: + why_collection_email: + html: You're receiving this email because your email address has been listed as the collection email for the collection %{collection_link}. + text: You're receiving this email because your email address has been listed as the collection email for the collection "%{collection_title}" (%{collection_url}). + why_maintainer: + html: You're receiving this email because you are an owner or moderator of the collection %{collection_link}. + text: You're receiving this email because you are an owner or moderator of the collection "%{collection_title}" (%{collection_url}). + general: + closing: + formal: Sincerely, + informal: Best, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Chapter %{position} of %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} word" + other: "%{count} words" + footer: + about: + html: The Sunset is a fan-run and fan-supported archive that relies on %{your_donations_link}. + text: 'The Sunset is a fan-run and fan-supported archive that relies on your donations: %{your_donations_url}.' + your_donations: your donations + sent_at: Sent at %{sent_at}. + why_policy_abuse: + contact_policy_abuse: contact Policy & Abuse + html: If you don't understand why you received this email, please %{contact_policy_abuse_link}. + text: 'If you don''t understand why you received this email, please contact Policy & Abuse: %{contact_policy_abuse_url}.' + why_support: + contact_support: contact Support + html: If you don't understand why you received this email, please %{contact_support_link}. + text: 'If you don''t understand why you received this email, please contact Support: %{contact_support_url}.' + greeting: + formal: + addressed_html: Hi %{name}, + unaddressed: Hi, + informal: + addressed_html: Hi, %{name}! + unaddressed: Hi! + introductory: Hello from the Archive of Our Own! + tag_wrangler_supervisors: Tag Wrangler Supervisors + metadata_label_indicator: ": " + signature: + abuse_team: The AO3 Policy & Abuse team + app_short_name: AO3 + open_doors: The Open Doors team + parent_org: Organization for Transformative Works + support: The AO3 Support team + roles: + anonymous_creator: Anonymous Creator + commenter_name: + html: "%{name} %{role_with_parens}" + text: "%{name} %{role_with_parens}" + guest_with_parens: "(Guest)" + official_with_parens: "(Official)" + registered_with_parens: "(Registered User)" + tag_wrangling_supervisor_mailer: + wrangler_username_change_notification: + name_changed: + html: The wrangler %{old_username} has changed their name to %{new_username}. + subject: "[%{app_name}] Wrangler name change" + user_mailer: + abuse_report: + copy: + comment: Description of the content or issue + intro: 'Here is a copy of your report for your reference:' + summary: Terms of Service violation + url: URL of the reported page + report_received: The Policy & Abuse team has received your report, and our volunteers will investigate as soon as they can. Because our team is small and we receive thousands of reports each month, it may take some time for us to get to your report. + resubmission: Please do not resubmit this report unless you have additional information that you did not include in your original report. Submitting multiple reports about the same issue may delay our response. + subject: "[%{app_name}] Abuse - %{summary}" + thank_you: Thank you for your patience. + admin_deleted_work_notification: + bye: Attached is a copy of your work for your reference. + contact_abuse: contact our Policy & Abuse team + deleted: + html: Your work %{title} was deleted from the Archive by a site admin. + text: Your work "%{title}" was deleted from the Archive by a site admin. + import_project: + html: If your work was part of an import project managed by our Open Doors team, please %{opendoors_link} with any further questions. + text: If your work was part of an import project managed by our Open Doors team, please contact Open Doors (%{opendoors_link}) with any further questions. + opendoors: contact Open Doors + subject: "[%{app_name}] Your work has been deleted by an admin" + tos_violation: + html: If it's possible your work violated the Archive's Terms of Service, please %{contact_abuse_link}. + text: If it's possible your work violated the Archive's Terms of Service, please contact our Policy & Abuse team (%{contact_abuse_url}). + admin_hidden_work_notification: + access: + one: While your work is hidden, you will still be able to access it through the link provided above, but it won't be available to other users or listed on your works page. + other: While your works are hidden, you will still be able to access them through the links provided above, but they won't be available to other users or listed on your works page. + check_email: + one: Please check your email, including your spam folder, as the Policy & Abuse committee may have already contacted you to explain why your work was hidden. + other: Please check your email, including your spam folder, as the Policy & Abuse committee may have already contacted you to explain why your works were hidden. + contact_abuse: contact the Policy & Abuse committee + content_policy: Content Policy + help: + html: + one: If you don't know why your work was hidden, and you have not received a separate email explaining why, please %{contact_abuse_link} directly. + other: If you don't know why your works were hidden, and you have not received a separate email explaining why, please %{contact_abuse_link} directly. + text: + one: 'If you don''t know why your work was hidden, and you have not received a separate email explaining why, please contact the Policy & Abuse committee directly: %{contact_abuse_url}.' + other: 'If you don''t know why your works were hidden, and you have not received a separate email explaining why, please contact the Policy & Abuse committee directly: %{contact_abuse_url}.' + hidden_multiple: "%{count} of your works have been hidden by the Policy & Abuse committee:" + hidden_one: + html: Your work %{title} has been hidden by the Policy & Abuse committee. + text: Your work "%{title}" (%{work_url}) has been hidden by the Policy & Abuse committee. + subject: + one: "[%{app_name}] Your work has been hidden by the Policy & Abuse committee" + other: "[%{app_name}] Your works have been hidden by the Policy & Abuse committee" + tos: AO3 Terms of Service + tos_faq: Terms of Service FAQ + tos_violation: + html: + one: If your work was hidden due to being in violation of the %{tos_link} (including the %{content_policy_link}), you will be required to take action to correct the violation. Failure to bring your work into compliance with the Terms of Service may result in your work being deleted from AO3. For more information, please refer to the %{tos_faq_link}. + other: If your works were hidden due to being in violation of the %{tos_link} (including the %{content_policy_link}), you will be required to take action to correct the violations. Failure to bring your works into compliance with the Terms of Service may result in your works being deleted from AO3. For more information, please refer to the %{tos_faq_link}. + text: + one: 'If your work was hidden due to being in violation of the AO3 Terms of Service (%{tos_url}), including the Content Policy (%{content_policy_url}), you will be required to take action to correct the violation. Failure to bring your work into compliance with the Terms of Service may result in your work being deleted from AO3. For more information, please refer to the Terms of Service FAQ: %{tos_faq_url}.' + other: 'If your works were hidden due to being in violation of the AO3 Terms of Service (%{tos_url}), including the Content Policy (%{content_policy_url}), you will be required to take action to correct the violations. Failure to bring your works into compliance with the Terms of Service may result in your works being deleted from AO3. For more information, please refer to the Terms of Service FAQ: %{tos_faq_url}.' + work_info: '- "%{title}" (%{work_url})' + admin_spam_work_notification: + contact_abuse: contact our Policy & Abuse Team + flagged_as_spam: + html: Your work %{work_link} has been flagged by our automated system as spam and hidden until it can be reviewed by our Policy & Abuse team. While the work is hidden it can only be accessed by you and AO3 site admins. + text: Your work "%{work_title}" (%{work_url}) has been flagged by our automated system as spam and hidden until it can be reviewed by our Abuse team. While the work is hidden it can only be accessed by you and AO3 site admins. + future: If we determine that your work is not spam, we'll unhide it. Other users will then be able to access and leave feedback on it as usual. Please note that we do not screen works for other kinds of violations at this time. If your work is reported to us for a different reason in the future, that will be investigated separately. + questions: + html: If you have any questions, please %{contact_abuse_link}. + text: If you have any questions, please contact our Policy & Abuse team (%{contact_abuse_url}). + subject: "[%{app_name}] Your work was hidden as spam" + anonymous_or_unrevealed_notification: + anonymous_info: Anonymous works are included in tag listings, but not on your works page. On the work, your username will be replaced with "Anonymous." + anonymous_unrevealed_info: The collection maintainers may later reveal your work but leave it anonymous. People who subscribe to you will not be notified of this change. Your work will be included in tag listings, but not on your works page. On the work, your username will be replaced with "Anonymous." + changed_status: + anonymous: + html: The collection maintainers of %{collection_link} have changed the status of your work %{work_link} to anonymous. + text: The collection maintainers of "%{collection_title}" (%{collection_url}) have changed the status of your work "%{work_title}" (%{work_url}) to anonymous. + anonymous_unrevealed: + html: The collection maintainers of %{collection_link} have changed the status of your work %{work_link} to anonymous and unrevealed. + text: The collection maintainers of "%{collection_title}" (%{collection_url}) have changed the status of your work "%{work_title}" (%{work_url}) to anonymous and unrevealed. + unrevealed: + html: The collection maintainers of %{collection_link} have changed the status of your work %{work_link} to unrevealed. + text: The collection maintainers of "%{collection_title}" (%{collection_url}) have changed the status of your work "%{work_title}" (%{work_url}) to unrevealed. + collection_items_link_text: Approved Collection Items page + do_not_want: + anonymous: + html: If you do not want your work to be anonymous, please visit your %{collection_items_link} to remove it from this collection. + text: 'If you do not want your work to be anonymous, please visit your Approved Collection Items page to remove it from this collection: %{collection_items_url}' + anonymous_unrevealed: + html: If you do not want your work to be anonymous and unrevealed, please visit your %{collection_items_link} to remove it from this collection. + text: 'If you do not want your work to be anonymous and unrevealed, please visit your Approved Collection Items page to remove it from this collection: %{collection_items_url}' + unrevealed: + html: If you do not want your work to be unrevealed, please visit your %{collection_items_link} to remove it from this collection. + text: 'If you do not want your work to be unrevealed, please visit your Approved Collection Items page to remove it from this collection: %{collection_items_url}' + faq_link_text: Collections FAQ + more_info: + html: For more information, visit our %{faq_link}. + text: 'For more information, visit our Collections FAQ: %{faq_url}' + subject: + anonymous: "[%{app_name}] Your work was made anonymous" + anonymous_unrevealed: "[%{app_name}] Your work was made anonymous and unrevealed" + unrevealed: "[%{app_name}] Your work was made unrevealed" + unrevealed_info: Unrevealed works are not included in tag listings or on your works page. Anyone who follows a link to the work will receive a notice that it is currently unrevealed, and they will be unable to access its content. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items page + archivist_notice: Because the collection maintainers are acting in their official capacity as Open Doors archivists, they are allowed to add your work to this collection, even if you have collection invitations disabled. Archivists will only add a work to a collection if it was hosted on an imported archive. + removal_instructions: + html: If you would like to remove your work from this collection, please visit your %{approved_items_link}. + text: 'If you would like to remove your work from this collection, please visit your Approved Collection Items page: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] An Open Doors archivist has added your work to a collection" + work_added: + html: The collection maintainers of %{collection_link} have added your work %{work_link} to their collection! + text: The collection maintainers of "%{collection_title}" (%{collection_url}) have added your work "%{work_title}" (%{work_url}) to their collection! + challenge_assignment_notification: + any: Any + assignment: + html: You have been assigned the following request in the %{link} challenge at Sunset! + text: You have been assigned the following request in the "%{collection_title}" challenge (%{collection_url}) at Sunset! + description: Description + due: This assignment is due at + footer: + challenge_profile: the challenge profile page + html: You're receiving this email because you signed up for the %{title} challenge. For more information about this challenge and contact information for the moderators, please visit %{challenge_profile_link}. + text: You're receiving this email because you signed up for the %{title} challenge (%{url}). For more information about this challenge and contact information for the moderators, please visit %{challenge_profile_url}. + look_up: + html: You can look up this assignment from %{your_assignments_link}. + text: You can look up this assignment from your Assignments page at %{your_assignments_url}. + your_assignments: your Assignments page + optional_tags: Optional Tags + prompt_url: Prompt URL + prompts: 'Prompts:' + recipient: Recipient + recipient_missing: 'None: contact a moderator for help!' + subject: "[%{app_name}][%{collection_title}] Your assignment!" + change_email: + confirm_change: + html: + one: If you made this request, check your email at %{unconfirmed_email} within %{count} day to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please %{contact_support_link}. + other: If you made this request, check your email at %{unconfirmed_email} within %{count} days to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please %{contact_support_link}. + text: + one: 'If you made this request, check your email at %{unconfirmed_email} within %{count} day to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please contact Support: %{contact_support_url}.' + other: 'If you made this request, check your email at %{unconfirmed_email} within %{count} days to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please contact Support: %{contact_support_url}.' + contact_policy_abuse: contact Policy & Abuse + contact_support: contact Support + email_change_form: submit the email change form + made_request: Someone has made a request to change the email address associated with your %{app_name} account. + not_made_request: + html: If you did not make this request, someone else may have access to your %{app_name} account. Please %{reset_password_link} or %{contact_policy_abuse_link}. + text: 'If you did not make this request, someone else may have access to your %{app_name} account. Please reset your password now (%{reset_password_url}) or contact Policy & Abuse: %{contact_policy_abuse_url}.' + reset_password: reset your password now + subject: "[%{app_name}] Email change request" + wrong_email: + html: If you entered the wrong email address, you will need to %{email_change_form_link} again. + text: 'If you entered the wrong email address, you will need to submit the email change form again: %{email_change_form_url}.' + change_username: + change_cooldown_html: + one: "%{app_name} usernames can only be changed once per day. You will be able to change your username again on %{date}." + other: "%{app_name} usernames can only be changed once every %{count} days. You will be able to change your username again on %{date}." + changed_html: The username for your %{app_name} account %{old_username} has been changed to %{new_username}. + contact_policy_abuse: contact Policy & Abuse + contact_support: contact Support + did_not_make_change: + html: If you did not make this change, someone else may have access to your %{app_name} account. Please %{reset_password_link} or %{contact_policy_abuse_link}. + text: 'If you did not make this change, someone else may have access to your %{app_name} account. Please reset your password now (%{reset_password_url}) or contact Policy & Abuse: %{contact_policy_abuse_url}.' + effects: + html: You can %{refer_faq_link} to learn how changing your username will affect your account. If you experience technical issues, such as seeing your old username on your works or bookmarks after a week, please %{contact_support_link}. + text: 'You can refer to our FAQ to learn how changing your username will affect your account: %{refer_faq_url}. If you experience technical issues, such as seeing your old username on your works or bookmarks after a week, please contact Support: %{contact_support_url}.' + refer_faq: refer to our FAQ + reset_password: reset your password now + subject: "[%{app_name}] Your username has been changed" + claim_notification: + access: + contact_support: contact AO3 Support + html: Depending on the archive, your works may have been imported restricted to registered users only (to keep them out of Google searches). If this is the case, the works will only be accessible by logged-in users unless you choose to make them fully visible. For help unlocking, orphaning, or deleting your works, please %{contact_support_link}. + text: Depending on the archive, your works may have been imported restricted to registered users only (to keep them out of Google searches). If this is the case, the works will only be accessible by logged-in users unless you choose to make them fully visible. For help unlocking, orphaning, or deleting your works, please contact AO3 Support at %{support_url}. + email_tips: If you're contacting us, please add email addresses from @transformativeworks.org to your list of safe contacts and check your spam folders for our reply. + introduction: + ao3_name: Sunset + html: You're receiving this e-mail because you had works in a fanworks archive that has been imported by %{open_doors_name_link} into the %{app_link} (AO3). Because this e-mail address is connected to one registered on the imported archive, the associated fanworks (listed below) have been automatically added to your AO3 account. + open_doors_name: Open Doors + text: You're receiving this e-mail because you had works in a fanworks archive that has been imported by Open Doors (%{open_doors_url}) into the Archive of Our Own (AO3 - %{app_url}). Because this e-mail address is connected to one registered on the imported archive, the associated fanworks (listed below) have been automatically added to your AO3 account. + mistake: + contact_open_doors: contact Open Doors + html: If this is a mistake and these are not your works, please don't delete them! Please just %{contact_open_doors_link} and we will sort it out. + text: If this is a mistake and these are not your works, please don't delete them! Please just contact Open Doors (%{open_doors_url}) and we will sort it out. + more_info: + ao3_news: AO3 News + contact_support: contact AO3 Support + faq_page: FAQ page + html: You can read announcements about recent archive moves at %{ao3_news_link}, and find additional information on Open Doors' %{faq_page_link} or %{tutorial_page_link}. For any questions not answered in the FAQ, tutorials, or this e-mail, please %{contact_support_link}. + text: You can read announcements about recent archive moves at AO3 News (%{news_url}), and find additional information on Open Doors' FAQ page (%{open_doors_faq_url}) or tutorials page (%{open_doors_tutorial_url}). For any questions not answered in the FAQ, tutorials, or this e-mail, please contact Support at %{support_url}. + tutorial_page: tutorial page + other_works: + contact_open_doors: contact Open Doors + html: If you had other works on the imported archive under an e-mail address you can no longer access, please %{contact_open_doors_link} with any information that can help verify your identity. + text: If you had other works on the imported archive under an e-mail address you can no longer access, please contact Open Doors with any information that can help verify your identity. + questions: + contact_support: contact AO3 Support + html: For other inquiries, please %{contact_support_link}. + text: For other inquiries, please contact AO3 Support at %{support_url}. + redirects: + html: To preserve rec lists and bookmarks, the imported archive's web addresses may redirect to the imported copy of these works for a limited time (check the announcement post for your archive to be sure). If you've already uploaded a copy of these works and you did %{negation} use the import from URL feature, there will be two copies of the same work on the AO3. + negation: NOT + subject: "[%{app_name}] Works uploaded" + update_redirect: + contact_open_doors: contact Open Doors + html: If you would like Open Doors to update the redirect to point to your pre-existing work, please delete the imported copy, and %{contact_open_doors_link} with your AO3 account name, your account name on the imported archive, and the title and URL of the fanwork you would like the redirect to point to. (If you have multiple works you would like to change the redirects for, you can list these in one email.) + text: If you would like Open Doors to update the redirect to point to your pre-existing work, please delete the imported copy, and contact Open Doors at %{open_doors_url} with your AO3 account name, your account name on the imported archive, and the title and URL of the fanwork you would like the redirect to point to. (If you have multiple works you would like to change the redirects for, you can list these in one email.) + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: '- "%{work_title}" (%{work_url})' + with_fandom: '- "%{work_title}" (%{work_url}) (%{fandom})' + works_by: 'These works were written under the e-mail: %{email}' + collection_notification: + assignments_sent: + complete: All assignments have now been sent out. + subject: Assignments sent + challenge_default: + complete: 'Signed-up participant %{offer_byline} has defaulted on their assignment for %{request_byline}. You may want to assign a pinch hitter on the collection assignments page: %{assignments_page_url}' + subject: Challenge default by %{offer_byline} + html: + received_message: 'You have received a message about your collection %{collection_link}:' + text: + received_message: 'You have received a message about your collection "%{collection_title}" (%{collection_url}):' + creatorship_notification: + explanation: When you're a co-creator on a work, you can be added to new chapters regardless of your co-creation settings. You will also be added to any series the work is added to. + html: + creation: "%{creation_link} by %{pseud_links}" + edit_chapter: edit the chapter + edit_series: edit the series + remove_chapter: If you've been added in error or don't want to be listed as a creator, you can %{edit_chapter_link} to remove yourself as creator. + remove_series: If you've been added in error or don't want to be listed as a creator, you can %{edit_series_link} to remove yourself as creator. + intro_chapter: 'The user %{adding_user} has listed your pseud %{pseud} as a co-creator on the following chapter:' + intro_series: 'The user %{adding_user} has listed your pseud %{pseud} as a co-creator on the following series:' + subject: "[%{app_name}] You've been added as a co-creator" + text: + creation: "%{title} (%{url}) by %{pseuds}" + remove_chapter: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the chapter to remove yourself as creator: %{url}' + remove_series: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the series to remove yourself as creator: %{url}' + creatorship_notification_archivist: + explanation: Because they are acting in their official capacity as an Open Doors archivist, they are allowed to add you without a request, even if you have co-creation disabled. + html: + creation: "%{creation_link} by %{pseud_links}" + edit_chapter: edit the chapter + edit_series: edit the series + edit_work: edit the work + remove_chapter: If you've been added in error or don't want to be listed as a creator, you can %{edit_chapter_link} to remove yourself as creator. + remove_series: If you've been added in error or don't want to be listed as a creator, you can %{edit_series_link} to remove yourself as creator. + remove_work: If you've been added in error or don't want to be listed as a creator, you can %{edit_work_link} to remove yourself as creator. + intro_chapter: 'The user %{archivist} has added your pseud %{pseud} as a co-creator on the following chapter:' + intro_series: 'The user %{archivist} has added your pseud %{pseud} as a co-creator on the following series:' + intro_work: 'The user %{archivist} has added your pseud %{pseud} as a co-creator on the following work:' + subject: "[%{app_name}] An archivist has added you as a co-creator" + text: + creation: "%{title} (%{url}) by %{pseuds}" + remove_chapter: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the chapter to remove yourself as creator: %{url}' + remove_series: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the series to remove yourself as creator: %{url}' + remove_work: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the work to remove yourself as creator: %{url}' + creatorship_request: + html: + creation: "%{creation_link} by %{pseud_links}" + instructions: You can accept or reject this request on your %{page_name} page. + page_name: Co-Creator Requests + intro_chapter: 'The user %{inviting_user} has invited your pseud %{pseud} to be listed as a co-creator on the following chapter:' + intro_series: 'The user %{inviting_user} has invited your pseud %{pseud} to be listed as a co-creator on the following series:' + intro_work: 'The user %{inviting_user} has invited your pseud %{pseud} to be listed as a co-creator on the following work:' + subject: "[%{app_name}] You've received a request to be a co-creator" + text: + creation: "%{title} (%{url}) by %{pseuds}" + instructions: 'You can accept or reject this request on your Co-Creator Requests page: %{url}' + delete_work_notification: + attachment: Attached is a copy of your work for your reference. + deleted_other: + html: Your work %{title} was deleted at the request of %{pseud}. + text: Your work "%{title}" was deleted at the request of %{pseud}. + deleted_yourself: + html: Your work %{title} was deleted at your request. + text: Your work "%{title}" was deleted at your request. + questions: + html: If you have questions, please %{support}. + text: If you have questions, please %{support} (%{url}). + subject: "[%{app_name}] Your work has been deleted" + support: contact Support + feedback: + additional_ticket: If you have additional questions or information, do not hesitate to send in another ticket. + introduction: 'We''re working hard to reply to everyone, and we''ll respond to you as soon as we can. Your communication is greatly valued, and it will be reviewed and answered by our volunteer Support team. In the meantime, here is a copy of the information you submitted through the Technical Support and Feedback form:' + subject: "[%{app_name}] Support - %{summary}" + invalid_signup_notification: + found_invalid: + html: We have found some invalid sign-ups in your gift exchange %{collection_link}. Potential matches can't be generated until these are cleaned up. + text: We have found some invalid sign-ups in your gift exchange "%{collection_title}" (%{collection_url}). Potential matches can't be generated until these are cleaned up. + see_details: + challenge_matching_help: the challenge matching help + html: Invalid sign-ups may be duplicates, or may not meet the requirements you've set for your challenge. Unfortunately, there is no automatic way to fix them, so you will have to manually edit or delete them. For more details, refer to %{challenge_matching_help_link}. + text: 'Invalid sign-ups may be duplicates, or may not meet the requirements you''ve set for your challenge. Unfortunately, there is no automatic way to fix them, so you will have to manually edit or delete them. For more details, refer to the challenge matching help: %{challenge_matching_help_url}.' + signup: 'Signup #%{signup_id}' + signups_here: 'Here are the invalid sign-ups:' + subject: "[%{app_name}][%{collection_title}] Invalid sign-ups found" + invitation: + been_invited: You've been invited to join Sunset! + features: With an account, you can post fanworks, use bookmarks to keep track of works you enjoyed, receive subscription emails when your favorite creators or works update, customize the way the site looks for you, and more! + has_invited: "%{user_name} has invited you to join the Archive of Our Own!" + html: + about: Sunset is a free, noncommercial archive built by and for fans. + activation_support: After you sign up, you'll receive an account activation email. If you do not receive this email after 48 hours, please %{support_link}. + faq: For more information, please check %{faq_link}. + faq_link_text: our FAQ + invitation_link_text: follow this link to sign up + join: If you'd like to join us, please %{invitation_link}. + otw_link_text: Organization for Transformative Works + support_link_text: contact Support + subject: "[%{app_name}] Invitation" + text: + about: Sunset is a free, noncommercial archive built by and for fans. Our servers are owned by our parent nonprofit, the Organization for Transformative Works (%{otw_url}), which works to protect fan rights and preserve fanworks. We welcome all kinds of fanworks, including fanfiction, fanart, fanvids, and podfic from any fandom. + activation_support: 'After you sign up, you''ll receive an account activation email. If you do not receive this email after 48 hours, please contact Support: %{support_url}.' + faq: 'For more information, please check our FAQ: %{faq_url}.' + join: 'If you''d like to join us, please follow this link to sign up: %{invitation_url}.' + invitation_to_claim: + access: + html: Depending on the archive, your works may have been imported restricted to registered users only (to keep them out of Google searches). If this is the case, the works will only be accessible by logged-in users unless you choose to make them fully visible. For help unlocking, orphaning, or deleting your works, please %{contact_support_link}. + text: Depending on the archive, your works may have been imported restricted to registered users only (to keep them out of Google searches). If this is the case, the works will only be accessible by logged-in users unless you choose to make them fully visible. For help unlocking, orphaning, or deleting your works, please contact AO3 Support. + claim_or_remove: + html: Claim or remove your works here. + text: 'Claim or remove your works here: %{claim_url}' + email_tips: If you're contacting us, please add email addresses from @transformativeworks.org to your list of safe contacts and check your spam folders for our reply. + html: + ao3_news: AO3 News + contact_open_doors: contact Open Doors + contact_support: contact AO3 Support + faq_page: FAQ page + open_doors_name: Open Doors + tutorial_page: tutorial page + introduction: + html: You're receiving this e-mail because an archive has recently been imported by %{open_doors_name_link} into the %{app_link} (%{app_short_name}), and we believe that the following fanworks belong to you. We'd like to give you a chance to claim (or delete/orphan) these works if you want to. And if you don't already have an account under a different e-mail, we'd like to invite you aboard! + text: You're receiving this e-mail because an archive has recently been imported by Open Doors (%{open_doors_link}) into the %{app_name} (%{app_short_name} - %{app_url}), and we believe that the following fanworks belong to you. We'd like to give you a chance to claim (or delete/orphan) these works if you want to. And if you don't already have an account under a different e-mail, we'd like to invite you aboard! + mistake: + html: If this is a mistake and these are not your works, please don't delete them! Please just %{contact_open_doors_link} and we will sort it out. + text: If this is a mistake and these are not your works, please don't delete them! Please just contact Open Doors (%{open_doors_link}) and we will sort it out. + more_info: + html: You can read announcements about recent archive moves at %{ao3_news_link}, and find additional information on Open Doors' %{faq_page_link} or %{tutorial_page_link}. For any questions not answered in the FAQ, tutorials, or this e-mail, please %{contact_support_link}. + text: You can read announcements about recent archive moves at AO3 News (%{news_link}), and find additional information on Open Doors' FAQ page (%{open_doors_faq_link}) or tutorials page (%{open_doors_tutorial_link}). For any questions not answered in the FAQ, tutorials, or this e-mail, please contact Support at %{support_link}. + other_works: + html: If you had other works on the imported archive under an e-mail address you can no longer access, please %{contact_open_doors_link} with any information that can help verify your identity. + text: If you had other works on the imported archive under an e-mail address you can no longer access, please contact Open Doors with any information that can help verify your identity. + questions: + html: For other inquiries, please %{contact_support_link}. + text: For other inquiries, please contact AO3 Support at %{support_link}. + redirects: To preserve rec lists and bookmarks, the imported archive's web addresses may redirect to the imported copy of these works for a limited time (check the announcement post for your archive to be sure). If you've already uploaded a copy of these works and you did NOT use the import from URL feature, there will be two copies of the same work on the archive. + subject: "[%{app_name}] Invitation to claim works" + unwanted: + html: If these works do belong to you, but you don't want them, you can orphan (so that they remain on the AO3, but with your name removed) or delete them (so that they are entirely removed from the AO3). You do not need to add these works to any account in order to orphan or delete them--you can do this directly from the claim link above. (For assistance, please %{contact_support_link}.) + text: If these works do belong to you, but you don't want them, you can orphan (so that they remain on the AO3, but with your name removed) or delete them (so that they are entirely removed from the AO3). You do not need to add these works to any account in order to orphan or delete them--you can do this directly from the claim link above. (For assistance, please contact Support at %{support_link}.) + update_redirect: + html: If you would like Open Doors to update the redirect to point to your pre-existing work, please delete the imported copy, and %{contact_open_doors_link} with your AO3 account name, your account name on the imported archive, and the title and URL of the fanwork you would like the redirect to point to. (If you have multiple works you would like to change the redirects for, you can list these in one email.) + text: If you would like Open Doors to update the redirect to point to your pre-existing work, please delete the imported copy, and contact Open Doors at %{open_doors_link} with your AO3 account name, your account name on the imported archive, and the title and URL of the fanwork you would like the redirect to point to. (If you have multiple works you would like to change the redirects for, you can list these in one email.) + uploaded_list: 'The works uploaded include:' + work_info: + no_fandom: '- "%{work_title}" (%{work_url})' + with_fandom: '- "%{work_title}" (%{work_url}) (%{fandom})' + invite_increase_notification: + body: + html: + one: We just wanted to let you know that you have %{count} new invitation, which can be used to create a new account at the Archive. You can invite a friend at %{invitation_page_link}. + other: We just wanted to let you know that you have %{count} new invitations, which can be used to create new accounts at the Archive. You can invite a friend at %{invitation_page_link}. + text: + one: We just wanted to let you know that you have %{count} new invitation, which can be used to create a new account at the Archive. You can invite a friend at your invitations page (%{invitation_page_url}). + other: We just wanted to let you know that you have %{count} new invitations, which can be used to create new accounts at the Archive. You can invite a friend at your invitations page (%{invitation_page_url}). + invitation_page_link_text: your invitations page + subject: "[%{app_name}] New invitations" + invite_request_declined: + main: + one: We regret to inform you that your request for a new invitation cannot be fulfilled at this time. + other: We regret to inform you that your request for %{count} new invitations cannot be fulfilled at this time. + reason: 'Your request was:' + subject: "[%{app_name}] Additional invitation request declined" + invited_to_collection_notification: + approve: + collection_items_page: Collection Items page + html: To approve or reject this request, please visit your %{collection_items_page_link}. + text: 'To approve or reject this request, please visit your Collection Items page: %{collection_items_page_url}.' + subject: "[%{app_name}][%{collection_title}] Request to include work in a collection" + would_like_to_include: + html: The collection maintainers of %{collection_link} would like to include your work %{work_link} in their collection! + text: The collection maintainers of "%{collection_title}" (%{collection_url}) would like to include your work "%{work_title}" (%{work_url}) in their collection! + potential_match_generation_notification: + finished_generating: + html: We have finished generating potential assignments for your gift exchange %{collection_link}. + text: We have finished generating potential assignments for your gift exchange "%{collection_title}" (%{collection_url}). + matches_available: + html: The potential matches and set assignments are available on its %{matching_page_link}. + matching_page: Matching page + text: 'The potential matches and set assignments are available on its Matching page: %{matching_page_url}.' + subject: "[%{app_name}][%{collection_title}] Potential assignment generation complete" + recipient_notification: + collection: + html: A gift work has been posted for you in the %{collection_link} collection at the Archive of Our Own! + text: A gift work has been posted for you in the "%{collection_title}" collection (%{collection_url}) at the Archive of Our Own! + no_collection: A gift work has been posted for you at the Archive of Our Own! + subject: + collection: "[%{app_name}][%{collection_title}] A gift work for you from %{collection_title}" + no_collection: "[%{app_name}] A gift work for you" + related_work_notification: + anonymous: an anonymous creator + approve: + html: Approve relationship and link back to this work from your work + text: 'Approve relationship and link back to this work from your work: %{related_work_url}' + can_come_back: "(You can come back to this page if you change your mind.)" + subject: "[%{app_name}] Related work notification" + work_listed: + html: Your work %{work_link} was listed as the inspiration of %{related_work_link} by %{work_creators}. + text: Your work "%{work_title}" (%{work_url}) was listed as the inspiration of "%{related_work_title}" (%{related_work_url}) by %{work_creators}. + signup_notification: + activate: + html: Please %{activate_account_link}. + text: 'Please follow this link to activate your account: %{activate_account_url}' + activate_your_account: follow this link to activate your account + admin_posts: AO3 News + bye: We hope you enjoy using the Archive. + contact_support: contact Support + faq: FAQ + features: + html: Once your account is up and running, you can post your fanworks, set up email subscriptions to let you know when your favorite creators or works have updated, set preferences to customize the way the site looks and works for you, keep track of the works you've accessed on the Archive via your history, and much more. + text: Once your account is up and running, you can post your fanworks, set up email subscriptions to let you know when your favorite creators or works have updated, set preferences to customize the way the site looks and works for you, keep track of the works you've accessed on the Archive via your history, and much more. + information: + html: There's lots of information and advice on how to use the Archive in our %{faq_link}. You'll find the latest news about site developments on %{admin_posts_link}. If you need more help, run into a bug, or have questions or comments, please %{contact_support_link}, who are always happy to help out. + text: 'There''s lots of information and advice on how to use the Archive in our FAQ at %{faq_url}. You''ll find the latest news about site developments on AO3 News at %{admin_posts_url}. If you need more help, run into a bug, or have questions or comments, please contact Support, who are always happy to help out: %{contact_support_url}.' + subject: "[%{app_name}] Activate your account" + welcome: Welcome to the Archive of Our Own, %{login}! + users: + mailer: + confirmation_instructions: + confirm_by: + html: If you don't confirm your request by %{date}, the link in this email will expire and you will need to %{email_change_form_link} again. + text: 'If you don''t confirm your request by %{date}, the link in this email will expire and you will need to submit the email change form again: %{email_change_form_url}.' + confirm_email_change: confirm your email change + did_not_make_request: If you did not make this request, you can safely ignore and delete this email. Someone else may have entered your email address by mistake. + email_change_form: submit the email change form + made_request: + html: + one: If you made this request, please log in and %{confirm_email_change_link} within %{count} day. + other: If you made this request, please log in and %{confirm_email_change_link} within %{count} days. + text: + one: 'If you made this request, please log in and confirm your email change within %{count} day: %{confirm_email_change_url}.' + other: 'If you made this request, please log in and confirm your email change within %{count} days: %{confirm_email_change_url}.' + request_to_change_email_html: Someone has made a request to change the email address associated with the %{app_name} account %{username} to this email address. + subject: "[%{app_name}] Confirm your email change" + password_change: + changed: The password for your %{app_name} account was changed on %{date}. + did_not_make_change: + contact_policy_abuse: contact Policy & Abuse + html: If you did not make this change, someone else may have access to your %{app_name} account. Please %{reset_password_link} or %{contact_policy_abuse_link}. + reset_password: reset your password now + text: 'If you did not make this change, someone else may have access to your %{app_name} account. Please reset your password now (%{reset_password_url}) or contact Policy & Abuse: %{contact_policy_abuse_url}.' + made_change: + contact_support: contact Support + html: If you made this change, you can %{login_link} or %{reset_password_link} if you've forgotten it. If you experience technical issues, please %{contact_support_link}. + login: log in with your new password + reset_password: reset your password + text: 'If you made this change, you can log in with your new password (%{login_url}) or reset your password if you''ve forgotten it (%{reset_password_url}). If you experience technical issues, please contact Support: %{contact_support_url}' + subject: "[%{app_name}] Your password has been changed" + reset_password_instructions: + expiration: If you do not use this link to reset your password within a week, it will expire, and you will have to request a new one. + intro: 'Someone has requested a password reset for your account. You can change your account password by following the link below and entering your new password:' + link_title: Change my password. + subject: "[%{app_name}] Reset your password" + unrequested: If you did not request this password reset, you may ignore this email and your previous password will continue to work. diff --git a/config/locales/mailers/en.yml.save b/config/locales/mailers/en.yml.save new file mode 100755 index 0000000..1e88dff --- /dev/null +++ b/config/locales/mailers/en.yml.save @@ -0,0 +1,678 @@ +--- +en: + admin: + mailer: + password_change: + changed: The password for your %{app_name} admin account was changed on %{date}. + did_not_make_change: If you did not make this change, someone else may have access to your %{app_name} admin account or your OTW email. Please let AD&T and VolCom know immediately so they can take steps to secure your accounts. + made_change: + html: If you made this change, you can %{login_link} or %{reset_password_link} if you'v login: log in with your new password + reset_password: reset your password + text: If you made this change, you can log in with your new password (%{login_url}) or reset your password if you've forgotten it (%{reset_password_url}). + secure_again: + html: When your accounts are secure again, please %{reset_password_link}. + reset_password: reset your admin password + text: 'When your accounts are secure again, please reset your admin password: %{reset_password_url}.' + subject: "[%{app_name}] Your admin password has been changed" + reset_password_instructions: + expiration: + one: If you do not use this link to reset your password within %{count} day, it will expire, and you will have to request a new one. + other: If you do not use this link to reset your password within %{count} days, it will expire, and you will have to request a new one. + intro: 'Someone has requested a password reset for your account. You can change your account password by following the link below and entering your new password:' + link_title_html: Change my password. + subject: "[%{app_name}] Reset your admin password" + unrequested: If you did not request this password reset, you may ignore this email and your previous password will continue to work. + admin_mailer: + set_password_notification: + created: Your AO3 admin account has been created. + expiration: + one: 'The link to set your password is good for %{count} day. If it no longer works, you can request a password reset and use the link that will be emailed to you instead: %{request_reset_url}.' + other: 'The link to set your password is good for %{count} days. If it no longer works, you can request a password reset and use the link that will be emailed to you instead: %{request_reset_url}.' + expiration_html: + one: The link to set your password is good for %{count} day. If it no longer works, you can %{request_reset_link} and use the link that will be emailed to you instead. + other: The link to set your password is good for %{count} days. If it no longer works, you can %{request_reset_link} and use the link that will be emailed to you instead. + finish: 'Please follow this link to set your password so you can log in: %{set_password_url}.' + finish_html: Please %{set_password_link} so you can log in. + request_reset: request a password reset + set_password: follow this link to set your password + subject: "[%{app_name}] Your AO3 admin account" + url: Admin login URL + username: Admin username + comment_mailer: + comment_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: "%{pseud_link} left the following comment on %{chapter_link} of %{work_link}:" + titled_text: "%{pseud} left the following comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):" + untitled_text: "%{pseud} left the following comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):" + other: + html: "%{pseud_link} left the following comment on %{commentable_link}:" + text: "%{pseud} left the following comment on %{title} (%{commentable_url}):" + tag: + html: "%{pseud_link} left the following comment on the tag %{tag_link}:" + text: "%{pseud} left the following comment on the tag %{tag} (%{tag_url}):" + subject: + chapter: "[%{app_name}] Comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Comment on %{title}" + tag: "[%{app_name}] Comment on the tag %{name}" + comment_reply_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: "%{pseud_link} replied to your comment on %{chapter_link} of %{work_link}:" + titled_text: "%{pseud} replied to your comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):" + untitled_text: "%{pseud} replied to your comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):" + other: + html: "%{pseud_link} replied to your comment on %{commentable_link}:" + text: "%{pseud} replied to your comment on %{title} (%{commentable_url}):" + tag: + html: "%{pseud_link} replied to your comment on the tag %{tag_link}:" + text: "%{pseud} replied to your comment on the tag %{tag} (%{tag_url}):" + subject: + chapter: "[%{app_name}] Reply to your comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Reply to your comment on %{title}" + tag: "[%{app_name}] Reply to your comment on the tag %{name}" + comment_reply_sent_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: 'You replied to a comment on %{chapter_link} of %{work_link}:' + titled_text: 'You replied to a comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):' + untitled_text: 'You replied to a comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):' + other: + html: 'You replied to a comment on %{commentable_link}:' + text: 'You replied to a comment on %{title} (%{commentable_url}):' + tag: + html: 'You replied to a comment on the tag %{tag_link}:' + text: 'You replied to a comment on the tag %{tag} (%{tag_url}):' + subject: + chapter: "[%{app_name}] Reply you left to a comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Reply you left to a comment on %{title}" + tag: "[%{app_name}] Reply you left to a comment on the tag %{name}" + comment_sent_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: 'You left the following comment on %{chapter_link} of %{work_link}:' + titled_text: 'You left the following comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):' + untitled_text: 'You left the following comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):' + other: + html: 'You left the following comment on %{commentable_link}:' + text: 'You left the following comment on %{title} (%{commentable_url}):' + tag: + html: 'You left the following comment on the tag %{tag_link}:' + text: 'You left the following comment on the tag %{tag} (%{tag_url}):' + subject: + chapter: "[%{app_name}] Comment you left on Chapter %{position} of %{title}" + other: "[%{app_name}] Comment you left on %{title}" + tag: "[%{app_name}] Comment you left on the tag %{name}" + edited_comment_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: "%{pseud_link} edited the following comment on %{chapter_link} of %{work_link}:" + titled_text: "%{pseud} edited the following comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):" + untitled_text: "%{pseud} edited the following comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):" + other: + html: "%{pseud_link} edited the following comment on %{commentable_link}:" + text: "%{pseud} edited the following comment on %{title} (%{commentable_url}):" + tag: + html: "%{pseud_link} edited the following comment on the tag %{tag_link}:" + text: "%{pseud} edited the following comment on the tag %{tag} (%{tag_url}):" + subject: + chapter: "[%{app_name}] Edited comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Edited comment on %{title}" + tag: "[%{app_name}] Edited comment on the tag %{name}" + edited_comment_reply_notification: + chapter: + titled: 'Chapter %{position}: %{title}' + untitled: Chapter %{position} + content: + chapter: + html: "%{pseud_link} edited their reply to your comment on %{chapter_link} of %{work_link}:" + titled_text: "%{pseud} edited their reply to your comment on Chapter %{chapter_position}: %{chapter_title} of %{work} (%{chapter_url}):" + untitled_text: "%{pseud} edited their reply to your comment on Chapter %{chapter_position} of %{work} (%{chapter_url}):" + other: + html: "%{pseud_link} edited their reply to your comment on %{commentable_link}:" + text: "%{pseud} edited their reply to your comment on %{title} (%{commentable_url}):" + tag: + html: "%{pseud_link} edited their reply to your comment on the tag %{tag_link}:" + text: "%{pseud} edited their reply to your comment on the tag %{tag} (%{tag_url}):" + subject: + chapter: "[%{app_name}] Edited reply to your comment on Chapter %{position} of %{title}" + other: "[%{app_name}] Edited reply to your comment on %{title}" + tag: "[%{app_name}] Edited reply to your comment on the tag %{name}" + kudo_mailer: + batch_kudo_notification: + guest: + one: a guest + other: "%{count} guests" + left_kudos: + html: + one: "%{givers_list} left kudos on %{commentable_link}." + other: "%{givers_list} left kudos on %{commentable_link}." + text: + one: '%{givers_list} left kudos on "%{commentable_title}" (%{commentable_url}).' + other: '%{givers_list} left kudos on "%{commentable_title}" (%{commentable_url}).' + single_guest: + giver: A guest + html: "%{giver} left kudos on %{commentable_link}." + text: A guest left kudos on "%{commentable_title}" (%{commentable_url}). + subject: "[%{app_name}] You've got kudos!" + mailer: + collections: + why_collection_email: + html: You're receiving this email because your email address has been listed as the collection email for the collection %{collection_link}. + text: You're receiving this email because your email address has been listed as the collection email for the collection "%{collection_title}" (%{collection_url}). + why_maintainer: + html: You're receiving this email because you are an owner or moderator of the collection %{collection_link}. + text: You're receiving this email because you are an owner or moderator of the collection "%{collection_title}" (%{collection_url}). + general: + closing: + formal: Sincerely, + informal: Best, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Chapter %{position} of %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} word" + other: "%{count} words" + footer: + about: + html: Sunset is a fan-run and fan-supported archive that relies on %{your_donations_link}. + text: 'Sunset is a fan-run and fan-supported archive that relies on your donations: %{your_donations_url}.' + your_donations: your donations + sent_at: Sent at %{sent_at}. + why_policy_abuse: + contact_policy_abuse: contact Policy & Abuse + html: If you don't understand why you received this email, please %{contact_policy_abuse_link}. + text: 'If you don''t understand why you received this email, please contact Policy & Abuse: %{contact_policy_abuse_url}.' + why_support: + contact_support: contact Support + html: If you don't understand why you received this email, please %{contact_support_link}. + text: 'If you don''t understand why you received this email, please contact Support: %{contact_support_url}.' + greeting: + formal: + addressed_html: Hi %{name}, + unaddressed: Hi, + informal: + addressed_html: Hi, %{name}! + unaddressed: Hi! + introductory: Hello from the Sunset! + tag_wrangler_supervisors: Tag Wrangler Supervisors + metadata_label_indicator: ": " + signature: + abuse_team: The Sunset Policy & Abuse team + app_short_name: Sunset + open_doors: The Open Doors team + parent_org: Sunset + support: The Sunset Support team + roles: + anonymous_creator: Anonymous Creator + commenter_name: + html: "%{name} %{role_with_parens}" + text: "%{name} %{role_with_parens}" + guest_with_parens: "(Guest)" + official_with_parens: "(Official)" + registered_with_parens: "(Registered User)" + tag_wrangling_supervisor_mailer: + wrangler_username_change_notification: + name_changed: + html: The wrangler %{old_username} has changed their name to %{new_username}. + subject: "[%{app_name}] Wrangler name change" + user_mailer: + abuse_report: + copy: + comment: Description of the content or issue + intro: 'Here is a copy of your report for your reference:' + summary: Terms of Service violation + url: URL of the reported page + report_received: The Policy & Abuse team has received your report, and our volunteers will investigate as soon as they can. Because our team is small and we receive thousands of reports each month, it may take some time for us to get to your report. + resubmission: Please do not resubmit this report unless you have additional information that you did not include in your original report. Submitting multiple reports about the same issue may delay our response. + subject: "[%{app_name}] Abuse - %{summary}" + thank_you: Thank you for your patience. + admin_deleted_work_notification: + bye: Attached is a copy of your work for your reference. + contact_abuse: contact our Policy & Abuse team + deleted: + html: Your work %{title} was deleted from the Archive by a site admin. + text: Your work "%{title}" was deleted from the Archive by a site admin. + import_project: + html: If your work was part of an import project managed by our Open Doors team, please %{opendoors_link} with any further questions. + text: If your work was part of an import project managed by our Open Doors team, please contact Open Doors (%{opendoors_link}) with any further questions. + opendoors: contact Open Doors + subject: "[%{app_name}] Your work has been deleted by an admin" + tos_violation: + html: If it's possible your work violated the Archive's Terms of Service, please %{contact_abuse_link}. + text: If it's possible your work violated the Archive's Terms of Service, please contact our Policy & Abuse team (%{contact_abuse_url}). + admin_hidden_work_notification: + access: + one: While your work is hidden, you will still be able to access it through the link provided above, but it won't be available to other users or listed on your works page. + other: While your works are hidden, you will still be able to access them through the links provided above, but they won't be available to other users or listed on your works page. + check_email: + one: Please check your email, including your spam folder, as the Policy & Abuse committee may have already contacted you to explain why your work was hidden. + other: Please check your email, including your spam folder, as the Policy & Abuse committee may have already contacted you to explain why your works were hidden. + contact_abuse: contact the Policy & Abuse committee + content_policy: Content Policy + help: + html: + one: If you don't know why your work was hidden, and you have not received a separate email explaining why, please %{contact_abuse_link} directly. + other: If you don't know why your works were hidden, and you have not received a separate email explaining why, please %{contact_abuse_link} directly. + text: + one: 'If you don''t know why your work was hidden, and you have not received a separate email explaining why, please contact the Policy & Abuse committee directly: %{contact_abuse_url}.' + other: 'If you don''t know why your works were hidden, and you have not received a separate email explaining why, please contact the Policy & Abuse committee directly: %{contact_abuse_url}.' + hidden_multiple: "%{count} of your works have been hidden by the Policy & Abuse committee:" + hidden_one: + html: Your work %{title} has been hidden by the Policy & Abuse committee. + text: Your work "%{title}" (%{work_url}) has been hidden by the Policy & Abuse committee. + subject: + one: "[%{app_name}] Your work has been hidden by the Policy & Abuse committee" + other: "[%{app_name}] Your works have been hidden by the Policy & Abuse committee" + tos: Sunset Terms of Service + tos_faq: Terms of Service FAQ + tos_violation: + html: + one: If your work was hidden due to being in violation of the %{tos_link} (including the %{content_policy_link}), you will be required to take action to correct the violation. Failure to bring your work into compliance with the Terms of Service may result in your work being deleted from AO3. For more information, please refer to the %{tos_faq_link}. + other: If your works were hidden due to being in violation of the %{tos_link} (including the %{content_policy_link}), you will be required to take action to correct the violations. Failure to bring your works into compliance with the Terms of Service may result in your works being deleted from AO3. For more information, please refer to the %{tos_faq_link}. + text: + one: 'If your work was hidden due to being in violation of the AO3 Terms of Service (%{tos_url}), including the Content Policy (%{content_policy_url}), you will be required to take action to correct the violation. Failure to bring your work into compliance with the Terms of Service may result in your work being deleted from AO3. For more information, please refer to the Terms of Service FAQ: %{tos_faq_url}.' + other: 'If your works were hidden due to being in violation of the AO3 Terms of Service (%{tos_url}), including the Content Policy (%{content_policy_url}), you will be required to take action to correct the violations. Failure to bring your works into compliance with the Terms of Service may result in your works being deleted from AO3. For more information, please refer to the Terms of Service FAQ: %{tos_faq_url}.' + work_info: '- "%{title}" (%{work_url})' + admin_spam_work_notification: + contact_abuse: contact our Policy & Abuse Team + flagged_as_spam: + html: Your work %{work_link} has been flagged by our automated system as spam and hidden until it can be reviewed by our Policy & Abuse team. While the work is hidden it can only be accessed by you and AO3 site admins. + text: Your work "%{work_title}" (%{work_url}) has been flagged by our automated system as spam and hidden until it can be reviewed by our Abuse team. While the work is hidden it can only be accessed by you and AO3 site admins. + future: If we determine that your work is not spam, we'll unhide it. Other users will then be able to access and leave feedback on it as usual. Please note that we do not screen works for other kinds of violations at this time. If your work is reported to us for a different reason in the future, that will be investigated separately. + questions: + html: If you have any questions, please %{contact_abuse_link}. + text: If you have any questions, please contact our Policy & Abuse team (%{contact_abuse_url}). + subject: "[%{app_name}] Your work was hidden as spam" + anonymous_or_unrevealed_notification: + anonymous_info: Anonymous works are included in tag listings, but not on your works page. On the work, your username will be replaced with "Anonymous." + anonymous_unrevealed_info: The collection maintainers may later reveal your work but leave it anonymous. People who subscribe to you will not be notified of this change. Your work will be included in tag listings, but not on your works page. On the work, your username will be replaced with "Anonymous." + changed_status: + anonymous: + html: The collection maintainers of %{collection_link} have changed the status of your work %{work_link} to anonymous. + text: The collection maintainers of "%{collection_title}" (%{collection_url}) have changed the status of your work "%{work_title}" (%{work_url}) to anonymous. + anonymous_unrevealed: + html: The collection maintainers of %{collection_link} have changed the status of your work %{work_link} to anonymous and unrevealed. + text: The collection maintainers of "%{collection_title}" (%{collection_url}) have changed the status of your work "%{work_title}" (%{work_url}) to anonymous and unrevealed. + unrevealed: + html: The collection maintainers of %{collection_link} have changed the status of your work %{work_link} to unrevealed. + text: The collection maintainers of "%{collection_title}" (%{collection_url}) have changed the status of your work "%{work_title}" (%{work_url}) to unrevealed. + collection_items_link_text: Approved Collection Items page + do_not_want: + anonymous: + html: If you do not want your work to be anonymous, please visit your %{collection_items_link} to remove it from this collection. + text: 'If you do not want your work to be anonymous, please visit your Approved Collection Items page to remove it from this collection: %{collection_items_url}' + anonymous_unrevealed: + html: If you do not want your work to be anonymous and unrevealed, please visit your %{collection_items_link} to remove it from this collection. + text: 'If you do not want your work to be anonymous and unrevealed, please visit your Approved Collection Items page to remove it from this collection: %{collection_items_url}' + unrevealed: + html: If you do not want your work to be unrevealed, please visit your %{collection_items_link} to remove it from this collection. + text: 'If you do not want your work to be unrevealed, please visit your Approved Collection Items page to remove it from this collection: %{collection_items_url}' + faq_link_text: Collections FAQ + more_info: + html: For more information, visit our %{faq_link}. + text: 'For more information, visit our Collections FAQ: %{faq_url}' + subject: + anonymous: "[%{app_name}] Your work was made anonymous" + anonymous_unrevealed: "[%{app_name}] Your work was made anonymous and unrevealed" + unrevealed: "[%{app_name}] Your work was made unrevealed" + unrevealed_info: Unrevealed works are not included in tag listings or on your works page. Anyone who follows a link to the work will receive a notice that it is currently unrevealed, and they will be unable to access its content. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items page + archivist_notice: Because the collection maintainers are acting in their official capacity as Open Doors archivists, they are allowed to add your work to this collection, even if you have collection invitations disabled. Archivists will only add a work to a collection if it was hosted on an imported archive. + removal_instructions: + html: If you would like to remove your work from this collection, please visit your %{approved_items_link}. + text: 'If you would like to remove your work from this collection, please visit your Approved Collection Items page: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] An Open Doors archivist has added your work to a collection" + work_added: + html: The collection maintainers of %{collection_link} have added your work %{work_link} to their collection! + text: The collection maintainers of "%{collection_title}" (%{collection_url}) have added your work "%{work_title}" (%{work_url}) to their collection! + challenge_assignment_notification: + any: Any + assignment: + html: You have been assigned the following request in the %{link} challenge at Sunset! + text: You have been assigned the following request in the "%{collection_title}" challenge (%{collection_url}) at Sunset! + description: Description + due: This assignment is due at + footer: + challenge_profile: the challenge profile page + html: You're receiving this email because you signed up for the %{title} challenge. For more information about this challenge and contact information for the moderators, please visit %{challenge_profile_link}. + text: You're receiving this email because you signed up for the %{title} challenge (%{url}). For more information about this challenge and contact information for the moderators, please visit %{challenge_profile_url}. + look_up: + html: You can look up this assignment from %{your_assignments_link}. + text: You can look up this assignment from your Assignments page at %{your_assignments_url}. + your_assignments: your Assignments page + optional_tags: Optional Tags + prompt_url: Prompt URL + prompts: 'Prompts:' + recipient: Recipient + recipient_missing: 'None: contact a moderator for help!' + subject: "[%{app_name}][%{collection_title}] Your assignment!" + change_email: + confirm_change: + html: + one: If you made this request, check your email at %{unconfirmed_email} within %{count} day to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please %{contact_support_link}. + other: If you made this request, check your email at %{unconfirmed_email} within %{count} days to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please %{contact_support_link}. + text: + one: 'If you made this request, check your email at %{unconfirmed_email} within %{count} day to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please contact Support: %{contact_support_url}.' + other: 'If you made this request, check your email at %{unconfirmed_email} within %{count} days to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please contact Support: %{contact_support_url}.' + contact_policy_abuse: contact Policy & Abuse + contact_support: contact Support + email_change_form: submit the email change form + made_request: Someone has made a request to change the email address associated with your %{app_name} account. + not_made_request: + html: If you did not make this request, someone else may have access to your %{app_name} account. Please %{reset_password_link} or %{contact_policy_abuse_link}. + text: 'If you did not make this request, someone else may have access to your %{app_name} account. Please reset your password now (%{reset_password_url}) or contact Policy & Abuse: %{contact_policy_abuse_url}.' + reset_password: reset your password now + subject: "[%{app_name}] Email change request" + wrong_email: + html: If you entered the wrong email address, you will need to %{email_change_form_link} again. + text: 'If you entered the wrong email address, you will need to submit the email change form again: %{email_change_form_url}.' + change_username: + change_cooldown_html: + one: "%{app_name} usernames can only be changed once per day. You will be able to change your username again on %{date}." + other: "%{app_name} usernames can only be changed once every %{count} days. You will be able to change your username again on %{date}." + changed_html: The username for your %{app_name} account %{old_username} has been changed to %{new_username}. + contact_policy_abuse: contact Policy & Abuse + contact_support: contact Support + did_not_make_change: + html: If you did not make this change, someone else may have access to your %{app_name} account. Please %{reset_password_link} or %{contact_policy_abuse_link}. + text: 'If you did not make this change, someone else may have access to your %{app_name} account. Please reset your password now (%{reset_password_url}) or contact Policy & Abuse: %{contact_policy_abuse_url}.' + effects: + html: You can %{refer_faq_link} to learn how changing your username will affect your account. If you experience technical issues, such as seeing your old username on your works or bookmarks after a week, please %{contact_support_link}. + text: 'You can refer to our FAQ to learn how changing your username will affect your account: %{refer_faq_url}. If you experience technical issues, such as seeing your old username on your works or bookmarks after a week, please contact Support: %{contact_support_url}.' + refer_faq: refer to our FAQ + reset_password: reset your password now + subject: "[%{app_name}] Your username has been changed" + claim_notification: + access: + contact_support: contact Sunset Support + html: Depending on the archive, your works may have been imported restricted to registered users only (to keep them out of Google searches). If this is the case, the works will only be accessible by logged-in users unless you choose to make them fully visible. For help unlocking, orphaning, or deleting your works, please %{contact_support_link}. + text: Depending on the archive, your works may have been imported restricted to registered users only (to keep them out of Google searches). If this is the case, the works will only be accessible by logged-in users unless you choose to make them fully visible. For help unlocking, orphaning, or deleting your works, please contact AO3 Support at %{support_url}. + email_tips: If you're contacting us, please add email addresses from @transformativeworks.org to your list of safe contacts and check your spam folders for our reply. + introduction: + ao3_name: Sunset + html: You're receiving this e-mail because you had works in a fanworks archive that has been imported by %{open_doors_name_link} into the %{app_link} (AO3). Because this e-mail address is connected to one registered on the imported archive, the associated fanworks (listed below) have been automatically added to your AO3 account. + open_doors_name: Open Doors + text: You're receiving this e-mail because you had works in a fanworks archive that has been imported by Open Doors (%{open_doors_url}) into the Archive of Our Own (AO3 - %{app_url}). Because this e-mail address is connected to one registered on the imported archive, the associated fanworks (listed below) have been automatically added to your AO3 account. + mistake: + contact_open_doors: contact Open Doors + html: If this is a mistake and these are not your works, please don't delete them! Please just %{contact_open_doors_link} and we will sort it out. + text: If this is a mistake and these are not your works, please don't delete them! Please just contact Open Doors (%{open_doors_url}) and we will sort it out. + more_info: + ao3_news: Sunset News + contact_support: contact Sunset Support + faq_page: FAQ page + html: You can read announcements about recent archive moves at %{ao3_news_link}, and find additional information on Open Doors' %{faq_page_link} or %{tutorial_page_link}. For any questions not answered in the FAQ, tutorials, or this e-mail, please %{contact_support_link}. + text: You can read announcements about recent archive moves at AO3 News (%{news_url}), and find additional information on Open Doors' FAQ page (%{open_doors_faq_url}) or tutorials page (%{open_doors_tutorial_url}). For any questions not answered in the FAQ, tutorials, or this e-mail, please contact Support at %{support_url}. + tutorial_page: tutorial page + other_works: + contact_open_doors: contact Open Doors + html: If you had other works on the imported archive under an e-mail address you can no longer access, please %{contact_open_doors_link} with any information that can help verify your identity. + text: If you had other works on the imported archive under an e-mail address you can no longer access, please contact Open Doors with any information that can help verify your identity. + questions: + contact_support: contact Sunset Support + html: For other inquiries, please %{contact_support_link}. + text: For other inquiries, please contact AO3 Support at %{support_url}. + redirects: + html: To preserve rec lists and bookmarks, the imported archive's web addresses may redirect to the imported copy of these works for a limited time (check the announcement post for your archive to be sure). If you've already uploaded a copy of these works and you did %{negation} use the import from URL feature, there will be two copies of the same work on the AO3. + negation: NOT + subject: "[%{app_name}] Works uploaded" + update_redirect: + contact_open_doors: contact Open Doors + html: If you would like Open Doors to update the redirect to point to your pre-existing work, please delete the imported copy, and %{contact_open_doors_link} with your AO3 account name, your account name on the imported archive, and the title and URL of the fanwork you would like the redirect to point to. (If you have multiple works you would like to change the redirects for, you can list these in one email.) + text: If you would like Open Doors to update the redirect to point to your pre-existing work, please delete the imported copy, and contact Open Doors at %{open_doors_url} with your AO3 account name, your account name on the imported archive, and the title and URL of the fanwork you would like the redirect to point to. (If you have multiple works you would like to change the redirects for, you can list these in one email.) + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: '- "%{work_title}" (%{work_url})' + with_fandom: '- "%{work_title}" (%{work_url}) (%{fandom})' + works_by: 'These works were written under the e-mail: %{email}' + collection_notification: + assignments_sent: + complete: All assignments have now been sent out. + subject: Assignments sent + challenge_default: + complete: 'Signed-up participant %{offer_byline} has defaulted on their assignment for %{request_byline}. You may want to assign a pinch hitter on the collection assignments page: %{assignments_page_url}' + subject: Challenge default by %{offer_byline} + html: + received_message: 'You have received a message about your collection %{collection_link}:' + text: + received_message: 'You have received a message about your collection "%{collection_title}" (%{collection_url}):' + creatorship_notification: + explanation: When you're a co-creator on a work, you can be added to new chapters regardless of your co-creation settings. You will also be added to any series the work is added to. + html: + creation: "%{creation_link} by %{pseud_links}" + edit_chapter: edit the chapter + edit_series: edit the series + remove_chapter: If you've been added in error or don't want to be listed as a creator, you can %{edit_chapter_link} to remove yourself as creator. + remove_series: If you've been added in error or don't want to be listed as a creator, you can %{edit_series_link} to remove yourself as creator. + intro_chapter: 'The user %{adding_user} has listed your pseud %{pseud} as a co-creator on the following chapter:' + intro_series: 'The user %{adding_user} has listed your pseud %{pseud} as a co-creator on the following series:' + subject: "[%{app_name}] You've been added as a co-creator" + text: + creation: "%{title} (%{url}) by %{pseuds}" + remove_chapter: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the chapter to remove yourself as creator: %{url}' + remove_series: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the series to remove yourself as creator: %{url}' + creatorship_notification_archivist: + explanation: Because they are acting in their official capacity as an Open Doors archivist, they are allowed to add you without a request, even if you have co-creation disabled. + html: + creation: "%{creation_link} by %{pseud_links}" + edit_chapter: edit the chapter + edit_series: edit the series + edit_work: edit the work + remove_chapter: If you've been added in error or don't want to be listed as a creator, you can %{edit_chapter_link} to remove yourself as creator. + remove_series: If you've been added in error or don't want to be listed as a creator, you can %{edit_series_link} to remove yourself as creator. + remove_work: If you've been added in error or don't want to be listed as a creator, you can %{edit_work_link} to remove yourself as creator. + intro_chapter: 'The user %{archivist} has added your pseud %{pseud} as a co-creator on the following chapter:' + intro_series: 'The user %{archivist} has added your pseud %{pseud} as a co-creator on the following series:' + intro_work: 'The user %{archivist} has added your pseud %{pseud} as a co-creator on the following work:' + subject: "[%{app_name}] An archivist has added you as a co-creator" + text: + creation: "%{title} (%{url}) by %{pseuds}" + remove_chapter: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the chapter to remove yourself as creator: %{url}' + remove_series: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the series to remove yourself as creator: %{url}' + remove_work: 'If you''ve been added in error or don''t want to be listed as a creator, you can edit the work to remove yourself as creator: %{url}' + creatorship_request: + html: + creation: "%{creation_link} by %{pseud_links}" + instructions: You can accept or reject this request on your %{page_name} page. + page_name: Co-Creator Requests + intro_chapter: 'The user %{inviting_user} has invited your pseud %{pseud} to be listed as a co-creator on the following chapter:' + intro_series: 'The user %{inviting_user} has invited your pseud %{pseud} to be listed as a co-creator on the following series:' + intro_work: 'The user %{inviting_user} has invited your pseud %{pseud} to be listed as a co-creator on the following work:' + subject: "[%{app_name}] You've received a request to be a co-creator" + text: + creation: "%{title} (%{url}) by %{pseuds}" + instructions: 'You can accept or reject this request on your Co-Creator Requests page: %{url}' + delete_work_notification: + attachment: Attached is a copy of your work for your reference. + deleted_other: + html: Your work %{title} was deleted at the request of %{pseud}. + text: Your work "%{title}" was deleted at the request of %{pseud}. + deleted_yourself: + html: Your work %{title} was deleted at your request. + text: Your work "%{title}" was deleted at your request. + questions: + html: If you have questions, please %{support}. + text: If you have questions, please %{support} (%{url}). + subject: "[%{app_name}] Your work has been deleted" + support: contact Support + feedback: + additional_ticket: If you have additional questions or information, do not hesitate to send in another ticket. + introduction: 'We''re working hard to reply to everyone, and we''ll respond to you as soon as we can. Your communication is greatly valued, and it will be reviewed and answered by our volunteer Support team. In the meantime, here is a copy of the information you submitted through the Technical Support and Feedback form:' + subject: "[%{app_name}] Support - %{summary}" + invalid_signup_notification: + found_invalid: + html: We have found some invalid sign-ups in your gift exchange %{collection_link}. Potential matches can't be generated until these are cleaned up. + text: We have found some invalid sign-ups in your gift exchange "%{collection_title}" (%{collection_url}). Potential matches can't be generated until these are cleaned up. + see_details: + challenge_matching_help: the challenge matching help + html: Invalid sign-ups may be duplicates, or may not meet the requirements you've set for your challenge. Unfortunately, there is no automatic way to fix them, so you will have to manually edit or delete them. For more details, refer to %{challenge_matching_help_link}. + text: 'Invalid sign-ups may be duplicates, or may not meet the requirements you''ve set for your challenge. Unfortunately, there is no automatic way to fix them, so you will have to manually edit or delete them. For more details, refer to the challenge matching help: %{challenge_matching_help_url}.' + signup: 'Signup #%{signup_id}' + signups_here: 'Here are the invalid sign-ups:' + subject: "[%{app_name}][%{collection_title}] Invalid sign-ups found" + invitation: + been_invited: You've been invited to join Sunset! + features: With an account, you can post fanworks, use bookmarks to keep track of works you enjoyed, receive subscription emails when your favorite creators or works update, customize the way the site looks for you, and more! + has_invited: "%{user_name} has invited you to join Sunset!" + html: + about: Sunset is a free, noncommercial femslash archive built by and for fans. Our servers are owned by our parent nonprofit, the %{otw_link}, which works to protect fan rights and preserve fanworks. We welcome all kinds of fanworks, including fanfiction, fanart, fanvids, and podfic from any fandom. + activation_support: After you sign up, you'll receive an account activation email. If you do not receive this email after 48 hours, please email femslashclub@proton.me again. + faq: For more information, please check %{faq_link}. + faq_link_text: our FAQ + invitation_link_text: follow this link to sign up + join: 'If you''d like to join us, please follow this link to sign up: %{invitation_url}.' + otw_link_text: Sunset + support_link_text: contact Support + subject: "[%{app_name}] Invitation" + text: + about: Sunset is a free, noncommercial archive built by and for fans. + activation_support: 'After you sign up, you''ll receive an account activation email. If you do not receive this email after 48 hours, please contact Agnes by email, listed on the index or about page.' + faq: 'For more information, please check our FAQ: %{faq_url}.' + join: 'If you''d like to join us, please follow this link to sign up: %{invitation_url}.' + invitation_to_claim: + access: + html: Depending on the archive, your works may have been imported restricted to registered users only (to keep them out of Google searches). If this is the case, the works will only be accessible by logged-in users unless you choose to make them fully visible. For help unlocking, orphaning, or deleting your works, please %{contact_support_link}. + text: Depending on the archive, your works may have been imported restricted to registered users only (to keep them out of Google searches). If this is the case, the works will only be accessible by logged-in users unless you choose to make them fully visible. For help unlocking, orphaning, or deleting your works, please contact AO3 Support. + claim_or_remove: + html: Claim or remove your works here. + text: 'Claim or remove your works here: %{claim_url}' + email_tips: If you're contacting us, please add email addresses from @transformativeworks.org to your list of safe contacts and check your spam folders for our reply. + html: + ao3_news: Sunset News + contact_open_doors: contact Open Doors + contact_support: contact AO3 Support + faq_page: FAQ page + open_doors_name: Open Doors + tutorial_page: tutorial page + introduction: + html: You're receiving this e-mail because an archive has recently been imported by %{open_doors_name_link} into the %{app_link} (%{app_short_name}), and we believe that the following fanworks belong to you. We'd like to give you a chance to claim (or delete/orphan) these works if you want to. And if you don't already have an account under a different e-mail, we'd like to invite you aboard! + text: You're receiving this e-mail because an archive has recently been imported by Open Doors (%{open_doors_link}) into the %{app_name} (%{app_short_name} - %{app_url}), and we believe that the following fanworks belong to you. We'd like to give you a chance to claim (or delete/orphan) these works if you want to. And if you don't already have an account under a different e-mail, we'd like to invite you aboard! + mistake: + html: If this is a mistake and these are not your works, please don't delete them! Please just %{contact_open_doors_link} and we will sort it out. + text: If this is a mistake and these are not your works, please don't delete them! Please just contact Open Doors (%{open_doors_link}) and we will sort it out. + more_info: + html: You can read announcements about recent archive moves at %{ao3_news_link}, and find additional information on Open Doors' %{faq_page_link} or %{tutorial_page_link}. For any questions not answered in the FAQ, tutorials, or this e-mail, please %{contact_support_link}. + text: You can read announcements about recent archive moves at AO3 News (%{news_link}), and find additional information on Open Doors' FAQ page (%{open_doors_faq_link}) or tutorials page (%{open_doors_tutorial_link}). For any questions not answered in the FAQ, tutorials, or this e-mail, please contact Support at %{support_link}. + other_works: + html: If you had other works on the imported archive under an e-mail address you can no longer access, please %{contact_open_doors_link} with any information that can help verify your identity. + text: If you had other works on the imported archive under an e-mail address you can no longer access, please contact Open Doors with any information that can help verify your identity. + questions: + html: For other inquiries, please %{contact_support_link}. + text: For other inquiries, please contact AO3 Support at %{support_link}. + redirects: To preserve rec lists and bookmarks, the imported archive's web addresses may redirect to the imported copy of these works for a limited time (check the announcement post for your archive to be sure). If you've already uploaded a copy of these works and you did NOT use the import from URL feature, there will be two copies of the same work on the archive. + subject: "[%{app_name}] Invitation to claim works" + unwanted: + html: If these works do belong to you, but you don't want them, you can orphan (so that they remain on the AO3, but with your name removed) or delete them (so that they are entirely removed from the AO3). You do not need to add these works to any account in order to orphan or delete them--you can do this directly from the claim link above. (For assistance, please %{contact_support_link}.) + text: If these works do belong to you, but you don't want them, you can orphan (so that they remain on the AO3, but with your name removed) or delete them (so that they are entirely removed from the AO3). You do not need to add these works to any account in order to orphan or delete them--you can do this directly from the claim link above. (For assistance, please contact Support at %{support_link}.) + update_redirect: + html: If you would like Open Doors to update the redirect to point to your pre-existing work, please delete the imported copy, and %{contact_open_doors_link} with your AO3 account name, your account name on the imported archive, and the title and URL of the fanwork you would like the redirect to point to. (If you have multiple works you would like to change the redirects for, you can list these in one email.) + text: If you would like Open Doors to update the redirect to point to your pre-existing work, please delete the imported copy, and contact Open Doors at %{open_doors_link} with your AO3 account name, your account name on the imported archive, and the title and URL of the fanwork you would like the redirect to point to. (If you have multiple works you would like to change the redirects for, you can list these in one email.) + uploaded_list: 'The works uploaded include:' + work_info: + no_fandom: '- "%{work_title}" (%{work_url})' + with_fandom: '- "%{work_title}" (%{work_url}) (%{fandom})' + invite_increase_notification: + body: + html: + one: We just wanted to let you know that you have %{count} new invitation, which can be used to create a new account at the Archive. You can invite a friend at %{invitation_page_link}. + other: We just wanted to let you know that you have %{count} new invitations, which can be used to create new accounts at the Archive. You can invite a friend at %{invitation_page_link}. + text: + one: We just wanted to let you know that you have %{count} new invitation, which can be used to create a new account at the Archive. You can invite a friend at your invitations page (%{invitation_page_url}). + other: We just wanted to let you know that you have %{count} new invitations, which can be used to create new accounts at the Archive. You can invite a friend at your invitations page (%{invitation_page_url}). + invitation_page_link_text: your invitations page + subject: "[%{app_name}] New invitations" + invite_request_declined: + main: + one: We regret to inform you that your request for a new invitation cannot be fulfilled at this time. + other: We regret to inform you that your request for %{count} new invitations cannot be fulfilled at this time. + reason: 'Your request was:' + subject: "[%{app_name}] Additional invitation request declined" + invited_to_collection_notification: + approve: + collection_items_page: Collection Items page + html: To approve or reject this request, please visit your %{collection_items_page_link}. + text: 'To approve or reject this request, please visit your Collection Items page: %{collection_items_page_url}.' + subject: "[%{app_name}][%{collection_title}] Request to include work in a collection" + would_like_to_include: + html: The collection maintainers of %{collection_link} would like to include your work %{work_link} in their collection! + text: The collection maintainers of "%{collection_title}" (%{collection_url}) would like to include your work "%{work_title}" (%{work_url}) in their collection! + potential_match_generation_notification: + finished_generating: + html: We have finished generating potential assignments for your gift exchange %{collection_link}. + text: We have finished generating potential assignments for your gift exchange "%{collection_title}" (%{collection_url}). + matches_available: + html: The potential matches and set assignments are available on its %{matching_page_link}. + matching_page: Matching page + text: 'The potential matches and set assignments are available on its Matching page: %{matching_page_url}.' + subject: "[%{app_name}][%{collection_title}] Potential assignment generation complete" + recipient_notification: + collection: + html: A gift work has been posted for you in the %{collection_link} collection at Sunset! + text: A gift work has been posted for you in the "%{collection_title}" collection (%{collection_url}) at Sunset! + no_collection: A gift work has been posted for you at Sunset! + subject: + collection: "[%{app_name}][%{collection_title}] A gift work for you from %{collection_title}" + no_collection: "[%{app_name}] A gift work for you" + related_work_notification: + anonymous: an anonymous creator + approve: + html: Approve relationship and link back to this work from your work + text: 'Approve relationship and link back to this work from your work: %{related_work_url}' + can_come_back: "(You can come back to this page if you change your mind.)" + subject: "[%{app_name}] Related work notification" + work_listed: + html: Your work %{work_link} was listed as the inspiration of %{related_work_link} by %{work_creators}. + text: Your work "%{work_title}" (%{work_url}) was listed as the inspiration of "%{related_work_title}" (%{related_work_url}) by %{work_creators}. + signup_notification: + activate: + html: Please %{activate_account_link}. + text: 'Please follow this link to activate your account: %{activate_account_url}' + activate_your_account: follow this link to activate your account + admin_posts: Sunset News + bye: We hope you enjoy using the Archive. + contact_support: contact Support + faq: FAQ + features: + html: Once your account is up and running, you can post your fanworks, set up email subscriptions to let you know when your favorite creators or works have updated, set preferences to customize the way the site looks and works for you, keep track of the works you've accessed on the Archive via your history, and much more. + text: Once your account is up and running, you can post your fanworks, set up email subscriptions to let you know when your favorite creators or works have updated, set preferences to customize the way the site looks and works for you, keep track of the works you've accessed on the Archive via your history, and much more. + information: + html: There's lots of information and advice on how to use the Archive in our %{faq_link}. You'll find the latest news about site developments on %{admin_posts_link}. If you need more help, run into a bug, or have questions or comments, please %{contact_support_link}, who are always happy to help out. + text: 'There''s lots of information and advice on how to use the Archive in our FAQ at %{faq_url}. You''ll find the latest news about site developments on AO3 News at %{admin_posts_url}. If you need more help, run into a bug, or have questions or comments, please contact Support, who are always happy to help out: %{contact_support_url}.' + subject: "[%{app_name}] Activate your account" + welcome: Welcome to Sunset, %{login}! + users: + mailer: + confirmation_instructions: + confirm_by: + html: If you don't confirm your request by %{date}, the link in this email will expire and you will need to %{email_change_form_link} again. + text: 'If you don''t confirm your request by %{date}, the link in this email will expire and you will need to submit the email change form again: %{email_change_form_url}.' + confirm_email_change: confirm your email change + did_not_make_request: If you did not make this request, you can safely ignore and delete this email. Someone else may have entered your email address by mistake. + email_change_form: submit the email change form + made_request: + html: + one: If you made this request, please log in and %{confirm_email_change_link} within %{count} day. + other: If you made this request, please log in and %{confirm_email_change_link} within %{count} days. + text: + one: 'If you made this request, please log in and confirm your email change within %{count} day: %{confirm_email_change_url}.' + other: 'If you made this request, please log in and confirm your email change within %{count} days: %{confirm_email_change_url}.' + request_to_change_email_html: Someone has made a request to change the email address associated with diff --git a/config/locales/models/en.yml b/config/locales/models/en.yml new file mode 100755 index 0000000..5561de8 --- /dev/null +++ b/config/locales/models/en.yml @@ -0,0 +1,293 @@ +--- +en: + activerecord: + attributes: + admin/role: + board: Board + board_assistants_team: Board Assistants Team + communications: Communications + development_and_membership: Development & Membership + docs: AO3 Docs + elections: Elections + legal: Legal + open_doors: Open Doors + policy_and_abuse: Policy & Abuse + superadmin: Super admin + support: Support + tag_wrangling: Tag Wrangling + translation: Translation + challenge_signup/offers: + url: Offer URL + challenge_signup/requests: + url: Request URL + chapters/creatorships: + base: 'Invalid creator:' + pseud_id: Pseud + creatorships: + base: 'Invalid creator:' + pseud_id: Pseud + external_work: + author: Creator + user_defined_tags_count: Fandom, relationship, and character tags + gift_exchange: + offers_num_allowed: Number of offers allowed per sign-up + offers_num_required: Number of offers required per sign-up + requests_num_allowed: Number of requests allowed per sign-up + requests_num_required: Number of requests required per sign-up + language: + short: Abbreviation + meta_tagging: + meta_tag: Metatag + meta_tag_id: Metatag + sub_tag: Subtag + sub_tag_id: Subtag + offer: + url: URL + request: + url: URL + role: + archivist: Archivist + no_resets: No Resets + official: Official + opendoors: Open Doors + protected_user: Protected User + tag_wrangler: Tag Wrangler + translator: Translator + series/creatorships: + base: 'Invalid creator:' + pseud_id: Pseud + skin/skin_parents: + parent_skin: Parent skin + user: + login: Username + work: + chapter_total_display: Chapters + summary: Summary + user_defined_tags_count: Fandom, relationship, character, and additional tags + word_count: Words + work/chapters: + base: 'Invalid chapter:' + content: Content + work/creatorships: + base: 'Invalid creator:' + pseud_id: Pseud + work/parent_work_relationships/parent: + author: The author of a parent work outside the archive + title: The title of a parent work outside the archive + url: Parent work URL + errors: + messages: + forbidden: "%{value} is not allowed" + numeric_with_optional_hash: 'may begin with an # and otherwise contain only numbers.' + models: + abuse_report: + attributes: + url: + not_on_archive: does not appear to be on this site. + block: + attributes: + blocked: + blank: Sorry, we couldn't find a user matching that name. + limit: Sorry, you have blocked too many accounts. + official: Sorry, you can't block an official user. + self: Sorry, you can't block yourself. + blocked_id: + taken: You have already blocked that user. + format: "%{message}" + bookmark: + attributes: + pseud: + required: can't be blank + comment: + attributes: + comment_content: + duplicate_comment: "^You've already left this comment here. (It may not appear right away for performance reasons.)" + commentable: + format: "%{message}" + guest_replies_off: Sorry, this user doesn't allow non-Archive users to reply to their comments. + user: + blocked_comment: Sorry, you have been blocked by one or more of this work's creators. + blocked_reply: Sorry, you have been blocked by that user. + format: "%{message}" + spam: This comment looks like spam to our system, sorry! Please try again. + creatorship: + attributes: + pseud_id: + taken: is already listed as a creator. + external_work: + attributes: + user_defined_tags_count: + at_most: must not add up to more than %{count}. You have entered %{value} of these tags, so you must remove %{diff} of them. + invitation: + attributes: + base: + format: "%{message}" + notification_could_not_be_sent: 'Notification email could not be sent: %{error}' + invite_request: + attributes: + email: + blocked_email: has been blocked at the owner's request. That means it can't be used for invitations. Please check the address to make sure it's yours to use and contact Sunset Support if you have any questions. + email_in_use: is already being used by an account holder. + kudo: + attributes: + commentable: + author_on_own_work: You can't leave kudos on your own work. + blank: What did you want to leave kudos on? + guest_on_restricted: You can't leave guest kudos on a restricted work. + user_is_banned: You cannot leave kudos while your account is banned. + user_is_suspended: You cannot leave kudos while your account is suspended. + commentable_type: + inclusion: What did you want to leave kudos on? + user: + archivist: Please log out of your archivist account! + blocked: Sorry, you have been blocked by one or more of this work's creators. + official: Please log out of your official account! + format: "%{message}" + taken: You have already left kudos here. :) + mute: + attributes: + muted: + blank: Sorry, we couldn't find a user matching that name. + limit: Sorry, you have muted too many accounts. + official: Sorry, you can't mute an official user. + self: Sorry, you can't mute yourself. + muted_id: + taken: You have already muted that user. + format: "%{message}" + prompt: + tags_not_in_fandom: "^These %{tag_label} tags in your %{prompt_type} are not in the selected fandom(s), %{fandom}: %{taglist} (Your moderator may be able to fix this.)" + related_work: + attributes: + parent: + blank: The work you listed as an inspiration does not seem to exist. + not_work: Only a link to a work can be listed as an inspiration. + protected: You can't use the related works function to cite works by the protected user %{login}. + format: "%{message}" + skin: + archive_in_title: Sorry, titles including the word 'Archive' are reserved for official skins. + attributes: + title: + taken: must be unique + banned_property: We don't currently allow the CSS property %{property} -- please notify Support if you think this is an error. + banned_value_for_property: "%{property} in %{selectors} cannot have the value %{value}, sorry!" + font_face: We don't allow the @font-face feature. + invalid_custom_property_name: The %{property} custom property in %{selectors} has an invalid name. Names can contain lowercase letters (a-z) in the English alphabet, numerals zero to nine (0-9), dashes (-), and underscores (_). + invalid_media: We don't currently support the media type %{media}, sorry! If we should, please let Support know. + no_public_preview: You need to upload a screencap if you want to share your skin. + no_rules_for_selectors: There don't seem to be any rules for %{selectors}. + no_valid_css: We couldn't find any valid CSS rules in that code. + no_valid_css_for_selectors: The code for %{selectors} doesn't seem to be a valid CSS rule. + work_skin_banned_value_for_property: The %{property} property in %{selectors} cannot have the value %{value} in work skins, sorry! + work_skin_custom_properties: Custom properties are not allowed in work skins. + work_skin_var: The var() function is not allowed in work skins. + skin/skin_parents: + attributes: + base: + format: "%{message}" + skin_parent: + attributes: + base: + format: "%{message}" + site_parent: You can't use %{title} as a parent unless replacing the default archive skin. + subscription: + attributes: + subscribable: + blank: The item you tried to subscribe to does not exist. It may have been deleted. + format: "%{message}" + user: + attributes: + age_over_13: + accepted: Sorry, you have to be over 18! + format: "%{message}" + data_processing: + accepted: Sorry, you need to consent to the processing of your personal data in order to sign up. + format: "%{message}" + email: + taken: "^This email is already associated with another account. Please try again with a different email address." + login: + admin_must_use_default: must use the default. Please contact your chairs to use something else. + changed_too_recently: + one: can only be changed once per day. You last changed your username on %{renamed_at}. + other: can only be changed once every %{count} days. You last changed your username on %{renamed_at}. + invalid: must be %{min_login} to %{max_login} characters (A-Z, a-z, _, 0-9 only), no spaces, cannot begin or end with underscore (_). + password_confirmation: + confirmation: doesn't match new password. + terms_of_service: + accepted: Sorry, you need to accept the Terms of Service in order to sign up. + format: "%{message}" + work: + attributes: + user_defined_tags_count: + at_most: must not add up to more than %{count}. Your work has %{value} of these tags, so you must remove %{diff} of them. + blocked_gifts: "%{byline} does not accept gifts." + blocked_your_gifts: "%{byline} does not accept gifts from you." + work/parent_work_relationships: + format: "%{message}" + models: + admin_blacklisted_email: + one: Banned Email + other: Banned Emails + archive_warning: + one: Warning + other: Warnings + bookmark: + one: Bookmark + other: Bookmarks + category: + one: Category + other: Categories + chapter: + one: Chapter + other: Chapters + character: + one: Character + other: Characters + comment: Comment + fandom: + one: Fandom + other: Fandoms + freeform: + one: Additional Tag + other: Additional Tags + pseud: Pseud + rating: + one: Rating + other: Ratings + related_work: + one: Related Work + other: Related Works + relationship: + one: Relationship + other: Relationships + series: + one: Series + other: Series + tag: + one: Tag + other: Tags + work: + one: Work + other: Works + attributes: + ticket_number: Ticket ID + challenge_assignment: + offer_byline: + none: "- none -" + pinch_hitter: "%{pinch_hitter_byline}* (pinch hitter)" + request_byline: + none: "- None -" + errors: + attributes: + icon: + invalid_format: content type is invalid + too_large: file size must be less than %{maximum_size} + ticket_number: + closed_ticket: must not be closed. + invalid_department: must be in your department. + required: must exist and not be spam. + url: + invalid: does not appear to be a valid URL. + story_parser: + on_archive: URL is for a work on the Archive. Please bookmark it directly instead. + subscriptions: + deleted: Deleted item diff --git a/config/locales/phrase-exports/README.md b/config/locales/phrase-exports/README.md new file mode 100755 index 0000000..b7427dc --- /dev/null +++ b/config/locales/phrase-exports/README.md @@ -0,0 +1 @@ +These files are automatically generated by Phrase and should not be edited. diff --git a/config/locales/phrase-exports/af.yml b/config/locales/phrase-exports/af.yml new file mode 100755 index 0000000..7084d26 --- /dev/null +++ b/config/locales/phrase-exports/af.yml @@ -0,0 +1,6 @@ +--- +af: + mailer: + general: + creation: + title_with_chapter_number: Hoofstuk %{position} van %{title} diff --git a/config/locales/phrase-exports/ar.yml b/config/locales/phrase-exports/ar.yml new file mode 100755 index 0000000..9c6628e --- /dev/null +++ b/config/locales/phrase-exports/ar.yml @@ -0,0 +1,547 @@ +--- +ar: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'التحذيرات:' + many: 'التحذيرات:' + one: 'التحذير:' + other: 'التحذيرات:' + two: 'التحذيران:' + category: + name_with_colon: + few: 'الفئات:' + many: 'الفئات:' + one: 'الفئة:' + other: 'الفئات:' + two: 'الفئتان:' + character: + name_with_colon: + few: 'الشخصيات:' + many: 'الشخصيات:' + one: 'الشخصية:' + other: 'الشخصيات:' + two: 'الشخصيتان:' + fandom: + name_with_colon: + few: 'الفاندومات:' + many: 'الفاندومات:' + one: 'الفاندوم:' + other: 'الفاندومات:' + two: 'الفاندومان:' + freeform: + name_with_colon: + few: 'وسوم إضافية:' + many: 'وسوم إضافية:' + one: 'وسم إضافي:' + other: 'وسوم إضافية:' + two: 'وسمان إضافيان:' + rating: + name_with_colon: 'التصنيف:' + relationship: + name_with_colon: + few: 'العلاقات:' + many: 'العلاقات:' + one: 'العلاقة:' + other: 'العلاقات:' + two: 'العلاقتان:' + work: + summary: المُلخص + models: + archive_warning: + few: التحذيرات + many: التحذيرات + one: التحذير + other: التحذيرات + two: التحذيران + category: + few: الفئات + many: الفئات + one: الفئة + other: الفئات + two: الفئتان + chapter: + few: الفصول + many: الفصول + one: الفصل + other: الفصول + two: الفصلان + character: + few: الشخصيات + many: الشخصيات + one: الشخصية + other: الشخصيات + two: الشخصيتان + fandom: + few: الفاندومات + many: الفاندومات + one: الفاندوم + other: الفاندومات + two: الفاندومان + freeform: + few: وسوم إضافية + many: وسوم إضافية + one: وسم إضافي + other: وسوم إضافية + two: وسمان إضافيان + rating: + few: التصنيفات + many: التصنيفات + one: التصنيف + other: التصنيفات + two: التصنيفان + relationship: + few: العلاقات + many: العلاقات + one: العلاقة + other: العلاقات + two: العلاقتان + series: + few: السلاسل + many: السلاسل + one: السلسلة + other: السلاسل + two: السلسلتان + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} ضيوف" + many: "%{count} ضيفاً" + one: ضيف + other: "%{count} ضيف" + two: ضيفين + left_kudos: + html: + few: حصلت على علامات امتياز للعمل %{commentable_link} من %{givers_list}. + many: حصلت على علامات امتياز للعمل %{commentable_link} من %{givers_list}. + one: حصلت على علامة امتياز للعمل %{commentable_link} من %{givers_list}. + other: حصلت على علامات امتياز للعمل %{commentable_link} من %{givers_list}. + two: حصلت على علامتي امتياز للعمل %{commentable_link} من %{givers_list}. + text: + few: حصلت على علامات امتياز للعمل %{commentable_title} (%{commentable_url}) + من %{givers_list}. + many: حصلت على علامات امتياز للعمل %{commentable_title} (%{commentable_url}) + من %{givers_list}. + one: حصلت على علامة امتياز للعمل %{commentable_title} (%{commentable_url}) + من %{givers_list}. + other: حصلت على علامات امتياز للعمل %{commentable_title} (%{commentable_url}) + من %{givers_list}. + two: حصلت على علامتي امتياز للعمل %{commentable_title} (%{commentable_url}) + من %{givers_list}. + single_guest: + giver: ضيف + html: حصلت على علامة امتياز للعمل %{commentable_link} من %{giver}. + text: حصلت على علامة امتياز للعمل %{commentable_title} (%{commentable_url}) + من ضيف. + subject: "[%{app_name}] حصلت على علامة امتياز!" + mailer: + general: + closing: + formal: بكل إخلاص وتقدير، + informal: مع التحية، + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: الفصل %{position} من %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} كلمات" + many: "%{count} كلمة" + one: كلمة + other: "%{count} كلمة" + two: كلمتان + footer: + general: + about: + html: AO3 هو أرشيف يدار من قبل المعجبين ويدعم من قبلهم أيضاً ويعتمد استمراره + على %{donate_link}. + text: 'AO3 هو أرشيف يدار من قبل المعجبين ويدعم من قبلهم أيضاً ويعتمد استمراره + على تبرعاتكم: %{donate_url}.' + html: + donate_link_text: تبرعاتك + support_link_text: تواصل مع لجنة الدعم + unwanted_email: + html: في حال تلقيك هذه الرسالة بالخطأ، رجاءاً %{support_link}. + text: في حال تلقيك هذه الرسالة بالخطأ، رجاءاً تواصل مع لجنة الدعم على + الرابط %{support_url}. + sent_at: أرسل في %{sent_at}. + greeting: + informal: + unaddressed: مرحباً! + introductory: مرحباً من Archive of Our Own – AO3 (الأرشيف من جانبنا) + metadata_label_indicator: ": " + signature: + app_short_name: AO3 + open_doors: فريق Open Doors (الأبواب المفتوحة) + parent_org: Organization for Transformative Works – OTW (منظمة الأعمال التحويلية) + support: فريق لجنة الدعم في AO3 + users: + mailer: + reset_password_instructions: + expiration: إذا ذا لم تستخدم الرابط الملحق لإعادة تعيين كلمة السر الخاصة بك + خلال أسبوع واحد، فستنتهي صلاحيته، وستحتاج إلى طلب رابط جديد. + intro: 'طلب أحدهم إعادة تعيين كلمة سر حسابك. يمكنك إعادة تعيين كلمة السر لحسابك + باتّباع الرابط التالي وإدخال كلمة السر الجديدة:' + link_title: إعادة تعيين كلمة السر الخاصة بي. + subject: إعادة تعيين كلمة السر الخاصة بك [%{app_name}] + unrequested: إذا لم ترسل هذا الطلب لإعادة تعيين كلمة السر، فيمكنك تجاهل هذا + البريد الإلكتروني والاستمرار باستعمال كلمة السر القديمة. + user_mailer: + admin_deleted_work_notification: + bye: تم إلحاق نسخة من عملك كَمَرجِع. + contact_abuse: التواصل مع لجنة السياسات والتعسفات + deleted: + html: تم حذف عملك %{title} من الأرشيف من قبل أحد المشرفين. + text: تم حذف عملك "%{title}" من الأرشيف من قبل أحد المشرفين. + html: + tos_violation: في حال انتهك عملك أحد شروط الخدمة للأرشيف، نرجو منك %{contact_abuse_link}. + import_project: + html: في حال كان عملك جزءاً من أحد مشاريع الاستيراد التي يديرها فريق الأبواب + المفتوحة، نرجو منك %{opendoors_link} وطرح كافة تساؤلاتك. + text: في حال كان عملك جزءاً من أحد مشاريع الاستيراد التي يديرها فريق الأبواب + المفتوحة، نرجو منك التواصل مع لجنة الأبواب المفتوحة (%{opendoors_link}) + وطرح كافة تساؤلاتك. + opendoors: التواصل مع لجنة الأبواب المفتوحة + subject: "[%{app_name}] تم حذف عملك من قبل أحد المشرفين" + text: + tos_violation: في حال انتهك عملك أحد شروط الخدمة للأرشيف، نرجو منك التواصل + مع لجنة السياسات والتعسفات (%{contact_abuse_url}). + admin_hidden_work_notification: + access: أثناء بقاء عملك مخفياً، ستظل قادرًا على الوصول إليه من خلال الرابط المتاح + أعلاه، لكنه لن يتم إدراجه في صفحة اعمالك، ولن يكون متاحًا لمستخدمي AO3 الآخرين. + check_email: يرجى التحقق من بريدك الإلكتروني، بما في ذلك مجلد البريد العشوائي، + حيث قد يكون فريق السياسات والتعسفات اتصل بك ليشرح لك سبب إخفاء عملك. + contact_abuse: تواصل مع لجنة السياسات والتعسفات + html: + help: إذا لم تكن متأكدًا من سبب إخفاء عملك، ولم تتلق مزيدًا من المعلومات بخصوص + هذا الأمر، رجاءً %{contact_abuse_link} مباشرةً. + hidden: عملك %{title} تم اخفائه من قبل فريق السياسات والتعسفات ولم يعد متاحاً + إلى العامة. + tos_violation: إذا تم إخفاء عملك بسبب انتهاك %{tos_link} الخاصة بـ AO3، فستتم + مطالبتك باتخاذ إجراء لتصحيح الانتهاك. قد يؤدي عدم تعديل عملك ليتوافق مع + شروط الخدمة إلى حذف عملك من AO3. + subject: "[%{app_name}] تم إخفاء عملك من قبل فريق السياسات والتعسفات" + text: + help: إذا لم تكن متأكدًا من سبب إخفاء عملك، ولم تتلق مزيدًا من المعلومات بخصوص + هذا الأمر، رجاءً %{contact_abuse_url} مباشرةً. + hidden: عملك "%{title}" (%{work_url}) تم اخفائه من قبل فريق السياسات والتعسفات + ولم يعد متاحاً إلى العامة. + tos_violation: إذا تم إخفاء عملك بسبب انتهاك %{tos_url} الخاصة بـ AO3، فستتم + مطالبتك باتخاذ إجراء لتصحيح الانتهاك. قد يؤدي عدم تعديل عملك ليتوافق مع + شروط الخدمة إلى حذف عملك من AO3. + tos: شروط الخدمة + anonymous_or_unrevealed_notification: + anonymous_info: يتم تضمين الأعمال المجهولة المصدر في قوائم الوسوم، ولكن ليس + في صفحة الأعمال الخاصة بك. في العمل، سيتم استبدال اسم المستخدم الخاص بك بكلمة + "Anonymous" (مجهول المصدر). + anonymous_unrevealed_info: قد يكشف مشرفو المجموعة لاحقًا عن عملك لكن سيتركونه + مجهول المصدر. لن يُنبه الأشخاص الذين يشتركون في صفحتك بهذا التغيير. بمجرد + الكشف عنه، سيُضمن عملك في قوائم الوسوم، ولكن ليس في صفحة عملك. في العمل، سيتم + استبدال اسم المستخدم الخاص بك بكلمة "Anonymous" (مجهول). + changed_status: + anonymous: + html: لقد غير مشرفو المجموعة %{collection_link} حالة عملك %{work_link} إلى + مجهول المصدر. + text: لقد غير مشرفو المجموعة "%{collection_title}" (%{collection_url}) حالة + عملك "%{work_title}" (%{work_url}) إلى مجهول المصدر. + anonymous_unrevealed: + html: لقد غير مشرفو المجموعة %{collection_link} حالة عملك %{work_link} إلى + مجهول المصدر وغير مكشوف. + text: لقد غير مشرفو المجموعة "%{collection_title}" (%{collection_url}) حالة + عملك "%{work_title}" (%{work_url}) إلى مجهول المصدر وغير مكشوف. + unrevealed: + html: لقد غير مشرفو المجموعة %{collection_link} حالة عملك %{work_link} إلى + غير مكشوف. + text: لقد غير مشرفو المجموعة "%{collection_title}" (%{collection_url}) حالة + عملك "%{work_title}" (%{work_url}) إلى غير مكشوف. + collection_items_link_text: صفحة Approved Collection Items (عناصر المجموعة المعتمدة) + do_not_want: + anonymous: + html: إذا كنت لا تريد أن يكون عملك مجهول المصدر، يرجى زيارة %{collection_items_link} + لإزالته من هذه المجموعة. + text: 'إذا كنت لا تريد أن يكون عملك مجهول المصدر، يرجى زيارة صفحة Approved + Collection Items (عناصر المجموعة المعتمدة) لإزالته من هذه المجموعة: %{collection_items_url}' + anonymous_unrevealed: + html: إذا كنت لا تريد أن يكون عملك مجهول المصدر وغير مكشوف، يرجى زيارة %{collection_items_link} + لإزالته من هذه المجموعة. + text: 'إذا كنت لا تريد أن يكون عملك مجهول المصدر وغير مكشوفًا، يرجى زيارة + صفحة Approved Collection Items (عناصر المجموعة المعتمدة) لإزالته من هذه + المجموعة: %{collection_items_url}' + unrevealed: + html: إذا كنت لا تريد أن يكون عملك غير مكشوفًا، يرجى زيارة %{collection_items_link} + لإزالته من هذه المجموعة. + text: 'إذا كنت لا تريد أن يكون عملك غير مكشوفًا، يرجى زيارة صفحة Approved + Collection Items (عناصر المجموعة المعتمدة) لإزالته من هذه المجموعة: %{collection_items_url}' + faq_link_text: الأسئلة المتداولة حول المجموعات + more_info: + html: للمزيد من المعلومات، تفضل بزيارة %{faq_link}. + text: 'للمزيد من المعلومات، تفضل بزيارة الأسئلة المتداولة حول المجموعات: %{faq_url}' + subject: + anonymous: "[%{app_name}] أصبح عملك مجهول المصدر" + anonymous_unrevealed: "[%{app_name}] أصبح عملك مجهول المصدر وغير مكشوف" + unrevealed: "[%{app_name}] أصبح عملك غير مكشوف" + unrevealed_info: لا يتم تضمين الأعمال غير المكشوفة في قوائم الوسوم أو في صفحة + الأعمال الخاصة بك. سيتلقى أي شخص يزور رابطًا للعمل إشعارًا بأنه لم يتم الكشف + عنه حاليًا، ولن يتمكن من الوصول إلى محتواه. + challenge_assignment_notification: + any: أي من الموجود + assignment: + html: تم تعيينك للطلب الآتي في تحدي %{link} على AO3! + description: 'الوصف:' + due: 'موعد تسليم المهمة:' + html: + footer: إنك تتلقى هذا البريد لانك اشتركت في تحدي %{title}. للمزيد من المعلومات + حول هذا التحدي ولمعلومات التواصل مع المشرفين، قم بزيارة %{footer_link}. + footer_link: صفحة التحدي الرئيسية + look_up: يمكنك الوصول إلى مهمتك من خلال %{link}. + look_up_link: صفحة Assignments (المهمات) الخاصة بك + optional_tags: 'وسوم اختيارية:' + prompts: 'المحفزات:' + prompt_url: 'رابط المحفز:' + recipient: 'المتلقي:' + recipient_missing: 'لا يوجد: تواصل مع أحد المشرفين للحصول على المساعدة!' + subject: "[%{app_name}][%{collection_title}] مهمّتك!" + text: + assignment: تم تعيينك للطلب الآتي في تحدي %{collection_title} (%{collection_url}) + على الأرشيف من جانبنا (AO3)! + footer: إنك تتلقى هذا البريد لأنك اشتركت في تحدي %{title} (%{url}). للمزيد + من المعلومات حول هذا التحدي ولمعلومات التواصل مع المشرفين، قم بزيارة %{profile_url}. + look_up: يمكنك الوصول إلى مهمتك من خلال صفحة Assignments (المهمات) الخاصة + بك على %{link}. + change_email: + changed: + html: "%{login}، تم تغيير البريد الالكتروني المرتبط بحسابك إلى %{email}" + text: "%{login}، تم تغيير البريد الالكتروني المرتبط بحسابك إلى %{email}" + subject: "[%{app_name}] تم تغيير البريد الالكتروني" + collection_notification: + assignments_sent: + complete: تم ارسال جميع المهام. + subject: تم ارسال المهام + html: + received_message: 'تلقيت رسالة بخصوص مجموعتك %{collection_link}:' + text: + received_message: 'تلقيت رسالة بخصوص مجموعتك "%{collection_title}"(%{collection_url}):' + creatorship_notification: + explanation: عندما تكون منتجاً مشاركاً لعمل ما، يمكن إضافتك إلى فصول جديدة بغض + النظر عن إعداداتك كمنتج مشارك. كما ستتم إضافتك إلى أية سلسلة يضاف العمل إليها. + html: + creation: "%{creation_link} بقلم %{pseud_links}" + edit_chapter: تحرير الفصل + edit_series: تحرير السلسلة + remove_chapter: إذا تمت إضافتك بالخطأ أو إن لم تكن ترغب في تسجيل اسمك كمنتج، + يمكنك %{edit_chapter_link} لإزالة نفسك من قائمة المنتجين. + remove_series: إذا تمت إضافتك بالخطأ أو إن لم تكن ترغب في تسجيل اسمك كمنتج، + يمكنك %{edit_series_link} لإزالة نفسك من قائمة المنتجين. + intro_chapter: 'أضاف المستخدم %{adding_user} اسمك المستعار %{pseud} إلى قائمة + المنتجين المشاركين للفصل التالي:' + intro_series: 'أضاف المستخدم %{adding_user} اسمك المستعار %{pseud} إلى قائمة + المنتجين المشاركين للسلسلة التالية:' + subject: "[%{app_name}] إشعار منتج مشارك" + text: + creation: "%{title} (%{url}) بقلم %{pseuds}" + remove_chapter: 'إذا تمت إضافتك بالخطأ أو إن لم تكن ترغب في تسجيل اسمك كمنتج، + يمكنك تحرير الفصل لإزالة نفسك من قائمة المنتجين: %{url}' + remove_series: 'إذا تمت إضافتك بالخطأ أو إن لم تكن ترغب في تسجيل اسمك كمنتج، + يمكنك تحرير السلسلة لإزالة نفسك من قائمة المنتجين: %{url}' + creatorship_notification_archivist: + explanation: بما أنه يعمل بصفته الرسمية كمؤرشف لمشروع الأبواب المفتوحة، يمكنه + اضافتك دون دعوة، حتى إن عطّلت خاصية المنتج المشارك. + html: + creation: "%{creation_link} من إنتاج %{pseud_links}" + edit_chapter: تحرير الفصل + edit_series: تحرير السلسلة + edit_work: تحرير العمل + remove_chapter: إن تمت إضافتك بالخطأ، أو إن لم ترغب في إدراج اسمك المستعار + كمنتج، باستطاعتك %{edit_chapter_link} لإزالة نفسك من قائمة المنتجين. + remove_series: إن تمت إضافتك بالخطأ، أو إن لم ترغب في إدراج اسمك المستعار + كمنتج، باستطاعتك %{edit_series_link} لإزالة نفسك من قائمة المنتجين. + remove_work: إن تمت إضافتك بالخطأ، أو إن لم ترغب في إدراج اسمك المستعار كمنتج، + باستطاعتك %{edit_work_link} لإزالة نفسك من قائمة المنتجين. + intro_chapter: 'أضاف المستخدم %{archivist} اسمك المستعار %{pseud} كمنتج مشارك + للفصل التالي:' + intro_series: 'أضاف المستخدم %{archivist} اسمك المستعار %{pseud} كمنتج مشارك + للسلسلة التالية:' + intro_work: 'أضاف المستخدم %{archivist} اسمك المستعار %{pseud} كمنتج مشارك للعمل + التالي:' + subject: "[%{app_name}] إشعار منتج مشارك من أمين الأرشيف المستورد" + text: + creation: "%{title} (%{url}) من إنتاج %{pseuds}" + remove_chapter: 'إن تمت إضافتك بالخطأ، أو إن لم ترغب في إدراج اسمك المستعار + كمنتج، باستطاعتك تحرير الفصل لإزالة نفسك من قائمة المنتجين: %{url}' + remove_series: 'إن تمت إضافتك بالخطأ، أو إن لم ترغب في إدراج اسمك المستعار + كمنتج، باستطاعتك تحرير السلسلة لإزالة نفسك من قائمة المنتجين: %{url}' + remove_work: 'إن تمت إضافتك بالخطأ، أو إن لم ترغب في إدراج اسمك المستعار كمنتج، + باستطاعتك تحرير العمل لإزالة نفسك من قائمة المنتجين: %{url}' + creatorship_request: + html: + creation: "%{creation_link} من قبل %{pseud_links}" + instructions: يمكنك قبول هذا الطلب أو رفضه في صفحة %{page_name} الخاصة بك. + page_name: Co-Creator Requests (طلبات المنتج المشارك) + intro_chapter: 'قام المستخدم %{inviting_user} بدعوة اسمك المستعار %{pseud} لكي + يضاف كمنتج مشارك على الفصل التالي:' + intro_series: 'قام المستخدم %{inviting_user} بدعوة اسمك المستعار %{pseud} لكي + يضاف كمنتج مشارك على السلسلة التالية:' + intro_work: 'قام المستخدم %{inviting_user} بدعوة اسمك المستعار %{pseud} لكي + يضاف كمنتج مشارك على العمل التالي:' + subject: "[%{app_name}] طلب منتج مشارك" + text: + creation: "%{title} (%{url}) من قبل %{pseuds}" + instructions: 'يمكنك قبول هذا الطلب أو رفضه في صفحة Co-Creator Requests (طلبات + المنتج المشارك) الخاصة بك: %{url}' + delete_work_notification: + attachment: تم إرفاق نسخة من عملك كمرجِع. + deleted_other: + html: تم حذف عملك %{title} بناءاً على طلب %{pseud}. + text: تم حذف عملك "%{title}" بناءاً على طلب %{pseud}. + deleted_yourself: + html: تم حذف عملك %{title} بناءاً على طلبك. + text: تم حذف عملك "%{title}" بناءاً على طلبك. + questions: + html: إن كان لديك أيّة تساؤلات، نرجو منك %{support}. + text: إن كان لديك أيّة تساؤلات، نرجو منك %{support} (%{url}). + subject: "[%{app_name}] تم حذف عملك" + support: التواصل مع لجنة الدعم + invitation_to_claim: + access: + text: إعتماداً على الأرشيف المستورد، أعمالك قد تكون حملت بشكل محصور بالمستخدمين + المسجلين فقط (لكي لا تظهر على بحث قوقل). في هذه الحالة، ستكون الأعمال متاحة + فقط للمستخدمين المسجلين إلا إذا أردت جعلها مرئية للجميع. للمساعدة في فتح + أعمالك، الإستغناء عنها أو حذفها، رجاءً تواصل مع فريق دعم AO3. + claim_or_remove: + html: املك أو احذف أعمالك هنا. + text: 'املك أو احذف أعمالك هنا: %{claim_url}' + email_tips: إذا تواصلت معنا، رجاءً اضف عناوين البريد الإلكتروني من @transformativeworks.org + إلى اللائحة المسموحة وتفقد ردنا ضمن ملف الرسائل غير المرغوب بها. + html: + ao3_news: أخبار AO3 + contact_open_doors: تواصل مع لجنة الأبواب المفتوحة + contact_support: تواصل مع فريق دعم AO3 + faq_page: صفحة الأسئلة المتداولة + tutorial_page: صفحة الدليل التوجيهي + introduction: + text: إنك تستلم هذا البريد الالكتروني بسبب أرشيف تم استيراده مؤخراً من قبل + Open Doors (مشروع الأبواب المفتوحة) (%{open_doors_link}) إلى %{app_name} + (%{app_short_name} - %{app_url})، ونحن نعتقد أن أعمال المعجبين التالية هي + من أعمالك. نود أن نمنحك الفرصة لامتلاك (أو حذف/الإستغناء عن) هذه الأعمال + إذا أردت. وإذا كنت لا تمتلك حساباً تحت بريد إلكتروني آخر، ندعوك للانضمام + لـ AO3! + mistake: + text: إذا كان هناك خطأ وهذه ليست أعمالك، رجاءً لا تقم بحذفها! رجاءً فقط تواصل + مع لجنة الأبواب المفتوحة (%{open_doors_link}) وسنصلح الأمر. + more_info: + text: تستطيع قراءة الإعلانات عن أحدث الاستيرادات إلى الأرشيف على أخبار AO3 + (%{news_link})، وتستطيع العثور على معلومات إضافية عن الأبواب المفتوحة من + خلال صفحة الأسئلة المتداولة (%{open_doors_faq_link}) أو صفحة الدليل التوجيهي + (%{open_doors_tutorial_link}). لأي أسئلة لم يتم الإجابة عنها في الاسئلة + المتداولة، الدليل التوجيهي أو هذا البريد الإلكتروني، رجاءً تواصل مع فريق + دعم AO3 على %{support_link}. + other_works: + text: إذا كانت لديك أعمال أخرى على الأرشيف المستورد تحت عنوان بريد إلكتروني + لم يعد بإمكانك أن تصله، رجاءً تواصل مع لجنة الأبواب المفتوحة بأي معلومات + يمكنها أن تساعد في التحقق من هويتك. + questions: + text: لإستفسرات أخرى، رجاءً تواصل مع فريق دعم AO3 على %{support_link}. + redirects: للحفاظ على الإشارات المرجعية ولوائح الأعمال الموصى بها، قد تعيد عناوين + الويب للأرشيف الذي تم استيراده التوجيه إلى النسخة المستوردة من هذه الأعمال + لفترة محدودة (تفقد منشور الإعلان لأرشيفك للتأكد). إذا حملت مسبقاً نسخة من + هذه الأعمال ولم تقم بإستخدام ميزة الإستيراد من عنوان الويب، سيكون هناك نسختان + من العمل نفسه على الأرشيف. + subject: "[%{app_name}] دعوة لامتلاك الأعمال" + unwanted: + text: إذا كانت هذه الأعمال حقاً ملكك، ولكنك لا تريدها، يمكنك الإستغناء عنها + (لكي تبقى على AO3، ولكن مع إزالة إسمك عنها) أو حذفها (لكي تحذف تماماً من + AO3). لا تحتاج إلى إضافة هذه الأعمال إلى أي حساب من أجل أن تستغني عنها أو + تحذفها. تستطيع القيام بهذا مباشرةً من الرابط أعلاه. (لطلب المساعدة، رجاءً + تواصل مع فريق دعم AO3 على %{support_link}.) + update_redirect: + text: إذا أردت من الأبواب المفتوحة أن تحدِّث إعادة التوجيه ليذهب إلى عملك + الموجود مسبقاً، رجاءً احذف النسخة المستوردة وتواصل مع لجنة الأبواب المفتوحة + على %{open_doors_link} بإستخدام إسم حسابك على AO3، وإسم حسابك على الأرشيف + المستورد، وعنوان العمل الذي تريد إعادة التوجيه إليه بالإضافة إلى عنوان الويب + (URL) التابع لهذا العمل. (إذا كانت لديك أعمال متعددة تود أن تغير إعادة التوجيه + لها، يمكنك إدراجها كلها في بريد إلكتروني واحد.) + uploaded_list: 'الأعمال المحمّلة تشمل:' + invite_increase_notification: + html: + body: + few: نود إعلامك بأنه لديك %{count} دعوات جديدة يمكن استخدامها لإنشاء حسابات + جديدة في AO3. بإمكانك دعوة صديق من خلال %{invitation_page_link}. + many: نود إعلامك بأنه لديك %{count} دعوة جديدة يمكن استخدامها لإنشاء حسابات + جديدة في AO3. بإمكانك دعوة صديق من خلال %{invitation_page_link}. + one: نود إعلامك بأنه لديك دعوة جديدة يمكن استخدامها لإنشاء حساب جديد في + AO3. بإمكانك دعوة صديق من خلال %{invitation_page_link}. + other: نود إعلامك بأنه لديك %{count} دعوة جديدة يمكن استخدامها لإنشاء حسابات + جديدة في AO3. بإمكانك دعوة صديق من خلال %{invitation_page_link}. + two: نود إعلامك بأنه لديك دعوتان جديدتان يمكن استخدامها لإنشاء حسابان جديدان + في AO3. بإمكانك دعوة صديق من خلال %{invitation_page_link}. + invitation_page_link_text: صفحة Invitations (دعواتك) + subject: "[%{app_name}] دعوات جديدة" + text: + body: + few: نود إعلامك بأنه لديك %{count} دعوات جديدة يمكن استخدامها لإنشاء حسابات + جديدة في AO3. بإمكانك دعوة صديق من خلال صفحة Invitations (دعواتك) (%{invitation_page_url}). + many: نود إعلامك بأنه لديك %{count} دعوة جديدة يمكن استخدامها لإنشاء حسابات + جديدة في AO3. بإمكانك دعوة صديق من خلال صفحة Invitations (دعواتك) (%{invitation_page_url}). + one: نود إعلامك بأنه لديك دعوة جديدة يمكن استخدامها لإنشاء حساب جديد في + AO3. بإمكانك دعوة صديق من خلال صفحة Invitations (دعواتك) (%{invitation_page_url}). + other: نود إعلامك بأنه لديك %{count} دعوة جديدة يمكن استخدامها لإنشاء حسابات + جديدة في AO3. بإمكانك دعوة صديق من خلال صفحة Invitations (دعواتك) (%{invitation_page_url}). + two: نود إعلامك بأنه لديك دعوتان جديدتان يمكن استخدامها لإنشاء حسابان جديدان + في AO3. بإمكانك دعوة صديق من خلال صفحة Invitations (دعواتك) (%{invitation_page_url}). + invite_request_declined: + main: + few: نأسف لإبلاغك أنه لا يمكن تلبية طلبك للحصول على %{count} دعوات جديدة في + هذا الوقت. + many: نأسف لإبلاغك أنه لا يمكن تلبية طلبك للحصول على %{count} دعوة جديدة في + هذا الوقت. + one: نأسف لإبلاغك أنه لا يمكن تلبية طلبك للحصول على دعوة جديدة في هذا الوقت. + other: نأسف لإبلاغك أنه لا يمكن تلبية طلبك للحصول على %{count} دعوة جديدة + في هذا الوقت. + two: نأسف لإبلاغك أنه لا يمكن تلبية طلبك للحصول على دعوتين جديدتين في هذا + الوقت. + zero: 'كان طلبك:' + reason: 'كان طلبك:' + subject: "[%{app_name}] طلب دعوة إضافية مرفوض" + recipient_notification: + html: + collection: لقد نُشر عملٌ مُهدى إليك في مجموعة %{collection_link} على AO3! + no_collection: لقد نُشر عملٌ مُهدى إليك في AO3! + subject: + collection: "[%{app_name}][%{collection_title}] عمل مُهدى إليك من %{collection_title}" + no_collection: "[%{app_name}] عمل مُهدى إليك" + text: + collection: لقد نُشر عملٌ مُهدى إليك في مجموعة "%{collection_title}" (%{collection_url}) + على AO3! + signup_notification: + activate: + html: رجاءاً %{activate_account_link}. + text: " رجاءاً اتبع هذا الرابط لتفعيل حسابك: %{activate_account_url}" + activate_your_account: اتبع هذا الرابط لتفعيل حسابك + admin_posts: أخبار AO3 + bye: نأمل أن تستمتع باستخدام الأرشيف. + contact_support: تواصل مع لجنة الدعم + faq: قائمة الأسئلة المتداولة + features: + html: بعد تفعيل حسابك، يمكنك البدء بنشر أعمالك، إعداد اشتراكات البريد الإلكتروني + لإعلامك عندما يقوم مبدعوك المفضلون بنشر أعمال جديدة أو عندما يتم تحديث عمل + تقوم بمتابعته، كما باستطاعتك تعيين تفضيلاتك لتخصيص طريقة ظهور الموقع وعمله + بالنسبة لك، ويمكنك متابعة الأعمال التي قمت بزيارتها سابقاً عن طريق السجل + خاصتك، والعديد من الخواص الأخرى. + text: بعد تفعيل حسابك، يمكنك البدء بنشر أعمالك، إعداد اشتراكات البريد الإلكتروني + لإعلامك عندما يقوم مبدعوك المفضلون بنشر أعمال جديدة أو عندما يتم تحديث عمل + تقوم بمتابعته، كما باستطاعتك تعيين تفضيلاتك لتخصيص طريقة ظهور الموقع وعمله + بالنسبة لك، ويمكنك متابعة الأعمال التي قمت بزيارتها سابقاً عن طريق السجل + خاصتك، والعديد من الخواص الأخرى. + information: + html: هناك الكثير من المعلومات والعديد من النصائح حول كيفية استخدام الموقع + في %{faq_link}. ستجد آخر الأخبار عن تطورات الموقع في %{admin_posts_link}. + إذا كنت بحاجة إلى المزيد من المساعدة، أو واجهتك مشكلة، أو كان لديك بعض الأسئلة + والتعليقات، نرجو منك %{contact_support_link}، الذين سيكونون سعداء دائماً + بتقديم العون. + text: 'هناك الكثير من المعلومات والعديد من النصائح حول كيفية استخدام الموقع + في قائمة الأسئلة المتداولة التي تجدها هنا: %{faq_url}. ستجد آخر الأخبار + عن تطورات الموقع على أخبار AO3 في المشاركات من مسؤولين الأرشيف التي تجدها + هنا: %{admin_posts_url}. إذا كنت بحاجة إلى المزيد من المساعدة، أو واجهتك + مشكلة، أو كان لديك بعض الأسئلة والتعليقات، نرجو منك التواصل مع فريق الدعم، + الذين سيكونون سعداء دائماً بتقديم العون: %{contact_support_url}.' + welcome: أهلا بك في Archive of Our Own، %{login}! diff --git a/config/locales/phrase-exports/bg.yml b/config/locales/phrase-exports/bg.yml new file mode 100755 index 0000000..539791d --- /dev/null +++ b/config/locales/phrase-exports/bg.yml @@ -0,0 +1,527 @@ +--- +bg: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Предупреждение:' + other: 'Предупреждения:' + category: + name_with_colon: + one: 'Категория:' + other: 'Категории:' + character: + name_with_colon: + one: 'Персонаж:' + other: 'Персонажи:' + fandom: + name_with_colon: + one: 'Фендъм:' + other: 'Фендъм:' + freeform: + name_with_colon: + one: 'Допълнителен таг:' + other: 'Допълнителни тагове:' + rating: + name_with_colon: 'Възрастова категория:' + relationship: + name_with_colon: + one: 'Oтношения:' + other: 'Oтношения:' + work: + chapter_total_display: Глави + summary: Резюме + models: + archive_warning: + one: Предупреждение + other: Предупреждения + category: + one: Категория + other: Категории + chapter: + one: Глава + other: Глави + character: + one: Персонаж + other: Персонажи + fandom: + one: Фендъм + other: Фендъм + freeform: + one: Допълнителен таг + other: Допълнителни тагове + rating: + one: Възрастова категория + other: Възрастови категории + relationship: + one: Oтношения + other: Oтношения + series: + one: Поредица + other: Поредици + kudo_mailer: + batch_kudo_notification: + guest: + one: един гост + other: "%{count} гости" + subject: "[%{app_name}] Имаш кудос!" + mailer: + general: + closing: + formal: С уважение, + informal: Поздрави, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Глава %{position} от %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} дума" + other: "%{count} думи" + footer: + general: + about: + html: AO3 е архив, който се управлява и поддържа от фенове и разчита на + %{donate_link}. + text: 'AO3 е архив, който се управлява и поддържа от фенове и разчита + на вашите дарения: %{donate_url}.' + html: + donate_link_text: вашите дарения + support_link_text: свържи се с екип Поддръжка + unwanted_email: + html: Ако си получил/а това съобщение по погрешка, моля, %{support_link}. + text: Ако си получил/а това съобщение по погрешка, моля, свържи се с екип + Поддръжка на %{support_url}. + sent_at: Изпратено в %{sent_at}. + greeting: + informal: + unaddressed: Здравей! + introductory: Привет от Archive of Our Own – AO3 (Нашият архив)! + metadata_label_indicator: ":" + signature: + abuse_team: Екип Политики и нарушения на АО3 + app_short_name: AO3 + open_doors: Екипът на Open Doors (Отворени врати) + parent_org: Organization for Transformative Works – OTW (Организация за преобразуващи + произведения) + support: Екип Поддръжка на AO3 + users: + mailer: + reset_password_instructions: + expiration: Ако в рамките на една седмица не използваш този линк, той ще стане + невалиден и ще трябва да заявиш промяната наново. + intro: 'Някой е заявил нулиране на паролата за твоя профил. Можеш да смениш + паролата на профила си като кликнеш на долния линк и въведеш нова парола:' + link_title: Смяна на моята парола. + subject: "[%{app_name}] Смяна на твоята парола" + unrequested: Ако тази заявка не е направена от теб, може да игнорираш този + имейл, а досегашната ти парола ще остане валидна. + user_mailer: + admin_deleted_work_notification: + bye: Прилагаме копие от произведението ти за информация. + contact_abuse: свържи се с нашия комитет Политики и нарушения + deleted: + html: Твоето произведение %{title} беше изтрито от AO3 от администратор на + сайта. + text: Твоето произведение "%{title}" беше изтрито от AO3 от администратор + на сайта. + html: + tos_violation: Ако е възможно произведението ти да е нарушило Правилата за + ползване на AO3, моля, %{contact_abuse_link}. + import_project: + html: Ако това произведение е било част от проект за присъединяване на творби + към АО3, който се управлява от екипа на Open Doors (Отворени врати), моля, + %{opendoors_link}, ако имаш допълнителни въпроси. + text: Ако това произведение е било част от проект за присъединяване на творби + към АО3, който се управлява от екипа на Open Doors (Отворени врати), моля, + свържи се с Open Doors (%{opendoors_link}), ако имаш допълнителни въпроси. + opendoors: свържи се с Open Doors + subject: "[%{app_name}] Произведението ти беше изтрито от администратор" + text: + tos_violation: Ако е възможно произведението ти да е нарушило Правилата за + ползване на AO3, моля, свържи се с нашия комитет Политики и нарушения (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Когато произведението ти е скрито, ти все още имаш достъп до него чрез + горния линк, но то няма да се показва на страницата с твоите произведения + и няма да бъде достъпно за други потребители в АО3. + check_email: Моля да провериш своя имейл, включително Спам папката, защото е + възможно екип Политики и нарушения вече да са се опитали да се свържат с теб, + за да обяснят причината, поради която произведението ти е било скрито. + contact_abuse: се свържи с екип Политики и нарушения + html: + help: Ако не си сигурен/а защо произведението ти е било скрито и не сме се + свързали с теб с по-нататъшна информация по въпроса, моля, директно %{contact_abuse_link}. + hidden: Твоето произведение %{title} беше скрито от екип Политики и нарушения + и вече не е публично достъпно. + tos_violation: Ако произведението ти е било скрито поради нарушение на %{tos_link} + на АО3, ще се наложи да поправиш нарушението. Ако не приведеш творбата си + в съответствие с Правилата за ползване, може да се стигне до окончателното + ѝ изтриване от АО3. + subject: "[%{app_name}] Произведението ти беше скрито от екип Политики и нарушения" + text: + help: 'Ако не си сигурен/а защо произведението ти е било скрито и не сме се + свързали с теб с по-нататъшна информация по въпроса, моля, директно се свържи + с екип Политики и нарушения: %{contact_abuse_url}.' + hidden: Произведението ти "%{title}" (%{work_url}) беше скрито от екип Политики + и нарушения и вече не е публично достъпно. + tos_violation: Ако произведението ти е било скрито поради нарушение на Правилата + за ползване на АО3 (%{tos_url}), ще се наложи да поправиш нарушението. Ако + не приведеш творбата си в съответствие с Правилата за ползване, може да + се стигне до окончателното ѝ изтриване от АО3. + tos: Правилата за ползване + anonymous_or_unrevealed_notification: + anonymous_info: Анонимните произведения се появяват в списъците на тагове, но + не и на страницата с всичките ти творби. В самото произведение твоето потребителско + име е заменено с "Anonymous" (Анонимен). + anonymous_unrevealed_info: По-късно организаторите на колекцията може да разкрият + произведението ти, но да го оставят анонимно. Хората, които са се абонирали + за теб като автор, няма да бъдат уведомени за тази промяна. След като бъде + разкрито, произведението ти ще се показва в списъците на тагове, но не и на + страницата с всичките ти творби. В самото произведение твоето потребителско + име ще бъде заменено с "Anonymous" (Анонимен). + changed_status: + anonymous: + html: Организаторите на колекцията %{collection_link} промениха статуса + на твоето произведение %{work_link} на анонимно. + text: Организаторите на колекцията "%{collection_title}" (%{collection_url}) + промениха статуса на твоето произведение "%{work_title}" (%{work_url}) + на анонимно + anonymous_unrevealed: + html: Организаторите на колекцията %{collection_link} промениха статуса + на твоето произведение %{work_link} на анонимно и неразкрито. + text: Организаторите на колекцията "%{collection_title}" (%{collection_url}) + промениха статуса на твоето произведене "%{work_title}" (%{work_url}) + на анонимно и неразкрито. + unrevealed: + html: Организаторите на колекцията %{collection_link} промениха статуса + на твоето произведение %{work_link} на неразкрито. + text: Организаторите на колекцията "%{collection_title}" (%{collection_url}) + промениха статуса на твоето произведене "%{work_title}" (%{work_url}) + на неразкрито. + collection_items_link_text: страницата Approved Collection Items (Одобрено съдържание + в колекции) + do_not_want: + anonymous: + html: Ако не искаш произведението ти да е анонимно, моля, отиди на %{collection_items_link}, + за да го премахнеш от тази колекция. + text: 'Ако не искаш произведението ти да е анонимно, моля, отиди на страницата + Approved Collection Items (Одобрено съдържание в колекции), за да го премахнеш + от тази колекция: %{collection_items_url}' + anonymous_unrevealed: + html: Ако не искаш произведението ти да е анонимно и неразкрито, моля, отиди + на %{collection_items_link}, за да го премахнеш от тази колекция. + text: 'Ако не искаш произведението ти да е анонимно и неразкрито, моля, + отиди на страницата Approved Collection Items (Одобрено съдържание в колекции), + за да го премахнеш от тази колекция: %{collection_items_url}' + unrevealed: + html: Ако не искаш произведението ти да е неразкрито, моля, отиди на %{collection_items_link}, + за да го премахнеш от тази колекция. + text: 'Ако не искаш произведението ти да е неразкрито, моля, отиди на страницата + Approved Collection Items (Одобрено съдържание в колекции), за да го премахнеш + от тази колекция: %{collection_items_url}' + faq_link_text: ЧЗВ за колекциите + more_info: + html: За повече информация, виж %{faq_link}. + text: 'За повече информация, виж ЧЗВ за колекциите: %{faq_url}' + subject: + anonymous: "[%{app_name}] Произведението ти беше променено на анонимно" + anonymous_unrevealed: "[%{app_name}] Произведението ти беше променено на анонимно + и неразкрито" + unrevealed: "[%{app_name}] Произведението ти беше променено на неразкрито" + unrevealed_info: Неразкритите произведения не се появяват нито в списъците на + тагове, нито на страницата с всичките ти творби. Всеки, който последва линка + към произведението, ще получи съобщение, че то все още не е разкрито и няма + да има достъп до съдържанието му. + archivist_added_to_collection_notification: + approved_collection_items_page: страница Approved Collection Items (Одобрено + съдържание на колекция) + archivist_notice: Тъй като модераторите на колекцията действат в официалното + си качество на архивисти в Open Doors (Отворени врати), те могат да добавят + твоето произведение към тази колекция дори когато опцията за получаване на + покани за колекции е изключена в твоите настройки. Архивистите добавят произведения + към колекции само ако те са били част от импортиран архив. + removal_instructions: + html: Ако желаеш да премахнеш творбата си от тази колекция, моля, посети твоята + %{approved_items_link}. + text: 'Ако желаеш да премахнеш творбата си от тази колекция, моля, посети + твоята страница Approved Collection Items (Одобрено съдържание на колекция): + %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Архивист на Open Doors (Отворени + врати) е добавил твоето произведение към колекция" + work_added: + html: Доброволците, които поддържат %{collection_link}, са добавили твоето + произведение %{work_link} към тяхната колекция! + text: Доброволците, поддържащи "%{collection_title}" (%{collection_url}), + са добавили твоето произведение "%{work_title}" (%{work_url}) към тяхната + колекция! + challenge_assignment_notification: + any: Всички + assignment: + html: Възложена ти е следната заявка от предизвикателството %{link} в АО3! + description: 'Описание:' + due: 'Краен срок за изпълнение на задачата:' + html: + footer: Получаваш този имейл във връзка с твоята регистрация в предизвикателството + %{title}. За повече информация относно предизвикателството и за това как + да се свържеш с модераторите, моля, виж %{footer_link}. + footer_link: страницата на предизвикателството + look_up: Можеш да намериш тази задача на %{link}. + look_up_link: страницата на твоите Assignments (Задачи) + optional_tags: 'Тагове по избор:' + prompts: 'Идеи:' + prompt_url: 'URL на идея:' + recipient: 'Получател:' + recipient_missing: 'Няма получател: свържи се с модератор за помощ!' + subject: "[%{app_name}][%{collection_title}] Твоята задача!" + text: + assignment: Възложена ти е следната заявка от предизвикателството "%{collection_title}" + (%{collection_url}) в АО3! + footer: Получаваш този имейл във връзка с твоята регистрация в предизвикателството + %{title} (%{url}). За повече информация относно предизвикателството и за + това как да се свържеш с модераторите, моля виж %{profile_url}. + look_up: Можеш да намериш тази задача на страницата на твоите Assignments + (Задачи) на %{link}. + change_email: + changed: + html: "%{login}, имейлът, който използваш за профила си, беше променен на + %{email}" + text: "%{login}, имейлът, който използваш за профила си, беше променен на + %{email}" + subject: "[%{app_name}] Промяна на имейл" + claim_notification: + access: + contact_support: свържи се с АО3 Поддръжка + html: В зависимост от архива твоите произведения може да са били добавени + с ограничение за достъп само от регистрирани потребители (за да не се появяват + като резултати при търсене в Гугъл). В този случай тези твои произведения + ще бъдат достъпни само за потребителите, които са влезли в профила си, освен + ако не решиш да ги направиш напълно достъпни. Ако се нуждаеш от помощ, за + да отключиш, изоставиш или изтриеш произведение, моля, %{contact_support_link}. + text: В зависимост от архива твоите произведения може да са били добавени + с ограничение за достъп само от регистрирани потребители (за да не се появяват + като резултати при търсене в Гугъл). В този случай тези твои произведения + ще бъдат достъпни само за потребителите, които са влезли в профила си, освен + ако не решиш да ги направиш напълно достъпни. Ако се нуждаеш от помощ, за + да отключиш, изоставиш или изтриеш произведение, моля, свържи се с АО3 Поддръжка + чрез %{support_url}. + email_tips: При връзка с нас, моля, добави имейл адресите от @transformativeworks.org + към твоя списък с безопасни контакти и провери спам папката си за нашия отговор. + introduction: + ao3_name: Archive of Our Own – AO3 (Нашият архив) + html: Получаваш този имейл, защото има твои произведения във фенски архив, + който е бил добавен от %{open_doors_name_link} към %{app_link}. Тъй като + този имейл адрес е свързан с имейла, регистриран в импортирания архив, съответните + фенски произведения (изредени по-долу) са автоматично добавени към твоя + АО3 профил. + open_doors_name: Open Doors (Отворени врати) + text: 'Получаваш този имейл, защото има твои произведения във фенски архив, + който е бил добавен от Open Doors (Отворени врати) (%{open_doors_url}) към + Archive of Our Own – AO3 (Нашият архив): %{app_url}. Тъй като този имейл + адрес е свързан с имейла, регистриран в импортирания архив, съответните + фенски произведения (изредени по-долу) са автоматично добавени към твоя + АО3 профил.' + mistake: + contact_open_doors: свържи се с Отворени врати + html: Ако това е грешка и тези произведения не са твои, моля не ги изтривай! + Моля, %{contact_open_doors_link} и ние ще се погрижим. + text: Ако това е грешка и тези произведения не са твои, моля не ги изтривай! + Моля, свържи се с Отворени врати (%{open_doors_url}) и ние ще се погрижим. + more_info: + ao3_news: АО3 Новини + contact_support: свържи се с АО3 Поддръжка + faq_page: страницата с ЧЗВ + html: Можеш да намериш новини за наскоро преместените архиви в %{ao3_news_link}, + както и да намериш допълнителна информация на %{faq_page_link} или %{tutorial_page_link} + на Отворени врати. Ако не намираш отговор в ЧЗВ, ръководствата или в този + имейл, моля, %{contact_support_link}. + text: Можеш да намериш новини за наскоро преместените архиви в АО3 Новини + (%{news_url}), както и да намериш допълнителна информация на страницата + с ЧЗВ (%{open_doors_faq_url}) или страницата с ръководства (%{open_doors_tutorial_url}) + на Отворени врати. Ако не намираш отговор в ЧЗВ, ръководствата или в този + имейл, моля, свържи се с АО3 Поддръжка чрез %{support_url}. + tutorial_page: страницата с ръководства + other_works: + contact_open_doors: свържи се с Отворени врати + html: Ако в импортирания архив има и други твои произведения, но свързани + с друг имейл, до който вече нямаш достъп, моля, %{contact_open_doors_link}, + като предоставиш всякаква информация, която може да потвърди самоличността + ти. + text: Ако в импортирания архив има и други твои произведения, но свързани + с друг имейл, до който вече нямаш достъп, моля, свържи се с Отворени врати, + като предоставиш всякаква информация, която може да потвърди самоличността + ти. + questions: + contact_support: свържи се с АО3 Поддръжка + html: При други въпроси, моля, %{contact_support_link}. + text: При други въпроси, моля, свържи се с АО3 Поддръжка чрез %{support_url}. + redirects: + html: За да се запазят препоръките и отметките, за кратък период от време + уеб адресите на импортирания архив може да пренасочват към импортираните + копия на тези произведения (провери публикацията със съобщението за твоя + архив). Ако копия на тези произведения вече са били качени от теб и %{negation} + е използвана опцията за импортиране чрез URL, в АО3 ще има две копия на + едно и също произведение. + subject: "[%{app_name}] Качени произведения" + update_redirect: + contact_open_doors: свържи с Отворени врати + html: Ако искаш Отворени врати да промени линковете, така че те да пренасочват + към вече съществуващото ти произведение, моля, изтрий импортираното копие + и се %{contact_open_doors_link}, като споменеш името на твоя АО3 профил, + името на профила ти в импортирания архив, както и заглавието и URL на фен-произведението, + към което искаш да води пренасочващият линк. (Ако искаш да промениш пренасочващите + линкове на няколко произведения, може да ги изредиш в един имейл.) + text: Ако искаш Отворени врати да промени линковете, така че те да пренасочват + към вече съществуващото ти произведение, моля, изтрий импортираното копие + и се свържи с Отворени врати чрез %{open_doors_url}, като споменеш името + на твоя АО3 профил, името на профила ти в импортирания архив, както и заглавието + и URL на фен-произведението, към което искаш да води пренасочващият линк. + (Ако искаш да промениш пренасочващите линкове на няколко произведения, може + да ги изредиш в един имейл.) + works_by: 'Тези произведения са свързани с този имейл: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Всички задачи са изпратени. + subject: Задачите са изпратени + html: + received_message: 'Имаш съобщение във връзка с твоята колекция %{collection_link}:' + text: + received_message: 'Имаш съобщение във връзка с твоята колекция "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Когато си съавтор на произведение, други потребители могат да те + добавят като съавтор и на новите глави, независимо от настройките ти за съавторство. + Това те прави и съавтор на всяка поредица, към която е добавено това произведение. + html: + creation: "%{creation_link} от %{pseud_links}" + edit_chapter: да редактираш главата + edit_series: да редактираш поредицата + remove_chapter: Ако са те добавили по погрешка или не желаеш да фигурираш + като създател, можеш %{edit_chapter_link}, за да премахнеш името си като + създател. + remove_series: Ако са те добавили по погрешка или не желаеш да фигурираш като + създател, можеш %{edit_series_link}, за да премахнеш името си като създател. + intro_chapter: 'Потребителят %{adding_user} е посочил псевдонима ти %{pseud} + като съавтор на следната глава:' + intro_series: 'Потребителят %{adding_user} е посочил псевдонима ти %{pseud} + като съавтор на следната поредица:' + subject: "[%{app_name}] Уведомление за съавторство" + text: + creation: "%{title} (%{url}) от %{pseuds}" + remove_chapter: 'Ако са те добавили по погрешка или не желаеш да фигурираш + като създател, можеш да редактираш главата, за да премахнеш името си като + създател: %{url}' + remove_series: 'Ако са те добавили по погрешка или не желаеш да фигурираш + като създател, можеш да редактираш поредицата, за да премахнеш името си + като създател: %{url}' + creatorship_notification_archivist: + explanation: В качеството си на архивист на Open Doors (Отворени врати), този + потребител има правото да те добавя като съавтор и без заявка, дори ако функцията + за съавторство е изключена в твоите настройки. + html: + creation: "%{creation_link} от %{pseud_links}" + edit_chapter: да редактираш главата + edit_series: да редактираш серията + edit_work: да редактираш произведението + remove_chapter: Ако са те добавили по погрешка или не желаеш да фигурираш + като създател, можеш %{edit_chapter_link}, за да премахнеш името си като + създател. + remove_series: Ако са те добавили по погрешка или не желаеш да фигурираш като + създател, можеш %{edit_series_link}, за да премахнеш името си като създател. + remove_work: Ако са те добавили по погрешка или не желаеш да фигурираш като + създател, можеш %{edit_work_link}, за да премахнеш името си като създател. + intro_chapter: 'Потребителят %{archivist} добави псевдонима ти %{pseud} като + съавтор на следната глава:' + intro_series: 'Потребителят %{archivist} добави псевдонима ти %{pseud} като + съавтор на следната серия:' + intro_work: 'Потребителят %{archivist} добави псевдонима ти %{pseud} като съавтор + на следното произведение:' + subject: "[%{app_name}] Уведомление за съавторство от архивист" + text: + creation: "%{title} (%{url}) от %{pseuds}" + remove_chapter: 'Ако са те добавили по погрешка или не желаеш да фигурираш + като създател, можеш да редактираш главата, за да премахнеш името си като + създател: %{url}' + remove_series: 'Ако са те добавили по погрешка или не желаеш да фигурираш + като създател, можеш да редактираш серията, за да премахнеш името си като + създател: %{url}' + remove_work: 'Ако са те добавили по погрешка или не желаеш да фигурираш като + създател, можеш да редактираш произведението, за да премахнеш името си като + създател: %{url}' + creatorship_request: + html: + creation: "%{creation_link} от %{pseud_links}" + instructions: Можеш да приемеш или откажеш тази покана на твоята страница + %{page_name}. + page_name: Co-Creator Requests (Покани за съавторство) + intro_chapter: 'Имаш покана от потребителя %{inviting_user} да добавиш псевдонима + си %{pseud} като съавтор на следната глава:' + intro_series: 'Имаш покана от потребителя %{inviting_user} да добавиш псевдонима + си %{pseud} като съавтор на следната серия:' + intro_work: 'Имаш покана от потребителя %{inviting_user} да добавиш псевдонима + си %{pseud} като съавтор на следното произведение:' + subject: "[%{app_name}] Покана за съавторство" + text: + creation: "%{title} (%{url}) от %{pseuds}" + instructions: Можеш да приемеш или откажеш тази покана на твоята страница + Co-Creator Requests (Покани за съавторство) %{url} + delete_work_notification: + attachment: Прилагаме копие от произведението ти за информация. + deleted_other: + html: Твоята творба %{title} беше изтрита по заявка на %{pseud}. + text: Твоята творба "%{title}" беше изтрита по заявка на %{pseud}. + deleted_yourself: + html: Твоята творба %{title} беше изтрита по твоя заявка. + text: Твоята творба "%{title}" беше изтрита по твоя заявка. + questions: + html: Ако имаш въпроси, моля, %{support}. + text: Ако имаш въпроси, моля, %{support} (%{url}). + subject: "[%{app_name}] Твоята творба беше изтрита" + support: свържи се с екип Поддръжка + invitation: + been_invited: Имаш покана да се присъединиш към нашия бета проект! + has_invited: "%{user_name} те покани да се присъединиш към нашия бета проект!" + html: + faq_link_text: нашите Често Задавани Въпроси + subject: "[%{app_name}] Покана" + invite_increase_notification: + html: + body: + one: Искаме да те информираме, че имаш %{count} нова покана, която може + да използваш за създаването на нов акаунт в AO3. Можеш да поканиш приятел + през %{invitation_page_link}. + other: Искаме да те информираме, че имаш %{count} нови покани, които може + да използваш за създаването на нови акаунти в AO3. Можеш да поканиш приятел + през %{invitation_page_link}. + invitation_page_link_text: твоята страница Invitations (Покани) + subject: "[%{app_name}] Нови покани" + text: + body: + one: Искаме да те информираме, че имаш %{count} нова покана, която може + да използваш за създаването на нов акаунт в AO3. Можеш да поканиш приятел + през твоята страница Invitations (Покани) (%{invitation_page_url}). + other: Искаме да те информираме, че имаш %{count} нови покани, които може + да използваш за създаването на нови акаунти в AO3. Можеш да поканиш приятел + през твоята страница Invitations (Покани) (%{invitation_page_url}). + invite_request_declined: + main: + one: За съжаление твоето искане за нова покана не може да бъде изпълнено в + този момент. + other: За съжаление твоето искане за %{count} нови покани не може да бъде + изпълнено в този момент. + reason: 'Твоето искане:' + subject: "[%{app_name}] Отхвърлено искане за допълнителен код за покана" + recipient_notification: + html: + collection: Някой е публикувал творба-подарък за теб в колекцията %{collection_link} + в AO3! + no_collection: Някой е публикувал творба-подарък за теб в AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Творба-подарък за теб от %{collection_title}" + no_collection: "[%{app_name}] Творба-подарък за теб" + text: + collection: Някой е публикувал творба-подарък за теб в колекцията "%{collection_title}" + (%{collection_url}) в AO3! diff --git a/config/locales/phrase-exports/bn.yml b/config/locales/phrase-exports/bn.yml new file mode 100755 index 0000000..a1af603 --- /dev/null +++ b/config/locales/phrase-exports/bn.yml @@ -0,0 +1,518 @@ +--- +bn: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'সতর্কীকরণ:' + other: 'সতর্কীকরণ:' + category: + name_with_colon: + one: 'শ্রেণী:' + other: 'শ্রেণী:' + character: + name_with_colon: + one: 'চরিত্র:' + other: 'চরিত্র:' + fandom: + name_with_colon: + one: 'অনুরাগী দল:' + other: 'অনুরাগী দল:' + freeform: + name_with_colon: + one: 'সংযোজিত ট্যাগ:' + other: 'সংযোজিত ট্যাগ:' + rating: + name_with_colon: 'রেটিং:' + relationship: + name_with_colon: + one: 'সম্পর্ক:' + other: 'সম্পর্ক:' + work: + chapter_total_display: অধ্যায় + summary: সারাংশ + models: + archive_warning: + one: সতর্কীকরণ + other: সতর্কীকরণ + category: + one: শ্রেণী + other: শ্রেণী + chapter: + one: অধ্যায় + other: অধ্যায় + character: + one: চরিত্র + other: চরিত্র + fandom: + one: অনুরাগী দল + other: অনুরাগী দল + freeform: + one: সংযোজিত ট্যাগ + other: সংযোজিত ট্যাগ + rating: + one: রেটিং + other: রেটিং + relationship: + one: সম্পর্ক + other: সম্পর্ক + series: + one: সংকলন + other: সংকলন + kudo_mailer: + batch_kudo_notification: + guest: + one: একজন অতিথি + other: "%{count}জন অতিথি" + left_kudos: + html: + one: "%{givers_list} বাহবা (কুডোস) দিয়ে গেছেন %{commentable_link}।" + other: "%{givers_list} বাহবা (কুডোস) দিয়ে গেছেন %{commentable_link}।" + text: + one: "%{givers_list} বাহবা (কুডোস) দিয়ে গেছেন %{commentable_title} (%{commentable_url})।" + other: "%{givers_list} বাহবা (কুডোস) দিয়ে গেছেন %{commentable_title} (%{commentable_url})।" + single_guest: + giver: একজন অতিথি + html: "%{giver} বাহবা (কুডোস) দিয়ে গেছেন %{commentable_link}।" + text: একজন অতিথি %{commentable_title} (%{commentable_url}) বাহবা (কুডোস) দিয়ে + গেছেন। + subject: "[%{app_name}]-তে আপনি বাহবা (কুডোস) পেয়েছেন!" + mailer: + general: + closing: + formal: ধন্যবাদান্তে, + informal: ভালো থাকবেন, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: "%{title}-এর %{position} অধ্যায়" + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} শব্দ" + other: "%{count} শব্দ" + footer: + general: + about: + html: AO3 একটি অনুরাগী চালিত এবং অনুরাগী সমর্থিত সংগ্রহশালা যেটি %{donate_link} + ওপর নির্ভরশীল। + text: 'AO3 একটি অনুরাগী চালিত এবং অনুরাগী সমর্থিত সংগ্রহশালা যেটা আপনার + দানের ওপর নির্ভরশীল: %{donate_url}।' + html: + donate_link_text: আপনার দানের + support_link_text: সাহায্য-র সাথে যোগাযোগ করুন + unwanted_email: + html: এই বার্তাটা যদি আপনি ভুলবশতঃ পেয়ে থাকেন, দয়া করে %{support_link}। + text: এই বার্তাটা যদি আপনি ভুলবশতঃ পেয়ে থাকেন, দয়া করে %{support_url}-তে + সাহায্য'র সাথে যোগাযোগ করুন। + sent_at: "%{sent_at}তে পাঠানো হয়েছে।" + greeting: + formal_html: প্রিয় %{name}, + informal: + addressed_html: নমস্কার, %{name}! + unaddressed: নমস্কার! + introductory: Archive of Our Own – AO3(আমাদের নিজস্ব সংগ্রহশালা) থেকে নমস্কার! + metadata_label_indicator: ":" + signature: + abuse_team: AO3 অপব্যবহার নিবারণ সমিতি + app_short_name: AO3 + open_doors: Open Doors (খোলা দরজা) বিভাগ + parent_org: Organization for Transformative Works – OTW (রূপান্তরাত্মক কর্মের + সংস্থা) + support: AO3 সাহায্য বিভাগ + users: + mailer: + reset_password_instructions: + expiration: আপনি যদি এক সপ্তাহের মধ্যে আপনার পাসওয়ার্ড রিসেট করার জন্য এই + লিঙ্কটি ব্যবহার না করেন, তবে এটির মেয়াদ শেষ হয়ে অকার্যকর হয়ে যাবে, এবং + আপনাকে একটি নতুন লিঙ্ক অনুরোধ করতে হবে৷ + intro: 'কেউ আপনার অ্যাকাউন্টের জন্য একটি পাসওয়ার্ড রিসেট করার অনুরোধ করেছে৷ + আপনার অ্যাকাউন্টের পাসওয়ার্ড পরিবর্তন করার জন্য, নীচের লিঙ্কটি অনুসরণ করে + নতুন পাসওয়ার্ড লিখুন:' + link_title: আমার পাসওয়ার্ড পরিবর্তন করব৷ + subject: "[%{app_name}] নতুন পাসওয়ার্ড সেট করুন" + unrequested: আপনি যদি পাসওয়ার্ড বদল করার জন্য অনুরোধ না করে থাকেন, তাহলে + আপনি এই ইমেলটিকে উপেক্ষা করতে পারেন এবং আপনার পূর্ববর্তী পাসওয়ার্ড কার্যকর + থাকবে৷ + user_mailer: + admin_hidden_work_notification: + access: আপনার কর্ম যতক্ষণ লুকানো আছে, আপনি উপরে দেওয়া লিঙ্কের মাধ্যমে এটি দেখতে + পারবেন, কিন্তু এটি আপনার কর্ম-পৃষ্ঠায় তালিকাভুক্ত হবে না এবং AO3-এর অন্যান্য + ব্যবহারকারীদের জন্য দৃশ্যমান হবে না। + check_email: অনুগ্রহ করে আপনার আপনার ইমেল দেখুন, স্প্যাম ফোল্ডারটাও দেখবেন, + নীতি ও অপব্যবহার নিবারণ সমিতি হয়তো ইতিমধ্যেই আপনার কাজ কেন লুকিয়ে রাখা হয়েছে + তা ব্যাখ্যা করে আপনাকে ইমেল করেছে৷ + contact_abuse: নীতি ও অপব্যবহার নিবারণ সমিতির সঙ্গে যোগাযোগ করুন + html: + help: আপনি যদি অনিশ্চিত হন যে আপনার কর্ম কেন লুকানো হয়েছে, এবং আপনি এই বিষয়ে + আরো খবর না পেয়ে থাকলে, অনুগ্রহ করে সরাসরি %{contact_abuse_link}। + hidden: আপনার কর্ম %{title} নীতি ও অপব্যবহার নিবারণ সমিতি দ্বারা লুকানো হয়েছে + এবং আর সর্বজনীনভাবে দৃশ্যমান নেই। + tos_violation: AO3-র %{tos_link} লঙ্ঘনের কারণে আপনার কর্ম লুকানো হলে সেই লঙ্ঘন + সংশোধন করার জন্য আপনাকে ব্যবস্থা নিতে হবে। পরিষেবা প্রাপ্তির শর্তাবলী মেনে + চলতে ব্যর্থ হলে AO3 থেকে আপনার কর্ম মুছে ফেলা হতে পারে। + subject: "[%{app_name}] আপনার কর্ম নীতি ও অপব্যবহার নিবারণ সমিতি দ্বারা লুকানো + হয়েছে" + text: + help: 'আপনি যদি অনিশ্চিত হন আপনার কর্ম কেন লুকানো হয়েছে, এবং আপনি এই বিষয়ে + আর খবর না পেয়ে থাকেন, তাহলে অনুগ্রহ করে সরাসরি নীতি ও অপব্যবহার নিবারণ + সমিতির সাথে যোগাযোগ করুন: %{contact_abuse_url}।' + hidden: আপনার কর্ম "%{title}" (%{work_url}) নীতি ও অপব্যবহার নিবারণ সমিতির + দ্বারা লুকানো হয়েছে এবং আর সর্বজনীনভাবে দৃশ্যমান নয়৷ + tos_violation: AO3-র %{tos_url} লঙ্ঘনের কারণে আপনার কর্ম লুকানো হয়ে থাকলে + সেই লঙ্ঘন সংশোধন করার জন্য আপনাকে ব্যবস্থা নিতে হবে। পরিষেবা প্রাপ্তির শর্তাবলী + মেনে চলতে ব্যর্থ হলে AO3 থেকে আপনার কর্ম মুছে ফেলা হতে পারে। + tos: পরিষেবা প্রাপ্তির শর্তাবলী + anonymous_or_unrevealed_notification: + anonymous_info: অজ্ঞাতনামা কর্ম সংযোজন (ট্যাগ) এর তালিকায় অন্তর্ভুক্ত হবে, কিন্তু + আপনার কর্মের পাতায় প্রদর্শিত হবে না। কর্মের ভিতরে আপনার ব্যবহারকারী নাম “Anonymous”(অজ্ঞাতনামা)-তে + পরিবর্তিত হবে। + anonymous_unrevealed_info: সংকলন রক্ষণাবেক্ষণকারীরা পরে আপনার কর্ম উদ্ঘাটন করতে + পারেন, কিন্তু এটিকে অজ্ঞাতনামা রাখতে পারেন। যেসব ব্যক্তিরা আপনার কাছে সাবস্ক্রাইব + করবেন, তারা এ বিষয়ে বিজ্ঞপ্তি পাবেন না। উদ্ঘাটন করার পর, আপনার কর্ম সংযোজন + (ট্যাগ) এর তালিকায় অন্তর্ভুক্ত হবে, কিন্তু আপনার কর্মের পাতায় প্রদর্শিত হবে + না। কর্মে ব্যবহারকারী নাম “Anonymous” (অজ্ঞাতনামা)-তে পরিবর্তিত হবে। + changed_status: + anonymous: + html: "%{collection_link}-এর সংকলন রক্ষণাবেক্ষণকারীরা আপনার কর্ম %{work_link} + অজ্ঞাতনামা করেছেন।" + text: '"%{collection_title}" (%{collection_url}) -এর সংকলন রক্ষণাবেক্ষণকারীরা + আপনার কর্ম "%{work_title}" (%{work_url}) অজ্ঞাতনামা করেছেন।' + anonymous_unrevealed: + html: "%{collection_link}-এর সংকলন রক্ষণাবেক্ষণকারীরা আপনার কর্ম %{work_link} + অজ্ঞাতনামা আর অনুদ্ঘাটিত করেছেন।" + text: '"%{collection_title}" (%{collection_url}) -এর সংকলন রক্ষণাবেক্ষণকারীরা + আপনার কর্ম "%{work_title}" (%{work_url}) অজ্ঞাতনামা আর অনুদ্ঘাটিত করেছেন।' + unrevealed: + html: "%{collection_link}-এর সংকলন রক্ষণাবেক্ষণকারীরা আপনার কর্ম %{work_link} + অনুদ্ঘাটিত করেছেন।" + text: '"%{collection_title}" (%{collection_url}) -এর সংকলন রক্ষণাবেক্ষণকারীরা + আপনার কর্ম "%{work_title}" (%{work_url}) অনুদ্ঘাটিত করেছেন।' + collection_items_link_text: Approved Collection Items (সংগ্রহে অনুমোদিত আইটেম) + পাতা + do_not_want: + anonymous: + html: আপনি যদি আপনার কর্মকে অজ্ঞাতনামা করতে অনিচ্ছুক হন, তবে কর্মটি ওই সংকলন + থেকে অপসারণ করার জন্যে অনুগ্রহ করে %{collection_items_link}-তে যান। + text: 'আপনি যদি আপনার কর্ম অজ্ঞাতনামা করতে অনিচ্ছুক হন, তবে কর্মটি এই সংকলন: + %{collection_items_url} থেকে বাদ দিতে অনুগ্রহ করে আপনার Approved Collection + Items (সংগ্রহে অনুমোদিত আইটেম) পাতায় যান।' + anonymous_unrevealed: + html: আপনি যদি আপনার কর্মকে অজ্ঞাতনামা আর অনুদ্ঘাটিত করতে অনিচ্ছুক হন, তবে + কর্মটি ওই সংকলন থেকে অপসারণ করার জন্যে অনুগ্রহ করে %{collection_items_link}-তে + যান। + text: 'আপনি যদি আপনার কর্ম অজ্ঞাতনামা বা অনুদ্ঘাটিত করতে অনিচ্ছুক হন, তবে + কর্মটি এই সংকলন: %{collection_items_url} থেকে বাদ দিতে অনুগ্রহ করে আপনার + Approved Collection Items (সংগ্রহে অনুমোদিত আইটেম) পাতায় যান।' + unrevealed: + html: আপনি যদি আপনার কর্মকে অনুদ্ঘাটিত করতে অনিচ্ছুক হন, তবে কর্মটি ওই সংকলন + থেকে অপসারণ করার জন্যে অনুগ্রহ করে %{collection_items_link}-তে যান। + text: 'আপনি যদি আপনার কর্ম অনুদ্ঘাটিত করতে অনিচ্ছুক হন, তবে কর্মটি এই সংকলন: + %{collection_items_url} থেকে বাদ দিতে অনুগ্রহ করে আপনার Approved Collection + Items (সংগ্রহে অনুমোদিত আইটেম) পাতায় যান।' + faq_link_text: সংকলন প্রা-জি-প্র + more_info: + html: আরো তথ্যের জন্যে, আমাদের %{faq_link} দেখুন। + text: 'আরো তথ্যের জন্যে, আমাদের সংকলন প্রা-জি-প্র: %{faq_url} দেখুন।' + subject: + anonymous: "[%{app_name}] আপনার কর্ম অজ্ঞাতনামা করা হয়েছে" + anonymous_unrevealed: "[%{app_name}] আপনার কর্ম অজ্ঞাতনামা আর অনুদ্ঘাটিত করা + হয়েছে" + unrevealed: "[%{app_name}] আপনার কর্ম অনুদ্ঘাটিত করা হয়েছে" + unrevealed_info: অনুদ্ঘাটিত কর্ম সংযোজন (ট্যাগ) এর তালিকায় বা আপনার কর্মের পাতায় + অন্তর্ভুক্ত হবে না। কেউ এই কর্মের একটি লিঙ্ক অনুসরণ করলে, একটি বিজ্ঞপ্তি পাবে + যে এই কর্মটি বর্তমানে অনুদ্ঘাটিত এবং তারা এর বিষয়বস্তু দেখতে পাবে না। + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (সংগ্রহে অনুমোদিত + আইটেম) পাতা + archivist_notice: সংকলন রক্ষণাবেক্ষণকারীরা তাদের অফিসিয়াল ক্ষমতা থেকে একজন + Open Doors (মুক্ত দ্বার) আর্কাইভিস্ট হিসাবে কাজ করছেন, তাই তারা আপনার কর্মকে + এই সংকলনে যোগ করতে পারেন, আপনি যদি সংকলনের আমন্ত্রণগুলি নিষ্ক্রিয় করে থাকেন, + তাহলেও। আর্কাইভিস্ট শুধুমাত্র একটি সংকলনে একটি কর্ম যোগ করবেন যদি এটি একটি + নিয়ে আসা সংগ্রহশালায় হোস্ট করা হয়। + removal_instructions: + html: আপনি যদি আপনার কর্মকে এই সংকলন থেকে অপসারণ করতে চান, তবে অনুগ্রহ করে + %{approved_items_link}-তে যান। + text: 'আপনি যদি আপনার কর্মকে এই সংকলন থেকে অপসারণ করতে চান, তবে অনুগ্রহ করে + আপনার Approved Collection Items (সংগ্রহে অনুমোদিত আইটেম) পাতায় যান: %{approved_items_url}' + subject: "[%{app_name}][%{collection_title}] একজন Open Doors (মুক্ত দ্বার) আর্কাইভিস্ট + আপনার কর্মকে একটি সংকলনে যোগ করেছে" + work_added: + html: "%{collection_link}-এর সংকলন রক্ষণাবেক্ষণকারীরা আপনার কর্ম %{work_link}-কে + তাদের সংকলনে যোগ করেছে!" + text: '"%{collection_title}" (%{collection_url})-এর সংকলন রক্ষণাবেক্ষণকারীরা + আপনার কর্ম "%{work_title}" (%{work_url})-কে তাদের সংকলনে যোগ করেছে!' + challenge_assignment_notification: + any: যেকোন + assignment: + html: AO3-তে %{link} চ্যালেঞ্জে আপনাকে নিম্নলিখিত সূত্রটি (প্রম্পট) বরাদ্দ + করা হয়েছে! + description: 'বর্ণনা:' + due: 'এই কর্মটি জমা দিতে হবে:' + html: + footer: আপনি এই ইমেলটি পাচ্ছেন কারণ আপনি %{title} চ্যালেঞ্জে যোগদান করছেন। + এই আহ্বান সম্বন্ধে আরো তথ্য এবং নিয়ামকদের সঙ্গে যোগাযোগের তথ্যের জন্যে, + অনুগ্রহ করে %{footer_link}-এ যান। + footer_link: আহ্বান নিয়ন্ত্রণ পাতা + look_up: আপনি %{link} থেকে এই বরাদ্দ কর্মটি দেখতে পারেন। + look_up_link: আপনার Assignments (বরাদ্দ কর্ম)-এর পাতা + optional_tags: 'ঐচ্ছিক সংযোজন:' + prompts: 'সূত্র:' + prompt_url: 'সূত্রের ইউ.আর.এল.:' + recipient: 'প্রাপক:' + recipient_missing: 'কেউ নেই: সাহায্যের জন্যে একজন নিয়ামকের সঙ্গে যোগাযোগ করুন!' + subject: "[%{app_name}][%{collection_title}] আপনার বরাদ্দ কর্ম!" + text: + assignment: AO3-তে "%{collection_title}" (%{collection_url}) চ্যালেঞ্জে আপনাকে + নিম্নলিখিত সূত্রটি বরাদ্দ করা হয়েছে! + footer: আপনি এই ইমেলটি পাচ্ছেন কারণ আপনি %{title} আহ্বানে (%{url}) যোগদান + করছেন। এই আহ্বান সম্বন্ধে আরো তথ্য এবং নিয়ামকদের সঙ্গে যোগাযোগের তথ্যের + জন্যে, অনুগ্রহ করে %{profile_url} যান। + look_up: আপনি এই বরাদ্দ কর্মটি আপনার Assignments (বরাদ্দ কর্ম)-এর পাতাতে এখানে + %{link} দেখতে পারেন। + change_email: + changed: + html: "%{login}, আপনার অ্যাকাউন্টের সাথে সম্পর্কিত ইমেল অ্যাড্রেস %{email}- + টা পরিবর্তন করা হয়েছে" + text: "%{login}, আপনার অ্যাকাউন্টের সাথে সম্পর্কিত ইমেল অ্যাড্রেস %{email}- + টা পরিবর্তন করা হয়েছে" + subject: "[%{app_name}] ইমেল পরিবর্তন করা হয়েছে" + claim_notification: + access: + contact_support: AO3 সহায়তা সমিতির সঙ্গে যোগাযোগ করুন + html: সংগ্রহশালার উপর ভিত্তি করে আপনার কর্ম শুধুমাত্র নিবন্ধিত (রেজিস্টার্ড) + ব্যবহারকারীদের দ্বারা প্রদর্শন যোগ্য হতে পারে (এটি সংগ্রহশালার কর্মগুলিকে + গুগুল সার্চের থেকে সরিয়ে রাখতে করা হয়)। এক্ষেত্রে, আপনি যদি আলাদা করে আপনার + কর্মগুলি সর্বসাধারণের কাছে প্রদর্শিত না করেন, তবে কর্মগুলি শুধুমাত্র লগড-ইন + ব্যবহারকারিকারীদের দ্বারা প্রদর্শিত হবে। আপনার কর্ম সর্বসাধারণ দ্বারা প্রদর্শন + যোগ্য করতে, কর্ম অনাথ করতে, বা কর্ম অপসারণ করতে অনুগ্রহ করে %{contact_support_link}। + text: সংগ্রহশালার উপর ভিত্তি করে আপনার কর্ম শুধুমাত্র নিবন্ধিত (রেজিস্টার্ড) + ব্যবহারকারীদের দ্বারা প্রদর্শন যোগ্য হতে পারে (এটি সংগ্রহশালার কর্মগুলিকে + গুগুল সার্চের থেকে সরিয়ে রাখতে করা হয়)। এক্ষেত্রে, আপনি যদি আলাদা করে আপনার + কর্মগুলি সর্বসাধারণের কাছে প্রদর্শিত না করেন, তবে কর্মগুলি শুধুমাত্র লগড-ইন + ব্যবহারকারিকারীদের দ্বারা প্রদর্শিত হবে। আপনার কর্ম সর্বসাধারণ দ্বারা প্রদর্শন + যোগ্য করতে, কর্ম অনাথ করতে, বা কর্ম অপসারণ করতে অনুগ্রহ করে AO3 সহায়তা সমিতির + সঙ্গে যোগাযোগ করুন - %{support_url}। + email_tips: আপনি যদি আমাদের সাথে যোগাযোগ করেন তাহলে অনুগ্রহ করে @transformativeworks.org + এর ইমেল অ্যাড্রেসগুলি আপনার নিরাপদ অ্যাড্রেসের তালিকায় যোগ করবেন, এবং আমাদের + উত্তরটি আপনার স্প্যাম ফোল্ডারেও খুঁজে দেখবেন। + introduction: + ao3_name: Archive of Our Own – AO3 (আমাদের নিজস্ব সংগ্রহশালা) + html: আপনি এই ইমেলটি পেয়েছেন কারণ %{open_doors_name_link} সমিতির দ্বারা %{app_link}-তে + ইমপোর্ট করে আনা একটি অনুরাগী সংগ্রহশালাতে আপনার কিছু অনুরাগীকর্ম ছিল। যেহেতু + এই ইমেল অ্যাড্রেস ইমপোর্ট করে আনা সংগ্রহশালাটিতে নিবন্ধন ছিল, তাই সংগ্রহশালাটিতে + এই ইমেলের সঙ্গে সংযুক্ত থাকা সমস্ত কর্ম (নিচে তালিকাভুক্ত) আপনার AO3 অ্যাকাউন্টে + যোগ করা হয়েছে। + open_doors_name: Open Doors (মুক্ত দ্বার) + text: আপনি এই ইমেলটি পেয়েছেন কারণ Open Doors (মুক্ত দ্বার সমিতি) (%{open_doors_url}) + দ্বারা Archive of Our Own – AO3 (আমাদের নিজস্ব সংগ্রহশালা)-তে %{app_url} + ইমপোর্ট করে আনা একটি অনুরাগী সংগ্রহশালাতে আপনার কিছু অনুরাগীকর্ম ছিল। যেহেতু + এই ইমেল অ্যাড্রেস ইমপোর্ট করে আনা সংগ্রহশালাটিতে নিবন্ধন ছিল, তাই সংগ্রহশালাটিতে + এই ইমেলের সঙ্গে সংযুক্ত থাকা সমস্ত কর্ম (নিচে তালিকাভুক্ত) আপনার AO3 অ্যাকাউন্টে + যোগ করা হয়েছে। + mistake: + contact_open_doors: মুক্ত দ্বারের সঙ্গে যোগাযোগ করুন + html: এখানে যদি কোন ভুল হয়ে থাকে এবং এই কর্মগুলি আপনার না হয়, তবে অনুগ্রহ + করে এগুলো অপসারণ (ডিলিট) করবেন না! দয়া করে %{contact_open_doors_link}, তাহলে + আমরা এই ব্যাপারটি দেখে ঠিক করে নেব। + text: এখানে যদি কোন ভুল হয়ে থাকে এবং এই কর্মগুলি আপনার না হয়, তবে অনুগ্রহ + করে এগুলো অপসারণ (ডিলিট) করবেন না! দয়া করে মুক্ত দ্বারের সঙ্গে যোগাযোগ করুন + (%{open_doors_url}), তাহলে আমরা এই ব্যাপারটি দেখে ঠিক করে নেব। + more_info: + ao3_news: AO3 সংবাদ + contact_support: AO3 সহায়তা সমিতির সঙ্গে যোগাযোগ করুন + faq_page: প্র-জি-প্র (FAQ) পাতা + html: সাম্প্রতিক সংগ্রহশালা ইমপোর্ট বিষয়ক ঘোষণা আপনি %{ao3_news_link}-এ পড়তে + পারেন, এবং এ বিষয়ে আরো তথ্যে মুক্ত দ্বারের %{faq_page_link} অথবা %{tutorial_page_link} + পাবেন। অন্য যেকোন প্রশ্ন যার উত্তর প্র-জি-প্র, পাঠগুলিতে, বা এই ইমেলে নেই, + সে বিষয়ে উত্তরের জন্য অনুগ্রহ করে %{contact_support_link}। + text: সাম্প্রতিক সংগ্রহশালা ইমপোর্ট বিষয়ক ঘোষণা আপনি AO3 সংবাদে (%{news_url}) + পড়তে পারেন, এবং এ বিষয়ে আরো তথ্যে মুক্ত দ্বারের প্র-জি-প্র পাতাতে (%{open_doors_faq_url}) + অথবা পাঠ (টিউটোরিয়াল) (%{open_doors_tutorial_url}) পাতাতে পাবেন। অন্য যেকোন + প্রশ্ন যার উত্তর প্র-জি-প্র, পাঠগুলিতে, বা এই ইমেলে নেই, সে বিষয়ে উত্তরের + জন্য অনুগ্রহ করে সহায়তা সমতির সঙ্গে যোগাযোগ করুন - %{support_url}। + tutorial_page: পাঠ (টিউটোরিয়াল) পাতা + other_works: + contact_open_doors: মুক্ত দ্বারের সঙ্গে যোগাযোগ করুন + html: ইমপোর্ট করে আনা সংগ্রহশালাতে আপনার যদি অন্য কোন কর্ম সংযুক্ত হয়ে থাকে + এমন একটি ইমেল অ্যাড্রেসের সঙ্গে যেটিতে আপনি বর্তমানে প্রবেশ করতে অক্ষম, + তাহলে অনুগ্রহ করে যেকোন তথ্য যা আপনার পরিচয় নিশ্চিত করতে পারবে, তা নিয়ে + %{contact_open_doors_link}। + text: ইমপোর্ট করে আনা সংগ্রহশালাতে আপনার যদি অন্য কোন কর্ম সংযুক্ত হয়ে থাকে + এমন একটি ইমেল অ্যাড্রেসের সঙ্গে যেটিতে আপনি বর্তমানে প্রবেশ করতে অক্ষম, + তাহলে অনুগ্রহ করে যেকোন তথ্য যা আপনার পরিচয় নিশ্চিত করতে পারবে তা নিয়ে + মুক্ত দ্বারের সঙ্গে যোগাযোগ করুন। + questions: + contact_support: AO3 সহায়তা সমিতির সঙ্গে যোগাযোগ করুন + html: আরো তথ্যের জন্য অনুগ্রহ করে %{contact_support_link}। + text: আরো তথ্যের জন্য অনুগ্রহ করে AO3 সহায়তা সমিতির সঙ্গে যোগাযোগ করুন - %{support_url}। + redirects: + html: রেক তালিকা এবং পুস্তকচিহ্ন সংরক্ষণ করার জন্য, ইমপোর্ট করে আনা সংগ্রহশালার + ওয়েব অ্যাড্রেসগুলি কিছু সময়ের জন্য সেই অনুরাগীকর্মের ইমপোর্ট করে আনা প্রতিলিপিতে + রিডিরেক্ট করতে পারে (এ বিষয়ে তথ্যের জন্যে আপনার সংগ্রহশালা সম্বন্ধীয় ঘোষণার + প্রকাশনটি পরে দেখুন)। আপনি যদি এই কর্মগুলির একটি প্রতিলিপি এর আগেই আপলোড + করে থাকেন ও যদি 'URL দ্বারা করে ইমপোর্ট করুন' ব্যবহার %{negation} করে থাকেন + , তবে AO3-তে একই কর্মের দুটি প্রতিলিপি থেকে যাবে। + subject: "[%{app_name}] কর্ম আপলোড হয়েছে" + update_redirect: + contact_open_doors: মুক্ত দ্বারের সঙ্গে যোগাযোগ করুন + html: আপনি যদি চান যে মুক্ত দ্বার এই রিডাইরেক্টটি আপনার আগে প্রকাশিত অনুরাগীকর্মের + সঙ্গে যুক্ত করুক, তাহলে অনুগ্রহ করে কর্মটির ইমপোর্ট করে আনা প্রতিলিপিটি + অপসারণ করুন, এবং আপনার AO3 অ্যাকাউন্ট এর নাম, ইমপোর্ট করে আনা সংগ্রহশালাটিতে + আপনার অ্যাকাউন্ট এর নাম, আর যে অনুরাগীকর্মে আপনি এই রিডাইরেক্টটি কার্যকর + করতে চান সেটির URL নিয়ে %{contact_open_doors_link}। (আপনার যদি একাধিক কর্ম + থাকে যেগুলির রিডাইরেক্টগুলি আপনি পরিবর্তন করতে চান, তাহলে সেই সব কর্মগুলি + আপনি একটি ইমেলেই তালিকা করে লিখে দিতে পারেন।) + text: আপনি যদি চান যে মুক্ত দ্বার এই রিডাইরেক্টটি আপনার আগে প্রকাশিত অনুরাগীকর্মের + সঙ্গে যুক্ত করুক, তাহলে অনুগ্রহ করে কর্মটির ইমপোর্ট করে আনা প্রতিলিপিটি + অপসারণ করুন, এবং আপনার AO3 অ্যাকাউন্ট এর নাম, ইমপোর্ট করে আনা সংগ্রহশালাটিতে + আপনার অ্যাকাউন্ট এর নাম, আর যে অনুরাগীকর্মে আপনি এই রিডাইরেক্টটি কার্যকর + করতে চান সেটির URL নিয়ে মুক্ত দ্বারের সঙ্গে যোগাযোগ করুন - %{open_doors_url}। + (আপনার যদি একাধিক কর্ম থাকে যেগুলির রিডাইরেক্টগুলি আপনি পরিবর্তন করতে চান, + তাহলে সেই সব কর্মগুলি আপনি একটি ইমেলেই তালিকা করে লিখে দিতে পারেন।) + works_by: 'এই কর্মগুলি এই ইমেলের সঙ্গে সংযুক্তিতে লেখা হয়েছিল: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: সব অ্যাসাইনমেন্ট পাঠানো হয়ে গেছে। + subject: অ্যাসাইনমেন্ট পাঠানো হয়েছে + html: + received_message: 'আপনার সংগ্রহ সম্পর্কে আপনি একটি বার্তা পেয়েছেন %{collection_link}:' + text: + received_message: 'আপনার সংগ্রহ সম্পর্কে আপনি একটি বার্তা পেয়েছেন "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: আপনি যখন একটা কর্মের সহ-স্রষ্টা হন, আপনি আপনার সহ-সৃষ্টি সেটিং + এ যাই থাক না কেন, আপনি নতুন অধ্যায়ে যুক্ত হতে পারেন। কোনো সিরিজে কর্মটা যুক্ত + হলে আপনিও সেই সিরিজে যুক্ত হবেন। + html: + creation: "%{pseud_links} দ্বারা %{creation_link}" + edit_chapter: অধ্যায় সম্পাদন করুন + edit_series: সিরিজটা সম্পাদন করুন + remove_chapter: আপনাকে যদি ভুলবশতঃ যোগ করা হয়ে থাকে বা আপনি স্রষ্টা হিসেবে + তালিকাভুক্ত হতে না চান, আপনি %{edit_chapter_link} স্রষ্টা তালিকা থেকে নিজেকে + সরিয়ে ফেলতে পারেন। + remove_series: আপনাকে যদি ভুলবশতঃ যোগ করা হয়ে থাকে বা আপনি স্রষ্টা হিসেবে + তালিকাভুক্ত হতে না চান, আপনি %{edit_series_link} স্রষ্টা তালিকা থেকে নিজেকে + সরিয়ে ফেলতে পারেন। + intro_chapter: 'ব্যবহারকারী %{adding_user} আপনার ছদ্মনাম %{pseud} নিম্নোক্ত + অধ্যায়ের জন্য সহ-স্রষ্টা হিসেবে তালিকাভুক্ত করেছেন:' + intro_series: 'ব্যবহারকারী %{adding_user} আপনার ছদ্মনাম %{pseud} নিম্নোক্ত সিরিজের + জন্য সহ-স্রষ্টা হিসেবে তালিকাভুক্ত করেছেন:' + subject: "[%{app_name}] সহ-স্রষ্টার বিজ্ঞপ্তি" + text: + creation: "%{pseuds} দ্বারা %{title} (%{url})" + remove_chapter: 'আপনাকে যদি ভুলবশতঃ যোগ করা হয়ে থাকে বা আপনি স্রষ্টা হিসেবে + তালিকাভুক্ত হতে না চান, আপনি অধ্যায়টা সম্পাদন করে স্রষ্টা তালিকা থেকে নিজেকে + সরিয়ে ফেলতে পারেন: %{url}' + remove_series: 'আপনাকে যদি ভুলবশতঃ যোগ করা হয়ে থাকে বা আপনি স্রষ্টা হিসেবে + তালিকাভুক্ত হতে না চান, আপনি সিরিজটা সম্পাদন করে স্রষ্টা তালিকা থেকে নিজেকে + সরিয়ে ফেলতে পারেন: %{url}' + creatorship_notification_archivist: + explanation: যেহেতু তারা তাদের অফিসিয়াল ক্ষমতা থেকে, একজন Open Doors (খোলা + দরজা) আর্কাইভিস্ট হিসাবে কাজ করছেন, তারা আপনাকে অনুরোধ ছাড়াই যোগ করতে পারেন, + আপনি যদি সহ-সৃষ্টি নিষ্ক্রিয় করে থাকেন তাহলেও। + html: + creation: "%{pseud_links} দ্বারা %{creation_link}" + edit_chapter: অধ্যায় সম্পাদনা + edit_series: সিরিজ সম্পাদনা + edit_work: কাজ সম্পাদনা + remove_chapter: আপনি যদি ভুল করে যুক্ত হয়ে থাকেন বা একজন স্রষ্টা হিসেবে তালিকাভুক্ত + হতে না চান, তাহলে আপনি নিজেকে স্রষ্টা হিসেবে অপসারিত %{edit_chapter_link} + করতে পারেন। + remove_series: আপনি যদি ভুল করে যুক্ত হয়ে থাকেন বা একজন স্রষ্টা হিসেবে তালিকাভুক্ত + হতে না চান, তাহলে আপনি নিজেকে স্রষ্টা হিসেবে অপসারিত %{edit_series_link} + করতে পারেন। + remove_work: আপনি যদি ভুল করে যুক্ত হয়ে থাকেন বা একজন স্রষ্টা হিসেবে তালিকাভুক্ত + হতে চান না , তাহলে আপনি নিজেকে স্রষ্টাহিসেবে অপসারিত %{edit_work_link} করতে + পারেন। + intro_chapter: 'ব্যবহারকারী %{archivist} নিম্নলিখিত অধ্যায় সহ-স্রষ্টা হিসাবে + আপনার ছদ্মনাম %{pseud} যুক্ত করেছেন:' + intro_series: 'ব্যবহারকারী %{archivist} নিম্নলিখিত সিরিজে সহ-স্রষ্টা হিসাবে + আপনার ছদ্মনাম %{pseud} যুক্ত করেছেন:' + intro_work: 'ব্যবহারকারী %{archivist} নিম্নলিখিত কাজের সহ-স্রষ্টা হিসাবে আপনার + ছদ্মনাম %{pseud} যুক্ত করেছেন:' + subject: "[%{app_name}] আর্কাইভিস্ট সহ-স্রষ্টা বিজ্ঞপ্তি" + text: + creation: "%{pseuds} দ্বারা %{title} (%{url})" + remove_chapter: 'আপনি যদি ভুল করে যুক্ত হয়ে থাকেন বা একজন স্রষ্টা হিসেবে + তালিকাভুক্ত হতে না চান, তাহলে আপনি নিজেকে স্রষ্টা হিসেবে অপসারিত করার জন্য + অধ্যায় সম্পাদনা করতে পারেন: %{url}' + remove_series: 'আপনি যদি ভুল করে যুক্ত হয়ে থাকেন বা একজন স্রষ্টা হিসেবে তালিকাভুক্ত + হতে না চান, তাহলে আপনি নিজেকে স্রষ্টা হিসেবে সরিয়ে দিতে সিরিজ সম্পাদনা + করতে পারেন: %{url}' + remove_work: 'আপনি যদি ভুল করে যুক্ত হয়ে থাকেন বা একজন স্রষ্টা হিসেবে তালিকাভুক্ত + হতে না চান, তাহলে আপনি নিজেকে স্রষ্টা হিসেবে সরিয়ে দিতে কাজ সম্পাদনা করতে + পারেন: %{url}' + creatorship_request: + html: + creation: "%{pseud_links} দ্বারা %{creation_link}" + instructions: আপনি আপনার %{page_name} পৃষ্ঠায় এই অনুরোধ গ্রহণ বা প্রত্যাখ্যান + করতে পারেন। + page_name: Co-Creator Requests (সহ-নির্মাতা আমন্ত্রণ) + intro_chapter: 'ব্যবহারকারী %{inviting_user} আপনার ছদ্মনাম %{pseud}-কে নিম্নলিখিত + অধ্যায়ের সহ-নির্মাতা হিসাবে তালিকাভুক্ত করার জন্য আমন্ত্রণ জানিয়েছেন:' + intro_series: 'ব্যবহারকারী %{inviting_user} আপনার ছদ্মনাম %{pseud}-কে নিম্নলিখিত + সিরিজের সহ-নির্মাতা হিসাবে তালিকাভুক্ত করার জন্য আমন্ত্রণ জানিয়েছেন:' + intro_work: 'ব্যবহারকারী %{inviting_user} আপনার ছদ্মনামকে %{pseud} নিম্নলিখিত + কাজের সহ-নির্মাতা হিসাবে তালিকাভুক্ত করার জন্য আমন্ত্রণ জানিয়েছেন:' + subject: "[%{app_name}] সহ-নির্মাতা আমন্ত্রণ" + text: + creation: "%{pseuds} দ্বারা %{title} (%{url})" + instructions: 'আপনি আপনার Co-Creator Requests (সহ-নির্মাতা আমন্ত্রণ) পৃষ্ঠায় + এই অনুরোধ গ্রহণ বা প্রত্যাখ্যান করতে পারেন: %{url}' + delete_work_notification: + attachment: আপনার কর্মের একটা প্রতিলিপি এই ইমেলের সাথে আপনার তথ্যের জন্য যুক্ত + করা আছে। + deleted_other: + html: আপনার কর্ম %{title} %{pseud} এর অনুরোধে বিনষ্ট (ডিলিট) করা হয়েছে। + text: আপনার কর্ম "%{title}" %{pseud} এর অনুরোধে বিনষ্ট (ডিলিট) করা হয়েছে। + deleted_yourself: + html: আপনার কর্ম %{title} আপনারই অনুরোধে বিনষ্ট (ডিলিট) করা হয়েছে। + text: আপনার কর্ম "%{title}" আপনারই অনুরোধে বিনষ্ট (ডিলিট) করা হয়েছে। + questions: + html: আপনার যদি কোনো প্রশ্ন থাকে, দয়া করে %{support}। + text: আপনার যদি কোনো প্রশ্ন থাকে, দয়া করে %{support} (%{url})। + subject: "[%{app_name}] আপনার কর্ম বিনষ্ট (ডিলিট) করা হয়েছে।" + support: সহায়তা সমিতির সঙ্গে যোগাযোগ করুন। + invite_increase_notification: + html: + body: + one: আমরা আপনাকে জানাতে চাই যে আপনার কাছে %{count}টা নতুন আমন্ত্রণ রয়েছে, + যা ব্যবহার করে AO3তে একটা নতুন অ্যাকাউন্ট তৈরি করা যাবে৷ আপনি %{invitation_page_link}তে + একজন বন্ধুকে আমন্ত্রণ জানাতে পারেন৷ + other: আমরা আপনাকে জানাতে চাই যে আপনার কাছে %{count}টি নতুন আমন্ত্রণ রয়েছে, + যেগুলি ব্যবহার করে AO3তে নতুন অ্যাকাউন্ট তৈরি করা যাবে৷ আপনি %{invitation_page_link}তে + একজন বন্ধুকে আমন্ত্রণ জানাতে পারেন৷ + invitation_page_link_text: আপনার Invitations (আমন্ত্রণ) পৃষ্ঠা + subject: "[%{app_name}] নতুন আমন্ত্রণ" + text: + body: + one: আমরা আপনাকে জানাতে চাই যে আপনার কাছে %{count}টা নতুন আমন্ত্রণ রয়েছে, + যা ব্যবহার করে AO3তে একটা নতুন অ্যাকাউন্ট তৈরি করা যাবে৷ আপনি (%{invitation_page_url})তে + একজন বন্ধুকে আমন্ত্রণ জানাতে পারেন৷ + other: আমরা আপনাকে জানাতে চাই যে আপনার কাছে %{count}টি নতুন আমন্ত্রণ রয়েছে, + যেগুলি ব্যবহার করে AO3তে নতুন অ্যাকাউন্ট তৈরি করা যাবে৷ আপনি (%{invitation_page_url})তে + একজন বন্ধুকে আমন্ত্রণ জানাতে পারেন৷ + invite_request_declined: + main: + one: আমরা দুঃখিত যে আপনার নতুন নিমন্ত্রনপত্রের জন্যে অনুরোধ এই সময় পূরণ করা + সম্ভব নয়। + other: আমরা দুঃখিত যে আপনার %{count}-টি নতুন নিমন্ত্রনপত্রের জন্যে অনুরোধ + এই সময় পূরণ করা সম্ভব নয়। + reason: 'আপনার অনুরোধ ছিল:' + subject: "[%{app_name}] সংযোজিত নিমন্ত্রণপত্রের অনুরোধ প্রত্যাখ্যান করা হয়েছে" + recipient_notification: + html: + collection: AO3–তে %{collection_link} সংকলনে আপনার জন্য একটি উপহার কর্ম প্রকাশ + করা হয়েছে! + no_collection: AO3-তে আপনার জন্য একটি উপহার কর্ম প্রকাশিত হয়েছে! + subject: + collection: "[%{app_name}][%{collection_title}] আপনার জন্য %{collection_title} + থেকে একটি উপহার কর্ম" + no_collection: "[%{app_name}] আপনার জন্য একটি উপহার কর্ম" + text: + collection: আপনার জন্য একটি উপহার কর্ম (%{collection_url}) AO3-তে "%{collection_title}" + সংকলনে প্রকাশ করা হয়েছে! diff --git a/config/locales/phrase-exports/ca.yml b/config/locales/phrase-exports/ca.yml new file mode 100755 index 0000000..1e677e3 --- /dev/null +++ b/config/locales/phrase-exports/ca.yml @@ -0,0 +1,628 @@ +--- +ca: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Advertiment:' + other: 'Advertiments:' + category: + name_with_colon: + one: 'Categoria:' + other: 'Categories:' + character: + name_with_colon: + one: 'Personatge:' + other: 'Personatges:' + fandom: + name_with_colon: + one: 'Fàndom:' + other: 'Fàndoms:' + freeform: + name_with_colon: + one: 'Etiqueta addicional:' + other: 'Etiquetes addicionals:' + rating: + name_with_colon: 'Classificació:' + relationship: + name_with_colon: + one: 'Relació:' + other: 'Relacions:' + work: + chapter_total_display: Capítols + summary: Resum + models: + archive_warning: + one: Advertiment + other: Advertiments + category: + one: Categoria + other: Categories + chapter: + one: Capítol + other: Capítols + character: + one: Personatge + other: Personatges + fandom: + one: Fàndom + other: Fàndoms + freeform: + one: Etiqueta addicional + other: Etiquetes addicionals + rating: + one: Classificació + other: Classificacions + relationship: + one: Relació + other: Relacions + series: + one: Sèrie + other: Sèries + kudo_mailer: + batch_kudo_notification: + guest: + one: 1 convidat/da + other: "%{count} convidats/des" + left_kudos: + html: + one: "%{givers_list} ha deixat kudos a %{commentable_link}." + other: "%{givers_list} han deixat kudos a %{commentable_link}." + text: + one: "%{givers_list} ha deixat kudos a %{commentable_title} (%{commentable_url})." + other: "%{givers_list} han deixat kudos a %{commentable_title} (%{commentable_url})." + single_guest: + giver: Un/a convidat/da + html: "%{giver} ha deixat kudos a %{commentable_link}." + text: Un/a convidat/da ha deixat kudos a %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] T'han deixat kudos!" + mailer: + general: + closing: + formal: Cordialment, + informal: Salutacions, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Capítol %{position} de %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} paraula" + other: "%{count} paraules" + footer: + general: + about: + html: L'AO3 és un arxiu gestionat i mantingut per fans que sobreviu gràcies + a %{donate_link}. + text: 'L''AO3 és un arxiu gestionat i mantingut per fans que sobreviu + gràcies a les vostres donacions: %{donate_url}.' + html: + donate_link_text: les vostres donacions + support_link_text: contacta amb Suport + unwanted_email: + html: Si has rebut aquest missatge per error, %{support_link}. + text: Si has rebut aquest missatge per error, contacta amb Suport a %{support_url}. + sent_at: Enviat el %{sent_at}. + greeting: + formal_html: Estimat/da %{name}, + informal: + addressed_html: Hola, %{name}! + unaddressed: Hola! + introductory: Hola de part de l'Archive of Our Own – AO3 (Un Arxiu Propi)! + metadata_label_indicator: ":" + signature: + abuse_team: L'equip de Polítiques i Prevenció de l'Abús d'AO3 + app_short_name: AO3 + open_doors: L'equip d'Open Doors (Projecte de Portes Obertes) + parent_org: Organization for Transformative Works – OTW (Organització per + a les Obres Transformatives) + support: L'equip de Suport de l'AO3 + users: + mailer: + reset_password_instructions: + expiration: Si no fas servir l'enllaç per canviar la teva contrasenya en una + setmana, aquest expirarà, i n'hauràs de sol·licitar un de nou. + intro: 'Algú ha sol·licitat un canvi de contrasenya pel teu compte. Pots canviar + la contrasenya associada al teu compte clicant a l''enllaç a continuació + i introduïnt la teva nova contrasenya:' + link_title: Canvia la meva contrasenya. + subject: "[%{app_name}] Canvia la teva contrasenya" + unrequested: Si no has sol·licitat un canvi de contrasenya, pots ignorar aquest + correu electrònic i la teva contrasenya anterior continuarà funcionant. + user_mailer: + admin_deleted_work_notification: + bye: S'adjunta una còpia de la teva obra com a referència. + contact_abuse: el Comitè de Polítiques i Prevenció de l'Abús + deleted: + html: La teva obra %{title} ha estat eliminada de l'AO3 per un/a administrador/a + del lloc web. + text: La teva obra "%{title}" ha estat eliminada de l'AO3 per un/a administrador/a + del lloc web. + html: + tos_violation: Si és possible que la teva obra hagi violat els Termes i condicions + de servei de l'AO3, posa't en contacte amb %{contact_abuse_link}. + import_project: + html: Si la teva obra formava part d'un projecte importat per l'equip d'Open + Doors (Projecte de Portes Obertes), contacta amb %{opendoors_link} si tens + qualsevol altra pregunta. + text: Si la teva obra formava part d'un projecte importat per l'equip d'Open + Doors (Projecte de Portes Obertes), contacta amb Open Doors (%{opendoors_link}) + si tens qualsevol altra pregunta. + opendoors: Open Doors + subject: "[%{app_name}] La teva obra ha estat eliminada per un/a administrador/a" + text: + tos_violation: Si és possible que la teva obra violés els Termes i condicions + de servei de l'AO3, posa't en contacte amb el Comitè de Polítiques i Prevenció + de l'Abús (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Mentre la teva obra estigui oculta, podràs seguir accedint-hi mitjançant + l'enllaç proporcionat a dalt, però ja no estarà llistada a la teva pàgina + d'obres i ja no estarà disponible per als altres usuaris/àries de l'AO3. + check_email: Revisa el teu correu electrònic, inclosa la teva carpeta de correu + brossa, ja que és possible que l'equip de Polítiques i Prevenció de l'Abús + d'AO3 ja s'hagi posat en contacte amb tu per explicar-te per què s'ha ocultat + la teva obra. + contact_abuse: contacta amb Polítiques i Prevenció de l'Abús d'AO3 + html: + help: Si no tens clar per què ha estat ocultada la teva obra i no has rebut + cap comunicació al respecte, %{contact_abuse_link} directament. + hidden: La teva obra %{title} ha estat ocultada per l'equip de Polítiques + i Prevenció de l'Abús d'AO3 i ja no és d'accés públic. + tos_violation: Si la teva obra ha estat ocultada degut a una violació dels + %{tos_link} de l'AO3, hauràs d'emprendre les mesures exigides per corregir + la infracció. L'incompliment dels Termes i condicions de servei pot comportar + que la teva obra sigui eliminada de l'AO3. + subject: "[%{app_name}] La teva obra ha estat ocultada per l'equip de Polítiques + i Prevenció de l'Abús d'AO3" + text: + help: 'Si no tens clar per què ha estat ocultada la teva obra i no has rebut + cap comunicació al respecte, contacta amb Polítiques i Prevenció de l''Abús + d''AO3 directament: %{contact_abuse_url}' + hidden: La teva obra "%{title}" (%{work_url}) ha estat ocultada per l'equip + de Polítiques i Prevenció de l'Abús d'AO3 i ja no és d'accés públic. + tos_violation: Si la teva obra ha estat ocultada degut a una violació dels + Termes i condicions de servei (%{tos_url}) de l'AO3, hauràs d'emprendre + les mesures exigides per corregir la infracció. L'incompliment dels Termes + i condicions de servei pot comportar que la teva obra sigui eliminada de + l'AO3. + tos: Termes i condicions de servei + anonymous_or_unrevealed_notification: + anonymous_info: Les obres anònimes s'inclouen a les llistes d'etiquetes però + no a la pàgina de les teves obres. Dins l'obra, el teu nom d'usuària o usuari + quedarà substituït per "Anonymous" (Anònim/a). + anonymous_unrevealed_info: Més endavant, els encarregats de la col·lecció poden + tornar a mostrar la teva obra però deixar-la com a anònima. La gent que tens + subscrita no serà notificada d'aquest canvi. Una vegada revelada, la teva + obra quedarà inclosa a les llistes d'etiquetes però no a la teva pàgina d'obres. + Dins l'obra, el teu nom d'usuària o usuari quedarà substituït per "Anonymous" + (Anònim/a). + changed_status: + anonymous: + html: Les persones encarregades de la col·lecció %{collection_link} han + canviat la condició de la teva obra %{work_link} a anònima. + text: Les persones encarregades de la col·lecció "%{collection_title}" (%{collection_url}) + han canviat l'estat de la teva obra "%{work_title}" (%{work_url}) a anònima. + anonymous_unrevealed: + html: Les persones encarregades de la col·lecció %{collection_link} han + canviat l'estat de la teva obra %{work_link} a anònima i oculta. + text: Les persones encarregades de la col·lecció "%{collection_title}" (%{collection_url}) + han canviat l'estat de la teva obra "%{work_title}" (%{work_url}) a anònima + i oculta. + unrevealed: + html: Les persones encarregades de la col·lecció %{collection_link} han + canviat l'estat de la teva obra %{work_link} a oculta. + text: Les persones encarregades de la col·lecció "%{collection_title}" (%{collection_url}) + han canviat l'estat de la teva obra "%{work_title}" (%{work_url}) a oculta. + collection_items_link_text: Pàgina d'Approved Collection Items (Elements aprovats + de la col·lecció) + do_not_want: + anonymous: + html: Si no vols que la teva obra sigui anònima, visita la %{collection_items_link} + per eliminar-la d'aquesta col·lecció. + text: 'Si no vols que la teva obra sigui anònima, visita la pàgina d''Approved + Collection Items (Elements aprovats de la col·lecció) per eliminar-la + d''aquesta col·lecció: %{collection_items_url}' + anonymous_unrevealed: + html: Si no vols que la teva obra sigui anònima ni oculta, visita la %{collection_items_link} + per eliminar-la d'aquesta col·lecció. + text: 'Si no vols que la teva obra sigui anònima ni oculta, visita la pàgina + d''Approved Collection Items (Elements aprovats de la col·lecció) per + eliminar-la d''aquesta col·lecció: %{collection_items_url}' + unrevealed: + html: Si no vols que la teva obra sigui oculta, visita la %{collection_items_link} + per eliminar-la d'aquesta col·lecció. + text: 'Si no vols que la teva obra sigui oculta, visita la pàgina d''Approved + Collection Items (Elements aprovats de la col·lecció) per eliminar-la + d''aquesta col·lecció: %{collection_items_url}' + faq_link_text: Preguntes freqüents sobre col·leccions + more_info: + html: Per a més informació, visita les %{faq_link}. + text: 'Per a més informació, consulta les Preguntes freqüents sobre Col·leccions: + %{faq_url}' + subject: + anonymous: "[%{app_name}] La teva obra s'ha canviat a anònima" + anonymous_unrevealed: "[%{app_name}] La teva obra s'ha canviat a anònima i + oculta" + unrevealed: "[%{app_name}] La teva obra s'ha canviat a oculta" + unrevealed_info: Les obres ocultes no apareixen a les llistes d'etiquetes ni + a la teva pàgina d'obres. Qualsevol persona que obri un enllaç a l'obra rebrà + una notificació informant que de moment és oculta i no podran accedir al seu + contingut. + archivist_added_to_collection_notification: + approved_collection_items_page: pàgina d'Approved Collection Items (Elements + de col·lecció aprovats) + archivist_notice: Com que les persones responsables de la col·lecció actuen + oficialment com a arxivistes d'Open Doors (Projecte de Portes Obertes), poden + afegir la teva obra a aquesta col·lecció encara que tinguis les invitacions + a col·leccions desactivades. Els i les arxivistes només afegeixen a col·leccions + obres que s'allotjaven a un arxiu importat. + removal_instructions: + html: Si vols retirar la teva obra d'aquesta col·lecció, ves a la teva %{approved_items_link}. + text: 'Si vols retirar la teva obra d''aquesta col·lecció, ves a la teva pàgina + d''Approved Collection Items (Elements de col·lecció aprovats): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Un/a arxivista d'Open Doors (Projecte + de Portes Obertes) ha afegit la teva obra a una col·lecció" + work_added: + html: Les persones responsables de %{collection_link} han afegit la teva obra + %{work_link} a la seva col·lecció! + text: Les persones responsables de "%{collection_title}" (%{collection_url}) + han afegit la teva obra "%{work_title}" (%{work_url}) a la seva col·lecció! + challenge_assignment_notification: + any: Qualsevol + assignment: + html: Se t'ha assignat la següent sol·licitud del repte %{link} a l'AO3! + description: 'Descripció:' + due: 'Aquesta tasca venç el:' + html: + footer: Estàs rebent aquest correu electrònic perquè et vas inscriure al repte + %{title}. Per a més informació sobre aquest repte i informació de contacte + dels moderadors o moderadores, visita %{footer_link}. + footer_link: la pàgina de perfil del repte + look_up: Pots consultar aquesta tasca a %{link}. + look_up_link: la teva pàgina d'Assignments (Tasques) + optional_tags: 'Etiquetes opcionals:' + prompts: 'Premisses:' + prompt_url: 'URL de la premissa:' + recipient: 'Destinatari o destinatària:' + recipient_missing: 'Cap: posa''t en contacte amb un moderador o una moderadora + per obtenir ajuda!' + subject: "[%{app_name}][%{collection_title}] La teva tasca!" + text: + assignment: Se t'ha assignat la següent sol·licitud del repte (%{collection_url}) + "%{collection_title}" a l'AO3! + footer: Estàs rebent aquest correu electrònic perquè et vas inscriure al repte + %{title} (%{url}). Per a més informació sobre aquest repte i informació + de contacte dels moderadors o moderadores, visita %{profile_url}. + look_up: Pots consultar aquesta tasca a la teva pàgina d'Assignments (Tasques) + a %{link}. + change_email: + changed: + html: "%{login}, l'adreça electrònica associada amb aquest compte ha canviat + a %{email}" + text: "%{login}, l'adreça electrònica associada amb aquest compte ha canviat + a %{email}" + subject: "[%{app_name}] Canvi d'adreça electrònica" + claim_notification: + access: + contact_support: contacta amb el Suport de l'AO3 + html: Depenent de l'arxiu, les teues obres poden haver estat importades de + manera restringida, amb la qual cosa tan sols els usuaris i les usuàries + registrades podran veure-les (per tal que no apareguen a les cerques de + Google). Si aquest és el cas, les obres només seran accessibles per als + usuaris i usuàries que han iniciat la sessió llevat que les faces visibles + per a tothom. Si necessites ajuda desbloquejant, deixant òrfena o esborrant + alguna de les teues obres, %{contact_support_link}. + text: Depenent de l'arxiu, les teues obres poden haver estat importades de + manera restringida, amb la qual cosa tan sols els usuaris i les usuàries + registrades podran veure-les (per tal que no apareguen a les cerques de + Google). Si aquest és el cas, les obres només seran accessibles per als + usuaris i usuàries que han iniciat la sessió llevat que les faces visibles + per a tothom. Si necessites ajuda desbloquejant, deixant òrfena o esborrant + alguna de les teues obres, contacta amb el Suport de l'AO3 a %{support_url}. + email_tips: Si ens contactes, recomanem que afiges les adreces de correu electrònic + de @transformativeworks.org a la teua llista de contactes segurs i que revises + la safata de correu brossa. + introduction: + ao3_name: Archive of Our Own – AO3 (Un Arxiu Propi) + html: Has rebut aquest missatge de correu perquè tens obres en un arxiu d'obres + de fans que ha estat importat per %{open_doors_name_link} a l'%{app_link}. + Com que aquesta adreça de correu està connectada a una registrada a l'arxiu + importat, les obres associades (que es mostren a continuació) s'han afegit + automàticament al teu compte de l'AO3. + open_doors_name: Open Doors (Projecte de Portes Obertes) + text: 'Has rebut aquest missatge de correu perquè tens obres en un arxiu d''obres + de fans que ha estat importat per Open Doors (Projecte de Portes Obertes) + (%{open_doors_url}) a l''Archive of Our Own – AO3 (Un Arxiu Propi): %{app_url}. + Com que aquesta adreça de correu està connectada a una registrada a l''arxiu + importat, les obres associades (que es mostren a continuació) s''han afegit + automàticament al teu compte de l''AO3.' + mistake: + contact_open_doors: Contacta amb Open Doors + html: Si hi ha hagut algun error i aquestes no són les teues obres, no les + esborres! %{contact_open_doors_link} i ho arreglarem. + text: Si hi ha hagut algun error i aquestes no són les teues obres, no les + esborres! Contacta amb Open Doors (%{open_doors_url}) i ho arreglarem. + more_info: + ao3_news: Notícies de l'AO3 + contact_support: contacta amb el Suport de l'AO3 + faq_page: pàgina de Preguntes freqüents + html: Pots llegir notícies sobre importacions recents a les %{ao3_news_link}, + i trobar informació addicional sobre Open Doors a la %{faq_page_link} o + la %{tutorial_page_link}. Si tens cap dubte que no haja estat resolt a les + Preguntes freqüents, els tutorials, o aquest correu, %{contact_support_link}. + text: Pots llegir notícies sobre importacions recents a les Notícies de l'AO3 + (%{news_url}), i trobar informació addicional sobre Open Doors a la pàgina + de Preguntes freqüents (%{open_doors_faq_url}) o la pàgina de tutorials + (%{open_doors_tutorial_url}). Si tens cap dubte que no haja estat resolt + a les Preguntes freqüents, els tutorials, o aquest correu, contacta amb + el Suport de l'AO3 a %{support_url}. + tutorial_page: pàgina de tutorials + other_works: + contact_open_doors: contacta amb Open Doors + html: Si tens obres a l'arxiu importat que estiguen vinculades a una adreça + de correu electrònic a què ja no tens accés, %{contact_open_doors_link} + amb qualsevol informació que puga ajudar a verificar la teua identitat. + text: Si tens obres a l'arxiu importat que estiguen vinculades a una adreça + de correu electrònic a què ja no tens accés, contacta amb Open Doors amb + qualsevol informació que puga ajudar a verificar la teua identitat. + questions: + contact_support: contacta amb el Suport de l'AO3 + html: Per a altres consultes, %{contact_support_link}. + text: Per qualsevol altra consulta, pots contactar amb el Suport de l'AO3 + a %{support_url}. + redirects: + html: Per tal de preservar les llistes de recomanacions i els marcadors, les + pàgines web de l'arxiu importat poden redirigir a una còpia importada de + les obres durant un temps limitat (pots revisar la publicació de la notícia + per assegurar-te). Si ja has publicat una còpia d'aquestes obres i %{negation} + has utilitzat l'opció d'importar des d'un URL, hi haurà dues còpies de la + mateixa obra a l'AO3. + subject: "[%{app_name}] Obres publicades" + update_redirect: + contact_open_doors: contactar amb Open Doors + html: Si vols que Open Doors actualitze la redirecció perquè enllace amb les + teues obres preexistents, pots esborrar la còpia importada i %{contact_open_doors_link} + amb el teu nom d'usuari o usuària de l'AO3 i de l'arxiu importat, i el títol + i URL de l'obra a la qual t'agradaria que es redirigira (si tens diverses + obres, pots fer una llista de totes en un mateix missatge). + text: Si vols que Open Doors actualitze la redirecció perquè enllace amb les + teues obres preexistents, pots esborrar la còpia importada i contactar amb + Open Doors a %{open_doors_url} incloent el teu nom d'usuari o usuària de + l'AO3 i de l'arxiu importat i el títol i URL de l'obra a la qual t'agradaria + que es redirigira (si tens diverses obres, pots fer una llista de totes + en un mateix missatge). + works_by: 'Aquestes obres foren escrites amb el correu electrònic: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: S'han enviat totes les tasques. + subject: Tasques enviades + html: + received_message: 'Has rebut un missatge sobre la col·lecció %{collection_link}:' + text: + received_message: 'Has rebut un missatge sobre la col·lecció "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Quan ets cocreador/a d'una obra, se't pot afegir a nous capítols + independentment de la configuració de la cocreació que tinguis al teu perfil. + També se t'afegirà a qualsevol sèrie a la qual s'incorpori la teva obra. + html: + creation: "%{creation_link} de %{pseud_links}" + edit_chapter: editar el capítol + edit_series: editar la sèrie + remove_chapter: Si t'han afegit per error o no vols que et registrin com a + creador/a, pots %{edit_chapter_link} per eliminar-te com a creador/a. + remove_series: Si t'han afegit per error o no vols que et registrin com a + creador/a, pots %{edit_series_link} per eliminar-te com a creador/a. + intro_chapter: 'L''usuari/ària %{adding_user} ha registrat el teu pseudònim + %{pseud} com a cocreador/a del següent capítol:' + intro_series: 'L''usuari/ària %{adding_user} ha registrat el teu pseudònim %{pseud} + com a cocreador/a de la següent sèrie:' + subject: "[%{app_name}] Notificació de cocreador/a" + text: + creation: "%{title} (%{url}) de %{pseuds}" + remove_chapter: 'Si t''han afegit per error o no vols que et registrin com + a creador/a, pots editar el capítol per eliminar-te com a creador/a: %{url}' + remove_series: 'Si t''han afegit per error o no vols que et registrin com + a creador/a, pots editar la sèrie per eliminar-te com a creador/a: %{url}' + creatorship_notification_archivist: + explanation: Actuant sota la seva competència d'arxivista de l'Open Doors (Projecte + de Portes Obertes), l'arxivista té permís per afegir-te sense invitació, fins + i tot si tens la configuració de co-creació desactivada. + html: + creation: "%{creation_link} de %{pseud_links}" + edit_chapter: editar el capítol + edit_series: editar la sèrie + edit_work: editar l'obra + remove_chapter: Si has estat afegit/da per error o no vols ser registrat/da + com a creador/a, pots %{edit_chapter_link} per eliminar-te com a creador/a. + remove_series: Si has estat afegit/da per error o no vols ser registrat/da + com a creador/a, pots %{edit_series_link} per eliminar-te com a creador/a. + remove_work: Si has estat afegit/da per error o no vols ser registrat/da com + a creador/a, pots %{edit_work_link} per eliminar-te com a creador/a. + intro_chapter: 'L''usuari/ària %{archivist} ha afegit el teu pseudònim %{pseud} + com a co-creador/a del capítol següent:' + intro_series: 'L''usuari/ària %{archivist} ha afegit el teu pseudònim %{pseud} + com a cocreador/a de la sèrie següent:' + intro_work: 'L''usuari/ària %{archivist} ha afegit el teu pseudònim %{pseud} + com a cocreador/a de la següent obra:' + subject: "[%{app_name}] Notificació de cocreador/a de l'arxivista" + text: + creation: "%{title} (%{url}) de %{pseuds}" + remove_chapter: 'Si has estat afegit/da per error o no vols ser registrat/da + com a creador/a, pots editar el capítol per eliminar-te com a creador/a: + %{url}' + remove_series: 'Si has estat afegit/da per error o no vols ser registrat/da + com a creador/a, pots editar la sèrie per eliminar-te com a creador/a: %{url}' + remove_work: 'Si has estat afegit/da per error o no vols ser registrat/da + com a creador/a, pots editar l''obra per eliminar-te com a creador/a: %{url}' + creatorship_request: + html: + creation: "%{creation_link} de %{pseud_links}" + instructions: Pots acceptar o rebutjar aquesta petició a la pàgina %{page_name}. + page_name: Co-Creator Requests (Peticions de cocreador/a) + intro_chapter: 'L''usuari/a %{inviting_user} ha convidat el teu pseudònim %{pseud} + a registrar-se com a cocreador/a al següent capítol:' + intro_series: 'L''usuari/a %{inviting_user} ha convidat el teu pseudònim %{pseud} + a registrar-se com a cocreador/a a la següent sèrie:' + intro_work: 'L''usuari/a %{inviting_user} ha convidat el teu pseudònim %{pseud} + a registrar-se com a cocreador/a a la següent obra:' + subject: "[%{app_name}] Petició de cocreador/a" + text: + creation: "%{title} (%{url}) de %{pseuds}" + instructions: 'Pots acceptar o rebutjar aquesta petició a la pàgina Co-Creator + Requests (Peticions de cocreador/a): %{url}' + delete_work_notification: + attachment: Pots trobar adjunta una còpia de la teva obra com a referència. + deleted_other: + html: La teva obra %{title} ha estat eliminada a petició de %{pseud}. + text: La teva obra "%{title}" ha estat eliminada a petició de %{pseud}. + deleted_yourself: + html: La teva obra %{title} ha estat eliminada a petició teva. + text: La teva obra "%{title}" ha estat eliminada a petició teva. + questions: + html: Si us plau, si tens cap pregunta %{support}. + text: Si us plau, si tens cap pregunta %{support} (%{url}). + subject: "[%{app_name}] La teva obra ha estat eliminada" + support: contacta amb Suport + invitation_to_claim: + access: + text: Depenent de l’arxiu, les teves obres es poden haver importat de manera + restringida només per als usuaris registrats (per evitar que apareguin a + les cerques de Google). Si aquest és el cas, les obres només seran accessibles + per usuaris que hagin iniciat sessió, a menys que escullis fer-les completament + visibles. Si necessites ajuda per desbloquejar, deixar orfes o eliminar + les teves obres, contacta amb Suport de l’AO3. + claim_or_remove: + html: Reclama o elimina les teves obres aquí. + text: 'Reclama o elimina les teves obres aquí: %{claim_url}' + email_tips: Si t’estàs posant en contacte amb nosaltres; si us plau, aprova + les adreces de correu electrònic de @transformativeworks.org i revisa la teva + carpeta de correu brossa si no trobes la nostra resposta. + html: + ao3_news: notícies de l’AO3 + contact_open_doors: contacta amb l’Open Doors + contact_support: contacta amb Suport de l’AO3 + faq_page: pàgina de preguntes freqüents + tutorial_page: pàgina del tutorial + introduction: + text: Estàs rebent aquest correu perquè un arxiu ha estat importat recentment + per l’Open Doors (%{open_doors_link}) a %{app_name} (%{app_short_name} - + %{app_url}), i creiem que les obres següents et poden pertànyer. Volem donar-te + l’oportunitat de reclamar (o eliminar/deixar orfes) aquestes obres si és + el que vols. I en cas que no tinguis ja un compte associat a una altra adreça + de correu, ens agradaria convidar-te a l’arxiu! + mistake: + text: Si això és un error i aquestes obres no són teves, no les esborris, + si us plau! Contacta amb l’Open Doors (%{open_doors_link}) i nosaltres ens + n’encarregarem. + more_info: + text: Pots llegir els anuncis sobre trasllats recents a l’arxiu a les notícies + de l’AO3 (%{news_link}), i trobar informació addicional a la pàgina de preguntes + freqüents de l’Open Doors (%{open_doors_faq_link}) o bé a la pàgina de tutorials + (%{open_doors_tutorial_link}). Per a qualsevol pregunta respecte a la qual + no vegis resposta a la pàgina de preguntes freqüents, als tutorials o en + aquest correu, contacta amb %{support_link}, si us plau. + other_works: + text: Si tens altres obres a l’arxiu importat enllaçades a una adreça de correu + a la qual ja no tens accés, contacta amb l’Open Doors amb qualsevol informació + que pugui ajudar a verificar la teva identitat, si us plau. + questions: + text: Per a qualsevol altre dubte, contacta amb Suport de l’AO3 a %{support_link}. + redirects: Per preservar llistes de recomanacions i marcadors, les adreces web + dels arxius importats poden redirigir a la còpia importada d’aquestes obres + durant un temps limitat (comprova la publicació de l’anunci del trasllat del + teu arxiu per assegurar-te’n). Si ja has publicat una còpia d’aquestes obres + i NO has fet servir l’eina d’importar des de l’URL, hi haurà dues còpies de + la mateixa obra a l’arxiu. + subject: "[%{app_name}] Invitació a reclamar obres" + unwanted: + text: Si aquestes obres són teves però no les vols, les pots deixar orfes + (de manera que es mantenen a l’AO3 però el teu nom queda eliminat) o esborrar-les + (de manera que quedin completament eliminades de l’AO3). No necessites afegir + aquestes obres a cap compte per tal d’abandonar-les o eliminar-les, ho pots + fer directament des de l’enllaç de reclamació de més amunt. (Si necessites + ajuda, contacta amb Suport a %{support_link}.) + update_redirect: + text: Si t’agradaria que l’Open Doors actualitzés la redirecció per dirigir-la + a la teva obra preexistent; si us plau, esborra la còpia importada i contacta + amb l’Open Doors a %{open_doors_link} tot indicant el nom del teu compte + a l’AO3, el nom del teu compte a l’arxiu importat i el títol i l’URL de + l’obra a la qual voldries efectuar la nova redirecció. (Si vols canviar + la redirecció de diverses obres, pots enumerar-les en un sol correu electrònic.) + uploaded_list: 'Les obres pujades inclouen:' + invite_increase_notification: + html: + body: + one: Tan sols et volíem fer saber que tens %{count} invitació nova, que + pots fer servir per crear nous comptes a l'AO3. Pots convidar una amistat + a %{invitation_page_link}. + other: Tan sols et volíem fer saber que tens %{count} invitacions noves, + que pots fer servir per crear nous comptes a l'AO3. Pots convidar una + amistat a %{invitation_page_link}. + invitation_page_link_text: la teva pàgina d'Invitations (Invitacions) + subject: "[%{app_name}] Noves invitacions" + text: + body: + one: Tan sols et volíem fer saber que tens %{count} invitació nova, que + pots fer servir per crear nous comptes a l'AO3. Pots convidar una amistat + a la teva pàgina d'invitacions (%{invitation_page_url}). + other: Tan sols et volíem fer saber que tens %{count} invitacions noves, + que pots fer servir per crear nous comptes a l'AO3. Pots convidar una + amistat a la teva pàgina d'invitacions (%{invitation_page_url}). + invite_request_declined: + main: + one: Lamentem informar-te que la teva sol·licitud d'una nova invitació no + es pot satisfer en aquests moments. + other: Lamentem informar-te que la teva sol·licitud de %{count} noves invitacions + no es pot satisfer en aquests moments. + reason: 'La teva sol·licitud era:' + subject: "[%{app_name}] Sol·licitud de codi d'invitació addicional rebutjada" + recipient_notification: + html: + collection: S'ha publicat una obra de regal per a tu a la col·lecció %{collection_link} + a l'AO3! + no_collection: S'ha publicat una obra de regal per a tu a l'AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Una obra de regal per a tu + de %{collection_title}" + no_collection: "[%{app_name}] Una obra de regal per a tu" + text: + collection: S'ha publicat una obra de regal per a tu a la col·lecció "%{collection_title}" + (%{collection_url}) a l'AO3! + signup_notification: + activate: + html: Si us plau %{activate_account_link}. + text: 'Segueix aquest enllaç per activar el teu compte: %{activate_account_url}' + activate_your_account: segueix aquest enllaç per activar el teu compte + admin_posts: Notícies de l’AO3 + bye: Esperem que estiguis gaudint amb l’Arxiu. + contact_support: contacta amb l’equip de Suport + faq: pàgina de Preguntes freqüents (FAQ) + features: + html: Un cop el teu compte estigui activat, podràs publicar les teves obres + de fan, configurar les teves subscripcions per a que t’avisem per correu + electrònic quan hi hagi cap actualització de les teves obres i creadors + o creadores preferides, personalitzar l’aspecte de la pàgina, controlar + a quines obres has accedit a l’AO3 fent servir el teu historial, i molt + més. + text: Un cop el teu compte estigui activat, podràs publicar les teves obres + de fan, configurar les teves subscripcions per a que t’avisem per correu + electrònic quan hi hagi cap actualització de les teves obres i creadors + o creadores preferides, personalitzar l’aspecte de la pàgina, controlar + a quines obres has accedit a l’AO3 fent servir el teu historial, i molt + més. + information: + html: Hi ha molta informació i consells sobre com fer servir l’AO3 a %{faq_link}. + A %{admin_posts_link} trobaràs les últimes notícies sobre el desenvolupament + del lloc web. Si necessites més ajuda, trobes un error o tens preguntes + o suggeriments, %{contact_support_link}, on t’ajudaran de bon grat. + text: 'Disposes de molta informació i consells sobre com fer servir l’AO3 + a la pàgina de FAQ %{faq_url}. Trobaràs les últimes notícies sobre el desenvolupament + del lloc web a %{admin_posts_url}. Si necessites més ajuda, trobes un error + o tens preguntes o suggeriments, contacta amb Suport, on t’ajudaran de bon + grat: %{contact_support_url}.' + welcome: Benvingut/da a l’Archive of Our Own - AO3, %{login}! diff --git a/config/locales/phrase-exports/cs.yml b/config/locales/phrase-exports/cs.yml new file mode 100755 index 0000000..bce1fa5 --- /dev/null +++ b/config/locales/phrase-exports/cs.yml @@ -0,0 +1,632 @@ +--- +cs: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Varování:' + one: 'Varování:' + other: 'Varování:' + category: + name_with_colon: + few: 'Kategorie:' + one: 'Kategorie:' + other: 'Kategorií:' + character: + name_with_colon: + few: 'Postavy:' + one: 'Postava:' + other: 'Postav:' + fandom: + name_with_colon: + few: 'Fandomy:' + one: 'Fandom:' + other: 'Fandomů:' + freeform: + name_with_colon: + few: 'Vedlejší tagy:' + one: 'Vedlejší tag:' + other: 'Vedlejších tagů:' + rating: + name_with_colon: 'Zařazení:' + relationship: + name_with_colon: + few: 'Vztahy:' + one: 'Vztah:' + other: 'Vztahů:' + work: + chapter_total_display: Kapitoly + summary: Shrnutí + models: + archive_warning: + few: Varování + one: Varování + other: Varování + category: + few: Kategorie + one: Kategorie + other: Kategorií + chapter: + few: Kapitoly + one: Kapitola + other: Kapitol + character: + few: Postavy + one: Postava + other: Postav + fandom: + few: Fandomy + one: Fandom + other: Fandomů + freeform: + few: Vedlejší tagy + one: Vedlejší tag + other: Vedlejších tagů + rating: + few: Zařazení + one: Zařazení + other: Zařazení + relationship: + few: Vztahy + one: Vztah + other: Vztahů + series: + few: Série + one: Série + other: Sérií + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} návštěvníků" + many: "%{count} návštěvníků" + one: návštěvníka + other: "%{count} návštěvníků" + left_kudos: + html: + few: Práce %{commentable_link} dostala kudos od %{givers_list}. + one: Práce %{commentable_link} dostala kudos od %{givers_list}. + other: Práce %{commentable_link} dostala kudos od %{givers_list}. + text: + few: Práce %{commentable_title} (%{commentable_url}) dostala kudos od %{givers_list}. + one: Práce %{commentable_title} (%{commentable_url}) dostala kudos od %{givers_list}. + other: Práce %{commentable_title} (%{commentable_url}) dostala kudos od + %{givers_list}. + single_guest: + giver: návštěvníka + html: Práce %{commentable_link} dostala kudos od %{giver}. + text: Práce %{commentable_title} (%{commentable_url}) dostala kudos od návštěvníka. + subject: "[%{app_name}] Máte nové kudos!" + mailer: + general: + closing: + formal: S pozdravem, + informal: S pozdravem, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Kapitola %{position} z díla %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} slova" + one: "%{count} slovo" + other: "%{count} slov" + footer: + general: + about: + html: AO3 je fanoušky vedený a podporovaný archiv, který spoléhá %{donate_link}. + text: 'AO3 je fanoušky vedený a podporovaný archiv, který spoléhá na vaše + příspěvky: %{donate_url}.' + html: + donate_link_text: na vaše příspěvky + support_link_text: kontaktujte Podporu + unwanted_email: + html: Pokud jste obdrželi tuto zprávu omylem, prosím %{support_link}. + text: Pokud jste obdrželi tuto zprávu omylem, prosím kontaktujte Podporu + na %{support_url}. + sent_at: Odesláno v %{sent_at}. + greeting: + formal_html: Dobrý den, %{name}, + informal: + addressed_html: Ahoj %{name}, + unaddressed: Ahoj, + introductory: Zdravíme z Archive of Our Own – AO3 (Našeho vlastního archivu), + metadata_label_indicator: ":" + signature: + abuse_team: AO3 Dohled na dodržování pravidel a zásad serveru + app_short_name: AO3 + open_doors: The Open Doors team (Tým Otevřených dvěří) + parent_org: Organization for Transformative Works – OTW (Společnost pro transformativní + tvorbu) + support: Podpora AO3 + users: + mailer: + reset_password_instructions: + expiration: Pokud tento odkaz nepoužijete ke změně hesla do sedmi dnů, vyprší + a budete si muset zažádat o nový. + intro: 'Byl vznesen požadavek na změnu hesla pro váš účet. Své heslo můžete + změnit kliknutím na následující odkaz a vyplněním nového hesla:' + link_title: Změnit heslo. + subject: "[%{app_name}] Změňte své heslo" + unrequested: Pokud jste si změnu hesla nevyžádal/a, můžete tento email ignorovat + a vaše stávající heslo zůstane platné. + user_mailer: + admin_deleted_work_notification: + bye: Kopii své práce najdete v příloze. + contact_abuse: obraťte se prosím na Dohled na dodržování pravidel a zásad serveru + deleted: + html: Vaše práce s názvem %{title} byla z Archivu smazána administrátorem. + text: Vaše práce s názvem "%{title}" byla z Archivu smazána administrátorem. + html: + tos_violation: V případě, že je možné, že vaše práce porušila Smluvní podmínky + Archivu, %{contact_abuse_link}. + import_project: + html: V případě, že byla vaše práce součástí projektu Open Doors (Otevřené + dveře), %{opendoors_link}. + text: V případě, že byla vaše práce součástí projektu Open Doors (Otevřené + dveře), obraťte se s případnými dotazy na Open Doors (%{opendoors_link}). + opendoors: obraťte se s případnými dotazy na Open Doors + subject: "[%{app_name}] Vaše práce byla smazána administrátorem" + text: + tos_violation: V případě, že je možné, že vaše práce porušila Smluvní podmínky + Archivu, obraťte se prosím na Dohled na dodržování pravidel a zásad serveru + (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Na stránku se skrytou prací se dostanete pomocí odkazu přiloženého výše, + nebude ale dostupná ostatním uživatelům AO3, a to ani ze stránky s přehledem + vašich prací. + check_email: Je možné, že vás výbor pro Dohled již kontaktoval ohledně důvodu + pro skrytí této práce, zkontrolujte proto prosím svoji e-mailovou schránku, + a to včetně složky s nevyžádanou poštou (spam). + contact_abuse: kontaktujte prosím výbor pro Dohled + html: + help: Pokud si nejste jisti, proč byla vaše práce skryta, a neobdrželi jste + další informace, na tento e-mail neodpovídejte, ale %{contact_abuse_link}. + hidden: Vaše práce %{title} byla skryta výborem pro Dohled na dodržování pravidel + a zásad serveru a není proto nadále veřejně dostupná. + tos_violation: Pokud byla vaše práce skryta z důvodu porušení %{tos_link} + AO3, budete muset práci upravit tak, aby s nimi byla v souladu. Pokud tak + neučiníte, hrozí, že bude vaše práce smazána. + subject: "[%{app_name}] Vaše práce byla skryta výborem pro Dohled na dodržování + pravidel a zásad serveru" + text: + help: 'Pokud si nejste jisti, proč byla vaše práce skryta, a neobdrželi jste + další informace, na tento e-mail neodpovídejte, ale kontaktujte prosím výbor + pro Dohled: %{contact_abuse_url}.' + hidden: Vaše práce "%{title}" (%{work_url}) byla skryta výborem pro Dohled + na dodržování pravidel a zásad serveru, a není proto nadále veřejně dostupná. + tos_violation: Pokud byla vaše práce skryta z důvodu porušení smluvních podmínek + AO3 (%{tos_url}), budete muset práci upravit tak, aby s nimi byla v souladu. + Jestli tak neučiníte, hrozí, že bude vaše práce smazána. + tos: smluvních podmínek + anonymous_or_unrevealed_notification: + anonymous_info: Anonymní práce jsou zahrnuty ve výpisech tagů, ale nejsou uvedeny + na stránce s vašimi pracemi. U dané práce bude vaše uživatelské jméno nahrazeno + slovem "Anonymous" (Anonymní). + anonymous_unrevealed_info: Správci sbírky mohou vaši práci později zveřejnit, + ale ponechat ji v anonymitě. Lidé, kteří se přihlásili k odběru vašich prací, + nebudou o této změně informováni. Po zveřejnění bude vaše práce zahrnuta ve + výpisech tagů, ale nebude uvedena na stránce s vašimi pracemi. Na stránce + práce bude vaše uživatelské jméno nahrazeno slovem "Anonymous" (Anonymní). + changed_status: + anonymous: + html: Správci sbírky %{collection_link} změnili status vaší práce %{work_link} + na anonymní. + text: Správci sbírky %{collection_title}" (%{collection_url}) změnili status + vaší práce "%{work_title}" (%{work_url}) na anonymní. + anonymous_unrevealed: + html: Správci sbírky %{collection_link} změnili status vaší práce %{work_link} + na anonymní a nezveřejněný. + text: Správci sbírky "%{collection_title}" (%{collection_url}) změnili status + vaší práce "%{work_title}" (%{work_url}) na nezveřejněný a anonymní. + unrevealed: + html: Správci sbírky %{collection_link} změnili stav vaší práce %{work_link} + na nezveřejněný. + text: Správci sbírky "%{collection_title}" (%{collection_url}) změnili status + vaší práce "%{work_title}" (%{work_url}) na nezveřejněný. + collection_items_link_text: Approved Collection Items (Schválené položky sbírky) + do_not_want: + anonymous: + html: Pokud nechcete, aby vaše práce byla anonymní, navštivte prosím stránku + %{collection_items_link} a odstraňte ji z této sbírky. + text: 'Pokud nechcete, aby vaše práce byla anonymní, navštivte prosím stránku + Approved Collection Items (Schválené položky sbírky) a odstraňte ji z + této sbírky: %{collection_items_url}' + anonymous_unrevealed: + html: Pokud nechcete, aby vaše práce byla anonymní a nezveřejněná, navštivte + prosím stránku %{collection_items_link} a odstraňte ji z této sbírky. + text: 'Pokud nechcete, aby vaše práce byla anonymní a nezveřejněná, navštivte + prosím stránku Approved Collection Items (Schválené položky sbírky) a + odstraňte ji z této sbírky: %{collection_items_url}' + unrevealed: + html: Pokud nechcete, aby vaše práce byla nezveřejněna, navštivte prosím + stránku %{collection_items_link} a odstraňte ji z této sbírky. + text: 'Pokud nechcete, aby vaše práce byla nezveřejněna, navštivte prosím + stránku Approved Collection Items (Schválené položky sbírky) a odstraňte + ji z této sbírky: %{collection_items_url}' + faq_link_text: Časté otázky ke sbírkám + more_info: + html: Pro více informací navštivte stránku %{faq_link}. + text: 'Pro více informací navštivte stránku Časté otázky ke sbírkám: %{faq_url}' + subject: + anonymous: "[%{app_name}] Vaše práce byla anonymizována" + anonymous_unrevealed: "[%{app_name}] Vaše práce byla anonymizována a skryta" + unrevealed: "[%{app_name}] Vaše práce byla skryta" + unrevealed_info: Nezveřejněné práce nejsou zahrnuty ve výpisech tagů ani uvedeny + na stránce s vašimi pracemi. Každý, kdo bude následovat odkaz na tuto práci, + obdrží oznámení, že práce je v danou chvíli nezveřejněná, a nebude mít přístup + k jejímu obsahu. + archivist_added_to_collection_notification: + approved_collection_items_page: stránku Approved Collection Items (Povolených + položek sbírek) + archivist_notice: Díky své funkci jakožto archiváři Open Doors (Otevřených dveří) + mají správci sbírky právo vaši práci přidat do této sbírky i v případě, že + nemáte přijímání pozvánek ke sbírkám povolené. Archiváři přidají práci do + sbírky pouze v případě, že byla zveřejněna v importovaném archivu. + removal_instructions: + html: Pokud chcete svoji práci z této sbírky odebrat, navštivte prosím svoji + %{approved_items_link} + text: 'Pokud chcete svoji práci z této sbírky odebrat, navštivte prosím svoji + stránku Approved Collection Items (Povolených položek sbírek): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Archivář Open Doors (Otevřených + dveří) přidal vaši práci do sbírky" + work_added: + html: Správci sbírky %{collection_link} přidali vaši práci %{work_link} do + své sbírky! + text: Správci sbírky "%{collection_title}" (%{collection_url}) přidali vaši + práci "%{work_title}" (%{work_url}) do své sbírky! + challenge_assignment_notification: + any: Jakékoliv + assignment: + html: Byla vám přidělena následující žádost ve výzvě %{link} na AO3! + description: 'Popis:' + due: 'Termín splnění zadání je do:' + html: + footer: Tento e-mail jste obdrželi, protože jste se přihlásili do výzvy %{title}. + Více informací o této výzvě a kontakty na moderátory najdete na %{footer_link}. + footer_link: profilové stránce výzvy + look_up: Toto zadání můžete najít na %{link}. + look_up_link: své stránce Assignments (Zadání) + optional_tags: 'Volitelné tagy:' + prompts: 'Náměty:' + prompt_url: 'URL námětu:' + recipient: 'Příjemce:' + recipient_missing: 'Žádný: pro pomoc kontaktujte moderátora!' + subject: "[%{app_name}][%{collection_title}] Vaše zadání!" + text: + assignment: Byla vám přidělena následující žádost ve výzvě "%{collection_title}" + (%{collection_url}) na AO3! + footer: Tento e-mail jste obdrželi, protože jste se přihlásili do výzvy %{title} + (%{url}). Více informací o této výzvě a kontakty na moderátory můžete najít + na %{profile_url}. + look_up: Toto zadání najdete na stránce Assignments (Zadání) pod odkazem %{link}. + change_email: + changed: + html: "%{login}, email spojený s vaším účtem byl změněn na %{email}" + text: "%{login}, email spojený s vaším účtem byl změněn na %{email}" + subject: "[%{app_name}] Email byl změněn" + claim_notification: + access: + contact_support: kontaktujte Podporu AO3 + html: V závislosti na typu archivu mohou být vaše importované práce dostupné + pouze registrovaným uživatelům (aby se nedostaly do vyhledávání Google). + Pokud se nerozhodnete je zpřístupnit všem uživatelům, budou přístupné pouze + přihlášeným uživatelům. Pokud potřebujete pomoct s odemknutím, opuštěním + nebo odstraněním vašich prací, %{contact_support_link}. + text: 'V závislosti na typu archivu mohou být vaše importované práce dostupné + pouze registrovaným uživatelům (aby se nedostaly do vyhledávání Google). + Pokud se nerozhodnete je zpřístupnit všem uživatelům, budou přístupné pouze + přihlášeným uživatelům. Pokud potřebujete pomoct s odemknutím, opuštěním + nebo odstraněním vašich prací, kontaktujte Podporu AO3: %{support_url}.' + email_tips: Pokud nás kontaktujete, přidejte si prosím e-mailové adresy @transformativeworks.org + do seznamu bezpečných kontaktů a zkontrolujte si složky spam, jestli v nich + nenajdete naši odpověď. + introduction: + ao3_name: Archive of Our Own – AO3 (Našeho vlastního archivu) + html: Tento e-mail vám zasíláme, protože jste měli v archivu fanouškovských + děl práce, které byly v rámci projektu %{open_doors_name_link} naimportovány + do %{app_link}. Vzhledem k tomu, že tato e-mailová adresa je spojena s adresou + zaregistrovanou v importovaném archivu, byla související (níže uvedená) + fanouškovská díla automaticky přiřazena k vašemu účtu na AO3 (Našem vlatním + archivu). + open_doors_name: Open Doors (Otevřené dveře) + text: 'Tento e-mail vám zasíláme, protože jste měli v archivu fanouškovských + děl práce, které byly v rámci projektu Open Doors (Otevřené dveře) (%{open_doors_url}) + naimportovány do Archive of Our Own – AO3 (Našeho vlastního archivu): %{app_url}. + Vzhledem k tomu, že tato e-mailová adresa je spojena s adresou zaregistrovanou + v importovaném archivu, byla související (níže uvedená) fanouškovská díla + automaticky přiřazena k vašemu účtu na AO3.' + mistake: + contact_open_doors: kontaktovat projekt Open Doors + html: Máte-li pocit, že vám tento e-mail by zaslán omylem a nejedná se o vaše + práce, prosím nemažte je! Stačí %{contact_open_doors_link} a my to vyřešíme. + text: Máte-li pocit, že vám tento e-mail by zaslán omylem a nejedná se o vaše + práce, prosím nemažte je! Stačí kontaktovat Open Doors (%{open_doors_url}) + a my to vyřešíme. + more_info: + ao3_news: Novinek AO3 + contact_support: Podporu AO3 + faq_page: Často kladené dotazy (FAQ) + html: Oznámení o nedávných přesunech v archivu si můžete přečíst na stránkách + %{ao3_news_link} a dodatečné informace najdete na stránkách Open Doors %{faq_page_link} + nebo %{tutorial_page_link}. Jakékoli otázky, na které nenaleznete odpověď + v často kladených dotazech, návodech nebo v tomto e-mailu, prosím směřujte + na %{contact_support_link}. + text: 'Oznámení o nedávných přesunech archivu si můžete přečíst na stránkách + Novinek AO3 (%{news_url}) a dodatečné informace najdete na stránkách Open + Doors s často kladenými dotazy (%{open_doors_faq_url}) nebo s návody (%{open_doors_tutorial_url}). + Jakékoli otázky, na které nenaleznete odpověď v často kladených dotazech, + návodech nebo v tomto e-mailu, prosím směřujte na Podporu AO3: %{support_url}.' + tutorial_page: Návody + other_works: + contact_open_doors: kontaktujte projekt Open Doors + html: Pokud jste v importovaném archivu měli další práce vedené pod e-mailovou + adresou, ke které již nemáte přístup, prosím %{contact_open_doors_link} + s jakoukoli informací, která pomůže k ověření vaší totožnosti. + text: Pokud jste v importovaném archivu měli další práce vedené pod e-mailovými + adresami, ke kterým již nemáte přístup, prosím kontaktujte projekt Open + Doors s jakoukoli informací, která pomůže k ověření vaší totožnosti. + questions: + contact_support: kontaktujte Podporu AO3 + html: S dalšími dotazy prosím %{contact_support_link}. + text: 'S dalšími dotazy prosím kontaktujte Podporu AO3: %{support_url}.' + redirects: + html: Z důvodu zachování záložek a seznamů s doporučeními mohou být webové + adresy importovaného archivu po omezenou dobu přesměrovány na importovanou + kopii těchto prací (pro jistotu zkontrolujte oznámení k vašemu archivu). + Pokud jste již nahráli kopii těchto děl a %{negation}použili jste funkci + importování z URL, budou na webu AO3 dvě kopie též práce. + subject: "[%{app_name}] Nahrané práce" + update_redirect: + contact_open_doors: kontaktujte projekt Open Doors + html: Chcete-li, aby projekt Open Doors aktualizoval přesměrování na vaši + již existující práci, smažte prosím importovanou kopii a %{contact_open_doors_link} + se jménem vašeho účtu na AO3, vašeho účtu v importovaném archivu a názvem + a URL fanouškovské práce, ke které chcete, aby přesměrování vedlo. (Pokud + máte více prací, u kterých chcete přesměrování změnit, můžete je uvést do + jednoho e-mailu.) + text: Chcete-li, aby projekt Open Doors aktualizoval přesměrování na vaši + již existující práci, smažte prosím importovanou kopii a kontaktujte projekt + Open Doors %{open_doors_url} se jménem vašeho účtu na AO3, vašeho účtu v + importovaném archivu a názvem a URL fanouškovské práce, ke které chcete, + aby přesměrování vedlo. (Pokud máte více prací, u kterých chcete přesměrování + změnit, můžete je uvést do jednoho e-mailu.) + works_by: 'Tyto práce byly vedeny pod e-mailovou adresou: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Všechna zadání byla rozeslána. + subject: Zadání rozeslána + html: + received_message: 'Máte novou zprávu o vaší sbírce %{collection_link}:' + text: + received_message: 'Máte novou zprávu o vaší sbírce "%{collection_title}" (%{collection_url}):' + creatorship_notification: + explanation: Pokud jste spoluautorkou/em práce, můžete být přidány/i jako spoluautorky/ři + nových kapitol nehledě na vaše nastavení preferencí ohledně spoluautorství. + Budete také přidáni do všech sérií, do nichž bude tato práce přidána. + html: + creation: "%{creation_link} od %{pseud_links}" + edit_chapter: editovat kapitolu + edit_series: editovat sérii + remove_chapter: Pokud jste byly/i přidány/i omylem nebo nechcete být uváděny/i + jako autor/ka, zvolte možnost %{edit_chapter_link}, abyste se autorství + zřekly/i. + remove_series: Pokud jste byly/i přidány/i omylem nebo nechcete být uváděny/i + jako autor/ka, zvolte možnost %{edit_series_link}, abyste se autorství zřekly/i. + intro_chapter: 'Uživatel/ka %{adding_user} uvedl/a váš pseudonym %{pseud} jako + spoluautorku/a následující kapitoly:' + intro_series: 'Uživatel/ka %{adding_user} uvedl/a váš pseudonym %{pseud} jako + spoluautorku/a následující série:' + subject: "[%{app_name}] Oznámení o spoluautorství" + text: + creation: "%{title} (%{url}) od %{pseuds}" + remove_chapter: 'Pokud jste byly/i přidány/i omylem nebo nechcete být uváděny/i + jako autor/ka, můžete kapitolu editovat, abyste se autorství zřekly/i: %{url}' + remove_series: 'Pokud jste byly/i přidány/i omylem nebo nechcete být uváděny/i + jako autor/ka, můžete sérii editovat, abyste se autorství zřekly/i: %{url}' + creatorship_notification_archivist: + explanation: Jedná s vlastní pravomocí jakožto archivář Open Doors (Otevřené + dveře), a proto vás smí přidat bez požadavku, i když jste pro svůj pseudonym + spoluautorství zakázali. + html: + creation: "%{creation_link} od %{pseud_links}" + edit_chapter: upravit kapitolu + edit_series: upravit sérii + edit_work: upravit práci + remove_chapter: Pokud jste byli přidáni omylem nebo nechcete být uváděni jako + autor, zvolte možnost %{edit_chapter_link}, abyste se autorství zřekli. + remove_series: Pokud jste byli přidáni omylem nebo nechcete být uváděni jako + autor, zvolte možnost %{edit_series_link}, abyste se autorství zřekli. + remove_work: Pokud jste byli přidáni omylem nebo nechcete být uváděni jako + autor, zvolte možnost %{edit_work_link}, abyste se autorství zřekli. + intro_chapter: 'Uživatel %{archivist} uvedl váš pseudonym %{pseud} jako spoluautora + následující kapitoly:' + intro_series: 'Uživatel %{archivist} uvedl váš pseudonym %{pseud} jako spoluautora + následující série:' + intro_work: 'Uživatel %{archivist} uvedl váš pseudonym %{pseud} jako spoluautora + následující práce:' + subject: "[%{app_name}] Oznámení archiváře o spoluautorství" + text: + creation: "%{title} (%{url}) od %{pseuds}" + remove_chapter: 'Pokud jste byli přidáni omylem nebo nechcete být uváděni + jako autor, můžete kapitolu upravit, abyste se autorství zřekli: %{url}' + remove_series: 'Pokud jste byli přidáni omylem nebo nechcete být uváděni jako + autor, můžete sérii upravit, abyste se autorství zřekli: %{url}' + remove_work: 'Pokud jste byli přidáni omylem nebo nechcete být uváděni jako + autor, můžete práci upravit, abyste se autorství zřekli: %{url}' + creatorship_request: + html: + creation: "%{creation_link} od %{pseud_links}" + instructions: Tuto pozvánku můžete přijmout nebo odmítnout na stránce %{page_name}. + page_name: Co-Creator Requests (Pozvánky ke spoluautorství) + intro_chapter: 'Uživatel %{inviting_user} zaslal vašemu pseudonymu %{pseud} + pozvánku ke spoluautorství u následující kapitoly:' + intro_series: 'Uživatel %{inviting_user} zaslal vašemu pseudonymu %{pseud} pozvánku + ke spoluautorství u následující série:' + intro_work: 'Uživatel %{inviting_user} zaslal vašemu pseudonymu %{pseud} pozvánku + ke spoluautorství u následující práce:' + subject: "[%{app_name}] Pozvánka ke spoluautorství" + text: + creation: "%{title} (%{url}) od %{pseuds}" + instructions: 'Tuto pozvánku můžete přijmout nebo odmítnout na stránce Co-Creator + Requests (Pozvánky ke spoluautorství): %{url}' + delete_work_notification: + attachment: Kopii své práce najdete v příloze. + deleted_other: + html: Vaše práce %{title} byla smazána na žádost %{pseud}. + text: Vaše práce "%{title}" byla smazána na žádost %{pseud}. + deleted_yourself: + html: Vaše práce %{title} byla na vaši žádost smazána. + text: Vaše práce "%{title}" byla na vaši žádost smazána. + questions: + html: Pokud máte nějaké otázky, prosím %{support}. + text: Pokud máte nějaké otázky, prosím %{support} (%{url}). + subject: "[%{app_name}] Vaše práce byla smazána" + support: kontaktujte Podporu + invitation_to_claim: + access: + text: V závislosti na archivu, ze kterého byly vaše práce importovány, mohly + být přístupné pouze registrovaným uživatelům (aby byly mimo dosah vyhledávání + Google). Pokud je toto váš případ, budou tyto práce dostupné pouze registrovaným + uživatelům, pokud se nerozhodnete učinit je plně přístupnými. Pro pomoc + se zpřístupňováním, opuštěním nebo mazáním vašich prací, kontaktujte prosím + Podporu AO3. + claim_or_remove: + html: Ke svým pracím se příhlásíte nebo je odstraníte zde. + text: 'Své práce si zaberete nebo odstraníte zde: %{claim_url}' + email_tips: Pokud se nás rozhodnete kontaktovat, prosím přidejte si e-mailové + adresy z domény @transformativeworks.org na svůj seznam povolených adres a + zkontrolujte složku spamu pro případ, že by naše odpověď skončila tam. + html: + ao3_news: AO3 News + contact_open_doors: kontaktujte Open Doors + contact_support: kontaktujte podporu AO3 + faq_page: stránce FAQ - často kladených otázek + tutorial_page: stránce s návody + introduction: + text: Dostali jste tento e-mail, protože v rámci projektu Open Doors (Otevřené + dveře) (%{open_doors_link}) došlo v nedávné době k importu archivu do %{app_name} + (%{app_short_name} - %{app_url}) a my věříme, že následující práce patří + vám. Rádi bychom vám umožnili se k těmto pracím přihlásit (nebo je smazat/opustit), + pokud máte zájem. A pokud ještě nemáte účet pod jiným emailem, chceme vás + tímto pozvat na palubu! + mistake: + text: Pokud došlo k omylu a toto nejsou vaše práce, prosím, nemažte je! Prosím, + kontaktujte Open Doors (%{open_doors_link}) a my se o to postaráme. + more_info: + text: Oznámení o nedávných přesunech archivu si můžete přečíst na AO3 News + (%{news_link}) a další informace najdete na Open Doors' FAQ – stránce často + kladených otázek k projektu Otevřené dveře (%{open_doors_faq_link}) nebo + na stránce s návody (%{open_doors_tutorial_link}). S jakýmikoliv otázkami + nezodpovězenými v FAQ a návodech nebo v tomto e-mailu prosím kontaktujte + Podporu na %{support_link}. + other_works: + text: Pokud jste v tomto importovaném archivu měli další práce uvedené pod + e-mailovou adresou, k níž již nemáte přístup, prosím kontaktujte Open Doors + s jakoukoliv informací, která by mohla pomoci ověřit vaši identitu. + questions: + text: S dalšími dotazy prosím kontaktujte Podporu AO3 na %{support_link}. + redirects: Za účelem zachování seznamů doporučení a záložek mohou webové adresy + importovaného archivu krátkodobě odkazovat na importované kopie těchto prací + (abyste se ujistili, zkontrolujte příspěvek s oznámeními o vašem archivu). + Pokud jste již nahráli kopii této práce a NEpoužili jste možnost importovat + z URL, budou v archivu dvě kopie této práce. + subject: "[%{app_name}] Výzva k přihlášení se o vaše práce" + unwanted: + text: Pokud vám tyto práce opravdu patří, ale nechcete je, můžete je opustit + (pak zůstanou na AO3, ale vaše jméno bude odstraněno) nebo je smazat (pak + budou z AO3 úplně odstraněny). Pro opuštění nebo smazání nepotřebujete tyto + práce přidávat k účtu – můžete tak udělat přímo pod odkazem výše. (Pro pomoc + prosím kontaktujte Podporu na %{support_link}.) + update_redirect: + text: Pokud si přejete, aby projekt Open Doors změnil přesměrování na vaši + již existující práci, prosím smažte importovanou kopii, kontaktujte Open + Doors pomocí tohoto odkazu %{open_doors_link} a sdělte jim vaše jméno na + AO3, vaše jméno na importovaném archivu a název a URL práce, na kterou chcete, + aby odkaz přesměrovával. (Pokud si přejete změnit přesměrování pro více + prací, můžete je všechny vyjmenovat v jednom emailu.) + uploaded_list: 'Mezi nahranými pracemi se nachází:' + invite_increase_notification: + html: + body: + few: Rádi bychom vám sdělili, že máte %{count} nové pozvánky. Tyto pozvánky + lze využít k vytvoření nových účtů na AO3. Své přátele můžete pozvat na + %{invitation_page_link}. + one: Rádi bychom vám sdělili, že máte %{count} novou pozvánku, kterou lze + využít k vytvoření nových účtů na AO3. Své přátele můžete pozvat na %{invitation_page_link}. + other: Rádi bychom vám sdělili, že máte %{count} nových pozvánek. Tyto pozvánky + lze využít k vytvoření nových účtů na AO3. Své přátele můžete pozvat na + %{invitation_page_link}. + invitation_page_link_text: své stránce s pozvánkami + subject: "[%{app_name}] Nové pozvánky" + text: + body: + few: Rádi bychom vám sdělili, že máte %{count} nové pozvánky. Tyto pozvánky + lze využít k vytvoření nových účtů na AO3. Své přátele můžete pozvat na + své stránce s pozvánkami (%{invitation_page_url}). + one: Rádi bychom vám sdělili, že máte %{count} novou pozvánku, kterou lze + využít k vytvoření nových účtů na AO3. Své přátele můžete pozvat na své + stránce s pozvánkami (%{invitation_page_url}). + other: Rádi bychom vám sdělili, že máte %{count} nových pozvánek. Tyto pozvánky + lze využít k vytvoření nových účtů na AO3. Své přátele můžete pozvat na + své stránce s pozvánkami (%{invitation_page_url}). + invite_request_declined: + main: + few: S lítostí vám oznamujeme, že vaší žádosti o %{count} nové pozvánky nemůže + být v současné době vyhověno. + many: S lítostí vám oznamujeme, že vaší žádosti o %{count} nových pozvánek + nemůže být v současné době vyhověno. + one: S lítostí vám oznamujeme, že vaší žádosti o novou pozvánku nemůže být + v současné době vyhověno. + other: S lítostí vám oznamujeme, že vaší žádosti o %{count} nových pozvánek + nemůže být v současné době vyhověno. + reason: 'Vaše žádost byla:' + subject: "[%{app_name}] Žádost o dodatečnou pozvánku zamítnuta" + recipient_notification: + html: + collection: Vám darovaná práce byla zveřejněna ve sbírce %{collection_link} + na AO3! + no_collection: Na AO3 pro vás byla zveřejněna fanouškovská práce! + subject: + collection: "[%{app_name}][%{collection_title}] Vám darovaná práce ze sbírky + %{collection_title}" + no_collection: "[%{app_name}] Fanouškovská práce jako dárek pro vás" + text: + collection: Ve sbírce "%{collection_title}" (%{collection_url}) na AO3 byla + zveřejněna vám darovaná práce! + signup_notification: + activate: + html: Prosím, %{activate_account_link}. + text: 'Prosím, aktivujte svůj účet pod tímto odkazem: %{activate_account_url}' + activate_your_account: 'Pro aktivaci vašeho účtu klikněte na tento odkaz ' + admin_posts: Novinky AO3 + bye: Doufáme, že se vám zde bude líbit. + contact_support: Kontaktujte naši Podporu + faq: FAQ + features: + html: Jakmile bude váš účet zprovozněn, budete moci přidávat své fanouškovské + práce, nastavit si upozornění na e-mail, které vás upozorní, pokud dojde + k aktualizaci u vašeho oblíbeného díla či autora, nastavit si vzhled stránky, + zaznamenávat v historii práce, které jste si již v Archivu zobrazili a mnoho + dalšího. + text: Jakmile bude váš účet zprovozněn, budete moci přidávat své fanouškovské + práce, nastavit si upozornění na email, které vám dá vědět v případě, že + dojde k aktualizaci u vašeho oblíbeného díla či autora, nastavit si vzhled + stránky, zaznamenávat v historii práce, které jste si již na Archivu zobrazili + a mnoho dalšího. + information: + html: Náš %{faq_link} poskytuje ohledně užívání Archivu spousta informací + a rad. Pokud vás zajímají novinky spojené s rozvojem stránky, můžete je + najít v %{admin_posts_link}. V případě, že budete potřebovat pomoc, narazíte + na chybu či budete mít dotaz nebo komentář, %{contact_support_link}, která + je vždy připravena a ochotna pomoci. + text: Pod odkazem na FAQ %{faq_url} najdete spoustu informací a rad k používání + Archivu. Novinky spojené s rozvojem stránky si můžete přečíst na Novinkách + AO3 pod odkazem %{admin_posts_url}. V případě, že budete potřebovat pomoc, + narazíte na chybu či budete mít dotaz nebo komentář, kontaktujte prosím + naši Podporu %{contact_support_url}, která je vždy připravena a ochotna + pomoci. + welcome: Vítejte v Archive of Our Own (Našem vlastním archivu), %{login}! diff --git a/config/locales/phrase-exports/cy.yml b/config/locales/phrase-exports/cy.yml new file mode 100755 index 0000000..2b40a5c --- /dev/null +++ b/config/locales/phrase-exports/cy.yml @@ -0,0 +1,672 @@ +--- +cy: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Rhybuddion:' + many: 'Rhybuddion:' + one: 'Rhybudd:' + other: 'Rhybuddion:' + two: 'Rhybuddion:' + category: + name_with_colon: + few: 'Categorïau:' + many: 'Categorïau:' + one: 'Categori:' + other: 'Categorïau:' + two: 'Categorïau:' + character: + name_with_colon: + few: 'Cymeriadau:' + many: 'Cymeriadau:' + one: 'Cymeriad:' + other: 'Cymeriadau:' + two: 'Cymeriadau:' + fandom: + name_with_colon: + few: 'Teyrnasoedd:' + many: 'Teyrnasoedd:' + one: 'Teyrnas:' + other: 'Teyrnasoedd:' + two: 'Teyrnasoedd:' + freeform: + name_with_colon: + few: 'Tagiau Ychwenegol:' + many: 'Tagiau Ychwenegol:' + one: 'Tag Ychwanegol:' + other: 'Tagiau Ychwenegol:' + two: 'Tagiau Ychwenegol:' + rating: + name_with_colon: 'Gradd:' + relationship: + name_with_colon: + few: 'Perthnasau:' + many: 'Perthnasau:' + one: 'Perythnas:' + other: 'Perthnasau:' + two: 'Perthnasau:' + work: + chapter_total_display: Penodau + summary: Crynodeb + models: + archive_warning: + few: Rhybuddion + many: Rhybuddion + one: Rhybudd + other: Rhybuddion + two: Rhybuddion + category: + few: Categorïau + many: Categorïau + one: Categori + other: Categorïau + two: Categorïau + chapter: + few: Penodau + many: Penodau + one: Pennod + other: Penodau + two: Penodau + character: + few: Cymeriadau + many: Cymeriadau + one: Cymeriad + other: Cymeriadau + two: Cymeriadau + fandom: + few: Teyrnasoedd + many: Teyrnasoedd + one: Teyrnas + other: Teyrnasoedd + two: Teyrnasoedd + freeform: + few: Tagiau Ychwanegol + many: Tagiau Ychwanegol + one: Tag Ychwanegol + other: Tagiau Ychwanegol + two: Tagiau Ychwanegol + rating: + few: Graddau + many: Graddau + one: Gradd + other: Graddau + two: Graddau + relationship: + few: Perthnasau + many: Perthnasau + one: Perythnas + other: Perthnasau + two: Perthnasau + series: + few: Cyfresau + many: Cyfresau + one: Cyfres + other: Cyfresau + two: Cyfresau + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} o westeion" + many: "%{count} o westeion" + one: un westai + other: "%{count} o westeion" + two: "%{count} o westeion" + left_kudos: + html: + one: Gadawodd %{givers_list} canmol ar %{commentable_link}. + other: Gadawodd %{givers_list} canmol ar %{commentable_link}. + text: + one: Gadawodd %{givers_list} canmol ar %{commentable_title} (%{commentable_url}). + other: Gadawodd %{givers_list} canmol ar %{commentable_title} (%{commentable_url}). + single_guest: + giver: un westai + html: Gadawodd %{giver} canmol ar %{commentable_link}. + text: Gadawodd un westai canmol ar %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Mae gennych chi canmol!" + mailer: + general: + closing: + formal: Yn gywir, + informal: Cofion, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Pennod %{position} o %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} o eiriau" + many: "%{count} o eiriau" + one: "%{count} gair" + other: "%{count} o eiriau" + two: "%{count} o eiriau" + footer: + general: + about: + html: Mae'r "Archive of Our Own - AO3" (Archif Ein Hun) yn archif a chaiff + ei rhedeg a'i chefnogi gan ffaniau, sy'n dibynu ar %{donate_link}. + text: 'Mae''r "Archive of Our Own" (Archif Ein Hun) yn archif a chaiff + ei rhedeg a''i chefnogi gan ffaniau, sy''n dibynu ar eich cyfranniadau: + %{donate_url}.' + html: + donate_link_text: eich cyfranniadau + support_link_text: cysylltwch â Chefnogaeth + unwanted_email: + html: Os rydych chi wedi derbyn y neges hon ar gam, %{support_link}. + text: 'Os rydych wedi derbyn y neges hon ar gam, cysylltwch â Chefnogaeth + fama: %{support_url}.' + sent_at: Anfonwyd at %{sent_at}. + greeting: + formal_html: I %{name}, + informal: + addressed_html: Helo, %{name}! + unaddressed: Helo! + introductory: Helo o'r "Archive of Our Own – AO3" (Archif Ein Hun)! + metadata_label_indicator: ":" + signature: + abuse_team: Y tîm Camdriniaeth + app_short_name: AO3 + open_doors: Y tîm "Open Doors" (Drysau Agored) + parent_org: '"Organisation for Transformative Works - OTW" (Mudiad Cyfryngau + Trawsffurfiadwy)' + support: Y tîm Cefnogaeth AO3 + users: + mailer: + reset_password_instructions: + expiration: Os na ddefnyddiwch y ddolen hon i ailosod eich cyfrinair o fewn + wythnos, bydd y ddolen yn dod i ben, a bydd rhaid i chi ofyn am un newydd. + intro: 'Mae rhywun yn ceisio ailosod y gyfrinair ar gyfer eich cyfrif. Gallwch + newid cyfrinair eich cyfrif trwy ddilyn y ddolen isod a mewnbynnu eich cyfrinair + newydd:' + link_title: Newid fy nghyfrinair. + subject: "[%{app_name}] Ailosod eich gyfrinair" + unrequested: Os na wnaethoch chi ceisio ailosod y cyfrinair hwn, gallwch anwybyddu'r + e-bost hwn a bydd eich cyfrinair blaenorol yn parhau i weithio. + user_mailer: + admin_deleted_work_notification: + bye: Cysylltwyd gopi o'ch gwaith am eich cofnodion. + contact_abuse: cysylltwch â'n Pwyllgor Polisi a Chamdriniaeth + deleted: + html: Dileüwyd eich gwaith %{title} o'r Archif gan weinyddydd. + text: Dileüwyd eich gwaith %{title} o'r Archif gan weinyddydd. + html: + tos_violation: Os mae'n bosib yr oedd eich gwaith yn torri Telerau'r Archif, + %{contact_abuse_link}. + import_project: + html: Os yr oedd eich gwaith yn rhan o brosiect mewforiad gan "Open Doors" + (Drysau Agored), %{opendoors_link} gyda unrhyw holiadau pellach. + text: Os yr oedd eich gwaith yn rhan o brosiect mewforiad gan "Open Doors" + (Drysau Agored), cysylltwch â Drysau Agored (%{opendoors_link}) gyda unrhyw + holiadau pellach. + opendoors: cysylltwch â Drysau Agored + subject: "[%{app_name}] Dileuwyd eich gwaith gan weinyddydd" + text: + tos_violation: Os mae'n bosib yr oedd eich gwaith yn torri Telerau'r Archif, + cysylltwch âg ein Pwyllgor Polisi a Chamdriniaeth (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Tra bod eich gwaith wedi'i guddio, gallwch barhau i gael gafael arno + trwy'r ddolen uchod, ond ni fydd yn cael ei restru ar eich tudalen waith, + nag ar gael i ddefnyddyddion AO3 eraill. + check_email: Gwiriwch eich e-bost, os gwelwch yn dda, gan gynnwys eich ffolder + sbam, oherwydd efallai bod y tîm eisoes wedi cysylltu â chi i esbonio pam + fod eich gwaith wedi'i guddio. + contact_abuse: cysylltwch â'r tîm Camdriniaeth + html: + help: Os ydych yn ansicr pam fod eich gwaith yn gudd, ac nid ydych wedi derbyn + cyfathrebu pellach ynghylch y mater hwn, %{contact_abuse_link}. + hidden: Mae eich gwaith %{title} wedi'i guddio gan y tîm Camdriniaeth a nid + yw'n bellach yn hygyrch i'r cyhoedd. + tos_violation: Os cafodd y gwaith ei guddio oherwydd toriad %{tos_link} yr + AO3, bydd rhaid i chi gywiro'r toriad. Gall methu â dod â'ch gwaith i gydymffurfio + â'r telerau arwain at y gwaith yn cael ei ddileu o'r AO3. + subject: "[%{app_name}] Mae eich gwaith wedi'i guddio gan y tîm Camdriniaeth" + text: + help: 'Os ydych yn ansicr pam fod eich gwaith yn gudd, ac nid ydych wedi derbyn + cyfathrebu pellach ynghylch y mater hwn, cysylltwch â''r tîm Camdriniaeth: + %{contact_abuse_url}.' + hidden: Mae eich gwaith "%{title}" (%{work_url}) wedi'i guddio gan y tîm Camdriniaeth + a nid yw'n bellach yn hygyrch i'r cyhoedd. + tos_violation: Os cafodd y gwaith ei guddio oherwydd toriad Telerau'r AO3 + (%{tos_url}), bydd rhaid i chi gywiro'r toriad. Gall methu â dod â'ch gwaith + i gydymffurfio â'r telerau arwain at y gwaith yn cael ei ddileu o'r AO3. + tos: Telerau + anonymous_or_unrevealed_notification: + anonymous_info: Mae gwaith dienw yn cael eu cynnwys mewn rhestrau tag, ond nid + ar eich tudalen gwaith. Ar y gwaith, bydd eich enw cyfrif yn cael ei ddisodli + gan "Anonymous" (Dienw) + anonymous_unrevealed_info: Gall y cynhalydd casglu ddatgelu eich gwaith ond + byddant yn ei adael yn ddienw. Ni fydd pobl sy'n tanysgrifio i chi yn cael + gwybod am y newid. Ar ôl cael ei ddatgelu, bydd eich gwaith yn cael ei gynnwys + mewn rhestrau tagiau, ond nid ar eich tudalen waith. Ar y gwaith, bydd eich + enw yn cael ei ddisodli gan "Anonymous" (Dienw). + changed_status: + anonymous: + html: Mae cynhalyddion casglu %{collection_link} wedi newid statws eich + gwaith %{work_link} i ddienw. + text: Mae cynhalydd casglu "%{collection_title}" (%{collection_url}) wedi + newid statws eich gwaith "%{work_title}" (%{work_url}) i ddienw. + anonymous_unrevealed: + html: Mae cynhalydd casglu %{collection_link} wedi newid statws eich gwaith + %{work_link} i ddienw ac anamlygadwy. + text: Mae cynhalydd casglu "%{collection_title}" (%{collection_url}) wedi + newid statws eich gwaith "%{work_title}" (%{work_url}) i ddienw ac anamlygadwy. + unrevealed: + html: Mae cynhalyddion casglu %{collection_link} wedi newid statws eich + gwaith %{work_link} i anamlygadwy. + text: Mae cynhalydd casglu "%{collection_title}" (%{collection_url}) wedi + newid statws eich gwaith "%{work_title}" (%{work_url}) i anamlygadwy. + collection_items_link_text: Tudalen "Approved Collection Items" (Eitemau Casglu + Cymeradwyol) + do_not_want: + anonymous: + html: Os nad ydych am i'ch gwaith fod yn ddienw, ewch i'ch %{collection_items_link} + i'w dileu o'r casgliad. + text: Os nad ydych am i'ch gwaith fod yn ddienw, ewch i'ch tudalen Eitemau + Casglu Cymeradwyol i'w dileu o'r casgliad. %{collection_items_url} + anonymous_unrevealed: + html: Os nad ydych am i'ch gwaith fod yn ddienw ac anamlygadwy, ewch i'ch + %{collection_items_link} i'w dileu o'r casgliad. + text: Os nad ydych am i'ch gwaith fod yn ddienw ac anamlygadwy, ewch i'ch + tudalen Eitemau Casglu Cymeradwyol i'w dileu o'r casgliad. %{collection_items_url} + unrevealed: + html: Os nad ydych am i'ch gwaith fod yn anamlygadwy, ewch i'ch %{collection_items_link} + i'w dileu o'r casgliad. + text: Os nad ydych am i'ch gwaith fod yn anamlygadwy, ewch i'ch tudalen + Eitemau Casglu Cymeradwyol i'w dileu o'r casgliad. %{collection_items_url} + faq_link_text: Holiadau Cyffredin Casgliadau + more_info: + html: Am mwy o wybodaeth, gwelwch y dudalen %{faq_link}. + text: 'Am mwy o wybodaeth, gwelwch y dudalen Holiadau Cyffredin Casgliadau: + %{faq_url}' + subject: + anonymous: "[%{app_name}] Gwnaed eich gwaith yn ddienw" + anonymous_unrevealed: "[%{app_name}] Gwnaed eich gwaith yn ddienw ac yn anamlygadwy" + unrevealed: "[%{app_name}] Gwnaed eich gwaith yn anamlygadwy" + unrevealed_info: Nid yw gwaith anamlygadwy wedi'i gynnwys mewn rhestrau tag + neu ar eich tudalen waith. Bydd pobl sy'n dilyn cysylltu i'r gwaith yn derbyn + hysbysiad ei fod yn anamlygadwy. Ni fyddant yn gallu cael gafael ar ei gynnwys. + archivist_added_to_collection_notification: + approved_collection_items_page: Tudalen Approved Collection Items (Eitemau Casglaid + Cymeradwy) + archivist_notice: Wrth weithdredu yn rhinwedd eu swydd fel archifyddion Open + Doors (Drysau Agored), caniateir iddynt ychwanegu eich gwaith at y casgliad + hwn, hyd yn oed os oes gennych wahoddiadau casglad wedi'u hanalluogi. Bydd + archifwyr yn ychwanegu gwaith at gasgliad dim ond os cafodd ei gynnal ar archif + wedi'i fewnforio. + removal_instructions: + html: Os hoffech dynnu eich gwaith o'r casgliad hwn, gwelwch eich %{approved_items_link}. + text: 'Os hoffech dynnu eich gwaith o''r casgliad hwn, gwelwch eich tudalen + Approved Collection Items (Eitemau Casglaid Cymeradwy): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Mae archifydd Open Doors (Drysau + Agored) wedi ychwanegu eich gwaith at gasgliad." + work_added: + html: Mae cynhalwyr y casgliad %{collection_link} wedi ychwanegu eich gwaith + %{work_link} to at eu casgliad! + text: Mae cynhalwyr y casgliad "%{collection_title}" (%{collection_url}) wedi + ychwanegu eich gwaith "%{work_title}" (%{work_url}) at eu casgliad! + challenge_assignment_notification: + any: Unrhyw + assignment: + html: Mae'r cais hon yn yr her %{link} ar Archif Ein Hun wedi'i aseinio i + chi! + description: 'Disgrifiad:' + due: 'Mae''r aseiniad hwn yn ddyledus am:' + html: + footer: Rydych chi'n derbyn yr ebost hyn oherwydd wnaethoch cofrestru ar gyfer + yr her %{title}. Am fwy o wybodaeth am yr her hon ac am fanylion cyswllt + y cymedrolyddion, gwelwch %{footer_link}. + footer_link: tudalen proffil yr her + look_up: Gallwch weld yr aseiniad hwn ar %{link}. + look_up_link: Eich Aseiniadau + optional_tags: 'Tagiau Ychwanegol:' + prompts: 'Annogion:' + prompt_url: 'URL Annogiad:' + recipient: 'Derbynydd:' + recipient_missing: 'Neb: cysylltwch â chymedrolydd am help!' + subject: "[%{app_name}][%{collection_title}] Eich Aseiniad!" + text: + assignment: Mae'r cais hon yn yr her "%{collection_title}" (%{collection_url}) + ar Archif Ein Hun wedi'i aseinio i chi! + footer: Rydych chi'n derbyn yr ebost hyn oherwydd wnaethoch cofrestru ar gyfer + y her %{title} (%{url}). Am fwy o wybodaeth am yr her hon ac am fanylion + cyswllt y cymedrolyddion, gwelwch %{profile_url}. + look_up: Gallwch edrych ar yr aseiniad hwn o'ch tudalen Assignments (Aseiniadau) + ar%{link}. + change_email: + changed: + html: "%{login}, newidwyd yr ebost cysylltiedig i'ch cyfrif i %{email}" + text: "%{login}, newidwyd yr ebost cysylltiedig i'ch cyfrif i %{email}" + subject: "[%{app_name}] Newidiad Ebost" + claim_notification: + access: + contact_support: cysylltwch â Chefnogaeth AO3 + html: Yn dibynnu ar yr archif, mae'n bosibl bod eich gweithiau wedi'u mewnforio + wedi'u cyfyngu i ddefnyddwyr cofrestredig yn unig (er mwyn eu hatal rhag + ymddangos mewn chwiliadau Google). Yn yr achos hwn, dim ond defnyddwyr sydd + wedi mewngofnodi fydd yn gallu eu gweld oni bai eich bod yn dewis eu gwneud + yn weladwy i bawb. Am help i ddatgloi, anghatrefu neu dileu'ch gwaith, %{contact_support_link}. + text: Yn dibynnu ar yr archif, mae'n bosibl bod eich gweithiau wedi'u mewnforio + wedi'u cyfyngu i ddefnyddwyr cofrestredig yn unig (er mwyn eu hatal rhag + ymddangos mewn chwiliadau Google). Yn yr achos hwn, dim ond defnyddwyr sydd + wedi mewngofnodi fydd yn gallu eu gweld oni bai eich bod yn dewis eu gwneud + yn weladwy i bawb. Am help i ddatgloi, anghatrefu neu dileu'ch gwaith, cysylltwch + â Chefnogaeth at %{support_url}. + email_tips: Os cysylltwch â ni, ychwanegwch gyfeiriadau e-bost oddi wrth @transformativeworks.org + to i'ch rhestr o gysylltiadau diogel a gwiriwch eich ffolder sothach am ein + hateb. + introduction: + ao3_name: Archive of Our Own – AO3 (Archif Ein Hun) + html: Rydych chi'n derbyn yr e-bost hwn oherwydd eich gwaith mewn archif Ffangyfryngau + sydd wedi'i fewnforio gan %{open_doors_name_link} i'r %{app_link}. Oherwydd + mae'r cyfeiriad e-bost hwn yn gysylltiedig ag un sydd wedi'i gofrestru ar + yr archif a fewnforiwyd, mae'r ffanweithiau (a restrir isod) cysylltiedig + wedi'u hychwanegu'n awtomatig at eich cyfrif AO3. + open_doors_name: Drysau Agored + text: 'Rydych chi''n derbyn yr e-bost hwn oherwydd eich gwaith mewn archif + Ffangyfryngau sydd wedi''i fewnforio gan Open Doors (Drysau Agored) (%{open_doors_url}) + i''r Archive of Our Own – AO3 (Archif Ein Hun): %{app_url}. Oherwydd bod + y cyfeiriad e-bost hwn yn gysylltiedig ag un sydd wedi''i gofrestru ar yr + archif a fewnforiwyd, mae''r ffanweithiau (a restrir isod) cysylltiedig + wedi''u hychwanegu''n awtomatig at eich cyfrif AO3.' + mistake: + contact_open_doors: cysylltwch â Drysau Agored + html: Os camgymeriad yw hyn, ac nid yw'r gweithiau hwn yn perthyn i chi, peidiwch + â'u dileu os gwelwch yn dda! %{contact_open_doors_link} i ddatrys y sefyllfa. + text: Os camgymeriad yw hyn, ac nid yw'r gweithiau hwn yn perthyn i chi, peidiwch + â'u dileu os gwelwch yn dda! Cysylltwch â Drysau Agored (%{open_doors_url}) + i ddatrys y sefyllfa. + more_info: + ao3_news: Newyddion AO3 + contact_support: cysylltwch â Chefnogaeth AO3 + faq_page: Tudalen Holiadau Cyffredin + html: Gallwch ddarllen cyhoeddiadau am symudiadau archif diweddar yn %{ao3_news_link}, + a dod o hyd i ragor o wybodaeth ar y %{faq_page_link} neu'r %{tutorial_page_link} + Drysau Agored. Am gwestiynau eraill heb eu hateb yn yr holiadau cyffredin, + tiwtorialau, neu'r e-bost hwn, %{contact_support_link}. + text: Gallwch ddarllen cyhoeddiadau am symudiadau archif diweddar yn Newyddion + AO3 (%{news_url}), a dod o hyd i ragor o wybodaeth ar dudalen holiadau cyffredin + (%{open_doors_faq_url}) neu dudalen tiwtorial (%{open_doors_tutorial_url}) + y Drysau Agored. Am gwestiynau eraill heb eu hateb yn yr holiadau cyffredin, + tiwtorialau, neu'r e-bost hwn, cysylltwch â Chefnogaeth at %{support_url}. + tutorial_page: dudalen tiwtorial + other_works: + contact_open_doors: cysylltwch â Drysau Agored + html: Os oedd gennych weithiau eraill ar yr archif a fewnforiwyd o dan gyfeiriad + e-bost ni allwch gael mynediad iddo fwyach, %{contact_open_doors_link} gydag + unrhyw wybodaeth a all wirio pwy ydych. + text: Os oedd gennych weithiau eraill ar yr archif a fewnforiwyd o dan gyfeiriad + e-bost ni allwch gael mynediad iddo fwyach, cysylltwch â Drysau Agored gydag + unrhyw wybodaeth a all wirio pwy ydych. + questions: + contact_support: cysylltwch â Chefnogaeth AO3 + html: Am ymholiadau eraill, %{contact_support_link}. + text: Am ymholiadau eraill, cysylltwch â Chefnogaeth AO3 at %{support_url}. + redirects: + html: I gadw rhestrau awgrymu a thudalnodau, gall cyfeiriadau gwe'r archif + a fewnforiwyd ailgyfeirio i'r copi o'r gweithiau hyn a fewnforiwyd am gyfnod + cyfyngedig (edrychwch ar bostiad cyhoeddiad eich archif i fod yn sicr). + Os ydych chi eisoes wedi uwchlwytho copi o'r gweithiau hyn a %{negation} + defnyddioch chi'r nodwedd mewnforio o URL, bydd dau gopi o'r un gwaith ar + AO3. + subject: "[%{app_name}] Gweithiau wedi'u llwytho i fyny" + update_redirect: + contact_open_doors: cysylltwch â Drysau Agored + html: Os hoffech i Ddrysau Agored ddiweddaru'r ailgyfeiriad i dynnu sylw at + eich gwaith sy'n bodoli eisoes, dilëwch y copi a fewnforiwyd, ac wedyn %{contact_open_doors_link} + gyda'ch enw cyfrif AO3 a'r archif a fewnforiwyd, a theitl ac URL y gwaith + yr hoffech i'r ailgyfeiriad gyfeirio ato. (I newid ailgyfeiriadau lluosog, + gallwch restr pob gwaith yn un e-bost.) + text: Os hoffech i Ddrysau Agored ddiweddaru'r ailgyfeiriad i dynnu sylw at + eich gwaith sy'n bodoli eisoes, dilëwch y copi a fewnforiwyd, a chysylltwch + â Drysau Agored at %{open_doors_url} gyda'ch enw cyfrif AO3 a'r archif a + fewnforiwyd, a theitl ac URL y gwaith yr hoffech i'r ailgyfeiriad gyfeirio + ato. (I newid ailgyfeiriadau lluosog, gallwch restr pob gwaith yn un e-bost.) + works_by: 'Ysgrifennwyd y gweithiau hyn o dan yr e-bost: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Mae pob aseiniad yn awr wedi'i hanfon. + subject: Aseiniadau wedi'i hanfon + html: + received_message: 'Rydych wedi derbyn neges amdan eich casgliad %{collection_link}:' + text: + received_message: 'Rydych wedi derbyn neges amdan eich casgliad "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Pan rydych yn gyd-greüydd ar waith, gallwch cael eich ychwwnegu + i benodau newydd waeth beth yw eich gosodiadau cyd-greu. Byddwch hefyd yn + cael eich ychwanegu i unrhyw gyfres mae'r gwaith yn cael ei ychwanegu ati. + html: + creation: "%{creation_link} gan %{pseud_links}" + edit_chapter: olygu'r bennod + edit_series: olygu'r gyfres + remove_chapter: Os ydych wedi cael eich ychwanegu ar gam neu nad ydych chi + am gael eich rhestru fel creüydd, gallwch %{edit_chapter_link} i dynnu'ch + hun fel creüydd. + remove_series: Os ydych wedi cael eich ychwanegu ar gam neu nad ydych chi + am gael eich rhestru fel creüydd, gallwch %{edit_series_link}i dynnu'ch + hun fel creüydd. + intro_chapter: 'Mae''r defnyddydd %{adding_user} wedi rhestru''ch ffugenw %{pseud} + fel cyd-greüydd ar y bennod ganlynol:' + intro_series: 'Mae''r defnyddydd %{adding_user} wedi rhestru''ch ffugenw %{pseud} + fel cyd-greüydd ar y gyfres ganlynol:' + subject: "[%{app_name}] Hysbysiad cyd-greüydd" + text: + creation: "%{title} (%{url}) gan %{pseuds}" + remove_chapter: Os ydych wedi cael eich ychwanegu ar gam neu nad ydych chi + am gael eich rhestru fel creüydd, gallwch golygu'r bennod ii dynnu'ch hun + fel creüydd. %{url} + remove_series: 'Os ydych wedi cael eich ychwanegu ar gam neu nad ydych chi + am gael eich rhestru fel creüydd, gallwch olygu''r gyfres i dynnu''ch hun + fel creüydd: %{url}' + creatorship_notification_archivist: + explanation: Oherwydd maent yn gweithio yn ei medr fel archifydd "Open Doors" + (Drysau Agored), gallant eich ychwanegu heb cais, hyd yn oed os rydych wedi + analluogi cyd-greu. + html: + creation: "%{creation_link} gan %{pseud_links}" + edit_chapter: golygu'r bennod + edit_series: golygu'r gyfres + edit_work: golygu'r gwaith + remove_chapter: Os rydych wedi cael eich ychwanegu ar gam, neu na hoffech + gael eich rhestru fel creüydd, gallwch %{edit_chapter_link}i dynnu eich + hun fel creüydd. + remove_series: Os rydych wedi cael eich ychwanegu ar gam, neu na hoffech gael + eich rhestru fel creüydd, gallwch %{edit_series_link}i dynnu eich hun fel + creüydd. + remove_work: Os rydych wedi cael eich ychwanegu ar gam, neu na hoffech gael + eich rhestru fel creüydd, gallwch %{edit_work_link}i dynnu eich hun fel + creüydd. + intro_chapter: 'Mae''r defnyddydd %{archivist} wedi ychwanegu %{pseud} fel cydgreüydd + ar y bennod canlynol:' + intro_series: 'Mae''r defnyddydd %{archivist} wedi ychwanegu %{pseud} fel cydgreüydd + ar y gyfres canlynol:' + intro_work: 'Mae''r defnyddydd %{archivist} wedi ychwanegu %{pseud} fel cydgreüydd + ar y gwaith canlynol:' + subject: "[%{app_name}] Hysbysiad cyd-greüydd archifydd" + text: + creation: "%{title} (%{url}) gan %{pseuds}" + remove_chapter: 'Os rydych wedi cael eich ychwanegu ar gam, neu na hoffech + gael eich rhestru fel creüydd, gallwch olygu''r bennod i dynnu eich hun + fel creüydd: %{url}' + remove_series: 'Os rydych wedi cael eich ychwanegu ar gam, neu na hoffech + gael eich rhestru fel creüydd, gallwch olygu''r gyfres i dynnu eich hun + fel creüydd: %{url}' + remove_work: 'Os rydych wedi cael eich ychwanegu ar gam, neu na hoffech gael + eich rhestru fel creüydd, gallwch olygu''r gwaith i dynnu eich hun fel creüydd: + %{url}' + creatorship_request: + html: + creation: "%{creation_link} gan %{pseud_links}" + instructions: Gallwch dderbyn neu gwrthod y cais yma ar eich tudalen %{page_name}. + page_name: '"Co-Creator Requests" (Ceisiau Cyd-Greüydd)' + intro_chapter: 'Mae''r defnyddydd %{inviting_user} wedi gwahodd eich ffugenw + %{pseud} fel cyd-greüydd ar y bennod ganlynol:' + intro_series: 'Mae''r defnyddydd %{inviting_user} wedi gwahodd eich ffugenw + %{pseud} fel cyd-greüydd ar y gyfres ganlynol:' + intro_work: 'Mae''r defnyddydd %{inviting_user} wedi gwahodd eich ffugenw %{pseud} + fel cyd-greüydd ar y gwaith canlynol:' + subject: Cais cyd-greüydd [%{app_name}] + text: + creation: "%{title} (%{url}) gan %{pseuds}" + instructions: 'Gallwch dderbyn neu gwrthod y cais yma ar eich tudalen "Co-Creator + Requests" (Ceisiau Cyd-Greüydd): %{url}' + delete_work_notification: + attachment: Cysylltwyd gopi o'ch gwaith am eich cofnodion. + deleted_other: + html: Caiff eich gwaith %{title} ei dileu yn ôl dymuniad %{pseud}. + text: Caiff eich gwaith "%{title}" ei dileu yn ôl dymuniad %{pseud}. + deleted_yourself: + html: Caiff eich gwaith %{title} ei dileu yn ôl eich dymuniad chi. + text: Caiff eich gwaith "%{title}" ei dileu yn ôl eich dymuniad chi. + questions: + html: Os mae gennych chi holiadau, %{support}. + text: Os mae gennych chi holiadau, %{support} (%{url}). + subject: "[%{app_name}] Mae eich gwaith wedi cael ei dileu" + support: cysylltwch â Chefnogaeth + invitation_to_claim: + access: + text: Yn dibynnu ar yr archif, efallai bod eich gweithiau wedi'u mewnforio + wedi'u cyfyngu i ddefnyddwyr cofrestredig yn unig (i'w cadw allan o chwiliadau + Gwgl). Os yw hyn yn wir, dim ond defnyddwyr sydd wedi mewngofnodi fydd yn + hygyrch i'r gwaith oni bai eich bod yn dewis eu gwneud yn gwbl weladwy. + I gael help i ddatgloi, amddifadu, neu ddileu eich gwaith, cysylltwch â + Chymorth AO3. + claim_or_remove: + html: Hawliwch neu ddileu eich gwaith yma. + text: 'Hawliwch neu ddileu eich gwaith yma: %{claim_url}' + email_tips: Os ydych yn cysylltu â ni, hawliwch gyfeiriadau e-bost o @transformativeworks.org + a gwiriwch eich ffolderau sbam am ein hateb os gwelwch yn dda. + html: + ao3_news: Newyddion AO3 + contact_open_doors: cysylltu Drysau Agored + contact_support: cysylltu cefnogaeth AO3 + faq_page: tudalen Cwestiynau Cyffredin + tutorial_page: tudalen tiwtorial + introduction: + text: Rydych chi'n derbyn yr e-bost hwn oherwydd bod archif wedi'i mewnforio + yn ddiweddar gan Ddrysau Agored (%{open_doors_link}) i'r%{app_name} (%{app_short_name} + - %{app_url}), a chredwn fod y ffanwaith canlynol yn perthyn i chi. Hoffem + roi cyfle i chi hawlio (neu ddileu/amddifadu) y gweithiau hyn os ydych chi + eisiau. Ac os nad oes gennych gyfrif eisoes o dan e-bost gwahanol, hoffem + eich gwahodd ar fwrdd! + mistake: + text: Os yw hwn yn gamgymeriad ac nid eich gweithiau chi yw’'r rhain, peidiwch + â'u dileu! Cysylltwch â Drysau Agored (%{open_doors_link}) a byddwn yn ei + ddatrys. + more_info: + text: Gallwch ddarllen cyhoeddiadau am symudiadau archif diweddar yn Newyddion + AO3 (%{news_link}), a dod o hyd i wybodaeth ychwanegol ar dudalen Cwestiynau + Cyffredin Drysau Agored (%{open_doors_faq_link}) neu dudalen tiwtorialau + (%{open_doors_tutorial_link}). Am unrhyw gwestiynau na chawsant eu hateb + yn y Cwestiynau Cyffredin, sesiynau tiwtorial, neu'r e-bost hwn, cysylltwch + â Chefnogaeth ar %{support_link}. + other_works: + text: Os oedd gennych weithiau eraill ar yr archif a fewnforiwyd o dan gyfeiriad + e-bost na allwch ei gyrchu mwyach, cysylltwch â Drysau Agored gydag unrhyw + wybodaeth a all helpu i wirio'ch hunaniaeth. + questions: + text: Am bob ymholiad arall, cysylltwch â Chefnogaeth AO3 ar %{support_link}. + redirects: Er mwyn cadw rhestrau argymhelliad a thudalnodau, gall cyfeiriadau + gwe'r archif a fewnforir ailgyfeirio i'r copi a fewnforiwyd o'r gweithiau + hyn am gyfnod cyfyngedig (gwiriwch y post cyhoeddi am eich archif i fod yn + sicr). Os ydych chi eisoes wedi uwchlwytho copi o'r gweithiau hyn ac NAD wnaethoch + chi ddefnyddio'r nodwedd mewnforio o URL, bydd dau gopi o'r un gwaith ar yr + archif. + subject: "[%{app_name}] Gwahoddiad i hawlio gwaith" + unwanted: + text: Os yw'r gweithiau hyn yn eiddo i chi, ond nad ydych eu heisiau, gallwch + amddifadu (fel eu bod yn aros ar yr AO3, ond gyda'ch enw wedi'i dynnu) neu + eu dileu (fel eu bod yn cael eu tynnu o'r AO3 yn llwyr). Nid oes angen i + chi ychwanegu'r gweithiau hyn i unrhyw gyfrif er mwyn eu hamddifadu neu + eu dileu - gallwch wneud hyn yn uniongyrchol o'r ddolen hawlio uchod. (Am + gymorth, cysylltwch â Chefnogaeth ar %{support_link}.) + update_redirect: + text: Os hoffech i Ddrysau Agored ddiweddaru'r ailgyfeiriad i fynd at eich + gwaith sy'n bodoli eisoes, dilëwch y copi a fewnforiwyd, a chysylltwch â + Drysau Agored ar %{open_doors_link} gyda'ch enw cyfrif AO3, enw'ch cyfrif + ar yr archif a fewnforiwyd, a'r teitl ac URL y ffanwaith yr hoffech i'r + ailgyfeiriad fynd ati. (Os oes gennych chi sawl gwaith yr hoffech chi newid + yr ailgyfeiriadau ar eu cyfer, gallwch chi restru'r rhain mewn un e-bost.) + uploaded_list: 'Mae’r gwaith a lanlwythwyd yn cynnwys:' + invite_increase_notification: + html: + body: + one: Hoffem ni gadael i chi gwybod bod gennych chi %{count} wahoddiad newydd, + a allwch ddefnyddio i greu cyfrifau newydd ar yr archif. Gallwch wahodd + ffrind at %{invitation_page_link}. + other: Hoffem ni gadael i chi gwybod bod gennych chi %{count} o wahoddion + newydd, a allwch ddefnyddio i greu cyfrifau newydd ar yr archif. Gallwch + wahodd ffrind at %{invitation_page_link}. + invitation_page_link_text: eich tudalen wahoddiad + subject: "[%{app_name}] Gwahoddiadau Newydd" + text: + body: + one: 'Hoffem ni gadael i chi gwybod bod gennych chi %{count} wahoddiad newydd, + a allwch ddefnyddio i greu cyfrifau newydd ar yr archif. Gallwch wahodd + ffrind at eich tudalen Invitations (Gwahoddiadau): %{invitation_page_url}.' + other: Hoffem ni gadael i chi gwybod bod gennych chi %{count} o wahoddion + newydd, a allwch ddefnyddio i greu cyfrifau newydd ar yr archif. Gallwch + wahodd ffrind at eich tudalen Invitations (Gwahoddiadau)%{invitation_page_url}. + invite_request_declined: + main: + few: Mae'n ddrwg gennym i'ch hysbysu na ellir cyflawni'ch cais am %{count} + wahoddiadau newydd ar hyn o bryd. + many: Mae'n ddrwg gennym i'ch hysbysu na ellir cyflawni'ch cais am %{count} + wahoddiadau newydd ar hyn o bryd. + one: Mae'n ddrwg gennym i'ch hysbysu na ellir cyflawni'ch cais am wahoddiad + newydd ar hyn o bryd. + other: Mae'n ddrwg gennym i'ch hysbysu na ellir cyflawni'ch cais am %{count} + wahoddiadau newydd ar hyn o bryd. + two: Mae'n ddrwg gennym i'ch hysbysu na ellir cyflawni'ch cais am %{count} + wahoddiadau newydd ar hyn o bryd. + reason: 'Roedd eich cais yn:' + subject: "[%{app_name}] Gwrthodwyd cais cod gwahoddiad ychwanegol" + recipient_notification: + html: + collection: Mae gwaith anrheg weid cael ei phostio yng nghasgliad %{collection_link} + ar yr AO3 ar eich cyfer! + no_collection: Mae gwaith anrheg weid cael ei phostio ar yr AO3 ar eich cyfer! + subject: + collection: "[%{app_name}][%{collection_title}] Gwaith anrheg ar eich cyfer + o %{collection_title}" + no_collection: "[%{app_name}] Gwaith anrheg ar eich cyfer" + text: + collection: Mae gwaith anrheg weid cael ei phostio yng nghasgliad "%{collection_title}" + (%{collection_url}) ar yr AO3 ar eich cyfer! + signup_notification: + activate: + html: "%{activate_account_link}." + text: 'Ysgogwch eich cyfrif: %{activate_account_url}' + activate_your_account: Ysgogwch eich cyfrif + admin_posts: pyst gweinyddydd yr archif + bye: Gobeithiym byddwch yn mwynhau defnyddio’r Archif! + contact_support: cysylltwch â’n tîm Cefnogaeth + faq: tudalen Holiadau Cyffredin + features: + html: Unwaith mae eich cyfrif wedi’i osod, gallwch postio eich ffanweithiau, + gosod tanysgrifiadau ebost i adael i chi gwybod pan mae eich ffanweithiau + neu greüydd hoff wedi diweddaru, gosod dewisadau i addasu’r ffordd mae’r + wefan yn edrych ac yn gweithio i chi, dilyn y nifer o weithiau rydych wedi’i + hedrych ar trwy eich hanes, a llawer fwy. + text: Unwaith mae eich cyfrif wedi’i osod, gallwch postio eich ffanweithiau, + gosod tanysgrifiadau ebost i adael i chi gwybod pan mae eich ffanweithiau + neu greüydd hoff wedi diweddaru, gosod dewisadau i addasu’r ffordd mae’r + wefan yn edrych ac yn gweithio i chi, dilyn y nifer o weithiau rydych wedi’i + hedrych ar trwy eich hanes, a llawer fwy. + information: + html: Mae na lwyth o wybodaeth a chefnogaeth ar sut i defnyddio’r archif yn + ein %{faq_link}. Gallwch darganfod ein newyddion fwyaf dilys yn ein %{admin_posts_link}. + Os mae angen help arnoch, neu rydych wedi darganfod gwall, neu mae gennych + chi sylwadau neu holiadau, %{contact_support_link}, a fydd yn hapus i’ch + helpu. + text: 'Mae na lwyth o wybodaeth a chefnogaeth ar sut i defnyddio’r archif + yn ein tudalen Holiadau Cyffredin at %{faq_url}. Gallwch darganfod ein newyddion + fwyaf dilys yn pyst gweinyddydd yr archif at %{admin_posts_url}. Os mae + angen help arnoch, neu rydych wedi darganfod gwall, neu mae gennych chi + sylwadau neu holiadau, cysylltwch âg ein tîm Cefnogaeth, a fydd yn hapus + i’ch helpu: %{contact_support_url}.' + welcome: Croeso i “Archive of Our Own” (Archif Ein Hun), %{login}! diff --git a/config/locales/phrase-exports/da.yml b/config/locales/phrase-exports/da.yml new file mode 100755 index 0000000..099734a --- /dev/null +++ b/config/locales/phrase-exports/da.yml @@ -0,0 +1,616 @@ +--- +da: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Advarsel:' + other: 'Advarsler:' + category: + name_with_colon: + one: 'Kategori:' + other: 'Kategorier:' + character: + name_with_colon: + one: 'Karakter:' + other: 'Karakterer:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandoms:' + freeform: + name_with_colon: + one: 'Yderligere tag:' + other: 'Yderligere tags:' + rating: + name_with_colon: 'Klassificering:' + relationship: + name_with_colon: + one: 'Forhold:' + other: 'Forhold:' + work: + chapter_total_display: Kapitler + summary: Resumé + models: + archive_warning: + one: Advarsel + other: Advarsler + category: + one: Kategori + other: Kategorier + chapter: + one: Kapitel + other: Kapitler + character: + one: Karakter + other: Karakterer + fandom: + one: Fandom + other: Fandoms + freeform: + one: Yderligere tag + other: Yderligere tags + rating: + one: Klassificering + other: Klassificeringer + relationship: + one: Forhold + other: Forhold + series: + one: Serie + other: Serier + kudo_mailer: + batch_kudo_notification: + guest: + one: en gæst + other: "%{count} gæster" + left_kudos: + html: + one: "%{givers_list} efterlod kudos på %{commentable_link}." + other: "%{givers_list} efterlod kudos på %{commentable_link}." + text: + one: "%{givers_list} efterlod kudos på %{commentable_title} (%{commentable_url})." + other: "%{givers_list} efterlod kudos på %{commentable_title} (%{commentable_url})." + single_guest: + giver: En gæst + html: "%{giver} efterlod kudos på %{commentable_link}." + text: En gæst efterlod kudos på %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Du har fået kudos!" + mailer: + general: + closing: + formal: Med venlig hilsen, + informal: Venlig hilsen, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Kapitel %{position} af %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} ord" + other: "%{count} ord" + footer: + general: + about: + html: AO3 er et fan-styret og fan-støttet arkiv, der er afhængig af %{donate_link}. + text: 'AO3 er et fan-styret og fan-støttet arkiv, der er afhængig af dine + bidrag: %{donate_url}.' + html: + donate_link_text: dine bidrag + support_link_text: kontakte Support + unwanted_email: + html: Hvis du har modtaget denne besked ved en fejl, bedes du %{support_link}. + text: Hvis du har modtaget denne besked ved en fejl, bedes du kontakte + Support på %{support_url}. + sent_at: Sendt %{sent_at}. + greeting: + formal_html: Kære %{name}, + informal: + addressed_html: Hej %{name}! + unaddressed: Hej! + introductory: Hej fra Archive of Our Own – AO3 (Vores Eget Arkiv)! + metadata_label_indicator: ":" + signature: + abuse_team: AO3's politik- og misbrugsteam + app_short_name: AO3 + open_doors: The Open Doors (Åbne døre) team + parent_org: Organization for Transformative Works – OTW (Organisationen for + Transformative Værker) + support: AO3 Support-team + users: + mailer: + reset_password_instructions: + expiration: Hvis du ikke benytter dette link til at nulstille dit password + inden for en uge, vil det udløbe, og du vil være nødt til at anmode om et + nyt. + intro: 'Nogen har anmodet om en nulstilling af password for din konto. Du + kan ændre dit password ved at følge linket nedenfor og indtaste dit nye + password:' + link_title: Ændr mit password. + subject: "[%{app_name}] Nulstil dit password" + unrequested: Hvis du ikke anmodede om nulstilling af password, kan du ignorere + denne e-mail, og dit tidligere password vil stadig fungere. + user_mailer: + admin_deleted_work_notification: + bye: Vedhæftet finder du en kopi af dit værk til orientering. + contact_abuse: kontakte vores komité for Retningslinjer & Misbrug + deleted: + html: Dit værk %{title} er blevet slettet fra AO3 af en administrator. + text: Dit værk "%{title}" er blevet slettet fra AO3 af en administrator. + html: + tos_violation: Hvis det er muligt, at dit værk har overtrådt AO3’s Brugsbetingelser, + kan du %{contact_abuse_link}. + import_project: + html: Hvis dit værk var en del af et importeringsprojekt fra Åbne Døre-holdet, + kan du %{opendoors_link}, hvis du har spørgsmål. + text: Hvis dit værk var en del af et importeringsprojekt fra Åbne Døre-holdet, + kan du kontakte Åbne Døre (%{opendoors_link}), hvis du har spørgsmål. + opendoors: kontakte Åbne Døre + subject: "[%{app_name}] Dit værk er blevet slettet af en administrator" + text: + tos_violation: Hvis det er muligt, at dit værk har overtrådt AO3’s Brugsbetingelser, + kan du kontakte vores komité for Retningslinjer & Misbrug (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Mens dit værk er skjult, kan du stadig tilgå det via det ovenstående + link, men det vil ikke være synligt på din værkside, og det vil ikke være + tilgængeligt for andre AO3-brugere. + check_email: Tjek venligst din e-mail, inklusive din spammappe, da Retningslinjer + & Misbrug-teamet allerede kan have kontaktet dig og forklaret grunden til, + at dit værk er blevet skjult. + contact_abuse: kontakte Retningslinjer & Misbrug + html: + help: Hvis du er i tvivl om, hvorfor dit værk er blevet skjult, og du ikke + har modtaget nogen beskeder vedrørende dette emne, kan du %{contact_abuse_link} + direkte. + hidden: Dit værk %{title} er blevet skjult af Retningslinjer & Misbrug-teamet + og er ikke længere offentligt tilgængeligt. + tos_violation: Hvis dit værk er blevet skjult, fordi det var i strid med AO3's + %{tos_link}, er du nødt til først at rette op på forsømmelsen. Hvis du ikke + formår at tilpasse dit værk, så det overholder Brugsbetingelserne, kan det + i sidste ende resultere i, at dit værk bliver slettet fra AO3. + subject: "[%{app_name}] Dit værk er blevet skjult af Retningslinjer & Misbrug-teamet" + text: + help: 'Hvis du er i tvivl om, hvorfor dit værk er blevet skjult, og du ikke + har modtaget nogen beskeder vedrørende dette emne, kan du kontakte Retningslinjer + & Misbrug direkte: %{contact_abuse_url}' + hidden: Dit værk "%{title}" (%{work_url}) er blevet skjult af Retningslinjer + & Misbrug-teamet og er ikke længere offentligt tilgængeligt. + tos_violation: Hvis dit værk blev skjult, fordi det var i strid med AO3's + Brugsbetingelser (%{tos_url}), er du nødt til først at rette op på forsømmelsen. + Hvis du ikke formår at tilpasse dit værk, så det overholder Brugsbetingelserne, + kan det i sidste ende resultere i, at dit værk bliver slettet fra AO3. + tos: Brugsbetingelser + anonymous_or_unrevealed_notification: + anonymous_info: Anonyme værker er inkluderet i tag-lister, men ikke på din side + for værker. På værket vil dit brugernavn blive erstattet med "Anonymous" (Anonym). + anonymous_unrevealed_info: Vedligeholderne vil måske senere afsløre dit værk, + men holde det anonymt. Folk, som abonnerer på dig, vil ikke få en notifikation + om denne ændring. Når det er afsløret, vil dit værk blive inkluderet i tag-lister, + men ikke på din side for værker. På værket vil dit brugernavn blive erstattet + med "Anonymous" (Anonym). + changed_status: + anonymous: + html: Vedligeholderne af %{collection_link} har ændret status på dit værk + %{work_link} til anonymt. + text: Vedligeholderne af "%{collection_title}" (%{collection_url}) har ændret + status på dit værk "%{work_title}" (%{work_url}) til anonymt. + anonymous_unrevealed: + html: Vedligeholderne af %{collection_link} har ændret status på dit værk + %{work_link} til anonymt og ikke-offentliggjort. + text: Vedligeholderne af "%{collection_title}" (%{collection_url}) har ændret + status på dit værk "%{work_title}" (%{work_url}) til anonymt og ikke-offentliggjort. + unrevealed: + html: Vedligeholderne af %{collection_link} har ændret status på dit værk + %{work_link} til ikke-offentliggjort. + text: Vedligeholderne af "%{collection_title}" (%{collection_url}) har ændret + status på dit værk "%{work_title}" (%{work_url}) til ikke-offentliggjort. + collection_items_link_text: Approved Collection Items page (Side for Godkendte + Samlingselementer) + do_not_want: + anonymous: + html: Hvis du ikke ønsker, at dit værk forbliver anonymt, besøg din %{collection_items_link} + for at fjerne det fra denne samling. + text: 'Hvis du ikke ønsker, at dit værk forbliver anonymt, besøg din Approved + Collection Items page (Din side for Godkendte Samlingselementer) for at + fjerne det fra denne samling: %{collection_items_url}' + anonymous_unrevealed: + html: Hvis du ikke ønsker, at dit værk forbliver anonymt og ikke-offentliggjort, + besøg din %{collection_items_link} for at fjerne det fra denne samling. + text: 'Hvis du ikke ønsker, at dit værk forbliver anonymt og ikke-offentliggjort, + besøg din Approved Collection Items page (Din side for Godkendte Samlingselementer) + for at fjerne det fra denne samling: %{collection_items_url}' + unrevealed: + html: Hvis du ikke ønsker, at dit værk forbliver ikke-offentliggjort, besøg + din %{collection_items_link} for at fjerne det fra denne samling. + text: 'Hvis du ikke ønsker, at dit værk forbliver ikke-offentliggjort, besøg + din Approved Collection Items page (Din side for Godkendte Samlingselementer) + for at fjerne det fra denne samling: %{collection_items_url}' + faq_link_text: Samlinger FAQ + more_info: + html: For mere information besøg vores %{faq_link}. + text: 'For mere information besøg vores Samlinger FAQ: %{faq_url}' + subject: + anonymous: "[%{app_name}] Dit værk er gjort anonymt" + anonymous_unrevealed: "[%{app_name}] Dit værk er gjort anonymt og ikke-offentligt." + unrevealed: "[%{app_name}] Dit værk blev til et ikke-offentliggjort værk" + unrevealed_info: Ikke-offentliggjorte værker er ikke inkluderet i tag-listerne + eller på din side for værker. Enhver, som følger et link til værket, vil få + en meddelelse om, at det på nuværende tidspunkt ikke er offentliggjort, og + de vil ikke være i stand til at få adgang til indholdet. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Godkendte værker + i en samling)-side + archivist_notice: Fordi samlingens vedligeholdere handler i deres officielle + rolle som Open Doors (Åbne Døre)-arkivarer, har de tilladelse til at tilføje + dit værk til denne samling, selv hvis du har slået invitationer til samlinger + fra. Arkivarerne vil kun tilføje et værk til en samling, hvis det har ligget + på et importeret arkiv. + removal_instructions: + html: Hvis du vil fjerne dit værk fra samlingen, kan du gå til din %{approved_items_link}. + text: 'Hvis du vil fjerne dit værk fra samlingen, kan du gå til din side for + Approved Collection Items (Godkendte genstande i samlinger): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] En Open Doors (Åbne Døre)-arkivar + har tilføjet dit værk til en samling" + work_added: + html: Vedligeholderne af samlingen %{collection_link} har tilføjet dit værk + %{work_link} til deres samling! + text: Vedligeholderne af samlingen "%{collection_title}" (%{collection_url}) + har tilføjet dit værk "%{work_title}" (%{work_url}) til deres samling! + challenge_assignment_notification: + any: Hvilken som helst + assignment: + html: Du er blevet tildelt følgende forespørgsel i %{link}-udfordringen på + Archive of Our Own! + description: 'Beskrivelse:' + due: 'Denne opgave har deadline den:' + html: + footer: Du modtager denne e-mail, fordi du tilmeldte dig %{title}-udfordringen. + For mere information om denne udfordring og moderatorernes kontaktinformation + gå til %{footer_link}. + footer_link: udfordringens profilside + look_up: Du kan se denne opgave på %{link}. + look_up_link: din Assignments (Opgaver)-side + optional_tags: 'Valgfrie tags:' + prompts: 'Inspiration:' + prompt_url: 'URL til inspiration:' + recipient: 'Modtager:' + recipient_missing: 'Ingen: kontakt en moderator for hjælp!' + subject: "[%{app_name}][%{collection_title}] Din opgave!" + text: + assignment: Du er blevet tildelt følgende forespørgsel i "%{collection_title}" + (%{collection_url})-udfordringen på Archive of Our Own! + footer: Du modtager denne e-mail, fordi du tilmeldte dig %{title}-udfordringen + (%{url}). For mere information om denne udfordring og moderatorernes kontaktinformation + gå til %{profile_url}. + look_up: Du kan se denne opgave på din Assignments (Opgaver)-side på %{link}. + change_email: + changed: + html: "%{login}, e-mailadressen, der er tilknyttet din konto, er blevet ændret + til %{email}" + text: "%{login}, e-mailadressen, der er tilknyttet din konto, er blevet ændret + til %{email}" + subject: "[%{app_name}] E-mail ændret" + claim_notification: + access: + contact_support: kontakte AO3 Support + html: Afhængig af arkivet kan dine værker være blevet importeret, så de er + begrænset til registrerede brugere (for at de ikke vises i Google-søgninger). + Hvis det er tilfældet, vil værkerne kun være tilgængelige for brugere, der + er logget ind, medmindre du vælger at gøre dem fuldt synlige. For at få + hjælp til at låse op for, frasige dig ophavsretten eller slette dine værker + kan du %{contact_support_link}. + text: Afhængig af arkivet kan dine værker være blevet importeret, så de er + begrænset til registrerede brugere (for at de ikke vises i Google-søgninger). + Hvis det er tilfældet, vil værkerne kun være tilgængelige for brugere, der + er logget ind, medmindre du vælger at gøre dem fuldt synlige. For at få + hjælp til at låse op for, frasige dig ophavsretten eller slette dine værker + kan du kontakte AO3 Support på %{support_url}. + email_tips: Hvis du kontakter os, så tilføj gerne e-mailadresser fra @transformativeworks.org + til din liste med kontakter, du har tillid til, og tjek dit spamfilter for + vores svar. + introduction: + ao3_name: Archive of Our Own – AO3 (Vores Eget Arkiv) + html: Du modtager denne e-mail, fordi du havde værker på et fanværk-arkiv, + der er blevet importeret af %{open_doors_name_link} til %{app_link}. Fordi + denne e-mailadresse er forbundet med en e-mail, der er registreret på det + importerede arkiv, er de tilknyttede fanværker (listet nedenfor) automatisk + blevet tilføjet til din AO3-konto. + open_doors_name: Open Doors (Åbne Døre) + text: 'Du har modtaget denne e-mail, fordi du havde værker på et fanværksarkiv, + der er blevet importeret af Open Doors (Åbne Døre) (%{open_doors_url}) til + Archive of Our Own – AO3 (Vores Eget Arkiv): %{app_url}. Fordi denne e-mailadresse + er forbundet med en e-mail, der er registreret i det importerede arkiv, + er de tilknyttede fanværker (listet nedenfor) automatisk blevet tilføjet + til din AO3-konto.' + mistake: + contact_open_doors: Kontakt Åbne Døre + html: Hvis dette er en fejl, og disse værker ikke er dine, skal du ikke slette + dem! %{contact_open_doors_link}, så ordner vi det. + text: Hvis dette er en fejl, og disse værker ikke er dine, skal du ikke slette + dem! Kontakt Åbne Døre (%{open_doors_url}), så ordner vi det. + more_info: + ao3_news: AO3 Nyheder + contact_support: kontakte AO3 Support + faq_page: FAQ-side + html: Du kan læse annonceringer om nylige arkivflytninger på %{ao3_news_link} + og finde yderligere information på Åbne Døres %{faq_page_link} eller %{tutorial_page_link}. + Hvis du har yderligere spørgsmål, der ikke er besvaret i FAQ'en, tutorials + eller denne e-mail, kan du %{contact_support_link}. + text: Du kan læse annonceringer om nylige arkivflytninger på AO3 Nyheder (%{news_url}) + og finde yderligere information på Åbne Døres FAQ-side (%{open_doors_faq_url}) + eller tutorials-side (%{open_doors_tutorial_url}). Hvis du har yderligere + spørgsmål, der ikke er besvaret i FAQ'en, tutorials eller denne e-mail, + kan du kontakte Support på %{support_url}. + tutorial_page: tutorial-side + other_works: + contact_open_doors: kontakt Åbne Døre + html: Hvis du havde andre værker på det importerede arkiv, men under en e-mailadresse, + du ikke længere kan tilgå, så %{contact_open_doors_link} med enhver information, + der kan hjælpe med at bekræfte din identitet. + text: Hvis du havde andre værker på det importerede arkiv, men under en e-mailadresse, + du ikke længere kan tilgå, så kontakt gerne Åbne Døre med enhver information, + der kan hjælpe med at bekræfte din identitet. + questions: + contact_support: kontakt AO3 Support + html: Har du andre forespørgsler, så %{contact_support_link}. + text: Har du andre forespørgsler, så kontakt AO3 Support på %{support_url}. + redirects: + html: Af hensyn til lister med anbefalinger eller bogmærker kan det importerede + arkivs hjemmeside i en begrænset periode omdirigere til de importerede kopier + af disse værker (tjek annonceringen om dit arkiv for at være sikker). Hvis + du allerede har uploadet en kopi af disse værker, og du %{negation} importerede + ved at bruge URL-funktionen, vil der være to kopier af det samme værk på + AO3. + subject: "[%{app_name}] Værker er blevet uploadet" + update_redirect: + contact_open_doors: kontakte Åbne Døre + html: Hvis du ønsker, at Åbne Døre opdaterer omdirigeringen, så den leder + til dit allerede eksisterende værk, så skal du slette den importerede kopi + og %{contact_open_doors_link} med dit brugernavn på AO3, dit brugernavn + på det importerede arkiv samt titel og URL på det fanværk, der skal omdirigeres + til. (Hvis du har flere værker, du gerne vil ændre omdirigeringen for, kan + du liste dem alle i én e-mail). + text: Hvis du ønsker, at Åbne Døre opdaterer omdirigeringen, så den leder + til dit allerede eksisterende værk, så skal du slette den importerede kopi + og kontakte Åbne Døre på %{open_doors_url} med dit brugernavn på AO3, dit + brugernavn på det importerede arkiv samt titel og URL på det fanværk, der + skal omdirigeres til. (Hvis du har flere værker, du gerne vil ændre omdirigeringen + for, kan du liste dem alle i én e-mail). + works_by: 'Disse værker var tilknyttet e-mailen: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Alle opgavetildelinger er blevet afsendt. + subject: Opgavetildelinger afsendt + html: + received_message: 'Du har modtaget en besked vedrørende din samling %{collection_link}:' + text: + received_message: 'Du har modtaget en besked vedrørende din samling "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Når du er medskaber på et værk, kan du blive tilføjet til nye kapitler + uanset dine indstillinger for at være medskaber. Du vil også blive tilføjet + til enhver serie, som værket bliver tilføjet. + html: + creation: "%{creation_link} af %{pseud_links}" + edit_chapter: redigere kapitlet + edit_series: redigere serien + remove_chapter: Hvis du er blevet tilføjet ved en fejl eller ikke vil stå + som skaber, kan du %{edit_chapter_link} for at fjerne dig selv som skaber. + remove_series: Hvis du er blevet tilføjet ved en fejl eller ikke vil stå som + medskaber, kan du %{edit_series_link} for at fjerne dig selv som skaber. + intro_chapter: 'Brugeren %{adding_user} har sat dit pseudonym %{pseud} som medskaber + på det følgende kapitel:' + intro_series: 'Brugeren %{adding_user} har sat dit pseudonym %{pseud} som medskaber + på følgende serie:' + subject: "[%{app_name}] Notifikation til medskaber" + text: + creation: "%{title} (%{url}) af %{pseuds}" + remove_chapter: 'Hvis du er blevet tilføjet ved en fejl eller ikke vil stå + som skaber, kan du redigere kapitlet for at fjerne dig selv som skaber: + %{url}' + remove_series: 'Hvis du er blevet tilføjet ved en fejl eller ikke vil stå + som skaber, kan du redigere serien for at fjerne dig selv som skaber: %{url}' + creatorship_notification_archivist: + explanation: Fordi de opererer i en officiel funktion som arkivar for Open Doors + (Åbne Døre), har de tilladelse til at tilføje dig uden en anmodning, selvom + du har deaktiveret samskabelse. + html: + creation: "%{creation_link} af %{pseud_links}" + edit_chapter: redigere kapitlet + edit_series: redigere serien + edit_work: redigere værket + remove_chapter: Hvis du er blevet tilføjet ved en fejl eller ikke ønsker at + være noteret som skaber, kan du %{edit_chapter_link} for at fjerne dig selv + som skaber. + remove_series: Hvis du er blevet tilføjet ved en fejl eller ikke ønsker at + være noteret som skaber, kan du %{edit_series_link} for at fjerne dig selv + som skaber. + remove_work: Hvis du er blevet tilføjet ved en fejl eller ikke ønsker at være + noteret som skaber, kan du %{edit_work_link} for at fjerne dig selv som + skaber. + intro_chapter: 'Brugeren %{archivist} har tilføjet dit pseudonym %{pseud} som + medskaber af følgende kapitel:' + intro_series: 'Brugeren %{archivist} har tilføjet dit pseudonym %{pseud} som + medskaber af følgende serie:' + intro_work: 'Brugeren %{archivist} har tilføjet dit pseudonym %{pseud} som medskaber + af følgende værk:' + subject: "[%{app_name}] Medskabernotifikation fra arkivar" + text: + creation: "%{title} (%{url}) af %{pseuds}" + remove_chapter: 'Hvis du er blevet tilføjet ved en fejl eller ikke ønsker + at være noteret som skaber, kan du redigere kapitlet for at fjerne dig selv + som skaber: %{url}' + remove_series: 'Hvis du er blevet tilføjet ved en fejl eller ikke ønsker at + være noteret som skaber, kan du redigere serien for at fjerne dig selv som + skaber: %{url}' + remove_work: 'Hvis du er blevet tilføjet ved en fejl eller ikke ønsker at + være noteret som skaber, kan du redigere værket for at fjerne dig selv som + skaber: %{url}' + creatorship_request: + html: + creation: "%{creation_link} af %{pseud_links}" + instructions: Du kan acceptere eller afvise denne anmodning på din side for + %{page_name}. + page_name: Co-Creator Requests (Medskaberanmodninger) + intro_chapter: 'Brugeren %{inviting_user} har inviteret dit pseudonym %{pseud} + til at blive listet som medskaber på følgende kapitel:' + intro_series: 'Brugeren %{inviting_user} har inviteret dit pseudonym %{pseud} + til at blive listet som medskaber på følgende serie:' + intro_work: 'Brugeren %{inviting_user} har inviteret dit pseudonym %{pseud} + til at blive listet som medskaber på følgende værk:' + subject: "[%{app_name}] Anmodning til medskaber" + text: + creation: "%{title} (%{url}) af %{pseuds}" + instructions: 'Du kan acceptere eller afvise denne anmodning på din side for + Co-Creator Requests (Medskaberanmodninger): %{url}' + delete_work_notification: + attachment: Vedhæftet finder du en kopi af dit værk til din orientering. + deleted_other: + html: Dit værk %{title} er blevet slettet efter anmodning fra %{pseud}. + text: Dit værk "%{title}" er blevet slettet efter anmodning fra %{pseud}. + deleted_yourself: + html: Dit værk %{title} er blevet slettet på din anmodning. + text: Dit værk "%{title}" er blevet slettet på din anmodning. + questions: + html: Hvis du har spørgsmål, kan du %{support}. + text: Hvis du har spørgsmål, kan du %{support} (%{url}). + subject: "[%{app_name}] Dit værk er blevet slettet" + support: kontakte Support + invitation_to_claim: + access: + text: Afhængig af arkivet er dine værker muligvis importeret således, at adgangen + er begrænset til registrerede brugere (for at holde dem ude af Google-søgninger). + Hvis det er tilfældet, er værkerne kun tilgængelige for brugere, der er + logget ind, medmindre du vælger at gøre dem tilgængelige for alle. Har du + brug for hjælp til at låse dine værker op, frasige dig ophavsretten eller + slette dine værker, kan du kontakte AO3 Support. + claim_or_remove: + html: Gør krav på, eller fjern dine værker her. + text: 'Gør krav på, eller fjern dine værker her: %{claim_url}' + email_tips: Hvis du kontakter os, beder vi dig om at whiteliste e-mailadresser + fra @transformativeworks.org, og husk at kigge i din spam-mappe for at se + om vores svar ligger der. + html: + ao3_news: AO3 Nyheder + contact_open_doors: kontakte Åbne Døre + contact_support: kontakte AO3 Support + faq_page: FAQ-side + tutorial_page: tutorial-side + introduction: + text: Du modtager denne e-mail, fordi et arkiv for nyligt er blevet importeret + af Open Doors (Åbne Døre) (%{open_doors_link}) til %{app_name} (%{app_short_name} + - %{app_url}), og vi mener, at følgende fanværker tilhører dig. Vi vil gerne + give dig mulighed for at gøre krav på (eller slette/frasige dig ophavsretten + på) disse værker, hvis du vil. Og hvis du ikke allerede har en konto på + en anden mail, vil vi gerne invitere dig med ombord! + mistake: + text: Hvis dette er en fejl, og det ikke er dine værker, må du endelig ikke + slette dem! Vær i stedet venlig at kontakte Åbne Døre %{open_doors_link}, + så ordner vi det. + more_info: + text: Du kan læse meddelelser om nye importeringer af arkiver på AO3 Nyheder + (%{news_link}) og finde mere information på Åbne Døres FAQ-side (%{open_doors_faq_link}) + eller tutorial-side (%{open_doors_tutorial_link}). Har du spørgsmål, der + ikke er blevet besvaret i FAQ'en, tutorials eller i denne mail, kan du kontakte + Support på %{support_link}. + other_works: + text: Hvis du havde andre værker på det importerede arkiv under en e-mailadresse, + som du ikke længere har adgang til, kan du kontakte Åbne Døre med information, + som kan hjælpe med at verificere din identitet. + questions: + text: For flere spørgsmål kan du kontakte AO3 Support på %{support_link}. + redirects: For at bevare anbefalede værker og bogmærker vil det importerede + arkivs URL'er muligvis omdirigere til de importerede kopier af disse værker + i en begrænset periode (se Åbne Døres meddelelse om dit arkiv for at være + sikker). Hvis du allerede har uploadet en kopi af disse værker, og du IKKE + brugte importér fra URL-funktionen, vil der være to kopier af det samme værk + på AO3. + subject: "[%{app_name}] Invitation til at gøre krav på værker" + unwanted: + text: Hvis disse værker tilhører dig, men du ikke vil gøre krav på dem, kan + du frasige dig ophavsretten (så værkerne bliver på AO3, men dit navn bliver + fjernet) eller slette dem (så værkerne bliver fjernet helt fra AO3). Du + behøver ikke at tilføje disse værker til en konto for at frasige dig ophavsretten + eller slette dem – du kan gøre dette med det samme via linket ovenfor. (Har + du brug for hjælp, kan du kontakte Support på %{support_link}.) + update_redirect: + text: Hvis du gerne vil have Åbne Døre til at opdatere omdirigeringen, så + den leder til dit eksisterende værk, skal du slette den importerede kopi + og kontakte Åbne Døre på %{open_doors_link} med din AO3-konto, din konto + på det importerede arkiv samt titlen og URL'et på det fanværk, du gerne + vil omdirigere til. (Hvis du har flere værker, hvor du gerne vil ændre omdirigeringen, + kan du liste dem alle op i én e-mail.) + uploaded_list: 'De uploadede værker inkluderer:' + invite_increase_notification: + html: + body: + one: Vi ville bare lige fortælle, at du har %{count} ny invitation, som + kan bruges til at oprette en ny konto på AO3. Du kan invitere en ven på + %{invitation_page_link}. + other: Vi ville bare lige fortælle, at du har %{count} nye invitationer, + som kan bruges til at oprette nye konti på AO3. Du kan invitere en ven + på %{invitation_page_link}. + invitation_page_link_text: din Invitations (Invitationer)-side + subject: "[%{app_name}] Nye invitationer" + text: + body: + one: Vi ville bare lige fortælle, at du har %{count} ny invitation, som + kan bruges til at oprette en ny konto på AO3. Du kan invitere en ven på + din Invitations (invitationer)-side (%{invitation_page_url}). + other: Vi ville bare lige fortælle, at du har %{count} nye invitationer, + som kan bruges til at oprette nye konti på AO3. Du kan invitere en ven + på din Invitations (invitationer)-side (%{invitation_page_url}). + invite_request_declined: + main: + one: Vi må desværre meddele dig, at din anmodning om en ny invitation ikke + kan opfyldes på nuværende tidspunkt. + other: Vi må desværre meddele dig, at din anmodning om %{count} nye invitationer + ikke kan opfyldes på nuværende tidspunkt. + reason: 'Din anmodning var:' + subject: "[%{app_name}] Anmodning om yderligere invitationer afvist" + recipient_notification: + html: + collection: Et værk er blevet udgivet som gave til dig i %{collection_link}-samlingen + på AO3! + no_collection: Et værk er blevet udgivet som gave til dig på AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Et værk i gave til dig fra + %{collection_title}" + no_collection: "[%{app_name}] Et værk i gave til dig" + text: + collection: Et værk er blevet udgivet som gave til dig i "%{collection_title}"-samlingen + (%{collection_url}) på AO3! + signup_notification: + activate: + html: Venligst %{activate_account_link}. + text: 'Følg venligst dette link for at aktivere din konto: %{activate_account_url}' + activate_your_account: følg dette link for at aktivere din konto + admin_posts: AO3 nyheder + bye: Vi håber, at du bliver glad for at bruge AO3. + contact_support: kontakte vores Support-team + faq: FAQ + features: + html: Når din konto er sat op, kan du publicere fanværker, oprette e-mailnotifikationer, + der fortæller dig, hvornår dine favoritskabere eller -værker opdaterer, + indstille hvordan hjemmesiden ser ud og fungerer for dig, holde styr på, + hvilke værker du har set på AO3 gennem din historik og meget mere. + text: Når din konto er sat op, kan du publicere fanværker, oprette e-mailnotifikationer, + der fortæller dig, hvornår dine favoritskabere eller -værker opdaterer, + indstille, hvordan hjemmesiden ser ud og fungerer for dig, holde styr på, + hvilke værker du har set på AO3 gennem din historik og meget mere. + information: + html: Der er masser af information om og råd til, hvordan du kan bruge AO3 + i vores %{faq_link}. Du kan finde de seneste nyheder om hjemmesidens udvikling + på %{admin_posts_link}. Hvis du har brug for mere hjælp, løber ind i en + fejl eller har spørgsmål eller kommentarer, kan du %{contact_support_link}, + som altid gerne vil hjælpe. + text: 'Der er masser af information om og råd til, hvordan du kan bruge AO3 + i vores FAQ her %{faq_url}. Du kan finde de seneste nyheder om hjemmesidens + udvikling på %{admin_posts_url}. Hvis du har brug for mere hjælp, løber + ind i en fejl eller har spørgsmål eller kommentarer, kan du tage fat i vores + Support-team, som altid gerne vil hjælpe, ved at: %{contact_support_url}.' + welcome: Velkommen til Archive of Our Own, %{login}! diff --git a/config/locales/phrase-exports/de.yml b/config/locales/phrase-exports/de.yml new file mode 100755 index 0000000..6a08347 --- /dev/null +++ b/config/locales/phrase-exports/de.yml @@ -0,0 +1,644 @@ +--- +de: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Warnung:' + other: 'Warnungen:' + category: + name_with_colon: + one: 'Kategorie:' + other: 'Kategorien:' + character: + name_with_colon: + one: 'Charakter:' + other: 'Charaktere:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandoms:' + freeform: + name_with_colon: + one: 'Zusätzliches Tag:' + other: 'Zusätzliche Tags:' + rating: + name_with_colon: 'Alterseinstufung:' + relationship: + name_with_colon: + one: 'Beziehung:' + other: 'Beziehungen:' + work: + chapter_total_display: Kapitel + summary: Zusammenfassung + models: + archive_warning: + one: Warnung + other: Warnungen + category: + one: Kategorie + other: Kategorien + chapter: + one: Kapitel + other: Kapitel + character: + one: Charakter + other: Charaktere + fandom: + one: Fandom + other: Fandoms + freeform: + one: Zusätzliches Tag + other: Zusätzliche Tags + rating: + one: Alterseinstufung + other: Alterseinfstufungen + relationship: + one: Beziehung + other: Beziehungen + series: + one: Serie + other: Serien + kudo_mailer: + batch_kudo_notification: + guest: + one: ein Gast + other: "%{count} Gäste" + left_kudos: + html: + one: "%{givers_list} hat Kudos für %{commentable_link} hinterlassen." + other: "%{givers_list} haben Kudos für %{commentable_link} hinterlassen." + text: + one: "%{givers_list} hat Kudos für %{commentable_title} (%{commentable_url}) + hinterlassen." + other: "%{givers_list} haben Kudos für %{commentable_title} (%{commentable_url}) + hinterlassen." + single_guest: + giver: Ein Gast + html: "%{giver} hat Kudos für %{commentable_link} hinterlassen." + text: Ein Gast hat Kudos für %{commentable_title} (%{commentable_url}) hinterlassen. + subject: "[%{app_name}] Du hast Kudos erhalten!" + mailer: + general: + closing: + formal: Mit freundlichen Grüßen + informal: Viele Grüße + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Kapitel %{position} von %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} Wort" + other: "%{count} Worte" + footer: + general: + about: + html: Das AO3 ist ein Archiv von Fans für Fans, das auf %{donate_link} + angewiesen ist. + text: 'Das AO3 ist ein Archiv von Fans für Fans, das auf Deine Spenden + angewiesen ist: %{donate_url}.' + html: + donate_link_text: Deine Spenden + support_link_text: wende Dich bitte an den Support + unwanted_email: + html: Solltest Du diese Nachricht irrtümlicherweise erhalten haben, %{support_link}. + text: Solltest Du diese Nachricht irrtümlicherweise erhalten haben, wende + Dich bitte unter %{support_url} an den Support. + sent_at: Gesendet %{sent_at}. + greeting: + formal_html: Hallo %{name}, + informal: + addressed_html: Hallo %{name}! + unaddressed: Hallo! + introductory: Hallo vom Archive of Our Own – AO3 (Ein Eigenes Archiv) + metadata_label_indicator: ":" + signature: + abuse_team: Das AO3 "Richtlinien und Missbrauch"-Team + app_short_name: AO3 + open_doors: Das "Open Doors"- (Offene Türen) Team + parent_org: Organization for Transformative Works – OTW (Organisation für + Transformative Werke) + support: Das AO3-Support-Team + users: + mailer: + reset_password_instructions: + expiration: Wenn Du den Link zur Passwortzurücksetzung nicht innerhalb der + nächsten sieben Tage nutzt, verfällt er und Du musst einen neuen anfordern. + intro: 'jemand hat ein neues Passwort für Dein Nutzer*innenkonto angefordert. + Du kannst Dein Passwort ändern, indem Du den untenstehenden Link anklickst + und Dein neues Passwort eingibst:' + link_title: Passwort ändern. + subject: "[%{app_name}] Setze Dein Passwort zurück" + unrequested: Wenn Du keine Zurücksetzung Deines Passworts beantragt hast, + kannst Du diese E-Mail ignorieren und Dein altes Passwort bleibt gültig. + user_mailer: + admin_deleted_work_notification: + bye: Anbei ist eine Kopie deines Werkes als Referenz. + contact_abuse: kontaktiere bitte unser “Richtlinien und Missbrauch”-Komitee + deleted: + html: dein Werk %{title} wurde von einem*r Webadministrator*in des AO3 gelöscht. + text: dein Werk "%{title}" wurde von einem*r Webadministrator*in des AO3 gelöscht. + html: + tos_violation: Wenn dein Werk eventuell die Nutzungsbedingungen des AO3 verletzt + hat, %{contact_abuse_link}. + import_project: + html: Falls dein Werk Teil eines Import-Projektes durch unser Open Doors- + (Offene Türen) Komitee war, %{opendoors_link} für alle weiteren Fragen. + text: Falls dein Werk Teil eines Import-Projektes durch unser Open Doors- + (Offene Türen) Komitee war, kontaktiere bitte Offene Türen (%{opendoors_link}) + für alle weiteren Fragen. + opendoors: kontaktiere bitte das “Offene Türen”-Komitee + subject: "[%{app_name}] Dein Werk wurde von einem*r Webadministrator*in gelöscht" + text: + tos_violation: Wenn dein Werk eventuell die Nutzungsbedingungen des AO3 verletzt + hat, kontaktiere bitte unser Richtlinien und Missbrauch-Komitee (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Obwohl Dein Werk verborgen ist, kannst Du es immer noch über den oben + angegebenen Link aufrufen; es wird jedoch weder in der Übersicht Deiner Werke + aufgelistet, noch ist es für andere AO3-Nutzer*innen verfügbar. + check_email: Bitte überprüfe Deine E-Mails, einschließlich Deines Spam-Ordners, + da das “Richtlinien und Missbrauch”-Komitee Dich möglicherweise bereits kontaktiert + hat, um zu erklären, warum Dein Werk verborgen wurde. + contact_abuse: kontaktiere das “Richtlinien und Missbrauch”-Komitee + html: + help: Wenn Du Dir nicht sicher bist, warum Dein Werk verborgen wurde und Du + keine weitere Mitteilung in dieser Angelegenheit erhalten hast, dann %{contact_abuse_link} + bitte direkt. + hidden: Dein Werk %{title} wurde vom “Richtlinien und Missbrauch”-Komitee + verborgen und ist nicht mehr öffentlich zugänglich. + tos_violation: Wenn Dein Werk aufgrund eines Verstoßes gegen die %{tos_link} + des AO3 verborgen wurde, musst Du Maßnahmen ergreifen, um den Verstoß zu + beheben. Wenn Du Dein Werk nicht in Übereinstimmung mit den Nutzungsbedingungen + bringst, wird es möglicherweise aus dem AO3 gelöscht. + subject: "[%{app_name}] Dein Werk wurde vom “Richtlinien und Missbrauch”-Komitee + verborgen" + text: + help: 'Wenn Du Dir nicht sicher bist, warum Dein Werk verborgen wurde und + Du keine weitere Mitteilung in dieser Angelegenheit erhalten hast, dann + kontaktiere das “Richtlinien und Missbrauch”-Komitee bitte direkt: %{contact_abuse_url}.' + hidden: Dein Werk “%{title}” (%{work_url}) wurde vom “Richtlinien und Missbrauch”-Komitee + verborgen und ist nicht mehr öffentlich zugänglich. + tos_violation: Wenn Dein Werk aufgrund eines Verstoßes gegen die Nutzungsbedingungen + des AO3 (%{tos_url}) verborgen wurde, musst Du Maßnahmen ergreifen, um den + Verstoß zu beheben. Wenn Du Dein Werk nicht in Übereinstimmung mit den Nutzungsbedingungen + bringst, wird es möglicherweise aus dem AO3 gelöscht. + tos: Nutzungsbedingungen + anonymous_or_unrevealed_notification: + anonymous_info: Anonyme Werke werden in Tag-Listen angezeigt, nicht jedoch auf + Deiner Werke-Seite. In dem Werk wird Dein Benutzer*innenname mit “Anonymous” + (Anonym) ersetzt. + anonymous_unrevealed_info: Die Betreuer*innen der Sammlung können Dein Werk + später enthüllen, aber dabei anonym belassen. Benutzer*innen, die Benachrichtigungen + zu Deinen Werken abonniert haben, werden über diese Änderung nicht informiert. + Sobald das Werk enthüllt wurde, wird es in Tag-Listen aufgeführt, nicht jedoch + auf Deiner Werke-Seite. In dem Werk wird Dein Name durch “Anonymous” (Anonym) + ersetzt. + changed_status: + anonymous: + html: die Betreuer*innen von %{collection_link} haben den Status Deines + Werks %{work_link} auf anonym gesetzt. + text: die Betreuer*innen von "%{collection_title}" (%{collection_url}) haben + den Status Deines Werks "%{work_title}" (%{work_url}) auf anonym gesetzt. + anonymous_unrevealed: + html: die Betreuer*innen von %{collection_link} haben den Status Deines + Werks %{work_link} auf anonym und verborgen gesetzt. + text: die Betreuer*innen von "%{collection_title}" (%{collection_url}) haben + den Status Deines Werks "%{work_title}" (%{work_url}) auf anonym und verborgen + gesetzt. + unrevealed: + html: die Betreuer*innen von %{collection_link} haben den Status Deines + Werks %{work_link} auf verborgen gesetzt. + text: die Betreuer*innen von "%{collection_title}" (%{collection_url}) haben + den Status Deines Werks "%{work_title}" (%{work_url}) auf verborgen gesetzt. + collection_items_link_text: Approved Collection Items (Seite für genehmigte + Objekte einer Sammlung) + do_not_want: + anonymous: + html: Wenn Du nicht möchtest, dass Dein Werk anonym angezeigt wird, dann + besuche bitte die %{collection_items_link} und entferne es aus der Sammlung. + text: 'Wenn Du nicht möchtest, dass Dein Werk anonym angezeigt wird, dann + besuche bitte Deine Approved Collection Items (Seite für genehmigte Objekte + einer Sammlung) und entferne es aus der Sammlung: %{collection_items_url}' + anonymous_unrevealed: + html: Wenn Du nicht möchtest, dass Dein Werk anonym und verborgen ist, dann + besuche bitte die %{collection_items_link} und entferne es aus der Sammlung. + text: 'Wenn Du nicht möchtest, dass Dein Werk anonymisiert und verborgen + wird, dann besuche bitte Deine Approved Collection Items (Seite für genehmigte + Objekte einer Sammlung) und entferne es aus der Sammlung: %{collection_items_url}' + unrevealed: + html: Wenn Du nicht möchtest, dass Dein Werk verborgen ist, dann besuche + bitte die %{collection_items_link} und entferne es aus der Sammlung. + text: 'Wenn Du nicht möchtest, dass Dein Werk verborgen wird, dann besuche + bitte Deine Approved Collection Items (Seite für genehmigte Objekte einer + Sammlung) und entferne es aus der Sammlung: %{collection_items_url}' + faq_link_text: Herausforderungen FAQ (Häufige Fragen) + more_info: + html: Weitere Informationen findest Du in unserer %{faq_link}. + text: 'Weitere Informationen findest Du in unseren Herausforderungen FAQ (Häufige + Fragen): %{faq_url}' + subject: + anonymous: "[%{app_name}] Dein Werk wurde anonymisiert" + anonymous_unrevealed: "[%{app_name}] Dein Werk wurde anonymisiert und verborgen" + unrevealed: "[%{app_name}] Dein Werk wurde verborgen" + unrevealed_info: Verborgene Werke werden nicht in Tag-Listen oder auf Deiner + Werke-Seite angezeigt. Jemand, der auf den Link zu Deinem Werk klickt, erhält + eine Nachricht, dass es zurzeit verborgen ist und kann darauf nicht zugreifen. + archivist_added_to_collection_notification: + approved_collection_items_page: Seite für Approved Collection Items (Zugelassene + Sammlungsgegenstände) + archivist_notice: Weil die Sammlungsinhaber*innen in ihrer Eigenschaft als offizielle + Open Doors (Offene Türen) Archivar*innen gehandelt haben, ist es ihnen erlaubt, + Dein Werk zu dieser Sammlung hinzuzufügen, auch wenn Du Sammlungseinladungen + deaktiviert hast. Archivar*innen werden nur Dein Werk zu einer Sammlung hinzufügen, + wenn es in einem importierten Archiv gehostet wird. + removal_instructions: + html: 'Wenn Du Dein Werk von dieser Sammlung entfernen möchtest, verwende + diesen Link: %{approved_items_link}.' + text: 'Wenn Du Dein Werk aus dieser Sammlung entfernen möchtest, besuche bitte + Deine Seite für Approved Collection Items (Zugelassene Sammlungsgegenstände): + %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Ein*e Open Doors (Offene Türen) + Archivar*in hat Dein Werk zu einer Sammlung hinzugefügt." + work_added: + html: Die Sammlungsinhaber*innen von %{collection_link} haben Dein Werk %{work_link} + zu ihrer Sammlung hinzugefügt! + text: Die Sammlungsinhaber*innen von "%{collection_title}" (%{collection_url}) + haben Dein Werk "%{work_title}" (%{work_url}) zu ihrer Sammlung hinzugefügt! + challenge_assignment_notification: + any: Jegliche + assignment: + html: Dir wurde folgender Wunsch in der Herausforderung %{link} im AO3 zugewiesen! + description: 'Beschreibung:' + due: 'Diese Aufgabe ist fällig am:' + html: + footer: Du erhältst diese E-Mail, weil Du Dich für die Herausforderung %{title} + angemeldet hast. Weitere Einzelheiten zu dieser Herausforderung, sowie die + Kontaktinformationen der Moderator*innen findest Du auf der %{footer_link}. + footer_link: Profilseite der Herausforderung + look_up: Du kannst diese Aufgabe auf %{link} anschauen. + look_up_link: Deine Assignments (Aufgaben) Seite + optional_tags: 'Optionale Tags:' + prompts: 'Anregungen:' + prompt_url: 'URL der Anregung:' + recipient: 'Empfänger*in:' + recipient_missing: 'Niemand: bitte eine*n Moderator*in um Hilfe!' + subject: "[%{app_name}][%{collection_title}] Deine Aufgabe!" + text: + assignment: Dir wurde folgender Wunsch in der Herausforderung "%{collection_title}" + (%{collection_url}) im AO3 zugewiesen! + footer: Du erhältst diese E-Mail, weil Du Dich für die Herausforderung %{title} + (%{url}) angemeldet hast. Weitere Einzelheiten zu dieser Herausforderung, + sowie Kontaktinformationen der Moderator*innen findest Du unter %{profile_url}. + look_up: Du kannst diese Aufgabe auf Deiner Assignments (Aufgaben) Seite unter + %{link} ansehen. + change_email: + changed: + html: "%{login}, die mit Deinem Konto verknüpfte E-Mail-Adresse wurde zu %{email} + geändert." + text: "%{login}, die mit Deinem Konto verknüpfte E-Mail-Adresse wurde zu %{email} + geändert." + subject: "[%{app_name}] E-Mail-Adresse geändert" + claim_notification: + access: + contact_support: kontaktiere den AO3 Support + html: Je nach Archiv kann es sein, dass Deine Werke nur für registrierte Nutzer + importiert wurden (um sie aus der Google-Suche herauszuhalten). Wenn dies + der Fall ist, sind die Werke nur für eingeloggte Benutzer zugänglich, außer, + Du machst sie vollständig sichtbar. Wenn Du Hilfe beim Freischalten, Auswildern + oder Löschen Deiner Werke benötigst, %{contact_support_link}. + text: Je nach Archiv kann es sein, dass Deine Werke nur für registrierte Nutzer + importiert wurden (um sie aus der Google-Suche herauszuhalten). Wenn dies + der Fall ist, sind die Werke nur für eingeloggte Benutzer zugänglich, außer, + Du machst sie vollständig sichtbar. Wenn Du Hilfe beim Freischalten, Auswildern + oder Löschen Deiner Werke benötigst, wende Dich bitte an AO3 Support unter + %{support_url}. + email_tips: Wenn Du uns kontaktierst, füge bitte E-Mail-Adressen von @transformativeworks.org + zur Liste Deiner sicheren Kontakte und prüfe Deinen Spam-Ordner auf unsere + Antwort. + introduction: + ao3_name: Archive of Our Own – AO3 (Ein Eigenes Archiv) + html: Du bekommst diese E-Mail, weil Du Werke in einem Fanwerk-Archiv hattest, + das von %{open_doors_name_link} in %{app_link} importiert wurde. Weil diese + E-Mail-Adresse mit einer im importierten Archiv registrierten Adresse verbunden + ist, wurden die zugehörigen Fanwerke (siehe unten) automatisch zu deinem + AO3-Konto hinzugefügt. + open_doors_name: Open Doors (Offene Türen) + text: 'Du bekommst diese E-Mail, weil Du Werke in einem Fanwerke-Archiv hattest, + die von Open Doors (Offene Türen) (%{open_doors_url}) ins Archive of Our + Own – AO3 (Ein Eigenes Archiv): %{app_url} importiert wurden. Weil diese + E-Mail Adresse mit einer im importierten Archiv registrierten Adresse verbunden + ist, wurden die zugehörigen Fanwerke (siehe unten) automatisch zu Deinem + AO3-Konto hinzugefügt.' + mistake: + contact_open_doors: kontaktiere Open Doors + html: Wenn wir einen Fehler gemacht haben und die Werke nicht Dir gehören, + lösch sie bitte nicht! Bitte %{contact_open_doors_link} und wir beheben + den Fehler. + text: Wenn wir einen Fehler gemacht haben und das nicht Deine Werke sind, + lösch sie bitte nicht! Bitte kontaktiere nur Open Doors (%{open_doors_url}) + und wir werden den Fehler beheben. + more_info: + ao3_news: AO3-News + contact_support: kontaktiere den AO3 Support + faq_page: Seite für häufig gestellte Fragen (FAQ) + html: Du kannst Ankündigungen über die jüngsten Archivumzüge unter %{ao3_news_link} + lesen und zusätzliche Informationen auf der Offene Türen %{faq_page_link} + oder %{tutorial_page_link} finden. Für andere Fragen, die nicht in dieser + Mail, den FAQ oder den Anleitungen beantwortet werden, %{contact_support_link}. + text: Du kannst Ankündigungen über die jüngsten Archivumzüge unter (%{news_url}) + lesen und zusätzliche Informationen auf der Open Doors Häufig gestellte + Fragen (FAQ) Seite (%{open_doors_faq_url}) oder Anleitungs Seite (%{open_doors_tutorial_url}). + Für andere Fragen, die nicht in dieser Mail, den FAQ oder den Anleitungen + beantwortet werden, kontaktiere bitte den Support unter %{support_url}. + tutorial_page: Tutorial-Seite + other_works: + contact_open_doors: kontaktiere Open Doors + html: Wenn Du andere Werke im importierten Archiv unter einer E-Mail-Adresse + hattest, die du nicht mehr aufrufen kannst, bitte %{contact_open_doors_link} + mit allen Informationen, die zur Überprüfung Deiner Identität beitragen + können. + text: Wenn Du andere Werke im importierten Archiv unter einer E-Mail Adresse + hattest, die Du nicht mehr aufrufen kannst, bitte kontaktiere Open Doors + mit allen Informationen, die zur Überprüfung Deiner Identität beitragen + können. + questions: + contact_support: kontaktiere den AO3 Support + html: Für andere Anfragen, bitte %{contact_support_link}. + text: Bei weiteren Anfragen, kontaktiere bitte den AO3 Support unter %{support_url}. + redirects: + html: Um Empfehlungslisten und Lesezeichen zu bewahren, werden die Webadressen + des importierten Archivs möglicherweise für eine begrenzte Zeit auf die + importierte Kopie dieser Werke umgeleitet (überprüfe die Ankündigung Deines + Archivs, um sicher zu sein). Wenn Du bereits eine Kopie dieser Werke hochgeladen + und %{negation} die Funktion "Importieren von URL" genutzt hast, werden + zwei Kopien desselben Werkes auf AO3 existieren. + subject: "[%{app_name}] Werke hochgeladen" + update_redirect: + contact_open_doors: kontaktiere Open Doors + html: Wenn Du möchtest, dass Open Doors die Weiterleitung auf Dein bereits + vorhandenes Werk aktualisiert, lösche bitte die importierte Kopie und %{contact_open_doors_link} + mit Deinem AO3 Kontonamen, Deinem Kontonamen im importieren Archiv sowie + dem Titel und der URL des Fanwerks, auf das die Weiterleitung verweisen + soll. (Wenn Du bei mehreren Werken die Weiterleitung ändern möchtest, kannst + Du diese in einer Mail auflisten.) + text: Wenn Du möchtest, dass Open Doors die Weiterleitung auf Dein bereits + vorhandenes Werk aktualisiert, lösche bitte die importierte Kopie und kontaktiere + Open Doors unter %{open_doors_url} mit Deinem AO3 Kontonamen, Deinem Kontonamen + im importieren Archiv sowie dem Titel und der URL des Fanwerks, auf das + die Weiterleitung verweisen soll. (Wenn Du bei mehreren Werken die Weiterleitung + ändern möchtest, kannst Du diese in einer E-Mail auflisten.) + works_by: Diese Werke wurden unter der E-Mail %{email} geschrieben + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Alle Aufgaben wurden versendet. + subject: Aufgaben versendet + html: + received_message: 'Du hast eine Nachricht zu Deiner Sammlung %{collection_link} + erhalten:' + text: + received_message: 'Du hast eine Nachricht zu Deiner Sammlung erhalten "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Wenn Du Mitschöpfer*in eines Werkes bist, kannst Du zu neuen Kapiteln + hinzugefügt werden, unabhängig von Deinen Einstellungen für Mitschöpfungen. + Wenn das Werk zu einer Serie hinzugefügt wird, wirst Du zu dieser ebenfalls + hinzugefügt. + html: + creation: "%{creation_link} von %{pseud_links}" + edit_chapter: das Kapitel bearbeiten + edit_series: die Serie bearbeiten + remove_chapter: Wenn Du versehentlich hinzugefügt wurdest oder nicht als Schöpfer*in + aufgeführt werden möchtest, kannst Du %{edit_chapter_link}, um Dich selbst + als Schöpfer*in zu entfernen. + remove_series: Wenn Du versehentlich hinzugefügt wurdest oder nicht als Schöpfer*in + aufgeführt werden möchtest, kannst Du %{edit_series_link}, um Dich selbst + als Schöpfer*in zu entfernen. + intro_chapter: 'Der/die Benutzer*in %{adding_user} hat Dein Pseudonym %{pseud} + als Mitschöpfer*in zu folgendem Kapitel hinzugefügt:' + intro_series: 'Der/die Benutzer*in %{adding_user} hat Dein Pseudonym %{pseud} + als Mitschöpfer*in zur folgenden Serie hinzugefügt:' + subject: "[%{app_name}] Mitschöpfer*in-Benachrichtigung" + text: + creation: "%{title} (%{url}) von %{pseuds}" + remove_chapter: 'Wenn Du versehentlich hinzugefügt wurdest oder nicht als + Schöpfer*in aufgeführt werden möchtest, kannst Du das Kapitel bearbeiten, + um Dich selbst als Schöpfer*in zu entfernen: %{url}' + remove_series: 'Wenn Du versehentlich hinzugefügt wurdest oder nicht als Schöpfer*in + aufgeführt werden möchtest, kannst Du die Serie bearbeiten, um Dich selbst + als Schöpfer*in zu entfernen: %{url}' + creatorship_notification_archivist: + explanation: In der Funktion als Archivist*in von Open Doors (Offene Türen) + darf er/sie Dich ohne Anfrage hinzufügen, selbst wenn Du die Option, als Mitschöpfer*in + geführt zu werden, deaktiviert hast. + html: + creation: "%{creation_link} von %{pseud_links}" + edit_chapter: das Kapitel bearbeiten + edit_series: die Serie bearbeiten + edit_work: das Werk bearbeiten + remove_chapter: Falls Du irrtümlicherweise hinzugefügt wurdest oder nicht + als Schöpfer*in angezeigt werden möchtest, kannst Du %{edit_chapter_link}, + um Dich als Schöpfer*in zu entfernen. + remove_series: Falls Du irrtümlicherweise hinzugefügt wurdest oder nicht als + Schöpfer*in angezeigt werden möchtest, kannst Du %{edit_series_link}, um + Dich als Schöpfer*in zu entfernen. + remove_work: Falls Du irrtümlicherweise hinzugefügt wurdest oder nicht als + Schöpfer*in angezeigt werden möchtest, kannst Du %{edit_work_link}, um Dich + als Schöpfer*in zu entfernen. + intro_chapter: 'Der/Die Benutzer*in %{archivist} hat Dein Pseudonym %{pseud} + als Mitschöpfer*in zu folgendem Kapitel hinzugefügt:' + intro_series: 'Der/Die Benutzer*in %{archivist} hat Dein Pseudonym %{pseud} + als Mitschöpfer*in zur folgenden Serie hinzugefügt:' + intro_work: 'Der/Die Benutzer*in %{archivist} hat Dein Pseudonym %{pseud} als + Mitschöpfer*in zu folgendem Werk hinzugefügt:' + subject: "[%{app_name}] Archivist*innen-Benachrichtigung zur Mitschöpferschaft" + text: + creation: "%{title} (%{url}) von %{pseuds}" + remove_chapter: 'Falls Du irrtümlicherweise hinzugefügt wurdest oder nicht + als Schöpfer*in angezeigt werden möchtest, kannst Du das Kapitel bearbeiten, + um Dich als Schöpfer*in zu entfernen: %{url}' + remove_series: 'Falls Du irrtümlicherweise hinzugefügt wurdest oder nicht + als Schöpfer*in angezeigt werden möchtest, kannst Du die Serie bearbeiten, + um Dich als Schöpfer*in zu entfernen: %{url}' + remove_work: 'Falls Du irrtümlicherweise hinzugefügt wurdest oder nicht als + Schöpfer*in angezeigt werden möchtest, kannst Du das Werk bearbeiten, um + Dich als Schöpfer*in zu entfernen: %{url}' + creatorship_request: + html: + creation: "%{creation_link} von %{pseud_links}" + instructions: Du kannst diese Anfrage auf deiner "%{page_name}"-Seite annehmen + oder ablehnen. + page_name: Co-Creator Requests (Mitschöpfer*innen-Anfragen) + intro_chapter: 'dein Pseud %{pseud} wurde von %{inviting_user} eingeladen, als + Mitschöpfer*in des folgenden Kapitels aufgeführt zu werden:' + intro_series: 'dein Pseud %{pseud} wurde von %{inviting_user} eingeladen, als + Mitschöpfer*in der folgenden Serie aufgeführt zu werden:' + intro_work: 'dein Pseud %{pseud} wurde von %{inviting_user} eingeladen, als + Mitschöpfer*in des folgenden Werkes aufgeführt zu werden:' + subject: "[%{app_name}] Mitschöpfer*innen-Anfrage" + text: + creation: "%{title} (%{url}) von %{pseuds}" + instructions: 'Du kannst diese Anfrage auf deiner "Co-Creator Requests"- (Mitschöpfer*innen-Anfragen) + Seite annehmen oder ablehnen: %{url}' + delete_work_notification: + attachment: Anbei ist eine Kopie Deines Werkes, als Referenz für Dich. + deleted_other: + html: Dein Werk %{title} wurde gemäß Anfrage von %{pseud} gelöscht. + text: Dein Werk "%{title}" wurde gemäß Anfrage von %{pseud} gelöscht. + deleted_yourself: + html: Dein Werk %{title} wurde gemäß Deiner Anfrage gelöscht. + text: Dein Werk "%{title}" wurde gemäß Deiner Anfrage gelöscht. + questions: + html: Wenn Du Fragen hast, %{support}. + text: Falls Du Fragen hast, bitte %{support} (%{url}). + subject: "[%{app_name}] Dein Werk wurde gelöscht" + support: kontaktiere bitte den Support + invitation_to_claim: + access: + text: Abhängig vom ursprünglichen Archiv kann es sein, dass Deine importierten + Werke nur für registrierte Benutzer*innen zugänglich sind (damit man sie + über Google nicht finden kann). Falls dies der Fall ist, können Deine Werke + nur von eingeloggten Benutzer*innen geöffnet werden, außer Du entscheidest + Dich dafür, sie frei zugänglich zu machen. Wenn du Hilfe brauchst, Deine + Werke frei zugänglich zu machen, sie auszuwildern oder zu löschen, kontaktiere + bitte den AO3 Support. + claim_or_remove: + html: Beanspruche Deine Werke oder entferne sie hier. + text: 'Beanspruche Deine Werke oder entferne sie hier: %{claim_url}' + email_tips: Wenn Du uns kontaktierst, füge bitte E-Mail-Adressen von @transformativeworks.org + zur Liste sicherer Absender hinzu und schau auch in Deinem Spam-Ordner nach + unserer Antwort. + html: + ao3_news: AO3 Neuigkeiten + contact_open_doors: kontaktiere bitte Open Doors + contact_support: kontaktiere bitte AO3 Support + faq_page: Häufig gestellte Fragen (FAQ) Seite + tutorial_page: Anleitungsseite + introduction: + text: 'Du bekommst diese E-Mail, da kürzlich ein Archiv durch Open Doors (Offene + Türen: %{open_doors_link}) in das %{app_name} (%{app_short_name} - Ein Eigenes + Archiv: %{app_url}) importiert wurde, und wir denken, dass die folgenden + Fanwerke Dir gehören. Wir möchten Dir gerne die Möglichkeit geben, diese + Werke als Deine in Anspruch zu nehmen (oder zu löschen/auszuwildern), sofern + Du das möchtest. Und wenn Du noch keinen Account bei uns hast (möglicherweise + über eine andere E-Mail-Adresse), würden wir Dich gerne zu uns einladen!' + mistake: + text: Falls wir uns irren und diese Werke nicht von Dir sind, lösche sie bitte + nicht! Kontaktiere bitte Open Doors unter %{open_doors_link}, und wir kümmern + uns darum. + more_info: + text: Du findest Ankündigungen zu kürzlichen Archiv-Umzügen unter AO3-Neuigkeiten + (%{news_link}) und weitere Informationen auf Open Doors FAQ-Seite (%{open_doors_faq_link}) + oder der Anleitungsseite (%{open_doors_tutorial_link}). Für Fragen, die + weder in den FAQ, den Anleitungen, noch in dieser E-Mail beantwortet werden, + kontaktiere den Support unter %{support_link}. + other_works: + text: Wenn Du noch weitere Werke auf dem importierten Archiv veröffentlicht + hast, die über eine E-Mail-Adresse laufen, auf die Du keinen Zugriff mehr + hast, kontaktiere bitte Open Doors mit sämtlichen Informationen, die dabei + helfen können, Deine Identität zu verifizieren. + questions: + text: Für alle weiteren Fragen kontaktiere bitte den AO3-Support unter %{support_link}. + redirects: Um Empfehlungslisten und Lesezeichen zu erhalten, kann es sein, dass + die Webadressen des importierten Archivs für eine begrenzte Zeit auf die importierte + Kopie dieser Werke umleiten (überprüfe die Ankündigung Deines Archivs, um + sicher zu gehen). Wenn Du diese Werke schon einmal hochgeladen hast und dabei + NICHT die Funktion "Import von URL" benutzt hast, gibt es nun zwei Versionen + des Werkes im Archiv. + subject: "[%{app_name}] Einladung zur Inanspruchnahme von Werken" + unwanted: + text: Wenn diese Werke Dir gehören, Du sie aber nicht behalten möchtest, kannst + Du sie auswildern (hierbei bleiben sie auf dem AO3 stehen, aber ohne Angabe + Deines Namens) oder löschen (dann werden sie komplett vom AO3 entfernt). + Du musst Deine Werke keinem Account hinzufügen, um sie auszuwildern oder + zu löschen – Du kannst beides direkt über den Inanspruchnahme-Link oben + erledigen. (Für Unterstützung dabei, kontaktiere bitte den Support unter + %{support_link}.) + update_redirect: + text: Wenn Du möchtest, dass Open Doors die Weiterleitung aktualisiert, um + auf Dein bereits existierendes Werk zu verweisen, lösche bitte die importierte + Kopie, und kontaktiere Open Doors unter %{open_doors_link} mit Deinem AO3-Accountnamen, + Deinem Accountnamen im importierten Archiv und dem Titel sowie der URL des + Fanwerks, auf das die Weiterleitung verweisen soll. (Falls Du die Weiterleitungen + für mehrere Werke ändern möchtest, kannst Du sie alle in einer E-Mail auflisten.) + uploaded_list: 'Die hochgeladenen Werke umfassen:' + invite_increase_notification: + html: + body: + one: wir wollten Dir nur Bescheid sagen, dass Du %{count} neue Einladung + hast, die man zur Erstellung neuer Benutzer*innenkonten im AO3 verwenden + kann. Du kannst Freund*innen auf %{invitation_page_link} einladen. + other: wir wollten Dir nur Bescheid sagen, dass Du %{count} neue Einladungen + hast, die man zur Erstellung neuer Benutzer*innenkonten im AO3 verwenden + kann. Du kannst Freund*innen auf %{invitation_page_link} einladen. + invitation_page_link_text: Deiner Invitations (Einladungs)-Seite + subject: "[%{app_name}] Neue Einladungen" + text: + body: + one: wir wollten Dir nur Bescheid sagen, dass Du %{count} neue Einladung + hast, die man zur Erstellung neuer Benutzer*innenkonten im AO3 verwenden + kann. Du kannst Freund*innen auf Deiner Invitations (Einladungs)-Seite + (%{invitation_page_url}) einladen. + other: wir wollten Dir nur Bescheid sagen, dass Du %{count} neue Einladungen + hast, die man zur Erstellung neuer Benutzer*innenkonten im AO3 verwenden + kann. Du kannst Freund*innen auf Deiner Invitations (Einladungs)-Seite + (%{invitation_page_url}) einladen. + invite_request_declined: + main: + one: leider können wir Deine Anfrage für eine neue Einladung zurzeit nicht + erfüllen. + other: leider können wir Deine Anfrage für %{count} neue Einladungen zurzeit + nicht erfüllen. + reason: 'Deine Anfrage war:' + subject: "[%{app_name}] Anfrage nach zusätzlichen Einladungscodes abgelehnt" + recipient_notification: + html: + collection: Ein Geschenk-Fanwerk wurde für Dich in der %{collection_link} + Sammlung im AO3 veröffentlicht! + no_collection: Ein Geschenk-Fanwerk wurde für Dich im AO3 veröffentlicht. + subject: + collection: "[%{app_name}][%{collection_title}] Ein Geschenk-Fanwerk für Dich + in %{collection_title}" + no_collection: "[%{app_name}] Ein Geschenk-Fanwerk für Dich" + text: + collection: Ein Geschenk-Fanwerk wurde für Dich in der "%{collection_title}" + Sammlung (%{collection_url}) im AO3 veröffentlicht! + signup_notification: + activate: + html: Bitte %{activate_account_link}. + text: 'Bitte folge diesem Link, um Dein Benutzerkonto zu aktivieren: %{activate_account_url}' + activate_your_account: folge diesem Link, um deinen Account zu aktivieren. + admin_posts: AO3-Newsletter + bye: Wir hoffen, dass es Dir im Archiv gefallen wird. + contact_support: kontaktiere bitte unser Support-Team + faq: Häufig gestellten Fragen (FAQ) + features: + html: Sobald Dein Benutzerkonto eingerichtet und aktiviert ist, kannst Du + Deine Fanwerke veröffentlichen, E-Mail-Benachrichtigungen einrichten, die + Dich informieren, wenn es Aktualisierungen von Deinen Lieblingsschöpfer*innen + oder -werken gibt, Deine Einstellungen anpassen, damit die Seite so aussieht + und funktioniert, wie es für Dich passt, über den Verlauf nachverfolgen, + welche Werke Du im Archiv angesehen hast und vieles mehr. + text: Sobald Dein Benutzerkonto eingerichtet und aktiviert ist, kannst Du + Deine Fanwerke veröffentlichen, E-Mail-Benachrichtigungen einrichten, die + Dich informieren, wenn es Aktualisierungen von Deinen Lieblingsschöpfer*innen + oder -werken gibt, Deine Einstellungen anpassen, damit die Seite so aussieht + und funktioniert, wie es für Dich passt, über den Verlauf nachverfolgen, + welche Werke Du im Archiv angesehen hast und vieles mehr. + information: + html: Es gibt eine Menge Informationen und Tipps zur Nutzung des Archivs in + unseren %{faq_link}. Du findest die aktuellsten Neuigkeiten zur Entwicklung + unserer Seite in unserem %{admin_posts_link}. Falls Du weitere Hilfe benötigen, + auf einen Bug stoßen oder Fragen oder Kommentare haben solltest, dann %{contact_support_link}, + dessen Mitglieder sich immer freuen, wenn sie Dir helfen können. + text: 'Es gibt eine Menge Informationen und Tipps zur Nutzung des Archivs + in unseren Häufig gestellten Fragen (FAQ) unter %{faq_url}. Du findest die + aktuellsten Neuigkeiten zur Entwicklung unseren AO3-Newslettern unter %{admin_posts_url}. + Falls Du weitere Hilfe benötigen, auf einen Bug stoßen oder Fragen oder + Kommentare haben solltest, dann kontaktiere bitte unser Support-Team, dessen + Mitglieder sich immer freuen, wenn sie Dir helfen können: %{contact_support_url}.' + welcome: Willkommen im Archive of Our Own - AO3 (Ein Eigenes Archiv), %{login}! diff --git a/config/locales/phrase-exports/el.yml b/config/locales/phrase-exports/el.yml new file mode 100755 index 0000000..4f68c73 --- /dev/null +++ b/config/locales/phrase-exports/el.yml @@ -0,0 +1,663 @@ +--- +el: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Προειδοποίηση:' + other: 'Προειδοποιήσεις:' + category: + name_with_colon: + one: 'Κατηγορία:' + other: 'Κατηγορίες:' + character: + name_with_colon: + one: 'Χαρακτήρας:' + other: 'Χαρακτήρες:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandoms:' + freeform: + name_with_colon: + one: 'Επιπρόσθετη Ετικέτα:' + other: 'Επιπρόσθετες Ετικέτες:' + rating: + name_with_colon: 'Καταλληλότητα:' + relationship: + name_with_colon: + one: 'Σχέση:' + other: 'Σχέσεις:' + work: + chapter_total_display: Κεφάλαια + summary: Περίληψη + models: + archive_warning: + one: Προειδοποίηση + other: Προειδοποιήσεις + category: + one: Κατηγορία + other: Κατηγορίες + chapter: + one: Κεφάλαιο + other: Κεφάλαια + character: + one: Χαρακτήρας + other: Χαρακτήρες + fandom: + one: Fandom + other: Fandoms + freeform: + one: Επιπρόσθετη Ετικέτα + other: Επιπρόσθετες Ετικέτες + rating: + one: Καταλληλότητα + other: Καταλληλότητες + relationship: + one: Σχέση + other: Σχέσεις + series: + one: Σειρά + other: Σειρές + kudo_mailer: + batch_kudo_notification: + guest: + one: ένας επισκέπτης + other: "%{count} επισκέπτες" + left_kudos: + html: + one: Ο/Η %{givers_list} άφησε μπράβο στο %{commentable_link}. + other: Οι %{givers_list} άφησαν μπράβο στο %{commentable_link}. + text: + one: Ο/Η %{givers_list} άφησε μπράβο στο %{commentable_title} (%{commentable_url}). + other: Οι %{givers_list} άφησαν μπράβο στο %{commentable_title} (%{commentable_url}). + single_guest: + giver: Ένας επισκέπτης + html: "%{giver} άφησε μπράβο στο %{commentable_link}." + text: Ένας επισκέπτης άφησε μπράβο στο %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] 'Εχεις μπράβο!" + mailer: + general: + closing: + formal: Με εκτίμηση, + informal: Χαιρετισμούς, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Κεφάλαιο %{position} του έργου %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} λέξη" + other: "%{count} λέξεις" + footer: + about: + html: Το ΑΟ3 είναι ένα αρχείο το οποίο διαχειρίζονται και υποστηρίζουν θαυμαστές και βασίζεται %{your_donations_link}. + text: 'Το AO3 είναι ένα αρχείο το οποίο διαχειρίζονται και υποστηρίζουν θαυμαστές και βασίζεται στις δωρεές σας: %{your_donations_url}.' + your_donations: στις δωρεές σας + sent_at: Στάλθηκε στις %{sent_at}. + why_policy_abuse: + contact_policy_abuse: επικοινωνήστε με τη Επιτροπή Πολιτικής & Κατάχρησης + html: Αν δεν καταλαβαίνετε τον λόγο που λάβατε αυτό το μήνυμα, παρακαλούμε %{contact_policy_abuse_link}. + text: 'Εάν δεν καταλαβαίνετε τον λόγο που λάβατε αυτό το μήνυμα, παρακαλούμε επικοινωνήστε με την Επιτροπή Πολιτικής & Κατάχρησης: %{contact_policy_abuse_url}.' + why_support: + contact_support: επικοινωνήστε με την Επιτροπή Υποστήριξης + html: Αν δεν καταλαβαίνετε τον λόγο που λάβατε αυτό το μήνυμα, παρακαλούμε %{contact_support_link}. + text: Εάν δεν καταλαβαίνετε τον λόγο που λάβατε αυτό το μήνυμα, παρακαλούμε επικοινωνήστε με την Επιτροπή Υποστήριξης %{contact_support_url}. + greeting: + formal: + addressed_html: Γειά, %{name}, + unaddressed: Γειά, + informal: + addressed_html: Γεια %{name}! + unaddressed: Γεια! + introductory: Γεια σας από το Archive of Our Own – AO3 (Το Αρχείο Μας)! + metadata_label_indicator: ":" + signature: + abuse_team: Η ομάδα Πολιτικής & Κατάχρησης του AO3 + app_short_name: AO3 + open_doors: Η ομάδα των Open Doors (Ανοιχτές Πόρτες) + parent_org: Organization for Transformative Works – OTW (Οργανισμός Μετασχηματιστικών Έργων) + support: Η ομάδα Υποστήριξης του AO3 + users: + mailer: + reset_password_instructions: + expiration: Αν δε χρησιμοποιήσετε αυτόν τον σύνδεσμο για να επαναφέρετε τον + κωδικό σας εντός μίας εβδομάδας, τότε θα λήξει και θα πρέπει να κάνετε καινούργια + αίτηση επαναφοράς. + intro: 'Kάποιος έκανε αίτηση για επαναφορά του κωδικού του λογαριασμού σας. + Μπορείτε να αλλάξετε τον κωδικό του λογαριασμού σας ακολουθώντας τον παρακάτω + σύνδεσμο και εισάγοντας τον νέο σας κωδικό:' + link_title: Αλλαγή του κωδικού μου. + subject: "[%{app_name}] Επαναφορά του κωδικού σας" + unrequested: Αν δεν κάνατε εσείς αυτήν την αίτηση επαναφοράς, μπορείτε να + αγνοήσετε αυτό το μήνυμα και ο παλιός κωδικός σας θα συνεχίσει να λειτουργεί. + user_mailer: + admin_deleted_work_notification: + bye: Συνημμένο είναι ένα αντίγραφο του έργου σας για αναφορά σας. + contact_abuse: επικοινωνήστε με την Επιτροπή Πολιτικής & Κατάχρησης + deleted: + html: Το έργο σας %{title} διαγράφηκε από το Αρχείο από έναν διαχειριστή της + ιστοσελίδας. + text: Το έργο σας "%{title}" διαγράφηκε από το AO3 από έναν διαχειριστή της + ιστοσελίδας. + html: + tos_violation: Αν είναι πιθανό το έργο σας να παραβίασε τους Όρους Παροχής + Υπηρεσιών του Αρχείου, παρακαλούμε %{contact_abuse_link}. + import_project: + html: Αν το έργο σας ήταν μέρος ενός προγράμματος εισαγωγής διαχειριζόμενο + από την ομάδα των Ανοιχτών Πορτών, παρακαλούμε %{opendoors_link} για περαιτέρω + ερωτήσεις. + text: Αν το έργο σας ήταν μέρος ενός προγράμματος εισαγωγής διαχειριζόμενο + από την ομάδα των Ανοιχτών Πορτών, παρακαλούμε επικοινωνήστε με τις Ανοιχτές + Πόρτες (%{opendoors_link}) για περαιτέρω ερωτήσεις. + opendoors: επικοινωνήστε με τις Ανοιχτές Πόρτες + subject: "[%{app_name}] Το έργο σας έχει διαγραφεί από έναν διαχειριστή" + text: + tos_violation: Αν είναι πιθανό το έργο σας να παραβίασε τους Όρους Παροχής + Υπηρεσιών του AO3, παρακαλούμε επικοινωνήστε με την Επιτροπή Πολιτικής & + Κατάχρησης (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Όσο το έργο σας παραμένει κρυφό, θα εξακολουθείτε να έχετε πρόσβαση + σε αυτό μέσω του παραπάνω συνδέσμου, αλλά δε θα εμφανίζεται στη σελίδα με + τη λίστα των έργων σας και δε θα είναι διαθέσιμο στους άλλους χρήστες του + AO3. + check_email: Παρακαλούμε ελέγξτε την ηλεκτρονική σας αλληλογραφία (email), συμπεριλαμβανομένου + και του φακέλου ανεπιθύμητης αλληλογραφίας (spam), καθώς μπορεί η ομάδα Πολιτικής + & Κατάχρησης να έχει ήδη επικοινωνήσει μαζί σας εξηγώντας γιατί το έργο σας + κατέστηι κρυφό. + contact_abuse: επικοινωνήστε απευθείας με την Επιτροπή Πολιτικής & Κατάχρησης + html: + help: Αν δε γνωρίζετε με βεβαιότητα γιατί το έργο σας κατέστη κρυφό και δεν + έχετε λάβει επιπλέον μηνύματα σχετικά με αυτό το θέμα, παρακαλούμε %{contact_abuse_link}. + hidden: Το έργο σας με τίτλο %{title} έχει καταστεί κρυφό από την ομάδα Πολιτικής + & Κατάχρησης και δεν είναι πλέον δημόσια προσβάσιμο. + tos_violation: Αν το έργο σας κατέστη κρυφό επειδή παραβίαζε τους %{tos_link} + του AO3, θα πρέπει να προβείτε σε ενέργειες προκειμένου να διορθώσετε την + παραβίαση. Μη συμμόρφωση του έργου σας με τους Όρους Παροχής Υπηρεσιών μπορεί + να οδηγήσει στη διαγραφή του έργου σας από το AO3. + subject: "[%{app_name}] Το έργο σας έχει καταστεί κρυφό από την ομάδα Πολιτικής + & Κατάχρησης" + text: + help: 'Αν δε γνωρίζετε με βεβαιότητα γιατί το έργο σας κατέστη κρυφό και δεν + έχετε λάβει επιπλέον μηνύματα σχετικά με αυτό το θέμα, παρακαλούμε επικοινωνήστε + απευθείας με την Επιτροπή Πολιτικής & Κατάχρησης: %{contact_abuse_url}.' + hidden: Το έργο σας με τίτλο "%{title}" (%{work_url}) έχει καταστεί κρυφό + από την ομάδα Πολιτικής & Κατάχρησης και δεν είναι πλέον δημόσια προσβάσιμο. + tos_violation: Αν το έργο σας κατέστη κρυφό επειδή παραβίαζε τους Όρους Παροχής + Υπηρεσιών του AO3 (%{tos_url}), θα πρέπει να προβείτε σε ενέργειες προκειμένου + να διορθώσετε την παραβίαση. Μη συμμόρφωση του έργου σας με τους Όρους Παροχής + Υπηρεσιών μπορεί να οδηγήσει στη διαγραφή του έργου σας από το AO3. + tos: Όροι Παροχής Υπηρεσιών + anonymous_or_unrevealed_notification: + anonymous_info: Τα ανώνυμα έργα συμπεριλαμβάνονται σε λίστες ετικετών, αλλά + όχι στη σελίδα των έργων σας. Στο συγκεκριμένο έργο, το όνομα χρήστη σας θα + αντικατασταθεί με το "Anonymous" (Ανώνυμος). + anonymous_unrevealed_info: Οι διαχειριστές της συλλογής μπορεί αργότερα να καταστήσουν + το έργο σας φανερό, αλλά να το αφήσουν ανώνυμο. Τα άτομα με συνδρομές στον + λογαριασμό σας θα ειδοποιηθούν για αυτήν την αλλαγή. Μόλις γίνει φανερό, το + έργο σας θα συμπεριλαμβάνεται στις λίστες ετικετών, αλλά όχι στη σελίδα των + έργων σας. Στο έργο σας, το όνομα χρήστη σας θα αντικατασταθεί με το "Anonymous" + (Ανώνυμος). + changed_status: + anonymous: + html: Οι διαχειριστές της συλλογής %{collection_link} έχουν αλλάξει την + κατάσταση του έργου σας %{work_link} σε "ανώνυμο". + text: Οι διαχειριστές της συλλογής "%{collection_title}" (%{collection_url}) + άλλαξαν την κατάσταση του έργου σας "%{work_title}" (%{work_url}) σε ανώνυμο. + anonymous_unrevealed: + html: Οι διαχειριστές της συλλογής %{collection_link} άλλαξαν την κατάσταση + του έργου σας %{work_link} σε "ανώνυμο και κρυμμένο". + text: Οι διαχειριστές της συλλογής "%{collection_title}" (%{collection_url}) + άλλαξαν την κατάσταση του έργου σας "%{work_title}" (%{work_url}) σε ανώνυμο + και κρυφό. + unrevealed: + html: Οι διαχειριστές της συλλογής %{collection_link} άλλαξαν την κατάσταση + του έργου σας %{work_link} σε "κρυμμένο". + text: Οι διαχειριστές της συλλογής "%{collection_title}" (%{collection_url}) + άλλαξαν την κατάσταση του έργου σας "%{work_title}" (%{work_url}) σε κρυφό. + collection_items_link_text: σελίδα Approved Collection Items (Εγκεκριμένα Αντικείμενα + Συλλογών) + do_not_want: + anonymous: + html: Αν δε θέλετε το έργο σας να είναι ανώνυμο, παρακαλούμε επισκεφθείτε + τη %{collection_items_link} για να το αφαιρέσετε από αυτήν τη συλλογή. + text: 'Αν δε θέλετε το έργο σας να είναι ανώνυμο, παρακαλούμε επισκεφθείτε + τη σελίδα Approved Collection Items (Εγκεκριμένα Αντικείμενα Συλλογών) + για να το αφαιρέσετε από αυτήν τη συλλογή: %{collection_items_url}' + anonymous_unrevealed: + html: Αν δε θέλετε το έργο σας να είναι ανώνυμο και κρυμμένο, παρακαλούμε + επισκεφθείτε τη %{collection_items_link} για να το αφαιρέσετε από αυτήν + τη συλλογή. + text: 'Αν δε θέλετε το έργο σας να είναι ανώνυμο και κρυμμένο, παρακαλούμε + επισκεφθείτε τη σελίδα Approved Collection Items (Εγκεκριμένα Αντικείμενα + Συλλογών) για να το αφαιρέσετε από αυτήν τη συλλογή: %{collection_items_url}' + unrevealed: + html: Αν δε θέλετε το έργο σας να είναι κρυμμένο, παρακαλούμε επισκεφθείτε + τη %{collection_items_link} για να το αφαιρέσετε από αυτήν τη συλλογή. + text: 'Αν δε θέλετε το έργο σας να είναι κρυμμένο, παρακαλούμε επισκεφθείτε + τη σελίδα Approved Collection Items (Εγκεκριμένα Αντικείμενα Συλλογών) + για να το αφαιρέσετε από αυτήν τη συλλογή: %{collection_items_url}' + faq_link_text: Συχνές Ερωτήσεις για τις Συλλογές + more_info: + html: Για περισσότερες πληροφορίες, επισκεφθείτε τις %{faq_link}. + text: 'Για περισσότερες πληροφορίες, επισκεφθείτε τις Συχνές Ερωτήσεις για + τις Συλλογές: %{faq_url}' + subject: + anonymous: "[%{app_name}] Το έργο σας κατέστη ανώνυμο." + anonymous_unrevealed: "[%{app_name}] Το έργο σας κατέστη ανώνυμο και κρυμμένο" + unrevealed: "[%{app_name}] Το έργο σας κατέστη κρυμμένο" + unrevealed_info: Τα κρυμμένα έργα δε συμπεριλαμβάνονται στις λίστες ετικετών + ή στη σελίδα των έργων σας. Οποιοσδήποτε ακολουθήσει έναν σύνδεσμο για το + έργο, θα λάβει ειδοποίηση πως είναι επί του παρόντος κρυμμένο και δεν είναι + δυνατή η πρόσβασή του. + archivist_added_to_collection_notification: + approved_collection_items_page: Σελίδα Approved Collection Items (Έργα Εγκεκριμένα + για Συλλογές) + archivist_notice: Καθώς οι προγραμματιστές συλλογών δρουν ως επίσημοι αρχειοφύλακες + του Open Doors (Ανοιχτές Πόρτες), τους επιτρέπεται να προσθέσουν το έργο σας + σε αυτή τη συλλογή, ακόμα κι αν έχετε τις προσκλήσεις σε συλλογές απενεργοποιημένες. + Οι αρχειοφύλακες θα προσθέσουν ένα έργο σε μια συλλογή μόνο [το έργο] φιλοξενούνταν + σε ένα εισαγόμενο αρχείο. + removal_instructions: + html: Αν θέλετε να αφαιρέσετε το έργο σας από αυτή τη συλλογή, παρακαλούμε + επισκεφθείτε τον σύνδεσμο %{approved_items_link}. + text: Αν θέλετε να αφαιρέσετε το έργο σας από αυτή τη συλλογή, παρακαλούμε + επισκεφθείτε τη σελίδα σας Approved Collection Items (Έργα Εγκεκριμένα για + Συλλογές) %{approved_items_url} + subject: "[%{app_name}][%{collection_title}] Ένας αρχειοφύλακας του Open Doors + (Ανοιχτές Πόρτες) πρόσθεσε το έργο σας σε μια συλλογή" + work_added: + html: Οι προγραμματιστές της συλλογής %{collection_link} πρόσθεσαν το έργο + σας %{work_link} στη συλλογή τους! + text: Οι προγραμματιστές της συλλογής "%{collection_title}" (%{collection_url}) + πρόσθεσαν το έργο σας "%{work_title}" (%{work_url}) στη συλλογή τους! + challenge_assignment_notification: + any: Οτιδήποτε + assignment: + html: Σας έχει ανατεθεί το ακόλουθο αίτημα στην πρόκληση %{link} στο ΑΟ3! + description: 'Περιγραφή:' + due: 'Η ανάθεση πρέπει να υποβληθεί ως τις:' + html: + footer: Λαμβάνετε αυτό το μήνυμα γιατί δηλώσατε συμμετοχή στην πρόκληση %{title}. + Για περισσότερες πληροφορίες σχετικά με αυτήν την πρόκληση και τα στοιχεία + επικοινωνίας των διαχειριστών της, παρακαλούμε μεταβείτε στο %{footer_link}. + footer_link: σελίδα προφίλ της πρόκλησης + look_up: Μπορείτε να ανατρέξετε σε αυτήν την ανάθεση στη %{link}. + look_up_link: σελίδα με τις Assignments (Αναθέσεις) σας + optional_tags: 'Προαιρετικές Ετικέτες:' + prompts: 'Προτροπές:' + prompt_url: 'URL προτροπής:' + recipient: 'Παραλήπτης:' + recipient_missing: 'Κενό: επικοινωνήστε με έναν διαχειριστή για βοήθεια!' + subject: "[%{app_name}][%{collection_title}] Η Ανάθεσή σας!" + text: + assignment: Σας έχει ανατεθεί το ακόλουθο αίτημα στην πρόκληση "%{collection_title}" + (%{collection_url}) στο AO3! + footer: Λαμβάνετε αυτό το μήνυμα γιατί δηλώσατε συμμετοχή στην πρόκληση %{title} + (%{url}). Για περισσότερες πληροφορίες σχετικά με αυτήν την πρόκληση και + τα στοιχεία επικοινωνίας των διαχειριστών της, παρακαλούμε μεταβείτε στο + %{profile_url}. + look_up: Μπορείτε να βρείτε πληροφορίες για αυτήν την ανάθεση στη σελίδα των + Assignments (Αναθέσεών) σας στο %{link}. + change_email: + changed: + html: "%{login}, η ηλεκτρονική διεύθυνση (email) που είχατε συσχετίσει με + τον λογαριασμό σας έχει αλλάξει σε %{email}" + text: "%{login}, η ηλεκτρονική διεύθυνση (email) που είχατε συσχετίσει με + τον λογαριασμό σας έχει αλλάξει σε %{email}" + subject: "[%{app_name}] Αλλαγή Ηλεκτρονικής Διεύθυνσης (Email)" + claim_notification: + access: + contact_support: Επικοινωνία με την Επιτροπή Υποστήριξης του ΑΟ3 + html: Ανάλογα με το αρχείο, τα έργα σας ενδέχεται να έχουν εισαχθεί ως περιορισμένα + μόνο σε εγγεγραμμένους χρήστες (ώστε να τα αποκρύψουν από αναζητήσεις στο + Google). Αν ισχύει αυτό, στα έργα θα έχουν πρόσβαση μόνο συνδεδεμένοι χρήστες + εκτός αν επιλέξετε να τα κάνετε ορατά σε όλους. Για βοήθεια με το ξεκλείδωμα, + την αποποίηση, ή τη διαγραφή των έργων σας, παρακαλούμε επικοινωνήστε με + το %{contact_support_link}. + text: Ανάλογα με το αρχείο, τα έργα σας ενδέχεται να έχουν εισαχθεί ως περιορισμένα + μόνο σε εγγεγραμμένους χρήστες (ώστε να τα αποκρύψουν από αναζητήσεις στο + Google). Αν ισχύει αυτό, στα έργα θα έχουν πρόσβαση μόνο συνδεδεμένοι χρήστες + εκτός αν επιλέξετε να τα κάνετε ορατά σε όλους. Για βοήθεια με το ξεκλείδωμα, + την αποποίηση, ή τη διαγραφή των έργων σας, παρακαλούμε επικοινωνήστε με + την Επιτροπή Υποστήριξης στο %{support_url}. + email_tips: Αν επικοινωνείτε μαζί μας, παρακαλούμε να προσθέσετε τις ηλεκτρονικές + διευθύνσεις από το @transformativeworks.org στη λίστα των ασφαλών επαφών σας + και ελέγξτε τους φακέλους ανεπιθύμητων μηνυμάτων για την απάντησή μας. + introduction: + ao3_name: Archive of Our Own – AO3 (Το Αρχείο Μας) + html: Λαμβάνετε αυτό το e-mail επειδή είχατε έργα σε ένα αρχείο έργων θαυμαστών + το οποίο εισήγαγαν οι %{open_doors_name_link} στο %{app_link}. Επειδή η + ηλεκτρονική αυτή διεύθυνση συνδέεται με μιά διεύθυνση καταγεγραμμένη στο + εισαγόμενο αρχείο, τα συσχετισμένα έργα θαυμαστών (αναγράφονται παρακάτω) + έχουν προστεθεί αυτόματα στον λογαριασμό σας στο AO3. + open_doors_name: Open Doors (Ανοιχτές Πόρτες) + text: 'Λαμβάνετε αυτό το e-mail επειδή είχατε έργα σε ένα αρχείο έργων θαυμαστών + το οποίο εισήγαγαν οι Open Doors (Ανοιχτές Πόρτες) (%{open_doors_url}) στο + Archive of Our Own – AO3 (Το Αρχείο Μας): %{app_url}. Επειδή η ηλεκτρονική + αυτή διεύθυνση συνδέεται με μιά διεύθυνση καταγεγραμμένη στο εισαγόμενο + αρχείο, τα συσχετισμένα έργα θαυμαστών (αναγράφονται παρακάτω) έχουν προστεθεί + αυτόματα στον λογαριασμό σας στο AO3.' + mistake: + contact_open_doors: Επικοινωνία με το Open Doors + html: Αν αυτό είναι σφάλμα και αυτά δεν είναι τα έργα σας, παρακαλούμε μην + τα διαγράψετε! Παρακαλούμε απλώς επικοινωνήστε με το %{contact_open_doors_link} + και θα το διευθετήσουμε. + text: Αν αυτό είναι σφάλμα και αυτά δεν είναι τα έργα σας, παρακαλούμε μην + τα διαγράψετε! Παρακαλούμε απλώς επικοινωνήστε με το %{open_doors_url} και + θα το διευθετήσουμε. + more_info: + ao3_news: Νέα του ΑΟ3 + contact_support: Επικοινωνία με την Επιτροπή Υποστήριξης του ΑΟ3 + faq_page: Σελίδα Συχνών Ερωτήσεων + html: Μπορείτε να διαβάσετε ανακοινώσεις για πρόσφατες μετακινήσεις αρχείων + στο %{ao3_news_link}, και να βρείτε πρόσθετες πληροφορίες στις σελίδες των + Ανοιχτών Πορτών %{faq_page_link} ή %{tutorial_page_link}. Για τυχόν ερωτήσεις + που δεν απαντήθηκαν στις Συχνές Ερωτήσεις, τους οδηγούς χρήσης, ή σε αυτό + το e-mail, παρακαλούμε %{contact_support_link}. + text: Μπορείτε να διαβάσετε ανακοινώσεις για πρόσφατες μετακινήσεις αρχείων + στα Νέα του ΑΟ3 (%{news_url}), και να βρείτε πρόσθετες πληροφορίες στη σελίδα + Συχνών Ερωτήσεων των Ανοιχτών Πορτών (%{open_doors_faq_url}) ή τη σελίδα + οδηγών χρήσης (%{open_doors_tutorial_url}). Για τυχόν ερωτήσεις που δεν + απαντήθηκαν στις Συχνές Ερωτήσεις, τους οδηγούς χρήσης, ή σε αυτό το e-mail, + παρακαλούμε επικοινωνήστε με την Επιτροπή Υποστήριξης στο %{support_url}. + tutorial_page: Σελίδα οδηγών χρήσης + other_works: + contact_open_doors: Επικοινωνία με το Open Doors + html: Αν είχατε άλλα έργα στο εισαγόμενο αρχείο κάτω από μία διεύθυνση ηλεκτρονικού + ταχυδρομείου στην οποία δεν έχετε πλέον πρόσβαση, παρακαλούμε %{contact_open_doors_link} + με οποιαδήποτε πληροφορία μπορεί να βοηθήσει στο να πιστοποιηθεί η ταυτότητά + σας. + text: Αν είχατε άλλα έργα στο εισαγόμενο αρχείο κάτω από μία διεύθυνση ηλεκτρονικού + ταχυδρομείου στην οποία δεν έχετε πλέον πρόσβαση, παρακαλούμε επικοινωνήστε + με τις Ανοιχτές Πόρτες με οποιαδήποτε πληροφορία μπορεί να βοηθήσει στο + να πιστοποιηθεί η ταυτότητά σας. + questions: + contact_support: Επικοινωνία με την Επιτροπή Υποστήριξης του ΑΟ3 + html: Για περαιτέρω ερωτήσεις, παρακαλούμε %{contact_support_link}. + text: Για περαιτέρω ερωτήσεις, παρακαλούμε επικοινωνήστε με την Επιτροπή Υποστήριξης + του ΑΟ3 %{support_url}. + redirects: + html: Για να διατηρήσετε λίστες προτεινόμενων έργων θαυμαστών και τους σελιδοδείκτες, + οι ιστότοποι των εισαγόμενων αρχείων δύναται να ανακατευθύνουν στο εισαγόμενο + αντίγραφο για περιορισμένο χρονικό διάστημα (δείτε την ανάρτηση δημοσίευσης + του αρχείου σας για να είστε σίγουροι). Αν έχετε ήδη ανεβάσει ένα αντίγραφο + αυτών των έργων και %{negation} χρησιμοποιήσατε τη λειτουργία εισαγωγής + από σύνδεσμο (URL), θα υπάρχουν δύο αντίγραφα του ίδιου έργου στο AO3. + subject: "[%{app_name}] Μεταφόρτωση Έργου" + update_redirect: + contact_open_doors: Επικοινωνία με το Open Doors + html: Αν θέλετε οι Ανοιχτές Πόρτες να ενημερώσουν την ανακατεύθυνση ώστε να + οδηγεί στο προϋπάρχον έργο σας, παρακαλούμε να διαγράψετε το εισαγόμενο + αντίγραφο, %{contact_open_doors_link} με το όνομα του λογαριασμού σας στο + AO3, το όνομα του λογαριασμού σας στο εισαγόμενο αρχείο, και τον τίτλο και + σύνδεσμο (URL) του έργου θαυμαστή στο οποίο θέλετε να οδηγεί η ανακατεύθυνση. + (Αν έχετε πολλαπλά έργα για τα οποία θέλετε να αλλάξετε την ανακατεύθυνση, + μπορείτε να τα αναφέρετε όλα σε ένα email.) + text: Αν θέλετε οι Ανοιχτές Πόρτες να ενημερώσουν την ανακατεύθυνση ώστε να + οδηγεί στο προϋπάρχον έργο σας, παρακαλούμε να διαγράψετε το εισαγόμενο + αντίγραφο, και να επικοινωνήσετε με τις Ανοιχτές Πόρτες στο %{open_doors_url} + με το όνομα του λογαριασμού σας στο AO3, το όνομα του λογαριασμού σας στο + εισαγόμενο αρχείο, και τον τίτλο και σύνδεσμο (URL) του έργου θαυμαστή στο + οποίο θέλετε να οδηγεί η ανακατεύθυνση. (Αν έχετε πολλαπλά έργα για τα οποία + θέλετε να αλλάξετε την ανακατεύθυνση, μπορείτε να τα αναφέρετε όλα σε ένα + email.) + works_by: Τα έργα αυτά έχουν δημιουργηθεί υπό την ηλεκτρονική διεύθυνση %{email} + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Όλες οι αναθέσεις έχουν αποσταλεί. + subject: Απεσταλμένες Αναθέσεις + html: + received_message: 'Έχετε λάβει ένα μήνυμα σχετικά με τη συλλογή σας %{collection_link}:' + text: + received_message: 'Έχετε λάβει ένα μήνυμα σχετικά με τη συλλογή σας "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Όταν είστε συνδημιουργός σε ένα έργο, μπορείτε να προστεθείτε σε + νέα κεφάλαια ανεξάρτητα από τις ρυθμίσεις συνδημιουργού που έχετε θέσει. Το + ψευδώνυμό σας θα προστεθεί και σε όποια σειρά έχει προστεθεί το εν λόγω έργο. + html: + creation: "%{creation_link} από τους %{pseud_links}" + edit_chapter: επεξεργαστείτε το κεφάλαιο + edit_series: επεξεργαστείτε τη σειρά + remove_chapter: Αν έχετε προστεθεί ως συνδημιουργός κατά λάθος ή αν δε θέλετε + να φαίνεστε ως συνδημιουργός, μπορείτε να %{edit_chapter_link} για να αφαιρέσετε + το όνομά σας. + remove_series: Αν έχετε προστεθεί ως συνδημιουργός κατά λάθος ή αν δε θέλετε + να φαίνεστε ως συνδημιουργός, μπορείτε να %{edit_series_link}για να αφαιρέσετε + το όνομά σας. + intro_chapter: 'Ο χρήστης/Η χρήστρια %{adding_user} πρόσθεσε το ψευδώνυμό σας + %{pseud} ως συνδημιουργό στο ακόλουθο κεφάλαιο:' + intro_series: 'Ο χρήστης/Η χρήστρια %{adding_user} ανέφερε το ψευδώνυμό σας + %{pseud} ως συνδημιουργό στην ακόλουθη σειρά έργων:' + subject: "[%{app_name}] Ειδοποίηση Συνδημιουργού" + text: + creation: "%{title} (%{url}) από τους %{pseuds}" + remove_chapter: 'Αν έχετε προστεθεί ως συνδημιουργός κατά λάθος ή αν δε θέλετε + να φαίνεστε ως συνδημιουργός, μπορείτε να επεξεργαστείτε το κεφάλαιο για + να αφαιρέσετε το όνομά σας: %{url}' + remove_series: Αν έχετε προστεθεί ως συνδημιουργός κατά λάθος ή αν δε θέλετε + να φαίνεστε ως συνδημιουργός, μπορείτε να αφαιρέσετε το όνομά σας:%{url} + creatorship_notification_archivist: + explanation: Καθώς δρα με την επίσημη ιδιότητα ενός αρχειονόμου του Open Doors + (Ανοιχτές Πόρτες), μπορεί να σας προσθέσει χωρίς αίτημα, ακόμη και αν έχετε + απενεργοποιήσει την επιλογή για τη συνδημιουργία. + html: + creation: "%{creation_link} από τους %{pseud_links}" + edit_chapter: επεξεργαστείτε το κεφάλαιο + edit_series: επεξεργαστείτε τη σειρά + edit_work: επεξεργαστείτε το έργο + remove_chapter: Εάν έχετε προστεθεί κατά λάθος ή δε θέλετε να εμφανίζεστε + ως δημιουργός, μπορείτε να %{edit_chapter_link} και να αφαιρέσετε τον εαυτό + σας από δημιουργό. + remove_series: Εάν έχετε προστεθεί κατά λάθος ή δε θέλετε να εμφανίζεστε ως + δημιουργός, μπορείτε να %{edit_series_link} και να αφαιρέσετε τον εαυτό + σας από δημιουργό. + remove_work: Εάν έχετε προστεθεί κατά λάθος ή δε θέλετε να εμφανίζεστε ως + δημιουργός, μπορείτε να %{edit_work_link} και να αφαιρέσετε τον εαυτό σας + από δημιουργό. + intro_chapter: 'Ο/Η χρήστης %{archivist} έχει προσθέσει το ψευδώνυμό σας %{pseud} + ως συνδημιουργό στο παρακάτω κεφάλαιο:' + intro_series: 'Ο/Η χρήστης %{archivist} έχει προσθέσει το ψευδώνυμό σας %{pseud} + ως συνδημιουργό στην παρακάτω σειρά:' + intro_work: 'Ο/H χρήστης %{archivist} έχει προσθέσει το ψευδώνυμό σας %{pseud} + ως συνδημιουργό στο παρακάτω έργο:' + subject: "[%{app_name}] Ειδοποίηση αρχειονόμου για συνδημιουργό" + text: + creation: "%{title} (%{url}) από τους %{pseuds}" + remove_chapter: 'Εάν έχετε προστεθεί κατά λάθος ή δε θέλετε να εμφανίζεστε + ως δημιουργός, μπορείτε να επεξεργαστείτε το κεφάλαιο για να αφαιρέσετε + τον εαυτό σας από δημιουργό: %{url}' + remove_series: 'Εάν έχετε προστεθεί κατά λάθος ή δε θέλετε να εμφανίζεστε + ως δημιουργός, μπορείτε να επεξεργαστείτε τη σειρά για να αφαιρέσετε τον + εαυτό σας από δημιουργό: %{url}' + remove_work: 'Εάν έχετε προστεθεί κατά λάθος ή δε θέλετε να εμφανίζεστε ως + δημιουργός, μπορείτε να επεξεργαστείτε το έργο για να αφαιρέσετε τον εαυτό + σας από δημιουργό: %{url}' + creatorship_request: + html: + creation: "%{creation_link} της/ου %{pseud_links}" + instructions: Μπορείτε να αποδεχθείτε ή να απορρίψετε αυτό το αίτημα στη σελίδα + %{page_name}. + page_name: Co-Creator Requests (Αιτήματα Συνδημιουργού) + intro_chapter: 'Ο χρήστης %{inviting_user} προσκάλεσε το ψευδώνυμό σας %{pseud} + να συμπεριληφθεί ως συνδημιουργός στο ακόλουθο κεφάλαιο:' + intro_series: 'Ο χρήστης %{inviting_user} προσκάλεσε το ψευδώνυμό σας %{pseud} + να συμπεριληφθεί ως συνδημιουργός στην ακόλουθη σειρά:' + intro_work: 'Ο χρήστης %{inviting_user} προσκάλεσε το ψευδώνυμό σας %{pseud} + να συμπεριληφθεί ως συνδημιουργός στο ακόλουθο έργο:' + subject: "[%{app_name}] Αίτημα συνδημιουργού" + text: + creation: "%{title} (%{url}) της/ου %{pseuds}" + instructions: 'Μπορείτε να αποδεχθείτε ή να απορρίψετε αυτό το αίτημα στη + σελίδα Co-Creator Requests (Αιτήματα Συνδημιουργού): %{url}' + delete_work_notification: + attachment: Έχουμε επισυνάψει ένα αντίγραφο του έργου σας προς ενημέρωσή σας. + deleted_other: + html: Το έργο σας, με τίτλο %{title}, διαγράφηκε κατόπιν αιτήματος του χρήστη + %{pseud}. + text: Το έργο σας, με τίτλο "%{title}", διαγράφηκε κατόπιν αιτήματος του χρήστη + %{pseud}. + deleted_yourself: + html: Το έργο σας, με τίτλο %{title}, διαγράφηκε κατόπιν δικού σας αιτήματος. + text: Το έργο σας, με τίτλο "%{title}", διαγράφηκε κατόπιν δικού σας αιτήματος. + questions: + html: Για τυχόν απορίες, παρακαλούμε %{support}. + text: Για τυχόν απορίες, παρακαλούμε %{support} (%{url}). + subject: "[%{app_name}] Το έργο σας έχει διαγραφεί" + support: επικοινωνήστε με την Επιτροπή Υποστήριξης + invitation_to_claim: + access: + text: Ανάλογα με το αρχείο, τα έργα σας μπορεί να έχουν εισαχθεί ώστε μόνο + οι εγγεγραμμένοι χρήστες να έχουν πρόσβαση σε αυτά (για να μην εμφανίζονται + σε αναζητήσεις στο Google). Σε αυτήν την περίπτωση, μόνο οι συνδεδεμένοι + χρήστες θα μπορούν να αποκτήσουν πρόσβαση στα έργα, εκτός και αν επιλέξετε + να τα καταστήσετε πλήρως ορατά. Για βοήθεια στο ξεκλείδωμα, την αποποίηση + ή τη διαγραφή των έργων σας, παρακαλούμε επικοινωνήστε με την Επιτροπή Υποστήριξης + του AO3. + claim_or_remove: + html: Διεκδικήστε ή αφαιρέστε τα έργα σας εδώ. + text: 'Διεκδικήστε ή αφαιρέστε τα έργα σας εδώ: %{claim_url}' + email_tips: Αν βρίσκεστε σε επικοινωνία μαζί μας, παρακαλούμε προσθέστε τις + ηλεκτρονικές διευθύνσεις από το @transformativeworks.org στη λίστα των ασφαλών + επαφών και ελέγξτε τον φάκελο ανεπιθύμητης αλληλογραφίας για την απάντησή + μας. + html: + ao3_news: Νέα του AO3 + contact_open_doors: επικοινωνήστε με τις Ανοιχτές Πόρτες + contact_support: επικοινωνήστε με την Επιτροπή Υποστήριξης του AO3 + faq_page: σελίδα Συχνών Ερωτήσεων + tutorial_page: σελίδα οδηγών χρήσης + introduction: + text: Λαμβάνετε αυτό το μήνυμα γιατί ένα αρχείο εισήχθη πρόσφατα από τις Ανοιχτές + Πόρτες (%{open_doors_link}) στο %{app_name} (%{app_short_name} - %{app_url}) + και πιστεύουμε πως τα ακόλουθα έργα θαυμαστών σάς ανήκουν. Θα θέλαμε να + σας δώσουμε την ευκαιρία να διεκδικήσετε (ή να διαγράψετε/αποποιηθείτε) + αυτά τα έργα εφόσον το επιθυμείτε. Και εάν δεν έχετε ήδη λογαριασμό με διαφορετική + ηλεκτρονική διεύθυνση (email), θα θέλαμε να σας προσκαλέσουμε να δημιουργήσετε + έναν! + mistake: + text: Αν πρόκειται για λάθος και αυτά δεν είναι τα έργα σας, σας παρακαλούμε + μην τα διαγράψετε! Παρακαλούμε απλά επικοινωνήστε με τις Ανοιχτές Πόρτες + (%{open_doors_link}) και θα το τακτοποιήσουμε. + more_info: + text: Μπορείτε να διαβάσετε τις ανακοινώσεις για τις πρόσφατες μεταφορές αρχείων + στα Νέα του AO3 (%{news_link}), και να βρείτε επιπλέον πληροφορίες στη σελίδα + Συχνών Ερωτήσεων των Ανοιχτών Πορτών (%{open_doors_faq_link}) ή στη σελίδα + των οδηγών χρήσης (%{open_doors_tutorial_link}). Για τυχόν ερωτήσεις που + δεν απαντήθηκαν στις Συχνές Ερωτήσεις, στους οδηγούς χρήσης ή στο παρόν + μήνυμα, παρακαλούμε επικοινωνήστε με την Επιτροπή Υποστήριξης στο %{support_link}. + other_works: + text: Αν είχατε και άλλα έργα στο εισαχθέν αρχείο υπό μια ηλεκτρονική διεύθυνση + στην οποία δεν έχετε πια πρόσβαση, παρακαλούμε επικοινωνήστε με τις Ανοιχτές + Πόρτες με οποιεσδήποτε πληροφορίες μπορούν να επιβεβαιώσουν την ταυτότητά. + questions: + text: Για άλλες ερωτήσεις, παρακαλούμε επικοινωνήστε με την Επιτροπή Υποστήριξης + του AO3 στο %{support_link}. + redirects: Προκειμένου να διατηρήσετε λίστες προτάσεων και σελιδοδείκτες, οι + ηλεκτρονικές διευθύνσεις του εισαχθέντος αρχείου μπορεί να οδηγούν στο εισαχθέν + αντίγραφο αυτών των έργων για λίγο καιρό (ελέγξτε την αναρτημένη ανακοίνωση + για το αρχείο σας για να βεβαιωθείτε). Εάν έχετε ήδη αναρτήσει ένα αντίγραφο + αυτών των έργων και ΔΕΝ χρησιμοποιήσατε τη λειτουργία εισαγωγής μέσω συνδέσμου + URL,τότε θα υπάρχουν στο αρχείο δύο αντίγραφα του ίδιου έργου. + subject: "[%{app_name}] Πρόσκληση για αναγνώριση έργων" + unwanted: + text: Αν αυτά τα έργα όντως ανήκουν σε εσάς, αλλά δεν τα θέλετε, μπορείτε + να τα αποποιηθείτε (έτσι ώστε να παραμείνουν στο AO3, αλλά χωρίς να εμφανίζεται + το όνομά σας) ή να τα διαγράψετε (έτσι ώστε να αφαιρεθούν πλήρως από το + AO3). Δεν χρειάζεται να προσθέσετε αυτά τα έργα σε κάποιον λογαριασμό προκειμένου + να τα αποποιηθείτε ή να τα διαγράψετε--μπορείτε να το κάνετε απευθείας από + τον παραπάνω σύνδεσμο. (Για βοήθεια, παρακαλούμε επικοινωνήστε με την Επιτροπή + Υποστήριξης στο %{support_link}.) + update_redirect: + text: Αν θέλετε οι Ανοιχτές Πόρτες να ενημερώσουν τον σύνδεσμο ανακατεύθυνσης + ώστε να οδηγεί στο προϋπάρχον έργο σας, παρακαλούμε διαγράψτε το εισαχθέν + αντίγραφο και επικοινωνήστε με τις Ανοιχτές Πόρτες στο %{open_doors_link} + με το όνομα του λογαριασμού σας στο AO3, το όνομα του λογαριασμού σας σε + ένα εισαχθέν αρχείο, καθώς και τον τίτλο και τον σύνδεσμο URL του έργου + λογοτεχνίας θαυμαστών στο οποίο θέλετε να οδηγεί ο σύνδεσμος ανακατεύθυνσης. + (Αν έχετε πολλαπλά έργα τους συνδέσμους ανακατεύθυνσης των οποίων θέλετε + να αλλάξετε, μπορείτε να τα απαριθμήσετε όλα σε ένα μήνυμα.) + uploaded_list: 'Τα αναρτημένα έργα περιλαμβάνουν τα:' + invite_increase_notification: + html: + body: + one: Θέλαμε απλά να σε ενημερώσουμε ότι έχεις μία νέα πρόσκληση που μπορεί + να χρησιμοποιηθεί για τη δημιουργία ενός νέου λογαριασμού στο AO3. Μπορείς + να προσκαλέσεις έναν φίλο σου στη %{invitation_page_link}. + other: Θέλαμε απλά να σε ενημερώσουμε ότι έχεις %{count} νέες προσκλήσεις + που μπορείς να χρησιμοποιηθούν για τη δημιουργία νέων λογαριασμών στο + AO3. Μπορείς να προσκαλέσεις έναν φίλο σου στη %{invitation_page_link}. + invitation_page_link_text: σελίδα των προσκλήσεών σου + subject: "[%{app_name}] Νέες Προσκλήσεις" + text: + body: + one: Θέλαμε απλά να σε ενημερώσουμε ότι έχεις %{count} νέες προσκλήσεις + που μπορούν να χρησιμοποιηθούν για τη δημιουργία ενός νέου λογαριασμού + στο AO3. Μπορείς να προσκαλέσεις έναν φίλο σου στη σελίδα σου Invitations + (Προσκλήσεις) (%{invitation_page_url}) + other: Θέλαμε απλά να σε ενημερώσουμε ότι έχεις %{count} νέες προσκλήσεις + που μπορούν να χρησιμοποιηθούν για τη δημιουργία νέων λογαριασμών στο + AO3. Μπορείς να προσκαλέσεις έναν φίλο σου στη σελίδα σου Invitations + (Προσκλήσεις) %{invitation_page_url}. + invite_request_declined: + main: + one: Είμαστε στη δυσάρεστη θέση να σας ενημερώσουμε πως το αίτημά σας για + νέα πρόσκληση δεν μπορεί να ικανοποιηθεί αυτήν τη στιγμή. + other: Είμαστε στη δυσάρεστη θέση να σας ενημερώσουμε πως το αίτημά σας για + %{count} νέες προσκλήσεις δεν μπορεί να ικανοποιηθεί αυτήν τη στιγμή. + reason: 'Το αίτημά σας ήταν:' + subject: "[%{app_name}] Το αίτημα για επιπλέον πρόσκληση απορρίφθηκε" + recipient_notification: + html: + collection: Ένα έργο-δώρο έχει αναρτηθεί για εσάς στη συλλογή %{collection_link} + στο AO3! + no_collection: Ένα έργο-δώρο αναρτήθηκε για εσάς στο AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Ένα έργο-δώρο για εσάς από + τη συλλογή %{collection_title}" + no_collection: "[%{app_name}] Ένα έργο-δώρο για εσάς" + text: + collection: Ένα έργο-δώρο έχει αναρτηθεί για εσάς στη συλλογή "%{collection_title}" + (%{collection_url}) στο AO3! + signup_notification: + activate: + html: Παρακαλούμε %{activate_account_link}. + text: 'Παρακαλούμε να ακολουθήσετε τον εξής σύνδεσμο για να ενεργοποιήσετε + τον λογαριασμό σας: %{activate_account_url}' + activate_your_account: ακολουθήστε αυτόν τον σύνδεσμο για να ενεργοποιήσετε + τον λογαριασμό σακ + admin_posts: Νέα του AO3 + bye: Ελπίζουμε να απολαύσετε το Αρχείο. + contact_support: επικοινωνήστε με την Επιτροπή Υποστήριξης + faq: Συχνές Ερωτήσεις + features: + html: Μόλις ενεργοποιηθεί ο λογαριασμός σας, μπορείτε να αναρτήσετε τα έργα + θαυμαστή σας, να ξεκινήσετε ηλεκτρονικές συνδρομές που θα σας ειδοποιούν + όταν οι αγαπημένοι σας δημιουργοί ή τα αγαπημένα σας έργα έχουν ενημερωθεί, + να ορίσετε τις προτιμήσεις σας ώστε να προσαρμόσετε την εμφάνιση και τη + λειτουργία της σελίδας, να κρατάτε αρχείο των έργων που επισκεφθήκατε στο + Αρχείο μέσω του ιστορικού σας και πολλά άλλα. + text: Μόλις ενεργοποιηθεί ο λογαριασμός σας, μπορείτε να αναρτήσετε τα έργα + θαυμαστή σας, να ξεκινήσετε ηλεκτρονικές συνδρομές που θα σας ειδοποιούν + όταν οι αγαπημένοι σας δημιουργοί ή τα αγαπημένα σας έργα έχουν ενημερωθεί, + να ορίσετε τις προτιμήσεις ώστε να προσαρμόσετε την εμφάνιση και τη λειτουργία + της σελίδας για εσάς, να κρατάτε αρχείο των έργων που επισκεφθήκατε στο + Αρχείο μέσω του ιστορικού σας και πολλά άλλα. + information: + html: Υπάρχουν πολλές πληροφορίες και συμβουλές για το πώς να χρησιμοποιήσετε + το Αρχείο στις %{faq_link}. Θα βρείτε τα τελευταία νέα σχετικά με τις + εξελίξεις στην ιστοσελίδα στα %{admin_posts_link}. Αν χρειάζεστε επιπλέον + βοήθεια, συναντήσετε κάποιο σφάλμα ή έχετε απορίες ή σχόλια, παρακαλούμε + %{contact_support_link}, η οποία είναι πάντα πρόθυμη να βοηθήσει. + text: 'Υπάρχουν πολλές πληροφορίες και συμβουλές για το πώς να χρησιμοποιήσετε + το Αρχείο στις Συχνές Ερωτήσεις στο %{faq_url}. Θα βρείτε τα τελευταία νέα + σχετικά με τις εξελίξεις στην ιστοσελίδα στις αναρτήσεις των Νέων του AO3 + στο %{admin_posts_url}. Αν χρειάζεστε επιπλέον βοήθεια, συναντήσετε κάποιο + σφάλμα ή έχετε απορίες ή σχόλια, παρακαλούμε επικοινωνήστε με την Επιτροπή + Υποστήριξης, η οποία είναι πάντα πρόθυμη να βοηθήσει: %{contact_support_url}.' + welcome: Καλώς ήρθατε στο AO3, %{login}! diff --git a/config/locales/phrase-exports/es.yml b/config/locales/phrase-exports/es.yml new file mode 100755 index 0000000..9830067 --- /dev/null +++ b/config/locales/phrase-exports/es.yml @@ -0,0 +1,623 @@ +--- +es: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Advertencia:' + other: 'Advertencias:' + category: + name_with_colon: + one: 'Categoría:' + other: 'Categorías:' + character: + name_with_colon: + one: 'Personaje:' + other: 'Personajes:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandoms:' + freeform: + name_with_colon: + one: 'Etiqueta adicional:' + other: 'Etiquetas adicionales:' + rating: + name_with_colon: 'Rating:' + relationship: + name_with_colon: + one: 'Relación:' + other: 'Relaciones:' + work: + chapter_total_display: Capítulos + summary: Resumen + models: + archive_warning: + one: Advertencia + other: Advertencias + category: + one: Categoría + other: Categorías + chapter: + one: Capítulo + other: Capítulos + character: + one: Personaje + other: Personajes + fandom: + one: Fandom + other: Fandoms + freeform: + one: Etiqueta adicional + other: Etiquetas adicionales + rating: + one: Rating + other: Ratings + relationship: + one: Relación + other: Relaciones + series: + one: Serie + other: Series + kudo_mailer: + batch_kudo_notification: + guest: + one: unx visitante + other: "%{count} visitantes" + left_kudos: + html: + one: "%{givers_list} dejó kudos en %{commentable_link}." + other: "%{givers_list} dejaron kudos en %{commentable_link}" + text: + one: "%{givers_list} dejó kudos en %{commentable_title} (%{commentable_url})." + other: "%{givers_list} dejaron kudos en %{commentable_title} (%{commentable_url})." + single_guest: + giver: Unx visitante + html: "%{giver} dejó kudos en %{commentable_link}." + text: Unx visitante dejó kudos en %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] ¡Recibiste kudos!" + mailer: + general: + closing: + formal: Atentamente, + informal: Saludos, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Capítulo %{position} de %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} palabra" + other: "%{count} palabras" + footer: + general: + about: + html: AO3 es un archivo administrado y mantenido por fans que depende + de %{donate_link}. + text: 'AO3 es un archivo administrado y mantenido por fans que depende + de tus donaciones: %{donate_url}.' + html: + donate_link_text: tus donaciones + support_link_text: Comunícate con Soporte Técnico + unwanted_email: + html: Si recibiste este mensaje por error, por favor %{support_link}. + text: Si recibiste este mensaje por error, por favor, comunícate con Soporte + Técnico en %{support_url}. + sent_at: 'Enviado: %{sent_at}.' + greeting: + formal_html: Estimadx %{name}, + informal: + addressed_html: "¡Hola %{name}!" + unaddressed: "¡Hola!" + introductory: Saludos de parte del Archive of Our Own – AO3 (Un Archivo Propio) + metadata_label_indicator: ":" + signature: + abuse_team: El equipo de Políticas y Prevención de Abuso del AO3 + app_short_name: AO3 + open_doors: El equipo de Open Doors (Puertas Abiertas) + parent_org: Organization for Transformative Works – OTW (Organización para + las Obras Transformativas) + support: El equipo de Soporte Técnico del AO3 + users: + mailer: + reset_password_instructions: + expiration: Si no utilizas este enlace para cambio de contraseña en una semana, + expirará y deberás solicitar uno nuevo. + intro: 'Alguien ha solicitado restablecer la contraseña de tu cuenta. Para + realizar el cambio, sigue el enlace a continuación e ingresa tu nueva contraseña:' + link_title: Cambiar mi contraseña. + subject: "[%{app_name}] Cambio de contraseña" + unrequested: Si no solicitaste un cambio de contraseña, puedes ignorar este + correo electrónico y tu contraseña previa será la misma. + user_mailer: + admin_deleted_work_notification: + bye: Para tu referencia, se adjunta una copia de tu obra. + contact_abuse: Comunicate con el comité de Políticas y Prevención de Abuso + deleted: + html: Tu obra %{title} ha sido eliminada del Archivo por unx admin del sitio. + text: Tu obra "%{title}" ha sido eliminada por unx admin del sitio. + html: + tos_violation: Si existe la posibilidad de que tu obra haya violado los Términos + y Condiciones de Servicio del Archivo, por favor %{contact_abuse_link}. + import_project: + html: Si tu obra es parte de un proyecto de importación administrado por nuestro + equipo de Open Doors (Puertas Abiertas), por favor %{opendoors_link} si + tienes más preguntas. + text: Si tu obra es parte de un proyecto administrado por nuestro equipo de + Open Doors (Puertas Abiertas) y tienes más preguntas, por favor comunícate + con Open Doors (%{opendoors_link}). + opendoors: Comunícate con Open Doors (Puertas Abiertas) + subject: "[%{app_name}] Tu obra ha sido eliminada por unx admin" + text: + tos_violation: Si existe la posibilidad de que tu obra haya violado los Términos + y Condiciones de Servicio del Archivo, por favor comunícate con el comité + de Políticas y Prevención de Abuso (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Mientras esté marcada como oculta, aún puedes acceder a tu obra mediante + el enlace anterior, pero no aparecerá en la lista de tu página de obras y + no estará disponible para otrxs usuarixs del AO3. + check_email: Por favor revisa tu correo, incluyendo la carpeta de spam, pues + es posible que el equipo de Políticas y Prevención de Abuso se haya comunicado + contigo para explicarte por qué tu obra fue marcada como oculta. + contact_abuse: ponte en contacto con Políticas y Prevención de Abuso + html: + help: Si no sabes por qué tu obra fue marcada como oculta y no recibiste ninguna + comunicación al respecto, por favor %{contact_abuse_link} directamente. + hidden: Tu obra %{title} ha sido marcada como oculta por el equipo de Políticas + y Prevención de Abuso y ya no está a disposición del público. + tos_violation: Si tu obra se marcó como oculta debido a una violación de los + %{tos_link} del AO3, se te solicitará que tomes las medidas pertinentes + para corregir dicha violación. Si no ajustas tu obra para que cumpla con + los Términos y Condiciones de Servicio, puede que tu obra sea eliminadadel + AO3. + subject: "[%{app_name}] Tu obra ha sido marcada como oculta por el equipo de + Políticas y Prevención de Abuso" + text: + help: 'Si no sabes por qué tu obra fue marcada como oculta y no recibiste + ninguna comunicación al respecto, por favor ponte en contacto con Políticas + y Prevención de Abuso directamente: %{contact_abuse_url}.' + hidden: Tu obra "%{title}" (%{work_url}) fue marcada como oculta por el equipo + de Políticas y Prevención de Abuso y ya no está a disposición del público. + tos_violation: Si tu obra se marcó como oculta debido a una violación de los + Términos y Condiciones de Servicio del AO3 (%{tos_url}), se te solicitará + que tomes las medidas pertinentes para corregir dicha violación. Si no ajustas + tu obra para que cumpla con los Términos y Condiciones de Servicio, puede + que tu obra sea eliminada del AO3. + tos: Términos y Condiciones de Servicio + anonymous_or_unrevealed_notification: + anonymous_info: Las obras anónimas están incluidas en los listados por etiquetas, + pero no aparecerán en tu página de obras. Tu nombre de usuarix será reemplazado + por "Anonymous" (Anónimo) en la obra. + anonymous_unrevealed_info: Lxs encargadxs de la colección pueden revelar tu + obra en el futuro pero dejarla anónima. No se le notificar[a a tus subscriptorxs + acerca de este cambio. Una vez revelada, tu obra se incluirá en los listados + por etiquetas, pero no aparecerá en tu página de obras. Tu nombre de usuarix + será reemplazado por "Anonymous" (Anónimo) en la obra. + changed_status: + anonymous: + html: Lxs encargadxs de la colección %{collection_link} han cambiado el + estado de tu obra %{work_link} a anónima. + text: Lxs encargadxs de la colección "%{collection_title}" (%{collection_url}) + han cambiado el estado de tu obra "%{work_title}" (%{work_url}) a anónima. + anonymous_unrevealed: + html: Lxs encargadxs de la colección %{collection_link} han cambiado el + estado de tu obra %{work_link} a anónima y sin revelar. + text: Lxs encargadxs de la colección "%{collection_title}" (%{collection_url}) + han cambiado el estado de tu obra "%{work_title}" (%{work_url}) a anónima + y no revelada + unrevealed: + html: Lxs encargadxs de la colección %{collection_link} han cambiado el + estado de tu obra %{work_link} a sin revelar. + text: Lxs encargadxs de la colección "%{collection_title}" (%{collection_url}) + han cambiado el estado de tu obra "%{work_title}" (%{work_url}) a no revelada. + collection_items_link_text: página de Approved Collection Items (Obras autorizadas + para estar en una colección) + do_not_want: + anonymous: + html: Si no quieres que tu obra sea anónima, por favor visita tu %{collection_items_link} + para eliminarla de la colección. + text: 'Si no quieres que tu obra sea anónima, por favor visita tu página + de Approved Collection Items (Obras autorizadas para estar en una colección) + para eliminarla de la colección: %{collection_items_url}' + anonymous_unrevealed: + html: Si no quieres que tu obra sea anónima y esté sin revelar, por favor + visita tu %{collection_items_link} para eliminarla de la colección. + text: 'Si no quieres que tu obra sea anónima y esté sin revelar, por favor + visita tu página de Approved Collection Items (Obras autorizadas para + estar en una colección) para eliminarla de la colección: %{collection_items_url}' + unrevealed: + html: Si no quieres que tu obra esté sin revelar, por favor visita tu %{collection_items_link} + para eliminarla de la colección. + text: 'Si no quieres que tu obra esté sin revelar, por favor visita tu página + de Approved Collection Items (Obras autorizadas para estar en una colección) + para eliminarla de la colección: %{collection_items_url}' + faq_link_text: FAQ (preguntas frecuentes) de colecciones + more_info: + html: Para más información, visita nuestras %{faq_link}. + text: 'Para más información, visita nuestras FAQ (preguntas frecuentes) de + colecciones: %{faq_url}' + subject: + anonymous: "[%{app_name}] Tu obra ahora es anónima" + anonymous_unrevealed: "[%{app_name}] Tu obra ahora es anónima y está sin revelar" + unrevealed: "[%{app_name}] Tu obra ahora está sin revelar" + unrevealed_info: Las obras sin revelar no están incluidas en los listados por + etiquetas ni aparecen en tu página de obras. Quien abre un enlace a la obra + recibirá un mensaje diciendo que todavía no ha sido revelada y que no tiene + acceso. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Artículos de colección + aprobados) + archivist_notice: Dado que lxs administradorxs de la colección actúan en su + capacidad oficial de archivistas para Open Doors (Puertas Abiertas), están + autorizados para añadir tu obra a esta colección, aún si tienes deshabilitadas + las invitaciones a colecciones. Lxs archivistas solo pueden añadir obras a + colecciones en el caso de que las obras estuvieran hospedadas en un archivo + importado. + removal_instructions: + html: Si deseas eliminar tu obra de esta colección, revisa tu página de %{approved_items_link}. + text: 'Si deseas eliminar tu obra de esta colección, revisa tu página de Approved + Collection Items (Artículos de colección aprobados): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Unx archivista de Open Doors (Puertas + Abiertas) añadió tu obra a una colección" + work_added: + html: "¡Lxs administradorxs de %{collection_link} añadieron tu obra %{work_link} + a su colección!" + text: ¡Lxs administradorxs de "%{collection_title}" (%{collection_url}) añadieron + tu obra "%{work_title}" (%{work_url}) a su colección! + challenge_assignment_notification: + any: Cualquiera + assignment: + html: "¡Te han asignado la siguiente solicitud en el desafío %{link} en el + AO3!" + description: 'Descripción:' + due: 'La fecha de entrega de esta tarea es:' + html: + footer: Has recibido este correo porque te inscribiste en el desafío %{title}. + Para más información sobre este desafío y sobre cómo comunicarte con quien + lo modera, por favor revisa %{footer_link}. + footer_link: página de perfil del desafío + look_up: Puedes buscar esta tarea en %{link}. + look_up_link: tu página de Assignments (Tareas) + optional_tags: 'Etiquetas opcionales:' + prompts: 'Sugerencias:' + prompt_url: 'URL de la sugerencia:' + recipient: 'Destinatarix:' + recipient_missing: 'No existe: contacta a quien modera para que lo solucione.' + subject: "[%{app_name}][%{collection_title}] ¡Tu tarea!" + text: + assignment: ¡Te han asignado la siguiente solicitud en el desafío "%{collection_title}" + (%{collection_url}) en el AO3 (Un Archivo Propio)! + footer: Has recibido este correo porque te inscribiste en el desafío %{title} + (%{url}). Para más información sobre este desafío y sobre cómo comunicarte + con quien lo modera, por favor revisa %{profile_url}. + look_up: Puedes buscar esta tarea en tu página de Assignments (Tareas) en + %{link} + change_email: + changed: + html: "%{login}, el correo electrónico asociado a tu cuenta se ha modificado + a %{email}" + text: "%{login}, el correo electrónico asociado a tu cuenta se ha modificado + a %{email}" + subject: "[%{app_name}] Cambio de correo electrónico" + claim_notification: + access: + contact_support: contacta a Soporte Técnico del AO3 + html: Dependiendo del archivo, tus obras pudieron ser importadas para usuarixs + registrados solamente (para mantenerlas fuera de las búsquedas de Google). + Si es el caso, las obras sólo serán accesibles para usuarixs con sesión + iniciada, a menos que elijas ponerlas a disposición general. Para ayudarte + a desbloquear, renunciar o eliminar tus obras, por favor, %{contact_support_link}. + text: Dependiendo del archivo, tus obras pudieron ser importadas para usuarixs + registrados solamente (para mantenerlas fuera de las búsquedas de Google). + Si es el caso, las obras sólo serán accesibles para usuarixs con sesión + iniciada, a menos que tu elijas hacerlas disponibles para todxs. Para ayudarte + a desbloquear, renunciar o eliminar tus obras, por favor, contacta a Soporte + Técnico del AO3 en %{support_url}. + email_tips: Si vas a contactarnos, añade los correos relacionados a @transformativeworks.org + a tu lista de contactos autorizados y revisa tus carpetas de correo no deseado + buscando nuestras respuestas. + introduction: + ao3_name: Archive of Our Own – AO3 (Un Archivo Propio) + html: Recibes este correo electrónico porque tienes obras en un archivo de + obras fan que ha sido importado por %{open_doors_name_link} a %{app_link}. + Dado que este correo electrónico está vinculado a tu registro en el archivo + importado, las obras asociadas al mismo (listadas abajo) se han añadido + de manera automática a tu cuenta en el AO3. + open_doors_name: Open Doors (Puertas Abiertas) + text: 'Recibes este correo electrónico porque tienes obras en un archivo de + obras fan que ha sido importado por Open Doors (Puertas Abiertas) (%{open_doors_url}) + al Archive of Our Own – AO3 (Un Archivo Propio): %{app_url}. Dado que este + correo electrónico está vinculado a tu registro en el archivo importado, + las obras asociadas al mismo (listadas abajo) se han añadido de manera automática + a tu cuenta en el AO3.' + mistake: + contact_open_doors: contacta a Open Doors + html: Si se trata de un error y no son tus obras, por favor, ¡no las elimines! + Solo %{contact_open_doors_link} y lo resolveremos. + text: Si se trata de un error y no son tus obras, por favor, ¡no las elimines! + Sólo contacta a Open Doors (%{open_doors_url}) y lo resolveremos. + more_info: + ao3_news: Noticias del AO3 + contact_support: contacta a Soporte Técnico del AO3 + faq_page: FAQ (Preguntas frecuentes) + html: Puedes leer los anuncios sobre mudanzas recientes de archivos en %{ao3_news_link} + y encontrar información adicional en las %{faq_page_link} de Open Doors + o %{tutorial_page_link}. Para cualquier pregunta que no se responda en las + FAQs, tutoriales o este correo electrónico, por favor, %{contact_support_link}. + text: Puedes leer los anuncios sobre mudanzas recientes de archivos en las + Noticias del AO3 (%{news_url}) y encontrar información adicional en las + FAQs de Open Doors (%{open_doors_faq_url}) o páginas de tutoriales (%{open_doors_tutorial_url}). + Para cualquier pregunta que no se responda en las FAQs, tutoriales o este + correo electrónico, por favor, contacta a Soporte Técnico en %{support_url}. + tutorial_page: páginas de tutoriales + other_works: + contact_open_doors: contacta a Open Doors + html: Si tienes otras obras en este archivo importado bajo un correo electrónico + al que ya no tienes acceso, por favor, %{contact_open_doors_link} con cualquier + información que pueda ser de ayuda para verificar tu identidad. + text: Si tienes otras obras en este archivo importado bajo un correo electrónico + al que ya no tienes acceso, por favor, contacta a Open Doors con cualquier + información que pueda ser de ayuda para verificar tu identidad. + questions: + contact_support: contacta a Soporte Técnico del AO3 + html: Para más consultas, por favor, %{contact_support_link}. + text: Para más consultas, por favor, contacta a Soporte Técnico del AO3 en + %{support_url}. + redirects: + html: Para preservar listas de recomendaciones y marcadores, la dirección + web del archivo importado redireccionará a la copia importada de esas obras + por tiempo limitado (revisa la publicación del anuncio de importación de + tu archivo para asegurarte). Si tu ya subiste una copia de estas obras y + %{negation} utilizaste la herramienta de importación desde la URL, habrá + dos copias de la misma obra en el AO3. + subject: "[%{app_name}] Obras importadas" + update_redirect: + contact_open_doors: contacta a Open Doors + html: Si deseas que Open Doors actualice la redirección para señalar tus obras + preexistentes, por favor, elimina la copia importada y %{contact_open_doors_link} + con el nombre de tu cuenta en el AO3, el nombre de tu cuenta en el archivo + importado y el título y URL de la obra fan que deseas redireccionar. (Si + tienes múltiples obras a las que quisieras cambiarles la redirección, puedes + listarlas en un correo electrónico). + text: Si deseas que Open Doors actualice la redirección para señalar tus obras + preexistentes, por favor, elimina la copia importada y contacta a Open Doors + en %{open_doors_url} con el nombre de tu cuenta en el AO3, el nombre de + tu cuenta en el archivo importado y el título y URL de la obra fan que deseas + redireccionar. (Si tienes múltiples obras a las que quisieras cambiarles + la redirección, puedes listarlas en un correo electrónico). + works_by: 'Estas obras se escribieron bajo este correo electrónico: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Ya se han enviado todas las tareas. + subject: Tareas enviadas + html: + received_message: 'Recibiste un mensaje sobre tu colección %{collection_link}:' + text: + received_message: 'Recibiste un mensaje sobre tu colección "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Cuando eres co-creadorx de una obra, te pueden añadir a nuevos + capítulos sin importar tu configuración de co-creación. También se añadirá + tu pseudónimo a cualquier serie que incluya esta obra. + html: + creation: "%{creation_link} por %{pseud_links}" + edit_chapter: editar el capítulo + edit_series: editar la serie + remove_chapter: Si has sido añadidx por error o no quieres aparecer como creadorx, + puedes %{edit_chapter_link} para eliminarte como creadorx. + remove_series: Si has sido agregadx por error o no deseas aparecer como co-creadorx, + puedes %{edit_series_link} para eliminarte como creadorx. + intro_chapter: 'La cuenta de usuarix %{adding_user} ha añadido tu pseudónimo + %{pseud} como co-creadorx del siguiente capítulo:' + intro_series: 'Elx usuarix %{adding_user} ha incluido tu pseudónimo %{pseud} + como co-creadorx en la siguiente serie:' + subject: "[%{app_name}] Notificación de co-creadorx" + text: + creation: "%{title} (%{url}) por %{pseuds}" + remove_chapter: 'Si has sido añadidx por error o no quieres aparecer como + creadorx, puedes editar el capítulo para eliminarte como creadorx: %{url}' + remove_series: 'Si has sido agregadx por error o no deseas aparecer como co-creadorx, + puedes editar la serie para eliminarte como creadorx: %{url}' + creatorship_notification_archivist: + explanation: Puesto que actúan en su capacidad oficial como archivistas de Open + Doors (Puertas Abiertas), se les permite añadirte sin que lo solicites, incluso + si tienes la co-creación deshabilitada. + html: + creation: "%{creation_link} por %{pseud_links}" + edit_chapter: editar el capítulo + edit_series: editar la serie + edit_work: editar la obra + remove_chapter: Si te han añadido por error o no quieres aparecer como creadorx, + puedes %{edit_chapter_link}} para eliminarte como creadorx. + remove_series: Si te han añadido por error o no quieres aparecer como creadorx, + puedes %{edit_series_link} para eliminarte como creadorx. + remove_work: Si te han añadido por error o no quieres aparecer como creadorx, + puedes %{edit_work_link} para eliminarte como creadorx. + intro_chapter: 'Elx usuarix %{archivist} ha añadido tu pseudónimo %{pseud} como + co-creadorx en el siguiente capítulo:' + intro_series: 'Elx usuarix %{archivist} ha añadido tu pseudónimo %{pseud} como + co-creadorx en la siguiente serie:' + intro_work: 'Elx usuarix %{archivist} ha añadido tu pseudónimo %{pseud} como + co-creadorx en la siguiente obra:' + subject: "[%{app_name}] Notificación de co-creadorx por parte de archivista" + text: + creation: "%{title} (%{url}) por %{pseuds}" + remove_chapter: 'Si te han añadido por error o no quieres aparecer como creadorx, + puedes editar el capítulo para eliminarte como creadorx: %{url}' + remove_series: 'Si te han añadido por error o no quieres aparecer como creadorx, + puedes editar la serie para eliminarte como creadorx: %{url}' + remove_work: 'Si te han añadido por error o no quieres aparecer como creadorx, + puedes editar la obra para eliminarte como creadorx: %{url}' + creatorship_request: + html: + creation: "%{creation_link} de %{pseud_links}" + instructions: Puedes aceptar o rechazar la solicitud en tu página de %{page_name}. + page_name: Co-Creator Requests (Solicitudes de co-creadorx) + intro_chapter: 'La cuenta de %{inviting_user} ha invitado a tu pseudónimo %{pseud} + a ser listado como co-creadorx del siguiente capítulo:' + intro_series: 'La cuenta de %{inviting_user} ha invitado a tu pseudónimo %{pseud} + a ser listado como co-creadorx de la siguiente serie:' + intro_work: 'La cuenta de %{inviting_user} ha invitado a tu pseudónimo %{pseud} + a ser listado como co-creadorx de la siguiente obra:' + subject: "[%{app_name}] Solicitud de co-creadorx" + text: + creation: "%{title} (%{url}) de %{pseuds}" + instructions: 'Puedes aceptar o rechazar la solicitud en tu página de Co-Creator + Requests (Solicitudes de co-creadorx): %{url}' + delete_work_notification: + attachment: Hemos adjuntado una copia de la obra como referencia. + deleted_other: + html: Tu obra %{title} fue eliminada a petición de %{pseud}. + text: Tu obra "%{title}" fue eliminada a petición de %{pseud}. + deleted_yourself: + html: Tu obra %{title} se ha eliminado como solicitaste. + text: Tu obra "%{title}" fue eliminada como solicitaste. + questions: + html: Si tienes alguna pregunta, por favor, %{support}. + text: Si tienes alguna pregunta, por favor, %{support} (%{url}). + subject: "[%{app_name}] Tu obra ha sido eliminada" + support: comunícate con Soporte Técnico + invitation_to_claim: + access: + text: Dependiendo del archivo, tus obras pueden haber sido importadas de forma + que solo lxs usuarixs registradxs pueden verlas (para que no aparezcan en + búsquedas de Google). Si es así, solo lxs usuarixs que hayan iniciado sesión + pueden acceder a las obras, salvo que elijas hacerlas visibles para todxs. + Para obtener ayuda acerca de cómo hacer tus obras accesibles, renunciar + a ellas o borrarlas, por favor, contacta a Soporte Técnico del AO3 (Un Archivo + Propio). + claim_or_remove: + html: Reclama o elimina tus obras aquí. + text: 'Reclama o elimina tus obras aquí: %{claim_url}' + email_tips: Si vas a contactarnos, por favor incluye los correos electrónicos + de @transformativeworks.org a tu lista autorizada de contactos y revisa la + carpeta de spam para asegurarte de que has recibido nuestra respuesta. + html: + ao3_news: Noticias del AO3 + contact_open_doors: contacta a Open Doors (Puertas Abiertas) + contact_support: contacta a Soporte Técnico del AO3 (Un Archivo Propio) + faq_page: página de FAQ (Preguntas frecuentes) + tutorial_page: página de tutorial + introduction: + text: Has recibido este correo electrónico porque recientemente Open Doors + (Puertas Abiertas) ha importado un archivo (%{open_doors_link}) al %{app_name} + (%{app_short_name} - %{app_url}) y creemos que estas obras de fan pueden + ser de tu autoría. Nos gustaría darte la oportunidad de reclamarlas (o borrarlas + o renunciar a ellas) si lo prefieres. Si todavía no tienes una cuenta con + otro correo electrónico, ¡nos gustaría invitarte! + mistake: + text: Si ocurrió un error y las obras no son tuyas, por favor, ¡no las borres! + Simplemente ponte en contacto con Puertas Abiertas (%{open_doors_link}) + y lo solucionaremos. + more_info: + text: Puedes encontrar anuncios acerca de mudanzas recientes de archivos en + las Noticias de AO3 (%{news_link}) e información adicional en las FAQ (Preguntas + frecuentes) de Puertas Abiertas (%{open_doors_faq_link}) o en la página + de tutoriales (%{open_doors_tutorial_link}). Para cualquier pregunta que + no esté incluida en las FAQ (Preguntas frecuentes), por favor, ponte en + contacto con Soporte Técnico en %{support_link}. + other_works: + text: Si tienes otras obras en el archivo importado asociadas a una dirección + de correo electrónico a la que ya no puedes acceder, por favor ponte en + contacto con Puertas Abiertas con cualquier información que pueda ayudarnos + a verificar tu identidad. + questions: + text: Para cualquier otra consulta, por favor, ponte en contacto con Soporte + Técnico del AO3 en %{support_link}. + redirects: Para conservar las listas de recomendaciones y los marcadores, las + direcciones web del archivo importado pueden redirigir a las copias importadas + de dichas obras por un tiempo (consulta la publicación sobre el archivo en + cuestión para asegurarte). Si ya has subido una copia de estas obras y NO + has utilizado la función importar desde URL, habrá dos copias de la misma + obra en el archivo. + subject: "[%{app_name}] Invitación para reclamar obras" + unwanted: + text: Si estas obras te pertenecen, pero no las quieres, puedes renunciar + a ellas (de forma que permanecen en el AO3, pero sin tu nombre) o borrarlas + (de manera que se eliminan completamente del AO3). No necesitas añadir las + obras a una cuenta para renunciar a ellas o borrarlas, sino que puedes hacerlo + mediante el enlace para reclamar obras que aparece arriba (Si necesitas + ayuda, por favor, %{support_link}). + update_redirect: + text: Si quieres que Puertas Abiertas actualice la redirección para que se + dirija a tu obra ya publicada, por favor, borra la copia importada y %{open_doors_link} + con tu nombre de usuarix en AO3 y en el archivo importado y el título y + URL de la obra de fan a la que te gustaría que se dirigiese la redirección + (puedes enlistarlas en el mismo correo electrónico si tienes varias cuya + redirección quieras cambiar). + uploaded_list: 'Las obras subidas incluyen:' + invite_increase_notification: + html: + body: + one: Solo queremos informarte que tienes %{count} invitación nueva que puedes + utilizar para crear una cuenta nueva en el AO3. Puedes invitar a tus amigxs + en %{invitation_page_link}. + other: Solo queremos informarte que tienes %{count} invitaciones nuevas + que puedes utilizar para crear nuevas cuentas en el AO3. Puedes invitar + a tus amigxs en %{invitation_page_link}. + invitation_page_link_text: tu página de invitaciones + subject: "[%{app_name}] Nuevas Invitaciones" + text: + body: + one: Solo queremos informarte que tienes %{count} invitación nueva que puedes + utilizar para crear una cuenta nueva en el AO3. Puedes invitar a tus amigxs + a tu página de Invitations (Invitaciones) en %{invitation_page_url}). + other: Solo queremos informarte que tienes %{count} invitaciones nuevas + que puedes utilizar para crear nuevas cuentas en el AO3. Puedes invitar + a tus amigxs a tu página de Invitations (Invitaciones) en %{invitation_page_url}). + invite_request_declined: + main: + one: Lamentamos informarte que en este momento no podemos cumplir con tu solicitud + de una nueva invitación. + other: Lamentamos informarte que en este momento no podemos cumplir con tu + solicitud de %{count} nuevas invitaciones. + reason: 'Tu solicitud era:' + subject: "[%{app_name}] Solicitud de código adicional de invitación rechazada" + recipient_notification: + html: + collection: "¡Se ha publicado una obra como regalo para ti en la colección + %{collection_link} en el AO3!" + no_collection: "¡Se ha publicado una obra como regalo para ti en el AO3!" + subject: + collection: "[%{app_name}][%{collection_title}] Tienes una obra de regalo + de %{collection_title}" + no_collection: "[%{app_name}] Tienes una obra de regalo" + text: + collection: ¡Se ha publicado una obra como regalo para ti en la colección + "%{collection_title}" (%{collection_url}) en el AO3! + signup_notification: + activate: + html: Por favor %{activate_account_link}. + text: 'Por favor sigue este enlace para activar tu cuenta: %{activate_account_url}' + activate_your_account: Sigue este enlace para activar tu cuenta + admin_posts: Noticias del AO3 + bye: Esperamos que disfrutes el AO3. + contact_support: contacta a Soporte Técnico + faq: FAQ + features: + html: Una vez que tu cuenta esté funcionando, podrás publicar obras de fans, + suscribirte para recibir notificaciones por email cuando tus autorxs favoritxs + publican o cuando se actualizan tus obras favoritas, establecer preferencias + para personalizar el sitio a tu gusto, estar al tanto de las obras a las + que has accedido en el AO3 por medio de tu historial y mucho más. + text: Una vez que tu cuenta esté funcionando, podrás publicar obras de fans, + suscribirte para recibir notificaciones por email cuando tus autorxs favoritxs + publican o cuando se actualizan tus obras favoritas, establecer preferencias + para personalizar el sitio a tu gusto, estar al tanto de las obras a las + que has accedido en el AO3 por medio de tu historial y mucho más. + information: + html: Hay mucha información y recomendaciones para el uso del AO3 en nuestras + %{faq_link}. Podrás encontrar las últimas noticias sobre los cambios al + sitio en %{admin_posts_link}. Si necesitas más ayuda, encuentras un error + o tienes preguntas o comentarios, por favor %{contact_support_link}, quienes + con gusto te ayudarán. + text: 'Hay mucha información y recomendaciones para el uso del AO3 en nuestras + FAQ en %{faq_url}. Podrás encontrar las últimas noticias sobre los cambios + al sitio en Noticias del AO3 en %{admin_posts_url}. Si necesitas más ayuda, + encuentras un error o tienes preguntas o comentarios, por favor contacta + a nuestro equipo de Soporte Técnico, quienes con gusto te ayudarán: %{contact_support_url}.' + welcome: "¡Te damos la bienvenida a Archive of Our Own, %{login}!" diff --git a/config/locales/phrase-exports/fa.yml b/config/locales/phrase-exports/fa.yml new file mode 100755 index 0000000..670038e --- /dev/null +++ b/config/locales/phrase-exports/fa.yml @@ -0,0 +1,533 @@ +--- +fa: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'هشدار:' + other: 'هشدارها:' + category: + name_with_colon: + one: 'دسته:' + other: 'دسته ها:' + character: + name_with_colon: + one: 'شخصیت:' + other: 'شخصیت ها:' + fandom: + name_with_colon: + one: 'فندوم:' + other: 'فندوم ها:' + freeform: + name_with_colon: + one: 'تگ اضافی:' + other: تگ های اضافی + rating: + name_with_colon: 'رتبه بندی:' + relationship: + name_with_colon: + one: 'رابطه:' + other: 'روابط:' + work: + summary: خلاصه + models: + archive_warning: + one: هشدار + other: هشدارها + category: + one: دسته + other: دسته ها + chapter: + one: فصل + other: فصل ها + character: + one: شخصیت + other: شخصیت ها + fandom: + one: فندوم + other: فندوم ها + freeform: + one: تگ اضافی + other: تگ های اضافی + rating: + one: رتبه بندی + other: رتبه بندی ها + relationship: + one: رابطه + other: روابط + series: + one: سری + other: سری ها + kudo_mailer: + batch_kudo_notification: + guest: + one: یک مهمان + other: "%{count} مهمان" + left_kudos: + html: + one: "%{givers_list} برای %{commentable_link} کودوس و قدردانی فرستاد." + other: "%{givers_list} برای %{commentable_link} کودوس و قدردانی فرستادند." + text: + one: "%{givers_list} برای %{commentable_title} (%{commentable_url}) کودوس + و قدردانی فرستاد." + other: "%{givers_list} برای %{commentable_title} (%{commentable_url}) کودوس + و قدردانی فرستادند." + single_guest: + giver: یک مهمان + html: "%{giver} براى %{commentable_link} كودوس و قدردانى فرستاد." + text: یک مهمان براى %{commentable_title} كودوس و قدردانى فرستاد (%{commentable_url}). + subject: "[%{app_name}] شما کودوس و قدردانی دریافت کردید!" + mailer: + general: + closing: + formal: با احترام، + informal: با آرزوی بهترین ها، + creation: + link_with_word_count: "(%{word_count}) %{creation_link}" + title_with_chapter_number: فصل %{position} از %{title} + title_with_word_count: (%{word_count}) "%{creation_title}" + word_count: + one: کلمه %{count} + other: کلمه %{count} + footer: + general: + about: + html: Archive of Our Own آرشیویست که توسط هواداران اداره و حمایت می شود + که به %{donate_link} تکیه می کند. + text: 'Archive of Our Own آرشیویست که توسط هواداران اداره و حمایت می شود + که به کمکهای مالی شما تکیه می کند: %{donate_url}.' + html: + donate_link_text: کمک های مالی شما + support_link_text: با پشتیبانی تماس بگیرید + unwanted_email: + html: اگر شما به اشتباه این پیام را دریافت کرده اید لطفا %{support_link}. + text: اگر شما به اشتباه این پیام را دریافت کرده اید لطفا با پشتیبانی تماس + بگیرید در %{support_url}. + sent_at: فرستاده شده در %{sent_at}. + greeting: + formal_html: "%{name} عزیز،" + informal: + addressed_html: سلام، %{name}! + unaddressed: سلام! + introductory: سلامی از Archive of Our Own – AO3 (آرشیوی از آن خودمان)! + metadata_label_indicator: ":" + signature: + abuse_team: تیم اختیارات AO3 + app_short_name: AO3 + open_doors: تیم Open Doors (درهای باز) + parent_org: Organization for Transformative Works – OTW (سازمانی برای آثار + دگرگون شونده) + support: تیم پشتیبانی AO3 + users: + mailer: + reset_password_instructions: + expiration: اگر شما از این لینک برای ریست کردن پسوردتان تا یک هفته استفاده + نکنید، این لینک منقضی می شود و مجبورید دوباره درخواست یک لینک جدید را بدهید. + intro: 'فردی برای اکانت شما درخواست ریست کردن پسورد داده است. شما می توانید + پسورد اکانتتان را با دنبال کردن لینک زیر و وارد کردن پسورد جدیدتان، تغییر + دهید:' + link_title: پسوردم را تغییر دهید. + subject: "[%{app_name}] پسوردتان را ريست كنيد" + unrequested: اگر شما برای ریست کردن پسوردتان درخواست نداده اید می توانید این + ایمیل را نادیده بگیرید و پسورد سابقتان به کار کردن ادامه خواهد داد. + user_mailer: + admin_deleted_work_notification: + bye: ضمیمه شده یک کپی از اثر شما برای مراجعه شماست. + contact_abuse: با تیم اختیارات ما تماس بگیرید + deleted: + html: اثر شما %{title} از آرشیو AO3 توسط یک ادمین سایت حذف شده است. + text: اثر شما "%{title}" از آرشیو AO3 توسط یک ادمین سایت حذف شده است. + html: + tos_violation: اگر احتمال دارد که اثر شما شرایط استفاده از خدمات آرشیو را + زیر سوال برده باشد، لطفا %{contact_abuse_link}. + import_project: + html: اگر اثر شما بخشی از یک پروژه ی واردات که توسط تیم Open Doors (درهای + باز) ما مدیریت شده است بوده، لطفا در صورت داشتن سوالهای بیشتر %{opendoors_link}. + text: اگر اثر شما بخشی از یک پروژه ی واردات که توسط تیم درهای باز ما مدیریت + شده است بوده، لطفا در صورت داشتن سوالهای بیشتر با Open Doors (درهای باز) + تماس بگیرید (%{opendoors_link}). + opendoors: با درهای باز تماس بگیرید + subject: "[%{app_name}] اثر شما توسط یک ادمین حذف شده است" + text: + tos_violation: اگر احتمال دارد که اثر شما شرایط خدمت آرشیو را زیر سوال برده + باشد، لطفا با کمیته ی اختیارات ما تماس بگیرید (%{contact_abuse_url}). + admin_hidden_work_notification: + access: اگرچه اثرتان مخفی است، شما باز هم از طریق لینکی که در بالا ارائه شده + است قادر به دسترسی به آن هستید، اما این اثر در صفحه ی آثار شما لیست نخواهد + شد و در دسترس کاربران دیگر AO3 نخواهد بود. + check_email: لطفا ایمیلتان، شامل فولدر اسپم (هرزنامه) تان، را چک کنید، به خاطر + اینکه تیم اختیارات ممکن است تاکنون با شما برای توضیح اینکه چرا اثرتان مخفی + شده است تماس گرفته باشد. + contact_abuse: با کمیته ی اختیارات تماس بگیرید + html: + help: اگر از اینکه چرا اثرتان مخفی شده است مطمئن نیستید و راجع به این موضوع + مکاتبات بیشتری دریافت نکرده اید، لطفا مستقیما %{contact_abuse_link}. + hidden: اثر شما %{title} توسط تیم اختیارات مخفی شده است و دیگر به صورت عمومی + در دسترس نیست. + tos_violation: اگر اثرتان به خاطر نقض %{tos_link} AO3 مخفی شده است، شما در + راستای اصلاح تخلف ملزم به انجام اقدام خواهید بود. عدم تطابق اثرتان با شرایط + استفاده از خدمات ممکن است به حذف اثرتان از AO3 منجر شود. + subject: "[%{app_name}] اثر شما توسط تیم اختیارات مخفی شده است" + text: + help: 'اگر از اینکه چرا اثرتان مخفی شده است مطمئن نیستید و راجع به این موضوع + مکاتبات بیشتری دریافت نکرده اید، لطفا مستقیما با کمیته ی اختیارات تماس بگیرید: + %{contact_abuse_url}.' + hidden: اثر شما، "%{title}" (%{work_url}) توسط تیم اختیارات مخفی شده است و + دیگر به صورت عمومی در دسترس نیست. + tos_violation: اگر اثرتان به خاطر نقض شرایط استفاده از خدمات AO3 (%{tos_url}) + مخفی شده است، شما در راستای اصلاح تخلف ملزم به اقدام خواهید بود. عدم تطابق + اثرتان با شرایط استفاده از خدمات ممکن است به حذف اثرتان از AO3 منجر شود. + tos: شرایط استفاده از خدمات + anonymous_or_unrevealed_notification: + anonymous_info: آثار ناشناس در لیست های تگ آورده می شوند ولی بر روی صفحه ی آثار + شما ظاهر نمی شوند. بر روی اثر، نام کاربری شما با "Anonymous" (ناشناس) جایگزین + خواهد شد. + anonymous_unrevealed_info: نگهدارندگان مجموعه ممکن است بعدا اثر شما را آشکار + کنند ولی آن را ناشناس باقی بگذارند. افرادی که مشترک شما هستند از این تغییر + مطلع نخواهند شد. زمانی که اثر شما آشکار شود در لیست های تگ ذکر خواهد شد ولی + در صفحه ی آثار شما ظاهر نخواهد شد. بر روی اثر نام کاربری شما با "Anonymous" + (ناشناس) جایگزین خواهد شد. + changed_status: + anonymous: + html: نگهدارندگان مجموعه ی %{collection_link} وضعیت اثر شما، %{work_link}، + را به ناشناس تغییر داده اند. + text: نگهداران مجموعه ی "%{collection_title}" (%{collection_url}) وضعیت + اثر شما "%{work_title}" (%{work_url}) را به ناشناس تغییر داده اند. + anonymous_unrevealed: + html: نگهدارندگان مجموعه ی %{collection_link} وضعیت اثر شما، %{work_link}، + را به ناشناس و پنهان تغییر داده اند. + text: نگهداران مجموعه ی "%{collection_title}" (%{collection_url}) وضعیت + اثر شما "%{work_title}" (%{work_url}) را به ناشناس و پنهان تغییر داده + اند. + unrevealed: + html: نگهدارندگان مجموعه ی %{collection_link} وضعیت اثر شما، %{work_link}، + را به پنهان تغییر داده اند. + text: نگهداران مجموعه ی "%{collection_title}" (%{collection_url}) وضعیت + اثر شما "%{work_title}" (%{work_url}) را به پنهان تغییر داده اند. + collection_items_link_text: صفحه ی Approved Collection Items (موارد مورد تایید + مجموعه) + do_not_want: + anonymous: + html: اگر نمی خواهید که اثرتان ناشناس باشد، لطفا به %{collection_items_link} + تان سر بزنید تا آن را از این مجموعه حذف کنید. + text: 'اگر نمی خواهید که اثرتان ناشناس باشد، لطفا به صفحه ی Approved Collection + Items (موارد مورد تایید مجموعه) تان سر بزنید تا آن را از این مجموعه حذف + کنید: %{collection_items_url}' + anonymous_unrevealed: + html: اگر نمی خواهید که اثرتان ناشناس و پنهان باشد، لطفا به %{collection_items_link} + تان سر بزنید تا آن را از این مجموعه حذف کنید. + text: 'اگر نمی خواهید که اثرتان ناشناس و پنهان باشد، لطفا به صفحه ی Approved + Collection Items (موارد مورد تایید مجموعه) تان سر بزنید تا آن را از این + مجموعه حذف کنید: %{collection_items_url}' + unrevealed: + html: اگر نمی خواهید که اثرتان پنهان باشد، لطفا به %{collection_items_link} + تان سر بزنید تا آن را از این مجموعه حذف کنید. + text: 'اگر نمی خواهید که اثرتان پنهان باشد، لطفا به صفحه ی Approved Collection + Items (موارد مورد تایید مجموعه) تان سر بزنید تا آن را از این مجموعه حذف + کنید: %{collection_items_url}' + faq_link_text: سوالات متداول مجموعه ها + more_info: + html: برای اطلاعات بیشتر، به %{faq_link}ی ما سری بزنید. + text: 'برای اطلاعات بیشتر به سوالات متداول مجموعه ها سری بزنید: %{faq_url}' + subject: + anonymous: "[%{app_name}] وضعیت اثر شما به ناشناس تغییر پیدا کرد" + anonymous_unrevealed: "[%{app_name}] وضعیت اثر شما به ناشناس و پنهان تغییر + پیدا کرد" + unrevealed: "[%{app_name}] وضعیت اثر شما به پنهان تغییر پیدا کرد" + unrevealed_info: آثار پنهان آثاری هستند که در لیست های تگ و صفحه ی آثار شما + ظاهر نمی شوند. هرکسی که لینکی را به این اثر دنبال کند یک اطلاعیه دریافت خواهد + کرد که این اثر در حال حاضر پنهان است و آنها نخواهند توانست که به محتوای آن + دست یابند. + challenge_assignment_notification: + any: هرچیزی + assignment: + html: درخواست ذیل در چالش %{link} در AO3 به شما محول شده است! + description: 'شرح:' + due: 'موعد انجام این وظیفه تا:' + html: + footer: شما این ایمیل را به دلیل ثبت نام در چالش %{title} دریافت کرده اید. + برای اطلاعات بیشتر در مورد این چالش و اطلاعات تماس مدیران، لطفا به %{footer_link} + سری بزنید. + footer_link: صفحه ی پروفایل چالش + look_up: شما می توانید این وظیفه را در %{link} جست و جو کنید. + look_up_link: پیج Assignments (وظایف) خود + optional_tags: 'تگهای اختیاری:' + prompts: 'درخواستها:' + prompt_url: 'آدرس اینترنتی درخواست:' + recipient: 'گیرنده:' + recipient_missing: 'هیچکس: برای کمک با یک مدیر تماس بگیرید!' + subject: "[%{app_name}][%{collection_title}] وظیفه شما!" + text: + assignment: درخواست ذیل در چالش "%{collection_title}" (%{collection_url}) + در AO3 به شما محول شده است! + footer: شما این ایمیل را به دلیل ثبت نام در چالش %{title} (%{url}) دریافت + کرده اید. برای اطلاعات بیشتر در مورد این چالش و اطلاعات تماس مدیران لطفا + %{profile_url} را ببینید. + look_up: شما می توانید این وظیفه را در پیج Assignments (وظایف) خود در %{link} + جست و جو کنید. + change_email: + changed: + html: "%{login}، ایمیل مرتبط با اکانت شما به ایمیل %{email} تغییر یافته است." + text: "%{login}، ایمیل مرتبط با اکانت شما به ایمیل %{email} تغییر یافته است." + subject: "[%{app_name}] تغییر ایمیل" + collection_notification: + assignments_sent: + complete: اکنون تمامی وظایف فرستاده شده اند. + subject: وظایف فرستاده شده + html: + received_message: 'شما پیامی راجع به مجموعه تان %{collection_link} دریافت + کرده اید:' + text: + received_message: 'شما پیامی راجع به مجموعه تان "%{collection_title}" (%{collection_url}) + دریافت کرده اید:' + creatorship_notification: + explanation: زمانی که شما تهیه کننده ی همکار یک اثر هستید، صرف نظر از تنظیمات + همکاریتان، می توانید به فصل های جدید اثر اضافه شوید. شما همچنین به سری هایی + که این اثر به آنها اضافه می شود پیوست خواهید شد. + html: + creation: "%{creation_link} توسط %{pseud_links}" + edit_chapter: فصل را ویرایش کنید + edit_series: سری را ویرایش کنید + remove_chapter: اگر شما به اشتباه اضافه شده اید یا نمی خواهید به عنوان تهیه + کننده ذکر شوید، می توانید %{edit_chapter_link} تا خودتان را به عنوان خالق + حذف کنید. + remove_series: اگر شما به اشتباه اضافه شده اید یا نمی خواهید به عنوان تهیه + کننده ذکر شوید،، می توانید %{edit_series_link} تا خودتان را به عنوان خالق + حذف کنید. + intro_chapter: 'کاربر %{adding_user} نام مستعار شما %{pseud} را به عنوان تهیه + کننده ی همکار برای فصل ذیل لیست کرده است:' + intro_series: 'کاربر %{adding_user} نام مستعار شما %{pseud} را به عنوان تهیه + کننده ی همکار برای سری ذیل لیست کرده است:' + subject: "[%{app_name}] اطلاعیه تهیه کننده همکار" + text: + creation: "%{title} (%{url}) توسط %{pseuds}" + remove_chapter: 'اگر شما به اشتباه اضافه شده اید یا نمی خواهید به عنوان تهیه + کننده ذکر شوید، می توانید فصل را ویرایش کنید تا خودتان را به عنوان خالق + حذف کنید: %{url}' + remove_series: 'اگر شما به اشتباه اضافه شده اید یا نمی خواهید به عنوان تهیه + کننده ذکر شوید، می توانید سری را ویرایش کنید تا خودتان را به عنوان خالق + حذف کنید: %{url}' + creatorship_notification_archivist: + explanation: به خاطر اینکه ایشان در حوزه ی رسمی خود به عنوان یک بایگان Open + Doors (درهای باز) فعالیت می کنند، اجازه دارند که شما را بدون هیچ درخواستی + اضافه کنند، حتی اگر شما تهیه کنندگی همکار خود را غیرفعال کرده باشید. + html: + creation: "%{creation_link} توسط %{pseud_links}" + edit_chapter: فصل را ویرایش کنید + edit_series: سری را ویرایش کنید + edit_work: اثر را ویرایش کنید + remove_chapter: اگر شما به اشتباه اضافه شده اید یا نمی خواهید که به عنوان + تهیه کننده ذکر شوید، می توانید %{edit_chapter_link} تا خودتان را به عنوان + خالق حذف کنید. + remove_series: اگر شما به اشتباه اضافه شده اید یا نمی خواهید که به عنوان تهیه + کننده ذکر شوید، می توانید %{edit_series_link} تا خودتان را به عنوان خالق + حذف کنید. + remove_work: اگر شما به اشتباه اضافه شده اید یا نمی خواهید که به عنوان تهیه + کننده ذکر شوید، می توانید %{edit_work_link} تا خودتان را به عنوان خالق حذف + کنید. + intro_chapter: 'کاربر %{archivist} نام مستعار شما %{pseud} را به عنوان تهیه + کننده ی همکار برای فصل ذیل اضافه کرده است:' + intro_series: 'کاربر %{archivist} نام مستعار شما %{pseud} را به عنوان تهیه کننده + ی همکار برای سری ذیل اضافه کرده است:' + intro_work: 'کاربر %{archivist} نام مستعار شما %{pseud} را به عنوان تهیه کننده + ی همکار برای اثر ذیل اضافه کرده است:' + subject: "[%{app_name}] اطلاعیه ی تهیه کننده ی همکار بایگان" + text: + creation: "%{title} (%{url}) توسط %{pseuds}" + remove_chapter: 'اگر شما به اشتباه اضافه شده اید یا نمی خواهید که به عنوان + تهیه کننده ذکر شوید، می توانید فصل را ویرایش کنید تا خودتان را به عنوان + خالق حذف کنید: %{url}' + remove_series: 'اگر شما به اشتباه اضافه شده اید یا نمی خواهید که به عنوان + تهیه کننده ذکر شوید، می توانید سری را ویرایش کنید تا خودتان را به عنوان + خالق حذف کنید: %{url}' + remove_work: 'اگر شما به اشتباه اضافه شده اید یا نمی خواهید که به عنوان تهیه + کننده ذکر شوید، می توانید اثر را ویرایش کنید تا خودتان را به عنوان خالق + حذف کنید: %{url}' + creatorship_request: + html: + creation: "%{creation_link} توسط %{pseud_links}" + instructions: شما می توانید این درخواست را در صفحه ی %{page_name} تان پذیرفته + یا رد کنید. + page_name: Co-Creator Requests (درخواست های پدیدآورنده ی همکار) + intro_chapter: 'کاربر %{inviting_user} نام مستعار شما، %{pseud}، را برای لیست + شدن به عنوان پدیدآورنده ی همکار در فصل زیر دعوت کرده است:' + intro_series: 'کاربر %{inviting_user} نام مستعار شما، %{pseud}، را برای لیست + شدن به عنوان پدیدآورنده ی همکار در سری زیر دعوت کرده است:' + intro_work: 'کاربر %{inviting_user} نام مستعار شما، %{pseud}، را برای لیست شدن + به عنوان پدیدآورنده ی همکار در اثر زیر دعوت کرده است:' + subject: "[%{app_name}] درخواست پدیدآورنده ی همکار" + text: + creation: "%{title} (%{url}) توسط %{pseuds}" + instructions: 'شما می توانید این درخواست را در صفحه ی Co-Creator Requests + (درخواست های پدیدآورنده ی همکار) تان پذیرفته یا رد کنید: %{url}' + delete_work_notification: + attachment: یک کپی از اثر شما برای اطلاعتان به این ایمیل ضمیمه شده است. + deleted_other: + html: اثر شما %{title} به درخواست %{pseud} حذف شد. + text: اثر شما "%{title}" به درخواست %{pseud} حذف شد. + deleted_yourself: + html: اثر شما %{title} به درخواست خودتان حذف شد. + text: اثر شما "%{title}" به درخواست خودتان حذف شد. + questions: + html: اگر سوالی دارید لطفا %{support}. + text: اگر سوالی دارید لطفا %{support} (%{url}). + subject: "[%{app_name}] اثر شما حذف شده است" + support: با پشتیبانی تماس بگیرید + invitation: + subject: "[%{app_name}] دعوتنامه" + invitation_to_claim: + access: + html: بسته به آرشیو، آثار شما ممکن است به صورت دسترسی محدود فقط برای کاربران + ثبت شده وارد شده باشند (تا خارج از جست و جوهای گوگل نگه داشته شوند). اگر + این حالت پیش آمده، آثار فقط برای کاربرانی که لاگین (وارد سایت) شده اند قابل + دسترسی خواهند بود، مگر اینکه شما تصمیم بگیرید که آنها را کاملا آشکار کنید. + برای کمک گرفتن در زمینه ی بازگشایی، بی مؤلف کردن و یا حذف آثارتان لطفا %{contact_support_link}. + text: بسته به آرشیو، آثار شما ممکن است به صورت دسترسی محدود فقط برای کاربران + ثبت شده وارد شده باشند (تا خارج از جست و جوهای گوگل نگه داشته شوند). اگر + این حالت پیش آمده، آثار فقط برای کاربرانی که لاگین (وارد سایت) شده اند قابل + دسترسی خواهد بود؛ مگر اینکه شما تصمیم بگیرید که آنها را کاملا آشکار کنید. + برای کمک گرفتن در زمینه ی بازگشایی، بی سرپرست کردن و یا حذف آثارتان لطفا + با پشتیبانی AO3 تماس بگیرید. + claim_or_remove: + html: آثارتان را در اینجا مطالبه یا حذف کنید. + text: 'آثارتان را در اینجا مطالبه یا حذف کنید: %{claim_url} ' + email_tips: اگر در حال تماس گرفتن با ما هستید لطفا ایمیل آدرسهایی از طرف @transformativeworks.org + را در لیست سفید خود قرار دهید و فولدرهای اسپم (پوشه های هرزنامه) خود را چک + کنید. + html: + ao3_news: اخبار AO3 + contact_open_doors: با درهای باز تماس بگیرید + contact_support: با پشتیبانی AO3 تماس بگیرید + faq_page: صفحه ی سوالات متداول + tutorial_page: صفحه ی آموزش + introduction: + html: شما به این علت این ایمیل را دریافت کرده اید چون اخیرا یک آرشیو توسط + %{open_doors_name_link} در %{app_link} (%{app_short_name}) وارد شده است + و ما فکر می کنیم که آثار ذیل متعلق به شما هستند. ما می خواهیم به شما این + فرصت را بدهیم که اگر تمایل دارید مالکیت این آثار را بر عهده بگیرید (یا آنها + را بی مؤلف کرده یا پاک کنید). و اگر هم اکنون حساب کاربری تحت ایمیل دیگری + ندارید ما علاقه مندیم که شما را دعوت کنیم تا به ما بپیوندید! + text: شما به این علت این ایمیل را دریافت کرده اید چون اخیرا یک آرشیو توسط + Open Doors (درهای باز) (%{open_doors_link}) در %{app_name} (%{app_short_name} + - %{app_url}) وارد شده است و ما فکر می کنیم که آثار ذیل متعلق به شما هستند. + ما می خواهیم به شما این فرصت را بدهیم که اگر تمایل دارید مالکیت این آثار + را بر عهده بگیرید (یا آنها را بی سرپرست کرده یا پاک کنید). و اگر هم اکنون + حساب کاربری تحت ایمیل دیگری ندارید ما علاقه مندیم که شما را دعوت کنیم تا + به ما بپیوندید! + mistake: + html: اگر اشتباهی صورت گرفته و این آثار از آن شما نیستند، لطفا آنها را پاک + نکنید! لطفا فقط %{contact_open_doors_link} و ما خودمان بقیه اش را حل می + کنیم. + text: اگر اشتباهی صورت گرفته و این آثار از آن شما نیستند لطفا آنها را پاک + نکنید! لطفا فقط با درهای باز تماس بگیرید (%{open_doors_link}) و ما خودمان + بقیه اش را حل می کنیم. + more_info: + html: شما می توانید اعلانیه های مربوط به انتقال آرشیوهای اخیر را در %{ao3_news_link} + بخوانید و اطلاعات بیشتر را در %{faq_page_link} یا %{tutorial_page_link} + Open Doors (درهای باز) بیابید. برای هرگونه سوالی که در سوالات متداول، آموزشها + یا این ایمیل به آن پاسخ داده نشده، لطفا %{contact_support_link}. + text: شما می توانید اعلانیه های مربوط به انتقال آرشیو اخیر را در اخبار AO3 + (%{news_link}) بخوانید و اطلاعات بیشتر را در صفحه ی سوالات متداول (%{open_doors_faq_link}) + یا صفحه ی آموزشهای (%{open_doors_tutorial_link}) Open Doors (درهای باز) + بیابید. برای هرگونه سوالی که در سوالات متداول، آموزشها یا این ایمیل به آن + پاسخ داده نشده لطفا با پشتیبانی در %{support_link} تماس بگیرید. + other_works: + html: اگر آثار دیگری بر روی آرشیو وارد شده داشته اید که تحت ایمیلی بوده اند + که دیگر به آن دسترسی ندارید، لطفا با هرگونه اطلاعاتی که به ما کمک می کند + تا هویت شما را شناسایی کنیم %{contact_open_doors_link}. + text: اگر آثار دیگری بر روی آرشیو وارد شده داشته اید که تحت ایمیلی بوده اند + که دیگر به آن دسترسی ندارید، لطفا با هرگونه اطلاعاتی که به ما کمک می کند + تا هویت شما را شناسایی کنیم با Open Doors (درهای باز) تماس بگیرید. + questions: + html: برای سوالات دیگر لطفا %{contact_support_link}. + text: برای سوالات دیگر لطفا با پشتیبانی AO3 در %{support_link} تماس بگیرید. + redirects: برای اینکه لیست پیشنهادات و بوکمارکها حفظ شوند آدرسهای وبسایت آرشیو + وارداتی ممکن است برای مدت محدودی به کپی وارداتی این آثار هدایت شوند (پست اعلامیه + را در مورد آرشیوتان بررسی کنید تا مطمئن شوید). اگر کپی ای از این آثار را آپلود + کرده اید ولی از ویژگی وارد کردن با استفاده از URL (آدرس اینترنتی) اینکار را + انجام ندادید در آن واحد دو کپی از یک اثر یکسان بر روی آرشیو خواهد بود. + subject: "[%{app_name}] دعوتنامه برای مطالبه ی آثار" + unwanted: + html: اگر این آثار متعلق به شما هستند ولی آنها را نمی خواهید، می توانید آنها + را بی مؤلف کنید (تا اینکه بر روی سایت AO3 باقی بمانند ولی بدون اسم شما) + یا آنها را حذف کنید (تا اینکه کاملا از روی AO3 پاک شوند). برای مؤلف کردن + نیازی به اضافه کردن این آثار به هیچ اکانتی یا حذف کردن آنها وجود ندارد--شما + می توانید این کار را مستقیما با استفاده از لینک مطالبه در بالا انجام دهید. + (برای کمک لطفا %{contact_support_link}.) + text: اگر این آثار متعلق به شما هستند ولی آنها را نمی خواهید، می توانید آنها + را بی سرپرست کنید (تا اینکه بر روی سایت AO3 باقی بمانند ولی بدون اسم شما) + یا آنها را حذف کنید (تا اینکه کاملا از روی AO3 پاک شوند). برای بی سرپرست + کردن نیازی به اضافه کردن این آثار به هیچ اکانتی یا حذف کردن آنها وجود ندارد--شما + می توانید این کار را مستقیما با استفاده از لینک مطالبه در بالا انجام دهید. + (برای کمک لطفا با پشتیبانی در %{support_link} تماس بگیرید.) + update_redirect: + html: اگر مایلید که Open Doors (درهای باز) آدرسی که دیگران به آن هدایت می + شوند را به کارهای سابق شما آپدیت کند، لطفا کپی وارداتی را حذف کرده و با + نام اکانت AO3 خود، نام اکانتتان بر روی آرشیو وارداتی و عنوان و آدرس URL + اثر هوادارانه ای که مد نظر است با %{contact_open_doors_link}. (اگر می خواهید + این تغییر را برای چندین اثر انجام دهید می توانید آنها را در یک ایمیل لیست + کنید.) + text: اگر مایلید که Open Doors (درهای باز) آدرسی که دیگران به آن هدایت می + شوند را به کارهای سابق شما آپدیت کند، لطفا کپی وارداتی را حذف کرده و با + نام اکانت AO3 خود، نام اکانتتان بر روی آرشیو وارداتی و عنوان و آدرس URL + اثر هوادارانه ای که مد نظر است با Open Doors (درهای باز) در %{open_doors_link} + تماس بگیرید. (اگر شما می خواهید این تغییر را برای چندین اثر انجام دهید می + توانید آنها را در یک ایمیل لیست کنید.) + uploaded_list: 'آثاری که آپلود شده اند عبارتند از:' + invite_increase_notification: + invitation_page_link_text: صفحه ی Invitations (دعوتنامه ها) شما + subject: "[%{app_name}] دعوتنامه های جدید" + invite_request_declined: + main: + one: ما ناراحتیم از اینکه به شما اطلاع می دهیم که درخواست شما برای یک دعوتنامه + ی جدید در حال حاضر قابل عملی شدن نیست. + other: ما ناراحتیم از اینکه به شما اطلاع می دهیم که درخواست شما برای %{count} + دعوتنامه ی جدید در حال حاضر قابل عملی شدن نیست. + reason: 'درخواست شما این بود که:' + subject: "[%{app_name}] درخواست کد دعوتنامه ی اضافی رد شد" + recipient_notification: + html: + collection: یک اثر هدیه برای شما در مجموعه ی %{collection_link} در AO3 پست + شده است! + no_collection: یک اثر هدیه برای شما در AO3 پست شده است! + subject: + collection: "[%{app_name}][%{collection_title}] یک اثر هدیه برای شما از %{collection_title}" + no_collection: "[%{app_name}] یک اثر هدیه برای شما" + text: + collection: یک اثر هدیه برای شما در مجموعه ی "%{collection_title}" (%{collection_url}) + در AO3 پست شده است! + signup_notification: + activate: + html: لطفا %{activate_account_link}. + text: 'لطفا این لینک را برای فعالسازی اکانت خود دنبال کنید: %{activate_account_url}' + activate_your_account: این لینک را برای فعالسازی اکانت خود دنبال کنید + admin_posts: اخبار AO3 + bye: ما امیدواریم که شما از استفاده از آرشیو لذت ببرید. + contact_support: با پشتیبانی تماس بگیرید + faq: سوالات متداول + features: + html: 'زمانی که اکانت شما فعال و درحال استفاده باشد، شما می توانید: آثار هوادارانه + ی تان را پست کنید، اشتراک های ایمیل ایجاد کنید تا هنگامی که خالقان یا آثار + مورد علاقه شما آپدیت شدند مطلع شوید، اولویت هایی را برای تغییر چگونگی ظاهر + و کار کردن سایت برای خودتان تعیین کنید، با استفاده از تاریخچه آثاری که به + آنها سر زده اید را پیگیری کنید و بسیاری موارد دیگر.' + text: 'زمانی که اکانت شما فعال و درحال استفاده باشد، شما می توانید: آثار هوادارانه + ی تان را پست کنید، اشتراک های ایمیل ایجاد کنید تا هنگامی که خالقان یا آثار + مورد علاقه شما آپدیت شدند مطلع شوید، اولویت هایی را برای تغییر چگونگی ظاهر + و کار کردن سایت برای خودتان تعیین کنید، با استفاده از تاریخچه آثاری که به + آنها سر زده اید را پیگیری کنید و بسیاری موارد دیگر.' + information: + html: اطلاعات و توصیه های زیادی راجع به اینکه چگونه از آرشیو استفاده کنید + در %{faq_link} ما وجود دارد. شما آخرین اخبار درباره ی پیشرفت های وبسایت + را در %{admin_posts_link} ما خواهید یافت. اگر شما به کمک بیشتر نیاز دارید، + به یک باگ برخورد کرده اید یا سوالات و نظراتی دارید لطفا %{contact_support_link}، + که همواره مشتاقند کمک کنند. + text: 'اطلاعات و توصیه های زیادی راجع به اینکه چگونه از آرشیو استفاده کنید + در سوالات متداول ما در %{faq_url} وجود دارد. شما آخرین اخبار درباره ی پیشرفت + های وبسایت را در اخبار AO3 در %{admin_posts_url} خواهید یافت. اگر شما به + کمک بیشتر نیاز دارید، به یک باگ برخورد کرده اید یا سوالات و نظراتی دارید + لطفا با تیم پشتیبانی ما تماس بگیرید، که همواره مشتاقند کمک کنند: %{contact_support_url}. + + ' + subject: اکانتتان را فعال کنید [%{app_name}] + welcome: "%{login}، به آرشیوی از آن خودمان خوش آمدید!" diff --git a/config/locales/phrase-exports/fi.yml b/config/locales/phrase-exports/fi.yml new file mode 100755 index 0000000..6afe9fa --- /dev/null +++ b/config/locales/phrase-exports/fi.yml @@ -0,0 +1,598 @@ +--- +fi: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Varoitus:' + other: 'Varoitukset:' + category: + name_with_colon: + one: 'Kategoria:' + other: 'Kategoriat:' + character: + name_with_colon: + one: 'Hahmo:' + other: 'Hahmot:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandomit:' + freeform: + name_with_colon: + one: 'Muu avainsana:' + other: 'Muut avainsanat:' + rating: + name_with_colon: 'Luokitus:' + relationship: + name_with_colon: + one: 'Suhde:' + other: 'Suhteet:' + work: + chapter_total_display: Lukuja + summary: Tiivistelmä + models: + archive_warning: + one: Varoitus + other: Varoitukset + category: + one: Kategoria + other: Kategoriat + chapter: + one: Luku + other: Lukuja + character: + one: Hahmo + other: Hahmot + fandom: + one: Fandom + other: Fandomit + freeform: + one: Muu avainsana + other: Muut avainsanat + rating: + one: Luokitus + other: Luokitukset + relationship: + one: Suhde + other: Suhteet + series: + one: Sarja + other: Sarjat + kudo_mailer: + batch_kudo_notification: + guest: + one: vieras + other: "%{count} vierasta" + left_kudos: + html: + one: "%{givers_list} kehui teosta %{commentable_link}." + other: "%{givers_list} kehuivat teosta %{commentable_link}." + text: + one: "%{givers_list} kehui teosta %{commentable_title} (%{commentable_url})." + other: "%{givers_list} kehuivat teosta %{commentable_title} (%{commentable_url})." + single_guest: + giver: Vieras + html: "%{giver} kehui teosta %{commentable_link}." + text: Vieras kehui teosta %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Sinulle on kehuja!" + mailer: + general: + closing: + formal: Terveisin, + informal: Parhain terveisin, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: "%{title}-teoksen luku %{position}" + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} sana" + other: "%{count} sanaa" + footer: + general: + about: + html: Archive of Our Own (Oma arkisto) on fanien pyörittämä ja tukema + arkisto, joka toimii %{donate_link} varassa. + text: 'Archive of Our Own (Oma arkisto) on fanien pyörittämä ja tukema + arkisto, joka toimii lahjoitustenne varassa: %{donate_url}.' + html: + donate_link_text: lahjoitustenne + support_link_text: ota yhteyttä Käyttäjätukeen + unwanted_email: + html: Jos olet saanut tämän viestin virheellisesti, ole hyvä ja %{support_link}. + text: Jos olet saanut tämän viestin virheellisesti, ole hyvä ja ota yhteyttä + Käyttäjätukeen osoitteessa %{support_url}. + sent_at: Lähetetty %{sent_at}. + greeting: + formal_html: Hei %{name}, + informal: + addressed_html: Hei, %{name}! + unaddressed: Hei! + introductory: Tervehdys Archive of Our Own – AO3:lta (Oma arkisto)! + metadata_label_indicator: ":" + signature: + abuse_team: AO3 Säännöt ja väärinkäytökset -toimikunta + app_short_name: AO3 + open_doors: Open Doors (Avoimet ovet) -tiimi + parent_org: Organization for Transformative Works – OTW (Transformatiivisten + teosten järjestö) + support: AO3 Käyttäjätukitiimi + users: + mailer: + reset_password_instructions: + expiration: Jos et käytä tätä linkkiä salasanasi vaihtamiseen viikon kuluessa, + se vanhenee, ja sinun on pyydettävä uusi linkki. + intro: 'Tilisi salasana on pyydetty asettamaan uudelleen. Voit vaihtaa salasanan + seuraamalla alla olevaa linkkiä ja syöttämällä uuden salasanasi:' + link_title: Vaihda salasanani. + subject: "[%{app_name}] Aseta uusi salasana" + unrequested: Jos et pyytänyt salasanan uudelleen asetusta, voit jättää tämän + viestin huomioimatta, ja vanha salasanasi pysyy voimassa. + user_mailer: + admin_deleted_work_notification: + bye: Tähän viestiin on liitetty tiedoksesi kopio teoksestasi. + contact_abuse: ota yhteyttä Säännöt ja väärinkäytökset -toimikuntaan + deleted: + html: Sivuston ylläpitäjä on poistanut teoksesi %{title} AO3:sta. + text: Sivuston ylläpitäjä on poistanut teoksesi "%{title}" AO3:sta. + html: + tos_violation: Jos teoksesi saattoi rikkoa AO3:n Käyttöehtoja, ole hyvä ja + %{contact_abuse_link}. + import_project: + html: Jos teoksesi kuului Open Doors (Avoimet ovet) -toimikunnan tuomaan projektiin, + ole hyvä ja %{opendoors_link}, jos sinulla on kysymyksiä. + text: Jos teoksesi kuului Open Doors (Avoimet ovet) -toimikunnan tuomaan projektiin, + ole hyvä ja ota yhteyttä Open Doors -toimikuntaan (%{opendoors_link}), jos + sinulla on kysymyksiä. + opendoors: ota yhteyttä Open Doors -toimikuntaan + subject: "[%{app_name}] Ylläpitäjä on poistanut teoksesi" + text: + tos_violation: Jos teoksesi saattoi rikkoa AO3:n Käyttöehtoja, ole hyvä ja + ota yhteyttä Säännöt ja väärinkäytökset -toimikuntaan (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Teoksen ollessa piilotettuna voit tarkastella sitä yllä olevan linkin + kautta, mutta se ei näy teokset-sivullasi eikä se ole muiden AO3-käyttäjien + saatavilla. + check_email: Tarkistathan sähköpostisi, myös roskapostikansion, sillä Säännöt + ja väärinkäytökset -toimikunta on saattanut jo ottaa yhteyttä ja selittää, + miksi teoksesi on piilotettu. + contact_abuse: ota yhteyttä Säännöt ja väärinkäytökset -toimikuntaan + html: + help: Mikäli olet epävarma siitä, miksi teoksesi piilotettiin, etkä ole saanut + yhteydenottoa asiaan liittyen, %{contact_abuse_link}. + hidden: Säännöt ja väärinkäytökset -toimikunta on piilottanut teoksesi %{title}, + eikä se ole enää julkisesti saatavilla. + tos_violation: Mikäli teoksesi piilotettiin siksi, että se rikkoi AO3:n %{tos_link}, + sinun tulee toimia rikkeen korjaamiseksi. Mikäli et muuta teostasi Käyttöehtojen + mukaiseksi, se saatetaan poistaa AO3:sta. + subject: "[%{app_name}] Säännöt ja väärinkäytökset -toimikunta on piilottanut + teoksesi" + text: + help: 'Mikäli olet epävarma siitä, miksi teoksesi piilotettiin, etkä ole saanut + yhteydenottoa asiaan liittyen, ota yhteyttä Säännöt ja väärinkäytökset -toimikuntaan: + %{contact_abuse_url}.' + hidden: Säännöt ja rikkomukset -toimikunta on piilottanut teoksesi “%{title}" + (%{work_url}) eikä se ole enää julkisesti saatavilla. + tos_violation: Mikäli teoksesi piilotettiin siksi, että se rikkoi AO3:n Käyttöehtoja + (%{tos_url}), sinun tulee toimia rikkeen korjaamiseksi. Mikäli et muuta + teostasi Käyttöehtojen mukaiseksi, se saatetaan poistaa AO3:sta. + tos: Käyttöehtoja + anonymous_or_unrevealed_notification: + anonymous_info: Anonyymit teokset näkyvät teoslistauksissa mutta eivät omalla + teossivullasi. Teoksessa käyttäjänimesi tilalla lukee “Anonymous” (anonyymi). + anonymous_unrevealed_info: Kokoelman ylläpitäjät saattavat myöhemmin paljastaa + teoksesi mutta jättää sen anonyymiksi. Teoksiesi ilmoitukset tilanneet eivät + saa ilmoitusta tästä muutoksesta. Paljastamisen jälkeen teoksesi näkyy avainsanalistauksissa + mutta ei teossivullasi. Teoksessa käyttäjänimesi tilalla lukee “Anonymous” + (anonyymi). + changed_status: + anonymous: + html: Kokoelman %{collection_link} ylläpitäjät ovat muuttaneet teoksesi + %{work_link} tilan anonyymiksi. + text: Kokoelman "%{collection_title}" (%{collection_url}) ylläpitäjät ovat + muuttaneet teoksesi "%{work_title}" (%{work_url}) tilan anonyymiksi. + anonymous_unrevealed: + html: Kokoelman %{collection_link} ylläpitäjät ovat muuttaneet teoksesi + %{work_link} tilan anonyymiksi ja paljastamattomaksi. + text: Kokoelman "%{collection_title}" (%{collection_url}) ylläpitäjät ovat + muuttaneet teoksesi "%{work_title}" (%{work_url}) tilan anonyymiksi ja + paljastamattomaksi. + unrevealed: + html: Kokoelman %{collection_link} ylläpitäjät ovat muuttaneet teoksesi + %{work_link} tilan paljastattomaksi. + text: Kokoelman "%{collection_title}" (%{collection_url}) ylläpitäjät ovat + muuttaneet teoksesi "%{work_title}" (%{work_url}) tilan paljastamattomaksi. + collection_items_link_text: Approved Collection Items (Hyväksytyt kokoelmateokset) + -sivullasi + do_not_want: + anonymous: + html: Jos et halua teoksesi olevan anonyymi, käy %{collection_items_link} + poistaaksesi sen tästä kokoelmasta. + text: 'Jos et halua teoksesi olevan anonyymi, käy Approved Collection Items + (Hyväksytyt kokoelmateokset) -sivullasi poistaaksesi sen tästä kokoelmasta: + %{collection_items_url}' + anonymous_unrevealed: + html: Jos et halua teoksesi olevan anonyymi ja paljastamaton, käy %{collection_items_link} + poistaaksesi sen tästä kokoelmasta. + text: 'Jos et halua teoksesi olevan anonyymi ja paljastamaton, käy Approved + Collection Items (Hyväksytyt kokoelmateokset) -sivullasi poistaaksesi + sen tästä kokoelmasta: %{collection_items_url}' + unrevealed: + html: Jos et halua teoksesi olevan paljastamaton, käy %{collection_items_link} + poistaaksesi sen tästä kokoelmasta. + text: 'Jos et halua teoksesi olevan paljastamaton, käy Approved Collection + Items (Hyväksytyt kokoelmateokset) -sivullasi poistaaksesi sen tästä kokoelmasta: + %{collection_items_url}' + faq_link_text: Kokoelmat-UKK:sta + more_info: + html: Lisätietoa %{faq_link}. + text: 'Lisätietoa Kokoelmat-UKK:sta: %{faq_url}' + subject: + anonymous: "[%{app_name}] Teoksestasi on tehty anonyymi" + anonymous_unrevealed: "[%{app_name}] Teoksestasi tehtiin anonyymi ja paljastamaton" + unrevealed: "[%{app_name}] Teoksesi tehtiin paljastamattomaksi" + unrevealed_info: Paljastamattomat teokset eivät näy avainsanalistauksissa tai + teossivullasi. Kaikki, jotka pääsevät teokseen linkin kautta, saavat ilmoituksen, + että se on toistaiseksi paljastamaton eivätkä pääse käsiksi sen sisältöön. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Hyväksytyt kokoelmateokset) + archivist_notice: Koska arkiston ylläpitäjät toimivat virallisissa rooleissaan + Open Doors (Avoimet ovet) -arkistonhoitajina, heillä on lupa lisätä teoksesi + tähän kokoelmaan vaikka olisitkin asettanut kokoelmakutsut pois päältä. Arkistonhoitajat + lisäävät teoksen kokoelmaan vain jos se oli tuodussa arkistossa. + removal_instructions: + html: Jos haluat poistaa teoksesi tästä kokoelmasta, mene %{approved_items_link} + -sivullesi. + text: 'Jos haluat poistaa teoksesi tästä kokoelmasta, mene Approved Collection + Items (Hyväksytyt kokoelmateokset) -sivullesi: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Open Doors (Avoimet ovet) -arkistonhoitaja + on lisännyt teoksesi kokoelmaan" + work_added: + html: Kokoelman %{collection_link} ylläpitäjät ovat lisänneet teoksesi %{work_link} + kokoelmaansa! + text: Kokoelman "%{collection_title}" (%{collection_url}) ylläpitäjät ovat + lisänneet teoksesi "%{work_title}" (%{work_url}) kokoelmaansa! + challenge_assignment_notification: + any: Mitä tahansa + assignment: + html: Sinulle on annettu toteutettavaksi pyyntö Archive of Our Ownin haasteessa + %{link}! + description: 'Kuvaus:' + due: 'Tehtävän on oltava valmis:' + html: + footer: Olet saanut tämän viestin koska ilmoittauduit mukaan haasteeseen %{title}. + Lisätietoa tästä haasteesta ja sen valvojien yhteystiedot löytyvät %{footer_link}. + footer_link: haasteen profiilista + look_up: Voit tarkastella tehtävänannon yksityiskohtia osoitteessa %{link} + look_up_link: Assignments (Tehtävänannot) -sivusi + optional_tags: 'Valinnaiset avainsanat:' + prompts: 'Ehdotukset:' + prompt_url: 'Ehdotuksen URL:' + recipient: 'Vastaanottaja:' + recipient_missing: 'Ei vastaanottajaa: ota yhteyttä valvojaan!' + subject: "[%{app_name}][%{collection_title}] Tehtävänantosi!" + text: + assignment: Sinulle on annettu toteutettavaksi pyyntö Archive of Our Own:n + haasteessa "%{collection_title}" (%{collection_url}) ! + footer: Olet saanut tämän viestin koska ilmoittauduit mukaan haasteeseen %{title} + (%{url}). Lisätietoa tästä haasteesta ja sen valvojien yhteystiedot löytyvät + osoitteesta %{profile_url}. + look_up: Voit tarkastella tehtävänannon yksityiskohtia Assignments (Tehtävänannot) + -sivulta osoitteessa %{link}. + change_email: + changed: + html: "%{login}, tunnuksesi uudeksi sähköpostiosoitteeksi on asetettu %{email}" + text: "%{login}, tunnuksesi uudeksi sähköpostiosoitteeksi on asetettu %{email}" + subject: "[%{app_name}] Sähköpostiosoite muutettu" + claim_notification: + access: + contact_support: ota yhteyttä AO3:n Käyttäjätukeen + html: Arkistosta riippuen teoksesi on saatettu tuoda siten, että ne ovat näkyvillä + vain rekisteröityneille käyttäjille (jotta ne eivät näy Google-hauissa). + Jos näin on, teokset ovat saatavilla vain sisäänkirjautuneille käyttäjille, + jollet valitse tehdä niistä täysin näkyviä. Saadaksesi apua teostesi lukituksen + poistamiseen, niistä luopumiseen tai poistamiseen %{contact_support_link} + text: Arkistosta riippuen teoksesi on saatettu tuoda siten, että ne ovat näkyvillä + vain rekisteröityneille käyttäjille (jotta ne eivät näy Google-hauissa). + Jos näin on, teokset ovat saatavilla vain sisäänkirjautuneille käyttäjille, + jollet valitse tehdä niistä täysin näkyviä. Saadaksesi apua teostesi lukituksen + poistamiseen, niistä luopumiseen tai poistamiseen ota yhteyttä AO3:n Käyttäjätukeen + %{support_url}. + email_tips: Jos otat yhteyttä meihin, lisää @transformativeworks.org-loppuiset + sähköpostiosoitteet turvallisten lähettäjien listallesi ja tarkista roskapostikansiosi + vastauksemme varalta. + introduction: + ao3_name: Archive of Our Own – AO3:een (Oma arkisto) + html: Saat tämän sähköpostin koska sinulla oli teoksia faniteosarkistossa, + jonka %{open_doors_name_link} on tuonut %{app_link}. Koska tämä sähköpostiosoite + on yhdistetty tuotuun arkistoon rekisteröityyn osoitteeseen, siihen liittyvät + teokset (listattuna alla) on automaattisesti lisätty AO3-tilillesi. + open_doors_name: Open Doors (Avoimet ovet) + text: 'Saat tämän sähköpostin koska sinulla oli teoksia faniteosarkistossa, + jonka Open Doors (Avoimet ovet (%{open_doors_url}) on tuonut Archive of + Our Own – AO3:een (Oma arkisto): %{app_url}. Koska tämä sähköpostiosoite + on yhdistetty tuotuun arkistoon rekisteröityyn osoitteeseen, siihen liittyvät + teokset (listattuna alla) on automaattisesti lisätty AO3-tilillesi.' + mistake: + contact_open_doors: Ota yhteyttä Avoimiin oviin + html: Jos tämä on virhe eivätkä nämä ole teoksiasi, ethän poista niitä! %{contact_open_doors_link} + ja me hoidamme asian. + text: Jos tämä on virhe eivätkä nämä ole teoksiasi, ethän poista niitä! Ota + vain yhteyttä Avoimiin oviin (%{open_doors_url}) ja me hoidamme asian. + more_info: + ao3_news: AO3:n Uutisista + contact_support: ota yhteyttä AO3:n Käyttäjätukeen + faq_page: UKK-sivulta + html: Voit lukea ilmoituksia viimeaikaisista arkistosiirroista %{ao3_news_link} + ja lisätietoa saat Avoimien ovien %{faq_page_link} tai %{tutorial_page_link}. + Jos sinulla on kysymyksiä, joihin ei löydy vastausta UKK:sta, tutoriaaleista + tai tästä sähköpostista, %{contact_support_link}. + text: Voit lukea ilmoituksia viimeaikaisista arkistosiirroista AO3:n Uutisista + (%{news_url}) ja lisätietoa saat Avoimien ovien UKK-sivulta (%{open_doors_faq_url}) + tai tutoriaalisivulta (%{open_doors_tutorial_url}). Jos sinulla on kysymyksiä, + joihin ei löydy vastausta UKK:sta, tutoriaaleista tai tästä sähköpostista, + ota yhteyttä Käyttäjätukeen %{support_url}. + tutorial_page: tutoriaalisivulta + other_works: + contact_open_doors: ota yhteyttä Avoimiin oviin + html: Jos sinulla oli muita teoksia tuodussa arkistossa sellaisen sähköpostiosoitteen + alla, johon sinulla ei enää ole pääsyä, %{contact_open_doors_link} ja anna + tietoa, joka voi auttaa identiteettisi varmistamisessa. + text: Jos sinulla oli muita teoksia tuodussa arkistossa sellaisen sähköpostiosoitteen + alla, johon sinulla ei enää ole pääsyä, ota yhteyttä Avoimiin oviin ja anna + tietoa, joka voi auttaa identiteettisi varmistamisessa. + questions: + contact_support: ota yhteyttä AO3:n Käyttäjätukeen + html: Muissa asioissa %{contact_support_link}. + text: 'Muissa asioissa ota yhteyttä AO3:n Käyttäjätukeen täällä: %{support_url}.' + redirects: + html: Suosituslistojen ja kirjanmerkkien säilyttämiseksi tuodun arkiston nettiosoitteet + saattavat uudelleenohjautua näiden teosten tuotuihin versioihin rajoitetun + ajan (tarkista arkistosi tuonti-ilmoitus saadaksesi varmuuden). Jos olet + jo julkaissut nämä teokset %{negation} käyttänyt tuo URLista -toimintoa, + AO3:ssa on kaksi versiota samasta teoksesta. + subject: "[%{app_name}] Tuotuja teoksia" + update_redirect: + contact_open_doors: ota yhteyttä Avoimiin oviin + html: Jos haluat Avoimien ovien päivittävän uudelleenohjauksen johtamaan jo + olemassa olevaan teokseesi, poista tuotu versio ja %{contact_open_doors_link}. + Liitä mukaan AO3-tilisi nimi, tuodun arkiston tilisi nimi sekä sen faniteoksen + nimi ja URL, johon haluaisit uudelleenohjauksen johtavan. (Jos sinulle on + useita teoksia, joihin haluaisit muuttaa uudelleenohjauksen, voit listata + ne kaikki samassa sähköpostissa.) + text: Jos haluat Avoimien ovien päivittävän uudelleenohjauksen johtamaan jo + olemassa olevaan teokseesi, poista tuotu versio ja ota yhteyttä Avoimiin + oviin %{open_doors_url}. Liitä mukaan AO3-tilisi nimi, tuodun arkiston tilisi + nimi sekä sen faniteoksen nimi ja URL, johon haluaisit uudelleenohjauksen + johtavan. (Jos sinulle on useita teoksia, joihin haluaisit muuttaa uudelleenohjauksen, + voit listata ne kaikki samassa sähköpostissa.) + works_by: Nämä teokset kirjoitettiin sähköpostin %{email} alla + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Kaikki tehtävänannot on nyt lähetetty. + subject: Tehtävänannot lähetetty + html: + received_message: 'Olet saanut kokoelmaasi %{collection_link} koskevan viestin:' + text: + received_message: 'Olet saanut kokoelmaasi "%{collection_title}" (%{collection_url}) + koskevan viestin:' + creatorship_notification: + explanation: Teoksen kanssatekijänä sinut voidaan lisätä uusiin lukuihin riippumatta + tilisi kanssatekijyysasetuksista. Sinut lisätään myös kaikkiin sarjoihin, + joihin teos lisätään. + html: + creation: "%{creation_link}, tekijä(t) %{pseud_links}" + edit_chapter: muokata lukua + edit_series: muokata sarjaa + remove_chapter: Jos sinut on lisätty virheellisesti tai et halua, että sinut + ilmoitetaan tekijäksi, voit %{edit_chapter_link} poistaaksesi itsesi tekijöistä. + remove_series: Jos sinut on lisätty virheellisesti tai et halua, että sinut + ilmoitetaan tekijäksi, voit %{edit_series_link} poistaaksesi itsesi tekijöistä. + intro_chapter: 'Käyttäjä %{adding_user} on ilmoittanut nimimerkkisi %{pseud} + kanssatekijäksi seuraavaan lukuun:' + intro_series: 'Käyttäjä %{adding_user} on ilmoittanut nimimerkkisi %{pseud} + kanssatekijäksi seuraavaan sarjaan:' + subject: "[%{app_name}] Ilmoitus kanssatekijäksi lisäämisestä" + text: + creation: "%{title} (%{url}), tekijä(t) %{pseuds}" + remove_chapter: 'Jos sinut on lisätty virheellisesti tai et halua, että sinut + ilmoitetaan tekijäksi, voit muokata lukua poistaaksesi itsesi tekijöistä: + %{url}' + remove_series: 'Jos sinut on lisätty virheellisesti tai et halua, että sinut + ilmoitetaan tekijäksi, voit muokata sarjaa poistaaksesi itsesi tekijöistä: + %{url}' + creatorship_notification_archivist: + explanation: Koska hän teki näin virallisessa Open Doors (Avoimet ovet) -arkistonhoitajan + roolissaan, hän pystyi lisäämään sinut ilman pyyntöä, vaikka sinulla olisi + toiseksi tekijäksi lisääminen poissa käytöstä. + html: + creation: "%{pseud_links}: %{creation_link}" + edit_chapter: muokata lukua + edit_series: muokata sarjaa + edit_work: muokata teosta + remove_chapter: Jos sinut on lisätty virheellisesti tai et halua tulla nimetyksi + tekijänä, voit %{edit_chapter_link} poistaaksesi itsesi tekijöistä. + remove_series: Jos sinut on lisätty virheellisesti tai et halua tulla nimetyksi + tekijänä, voit %{edit_series_link} poistaaksesi itsesi tekijöistä. + remove_work: Jos haluat poistaa itsesi tekijöistä, koska sinut on lisätty + tekijäksi virheellisesti tai et halua olla nimettynä tekijänä, voit %{edit_work_link} + linkin kautta. + intro_chapter: 'Käyttäjä %{archivist} on lisännyt nimimerkkisi %{pseud} toiseksi + tekijäksi seuraavaan lukuun:' + intro_series: 'Käyttäjä %{archivist} on lisännyt nimimerkkisi %{pseud} toisena + tekijänä seuraavaan sarjaan:' + intro_work: 'Käyttäjä %{archivist} on lisännyt nimimerkkisi %{pseud} toiseksi + tekijäksi seuraavaan teokseen:' + subject: "[%{app_name}] Arkistonhoitajan ilmoitus toiseksi tekijäksi lisäämisestä" + text: + creation: "%{pseuds}: %{title} (%{url})" + remove_chapter: 'Jos sinut on lisätty tekijäksi virheellisesti tai et halua + tulla nimetyksi tekijänä, voit poistaa itsesi tekijänä muokkaamalla lukua: + %{url}' + remove_series: 'Jos sinut on lisätty tekijäksi virheellisesti tai et halua + tulla nimetyksi tekijänä, voit poistaa itsesi tekijänä muokkaamalla sarjaa: + %{url}' + remove_work: 'Jos haluat poistaa itsesi tekijöistä, koska sinut on lisätty + tekijäksi virheellisesti tai et halua olla nimettynä tekijänä, teos on muokattavissa + linkin kautta: %{url}' + creatorship_request: + html: + creation: "%{creation_link} tekijältä %{pseud_links}" + instructions: Voit hyväksyä tai hylätä kutsun %{page_name} -sivullasi. + page_name: Co-Creator Requests (Pyynnöt kanssatekijäksi) + intro_chapter: 'Käyttäjä %{inviting_user} on kutsunut nimimerkkisi %{pseud} + listattavaksi seuraavan luvun kanssatekijäksi:' + intro_series: 'Käyttäjä %{inviting_user} on kutsunut nimimerkkisi %{pseud} listattavaksi + seuraavan sarjan kanssatekijäksi:' + intro_work: 'Käyttäjä %{inviting_user} on kutsunut nimimerkkisi %{pseud} listattavaksi + seuraavan teoksen kanssatekijäksi:' + subject: "[%{app_name}] Kutsu kanssatekijäksi" + text: + creation: "%{title} (%{url}) tekijältä %{pseuds}" + instructions: 'Voit hyväksyä tai hylätä kutsun Co-Creator Requests (Pyynnöt + kanssatekijäksi) -sivullasi: %{url}' + delete_work_notification: + attachment: Kopio teoksesta on liitetty viestiin sinua varten. + deleted_other: + html: teoksesi %{title} on poistettu nimimerkin %{pseud} pyynnöstä. + text: teoksesi "%{title}" on poistettu nimimerkin %{pseud} pyynnöstä. + deleted_yourself: + html: teoksesi %{title} on poistettu pyynnöstäsi. + text: teoksesi "%{title}" on poistettu pyynnöstäsi. + questions: + html: Jos sinulla on kysyttävää, ole hyvä ja %{support}. + text: Jos sinulla on kysyttävää, ole hyvä ja %{support} (%{url}). + subject: "[%{app_name}] Teoksesi on poistettu" + support: ota yhteyttä Käyttäjätukeen + invitation_to_claim: + access: + text: Joistakin arkistoista tuodut teokset on voitu asettaa vain rekisteröityneiden + käyttäjien saataville (jotta ne eivät näy Google-hauissa). Siinä tapauksessa + vain sisäänkirjautuneet käyttäjät pääsevät niihin, ellet itse aseta niitä + täysin avoimiksi. Jos haluat apua teostesi avaamiseen, hylkäämiseen tai + poistamiseen, ole hyvä ja ota yhteyttä AO3:n Käyttäjätukeen. + claim_or_remove: + html: Ilmoita omistajuudesta tai poista teoksesi. + text: 'Ilmoita omistajuudesta tai poista teoksesi täällä: %{claim_url}' + email_tips: Jos otat meihin yhteyttä, ole hyvä ja lisää @transformativeworks.org + sallittujen lähettäjien listalle ja tarkista, onko vastauksemme päätynyt roskapostikansioon. + html: + ao3_news: AO3:n uutiset + contact_open_doors: ota yhteyttä Open Doorsiin + contact_support: ota yhteyttä AO3 käyttäjätukeen + faq_page: UKK-sivu + tutorial_page: ohjesivu + introduction: + text: Saat tämän sähköpostin, koska Open Doors (%{open_doors_link}) on tuonut + AO3:een teoksia ulkoisesta arkistosta %{app_name} (%{app_short_name} - %{app_url}) + ja uskomme seuraavien faniteosten kuuluvan sinulle. Haluamme antaa sinulle + mahdollisuuden ilmoittaa, että teokset kuuluvat sinulle (tai poistaa tai + hylätä ne). Jos sinulla ei vielä ole tunnusta toisella sähköpostiosoitteella, + haluamme myös kutsua sinut mukaan! + mistake: + text: Jos olemme tehneet virheen eivätkä nämä ole sinun teoksiasi, ole hyvä + äläkä poista niitä! Ota yhteyttä Open Doorsiin (%{open_doors_link}), niin + selvitämme asian. + more_info: + text: Voit lukea viimeaikaisista arkistosiirroista AO3:n uutisista (%{news_link}) + ja löytää enemmän tietoa Open Doorsin UKK-sivulta (%{open_doors_faq_link}) + tai tutoriaaleista (%{open_doors_tutorial_link}). Jos sinulla on kysymyksiä, + joihin et löydä vastauksia UKK:sta, tutoriaaleista tai tästä sähköpostista, + ole hyvä ja ota yhteyttä Käyttäjätukeen (%{support_link}). + other_works: + text: Jos sinulla oli tuodussa arkistossa muita teoksia, jotka on liitetty + sähköpostiosoitteeseen, johon sinulla ei enää ole pääsyä, ole hyvä ja ota + yhteyttä Open Doorsiin mahdollisten todisteiden kanssa. + questions: + text: Jos sinulla on muuta kysyttävää, ole hyvä ja ota yhteyttä AO3:n Käyttäjätukeen + osoitteessa %{support_link}. + redirects: Siirretyn arkiston verkko-osoitteet saatetaan uudelleenohjata teosten + tuotuihin kopioihin rajoitetun ajan, jotta suosituslistat ja kirjanmerkit + toimisivat edelleen. (Tarkasta arkiston tuomisesta kertovasta uutisesta, tehdäänkö + näin.) Jos olet jo itse lisännyt teokset arkistoon ja ET käyttänyt tuo URL:stä + -toimintoa, teoksista on arkistossa kaksi kopiota. + subject: "[%{app_name}] Ilmoita teosten omistajuudesta" + unwanted: + text: Jos nämä teokset kuuluvat sinulle, mutta et halua niitä, voit hylätä + (jolloin ne jäävät AO3:een, mutta nimeäsi ei ilmoiteta niiden yhteydessä) + tai poistaa (jolloin ne katoavat kokonaan AO3:sta) ne. Sinun ei tarvitse + lisätä näitä teoksia millekään tunnukselle hylätäksesi tai poistaaksesi + ne–voit tehdä sen suoraan yllä olevan ilmoituslinkin kautta. (Jos haluat + apua, ole hyvä ja ota yhteyttä Käyttäjätukeen osoitteessa %{support_link}.) + update_redirect: + text: Jos haluat Open Doorsin päivittävän edelleenohjauksen jo lisäämääsi + teokseen, ole hyvä ja poista tuotu kopio ja ota yhteyttä Open Doorsiin osoitteessa + %{open_doors_link}. Ilmoita AO3-käyttäjätunnuksesi, tuodun arkiston käyttäjätunnuksesi + sekä sen faniteoksen nimi ja URL, johon haluat uudelleenohjauksen osoittavan. + (Jos haluat siirtää usean faniteoksen uudelleenohjaukset, voit listata ne + kaikki samaan sähköpostiin.) + uploaded_list: 'Seuraavat teokset ladattiin:' + invite_increase_notification: + html: + body: + one: Halusimme vain kertoa, että sinulla on %{count} uusi kutsu, jolla arkistoon + voi luoda uuden tunnuksen. Voit kutsua ystävän mukaan %{invitation_page_link}. + other: Halusimme vain kertoa, että sinulla on %{count} kpl uusia kutsuja, + joilla arkistoon voi luoda uusia tunnuksia. Voit kutsua ystäviä mukaan + %{invitation_page_link}. + invitation_page_link_text: Invitations (Kutsut) -sivullasi + subject: "[%{app_name}] Uusia kutsuja" + text: + body: + one: Halusimme vain kertoa, että sinulla on %{count} uusi kutsu, jolla arkistoon + voi luoda uuden tunnuksen. Voit kutsua ystävän mukaan Invitations (Kutsut) + -sivullasi %{invitation_page_url}. + other: Halusimme vain kertoa, että sinulla on %{count} kpl uusia kutsuja, + joilla arkistoon voi luoda uusia tunnuksia. Voit kutsua ystäviä mukaan + Invitations (Kutsut) -sivullasi %{invitation_page_url}. + invite_request_declined: + main: + one: Valitettavasti joudumme ilmoittamaan, että emme voi myöntää sinulle uutta + kutsua. + other: Valitettavasti joudumme ilmoittamaan, että emme voi myöntää sinulle + %{count} uutta kutsua. + reason: 'Pyyntösi oli:' + subject: "[%{app_name}] Pyyntösi ylimääräisistä kutsukoodeista on hylätty" + recipient_notification: + html: + collection: Sinulle lahjoitettu teos on julkaistu AO3:ssa kokoelmassa %{collection_link}! + no_collection: Sinulle lahjoitettu teos on julkaistu AO3:ssa! + subject: + collection: "[%{app_name}][%{collection_title}] Lahjateos sinulle kokoelmassa + %{collection_title}" + no_collection: "[%{app_name}] Sinulle on lahjoitettu teos" + text: + collection: Sinulle lahjoitettu teos on julkaistu AO3:ssa kokoelmassa "%{collection_title}", + jonka linkki on (%{collection_url})! + signup_notification: + activate: + html: Ole hyvä ja %{activate_account_link}. + text: 'Aktivoi tunnuksesi: %{activate_account_url}' + activate_your_account: käytä tätä linkkiä aktivoidaksesi käyttäjätilisi + admin_posts: AO3:n uutisista + bye: Toivomme, että nautit AO3:n käytöstä. + contact_support: ota yhteyttä Käyttäjätukeemme + faq: UKK:mme + features: + html: Kun tunnuksesi on valmis, voit julkaista faniteoksiasi, tilata suosikkitekijöidesi + ja -teostesi päivitykset sähköpostiisi, muuttaa sivuston ulkonäköä ja toimintoja + asetuksistasi, pitää kirjaa AO3:ssa avaamistasi teoksista ja paljon muuta. + text: Kun tunnuksesi on valmis, voit julkaista faniteoksiasi, tilata suosikkitekijöidesi + ja -teostesi päivitykset sähköpostiisi, muuttaa sivuston ulkonäköä ja toimintoja + asetuksistasi, pitää kirjaa AO3:ssa avaamistasi teoksista ja paljon muuta. + information: + html: "%{faq_link} sisältää paljon tietoa ja neuvoja AO3:n käyttöön. Uusimmat + tiedot sivuston muutoksista löydät %{admin_posts_link}. Jos tarvitset apua + tai törmäät bugiin, tai sinulla on kysymyksiä tai kommentteja, ole hyvä + ja %{contact_support_link}, joka auttaa aina mielellään." + text: UKK:mme osoitteessa %{faq_url} sisältää paljon tietoa ja neuvoja AO3:n + käyttöön. Uusimmat tiedot sivuston muutoksista löydät AO3:n uutisista osoitteessa + %{admin_posts_url}. Jos tarvitset apua tai törmäät bugiin, tai sinulla on + kysymyksiä tai kommentteja, ole hyvä ja ota yhteyttä Käyttäjätukeemme, joka + auttaa aina mielellään osoitteessa %{contact_support_url}. + welcome: Tervetuloa AO3:een, %{login}! diff --git a/config/locales/phrase-exports/fil.yml b/config/locales/phrase-exports/fil.yml new file mode 100755 index 0000000..27e9cd5 --- /dev/null +++ b/config/locales/phrase-exports/fil.yml @@ -0,0 +1,2 @@ +--- +fil: {} diff --git a/config/locales/phrase-exports/fr.yml b/config/locales/phrase-exports/fr.yml new file mode 100755 index 0000000..bb50673 --- /dev/null +++ b/config/locales/phrase-exports/fr.yml @@ -0,0 +1,672 @@ +--- +fr: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Avertissement :' + other: 'Avertissements :' + category: + name_with_colon: + one: 'Catégorie :' + other: 'Catégories :' + character: + name_with_colon: + one: 'Personnage :' + other: 'Personnages :' + fandom: + name_with_colon: + one: 'Fandom :' + other: 'Fandoms :' + freeform: + name_with_colon: + one: 'Tag supplémentaire :' + other: 'Tags supplémentaires :' + rating: + name_with_colon: 'Classification :' + relationship: + name_with_colon: + one: 'Relation :' + other: 'Relations :' + work: + chapter_total_display: Chapitres + summary: Résumé + models: + archive_warning: + one: Avertissement + other: Avertissements + category: + one: Catégorie + other: Catégories + chapter: + one: Chapitre + other: Chapitres + character: + one: Personnage + other: Personnages + fandom: + one: Fandom + other: Fandoms + freeform: + one: Tag supplémentaire + other: Tags supplémentaires + rating: + one: Classification + other: Classifications + relationship: + one: Relation + other: Relations + series: + one: Série + other: Séries + kudo_mailer: + batch_kudo_notification: + guest: + one: un/une invité-e + other: "%{count} invité-e-s" + left_kudos: + html: + one: "%{givers_list} a félicité votre œuvre %{commentable_link}." + other: "%{givers_list} ont félicité votre œuvre %{commentable_link}." + text: + one: "%{givers_list} a félicité votre œuvre %{commentable_title} (%{commentable_url})." + other: "%{givers_list} ont félicité votre œuvre %{commentable_title} (%{commentable_url})." + single_guest: + giver: Un/Une invité-e + html: "%{giver} a félicité votre œuvre %{commentable_link}." + text: Un/Une invité-e a félicité votre œuvre %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Vous avez reçu des félicitations !" + mailer: + general: + closing: + formal: Bien cordialement, + informal: Cordialement, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Chapitre %{position} de %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} mot" + other: "%{count} mots" + footer: + general: + about: + html: Le site Archive of Our Own est une archive gérée et financée par + les fans, qui dépend de %{donate_link}. + text: 'Le site Archive of Our Own est une archive gérée et financée par + les fans, qui dépend de vos dons : %{donate_url}.' + html: + donate_link_text: vos dons + support_link_text: contacter le Support Technique + unwanted_email: + html: Si vous avez reçu ce message par erreur, veuillez %{support_link}. + text: 'Si vous avez reçu ce message par erreur, veuillez contacter le + Support Technique à l''adresse suivante : %{support_url}.' + sent_at: Envoyé le %{sent_at}. + greeting: + formal_html: Cher/Chère %{name}, + informal: + addressed_html: Bonjour, %{name} ! + unaddressed: Bonjour ! + introductory: Bonjour de la part d'Archive of Our Own – AO3 (Notre Propre + Archive) ! + metadata_label_indicator: ":" + signature: + abuse_team: L'équipe Modération d'AO3 + app_short_name: AO3 + open_doors: L'équipe du Projet Open Doors + parent_org: Organization for Transformative Works – OTW (Organisation pour + les Œuvres Transformatives) + support: L'équipe de Support Technique d'AO3 + users: + mailer: + reset_password_instructions: + expiration: Ce lien est valable une semaine. S'il n'est pas utilisé dans ce + délai, il arrivera à expiration et vous devrez alors en demander un nouveau. + intro: 'Nous avons reçu une demande de réinitialisation du mot de passe de + votre compte. Pour le modifier, suivez le lien ci-dessous et entrez votre + nouveau mot de passe :' + link_title: Modifier mon mot de passe. + subject: "[%{app_name}] Réinitialisation du mot de passe" + unrequested: Si vous n'êtes pas à l'origine de cette demande, veuillez ignorer + ce message. Votre ancien mot de passe restera alors valide. + user_mailer: + admin_deleted_work_notification: + bye: Vous trouverez une copie de votre œuvre en pièce jointe. + contact_abuse: contacter notre Comité Modération + deleted: + html: Votre œuvre %{title} a été supprimée de l'Archive par un-e administrateur-trice + du site. + text: Votre œuvre "%{title}" a été supprimée de l'Archive par un-e administrateur-trice + du site. + html: + tos_violation: S'il est possible que votre œuvre ait enfreint les Conditions + d'Utilisation, veuillez %{contact_abuse_link}. + import_project: + html: Si votre œuvre faisait partie d'un projet d'importation réalisé par + Open Doors, veuillez %{opendoors_link} pour toute question supplémentaire. + text: Si votre œuvre faisait partie d'un projet d'importation réalisé par + Open Doors, veuillez contacter Open Doors (Portes Ouvertes) (%{opendoors_link}) + pour toute question supplémentaire. + opendoors: contacter Open Doors (Portes Ouvertes) + subject: "[%{app_name}] Votre œuvre a été supprimée par un-e administrateur-trice" + text: + tos_violation: S'il est possible que votre œuvre ait enfreint les Conditions + d'Utilisation, veuillez contacter notre Comité Modération (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Durant cette période, vous pourrez toujours y accéder grâce au lien + fourni ci-dessus, toutefois elle ne fera pas partie de la liste de vos œuvres + et ne sera pas accessible aux autres utilisateur-trice-s d'AO3. + check_email: Vérifiez vos e-mails, y compris le dossier des indésirables, car + le Comité Modération vous a peut-être déjà contacté-e pour vous en expliquer + la raison. + contact_abuse: contacter le Comité Modération + html: + help: Si vous ignorez pour quelle raison votre œuvre a été cachée et que vous + n'avez pas reçu de communication à ce sujet, merci de contacter %{contact_abuse_link} + directement. + hidden: Votre œuvre %{title} a été cachée par le Comité Modération et n'est + plus accessible au public. + tos_violation: Si votre œuvre a été cachée suite à une violation des %{tos_link} + d'AO3, vous devrez corriger cette violation. À défaut, vous encourez le + risque qu'elle soit supprimée. + subject: "[%{app_name}] Votre œuvre a été cachée par le Comité Modération" + text: + help: 'Si vous ignorez pour quelle raison votre œuvre a été cachée et que + vous n''avez pas reçu de communication à ce sujet, merci de contacter le + Comité Modération directement : %{contact_abuse_url}.' + hidden: Votre œuvre "%{title}" (%{work_url}) a été cachée par le Comité Modération + et n'est plus accessible au public. + tos_violation: Si votre œuvre a été cachée suite à une violation des Conditions + d'Utilisation d'AO3 (%{tos_url}), vous devez corriger cette violation. À + défaut, vous encourez le risque qu'elle soit supprimée. + tos: Conditions d'Utilisation + anonymous_or_unrevealed_notification: + anonymous_info: Les œuvres anonymes apparaissent dans les listes de tags mais + pas sur la page rassemblant vos œuvres. Sur l'œuvre, votre nom d'utilisateur-trice + sera remplacé par "Anonymous" (Anonyme). + anonymous_unrevealed_info: Il se peut que les personnes qui maintiennent la + collection révèlent votre œuvre tout en la laissant anonyme. Les personnes + abonnées à vos mises à jour ne recevront pas de notification lors de ce changement. + Une fois révélée, votre œuvre sera incluse dans les listes de tags mais pas + dans la page regroupant vos œuvres. Sur l'œuvre, votre nom d'utilisateur-trice + sera remplacé par "Anonymous" (Anonyme). + changed_status: + anonymous: + html: Les personnes qui maintiennent %{collection_link} ont changé le statut + de votre œuvre %{work_link} en anonyme. + text: Les personnes qui maintiennent "%{collection_title}" (%{collection_url}) + ont changé le statut de votre œuvre "%{work_title}" (%{work_url}) en anonyme. + anonymous_unrevealed: + html: Les personnes qui maintiennent %{collection_link} ont changé le statut + de votre œuvre %{work_link} pour en faire une œuvre anonyme non révélée. + text: Les personnes qui maintiennent "%{collection_title}" (%{collection_url}) + ont changé le statut de votre œuvre "%{work_title}" (%{work_url}) pour + en faire une œuvre anonyme non révélée. + unrevealed: + html: Les personnes qui maintiennent %{collection_link} ont changé le statut + de votre œuvre %{work_link} pour en faire une œuvre non révélée. + text: Les personnes qui maintiennent "%{collection_title}" (%{collection_url}) + ont changé le statut de votre œuvre "%{work_title}" (%{work_url}) pour + en faire une œuvre non révélée. + collection_items_link_text: Approved Collection Items page (page des Objets + approuvés dans une Collection) + do_not_want: + anonymous: + html: Si vous ne souhaitez pas que votre œuvre soit anonyme, veuillez consulter + votre %{collection_items_link} afin de la retirer de cette collection. + text: 'Si vous ne souhaitez pas que votre œuvre soit anonyme, veuillez consulter + votre Approved Collection Items page (page des Objets approuvés dans une + Collection) afin de la retirer de cette collection : %{collection_items_url}' + anonymous_unrevealed: + html: Si vous ne souhaitez pas que votre œuvre soit anonyme et non révélée, + veuillez consulter votre %{collection_items_link} afin de la retirer de + cette collection. + text: 'Si vous ne souhaitez pas que votre œuvre soit anonyme et non révélée, + veuillez consulter votre Approved Collection Items page (page des Objets + approuvés dans une Collection) afin de la retirer de cette collection + : %{collection_items_url}' + unrevealed: + html: Si vous ne souhaitez pas que votre œuvre soit non révélée, veuillez + consulter votre %{collection_items_link} afin de la retirer de cette collection. + text: 'Si vous ne souhaitez pas que votre œuvre soit non révélée, veuillez + consulter votre Approved Collection Items page (page des Objets approuvés + dans une Collection) afin de la retirer de cette collection : %{collection_items_url}' + faq_link_text: FAQ Collections + more_info: + html: Pour plus d'information, consultez notre %{faq_link}. + text: 'Pour plus d''informations, consultez notre FAQ "Collections" : %{faq_url}' + subject: + anonymous: "[%{app_name}] Votre œuvre a été rendue anonyme" + anonymous_unrevealed: "[%{app_name}] Votre œuvre a été rendue anonyme et non + révélée" + unrevealed: "[%{app_name}] Votre œuvre a été changée en œuvre non révélée" + unrevealed_info: Les œuvres non révélées n'apparaissent pas dans les listes + de tags ou sur la page rassemblant vos œuvres. Quiconque suit un lien vers + l'œuvre sera informé qu'elle est actuellement non révélée et ne pourra pas + accéder à son contenu. + archivist_added_to_collection_notification: + approved_collection_items_page: page Approved Collection Items (page des Objets + approuvés dans une collection) + archivist_notice: Puisque les responsables de la collection agissent en leur + qualité officielle d'archivistes d'Open Doors (Portes Ouvertes), ils/elles + sont autorisé-e-s à ajouter votre œuvre à cette collection, même si vous avez + désactivé les invitations à des collections. Les archivistes ajouteront uniquement + une œuvre à une collection si elle était hébergée sur une archive importée. + removal_instructions: + html: Si vous souhaitez retirer votre œuvre de cette collection, veuillez + vous rendre sur votre %{approved_items_link}. + text: 'Si vous souhaitez retirer votre œuvre de cette collection, veuillez + vous rendre sur votre page Approved Collection Items (page des Objets approuvés + dans une collection) : %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Un/Une Archiviste d'Open Doors + (Portes Ouvertes) a ajouté votre œuvre à une collection" + work_added: + html: Le/La responsable de %{collection_link} a ajouté votre œuvre %{work_link} + à sa collection ! + text: Les responsables "%{collection_title}" (%{collection_url}) ont ajouté + votre oeuvre "%{work_title}" (%{work_url}) à leur collection ! + challenge_assignment_notification: + any: Non spécifié + assignment: + html: La demande suivante vous a été attribuée dans le cadre du défi %{link} + sur Archive of Our Own ! + description: 'Description :' + due: 'Cette tâche est à terminer avant le :' + html: + footer: Vous avez reçu cet e-mail car vous vous êtes inscrit-e au défi %{title}. + Pour plus d'informations sur ce défi et savoir comment contacter les modérateur-trice-s, + veuillez consulter %{footer_link}. + footer_link: la page de profil du défi + look_up: Vous pouvez accéder à cette tâche via %{link}. + look_up_link: votre page Assignments (Tâches) + optional_tags: 'Tags optionnels :' + prompts: 'Prompts :' + prompt_url: 'URL du prompt :' + recipient: 'Destinataire :' + recipient_missing: 'Aucun-e : contactez un/une modérateur-trice pour demander + de l''aide !' + subject: "[%{app_name}][%{collection_title}] Vous Avez Reçu une Tâche !" + text: + assignment: La demande suivante vous a été attribuée dans le cadre du défi + "%{collection_title}" (%{collection_url}) sur Archive of Our Own ! + footer: Vous avez reçu cet e-mail car vous vous êtes inscrit-e au défi %{title} + (%{url}). Pour plus d'informations sur ce défi et savoir comment contacter + les modérateur-trice-s, veuillez consulter %{profile_url}. + look_up: Vous pouvez retrouver cette tâche dans votre page Assignments (Tâches) + à l'adresse %{link}. + change_email: + changed: + html: "%{login}, l'adresse e-mail associée à votre compte a été remplacée + par %{email}" + text: "%{login}, l'adresse e-mail associée à votre compte a été remplacée + par %{email}" + subject: "[%{app_name}] Changement d'adresse e-mail" + claim_notification: + access: + contact_support: contacter le support technique d'AO3 + html: Dans certains cas, il se peut que vos œuvres aient été importées de + manière à être visibles uniquement pour les utilisateur-trice-s connecté-e-s + (afin qu'elles n'apparaissent pas dans les résultats de recherche Google). + Si c'est le cas, cette restriction s'appliquera à vos œuvres jusqu'à ce + que vous décidiez de les rendre pleinement visibles. Pour savoir comment + déverrouiller l'accès à vos œuvres, les supprimer ou les rendre orphelines, + veuillez %{contact_support_link}. + text: Dans certains cas, il se peut que vos œuvres aient été importées de + manière à être visibles uniquement pour les utilisateur-trice-s connecté-e-s + (afin qu'elles n'apparaissent pas dans les résultats de recherche Google). + Si c'est le cas, cette restriction s'appliquera à vos œuvres jusqu'à ce + que vous décidiez de les rendre pleinement visibles. Pour savoir comment + déverrouiller l'accès à vos œuvres, les supprimer ou les rendre orphelines, + veuillez contacter le support technique d'AO3 à l'adresse %{support_url}. + email_tips: Si vous souhaitez nous contacter, veuillez ajouter le domaine @transformativeworks.org + à votre liste de contacts autorisés. Il se peut aussi que notre réponse atterrisse + dans vos dossiers de spam. + introduction: + ao3_name: Archive of Our Own – AO3 (Notre Propre Archive) + html: Vous recevez ce message car des œuvres vous appartenant publiées sur + une archive d'œuvres de fans ont été importées sur %{app_link} par %{open_doors_name_link}. + Cette adresse e-mail étant liée à celle que vous utilisez sur l'archive + importée, les œuvres de fans associées ont été ajoutées automatiquement + sur votre compte AO3. + open_doors_name: Open Doors (Portes Ouvertes) + text: 'Vous recevez ce message car des œuvres vous appartenant, publiées sur + une archive d''œuvres de fans, ont été importées sur Archive of Our Own + – AO3 (Notre Propre Archive): %{app_url} par notre équipe Open Doors (Portes + Ouvertes) (%{open_doors_url}) depuis une archive d''œuvres de fans. Cette + adresse e-mail étant liée à celle que vous utilisez sur l''archive importée, + les œuvres de fans associées (recensées ci-dessous) ont été ajoutées automatiquement + sur votre compte AO3.' + mistake: + contact_open_doors: notre équipe Open Doors + html: 'Si ces œuvres vous ont été attribuées par erreur, nous vous demandons + de ne pas les supprimer : contactez simplement %{contact_open_doors_link}, + et nous réglerons le problème.' + text: 'Si ces œuvres vous ont été attribuées par erreur, nous vous demandons + de ne pas les supprimer : contactez simplement notre équipe Open Doors (%{open_doors_url}), + et nous réglerons le problème.' + more_info: + ao3_news: Actualités d'AO3 + contact_support: contacter le support technique d'AO3 + faq_page: FAQ + html: Vous trouverez les annonces relatives aux importations récentes dans + les %{ao3_news_link}. Pour des informations d'ordre plus général, la %{faq_page_link} + "Open Doors" et le %{tutorial_page_link} associé sont à votre disposition. + Si vous n'y trouvez pas la réponse à vos questions, veuillez %{contact_support_link}. + text: Vous trouverez les annonces relatives aux importations récentes dans + les Actualités d'AO3 (%{news_url}). Pour des informations d'ordre plus général, + la FAQ "Open Doors" (%{open_doors_faq_url}) et le tutoriel associé (%{open_doors_tutorial_url}) + sont à votre disposition. Si vous n'y trouvez pas la réponse à vos questions, + veuillez contacter le support technique d'AO3 à l'adresse %{support_url}. + tutorial_page: tutoriel + other_works: + contact_open_doors: contacter l'équipe Open Doors + html: Si vous avez publié d'autres œuvres sur l'archive importée, mais que + vous n'avez plus accès à l'adresse e-mail associée, veuillez %{contact_open_doors_link} + en fournissant un maximum d'informations qui pourraient nous aider à vérifier + votre identité. + text: Si vous avez publié d'autres œuvres sur l'archive importée, mais que + vous n'avez plus accès à l'adresse e-mail associée, veuillez contacter l'équipe + Open Doors en fournissant un maximum d'informations qui pourraient nous + aider à vérifier votre identité. + questions: + contact_support: contacter le support technique d'AO3 + html: Pour toute autre demande, merci de %{contact_support_link}. + text: Pour toute autre demande, merci de contacter le support technique d'AO3 + à l'adresse %{support_url}. + redirects: + html: Pour assurer la continuité des listes de recommandation et des marque-pages, + il se peut que l'adresse de l'archive importée redirige les utilisateur-trice-s + vers la copie importée des œuvres concernées pour une durée limitée (pour + savoir si c'est le cas, consultez le billet annonçant l'importation de votre + archive). Si vous avez déjà publié une copie de ces œuvres sur AO3 %{negation} + passer par notre outil d'importation par URL, il existera deux copies de + cette œuvre sur AO3. + subject: "[%{app_name}] Œuvres importées" + update_redirect: + contact_open_doors: contacter l'équipe Open Doors + html: Si vous souhaitez qu'Open Doors mette à jour la redirection pour l'associer + à votre œuvre préexistante, veuillez supprimer la copie importée et %{contact_open_doors_link} + en précisant votre nom (ou vos noms) d'utilisateur-trice sur AO3 et sur + l'archive importée, ainsi que le titre et l'URL de l'œuvre vers laquelle + vous souhaitez programmer la redirection. (Si vous souhaitez effectuer cette + opération pour plusieurs œuvres, vous pouvez en dresser la liste dans un + même e-mail.) + text: Si vous souhaitez qu'Open Doors mette à jour la redirection pour l'associer + à votre œuvre préexistante, veuillez supprimer la copie importée et contacter + l'équipe Open Doors à l'adresse %{open_doors_url} en précisant votre nom + (ou vos noms) d'utilisateur-trice sur AO3 et sur l'archive importée, ainsi + que le titre et l'URL de l'œuvre vers laquelle vous souhaitez programmer + la redirection. (Si vous souhaitez effectuer cette opération pour plusieurs + œuvres, vous pouvez en dresser la liste dans un même e-mail.) + works_by: 'Ces œuvres ont été publiées en association avec l''adresse suivante + : %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Toutes les tâches ont été envoyées. + subject: Tâches envoyées + html: + received_message: 'Vous avez reçu un message à propos de votre collection + %{collection_link} :' + text: + received_message: 'Vous avez reçu un message à propos de votre collection + "%{collection_title}" (%{collection_url}) :' + creatorship_notification: + explanation: Lorsque vous êtes co-créateur-trice d'une œuvre, votre nom peut + être ajouté à de nouveaux chapitres quels que soient les paramètres de la + co-création. Il pourra également être ajouté à toute série à laquelle l'œuvre + serait annexée. + html: + creation: "%{creation_link} par %{pseud_links}" + edit_chapter: modifier le chapitre + edit_series: modifier la série + remove_chapter: Si votre nom a été ajouté par erreur ou si vous ne souhaitez + pas figurer en tant que créateur-trice, vous pouvez %{edit_chapter_link} + et en retirer votre nom. + remove_series: Si votre nom a été ajouté par erreur ou si vous ne souhaitez + pas figurer en tant que créateur-trice, vous pouvez %{edit_series_link} + et en retirer votre nom. + intro_chapter: 'L''utilisateur-trice %{adding_user} a ajouté votre pseudo %{pseud} + en tant que co-créateur-trice pour le chapitre suivant :' + intro_series: 'L''utilisateur-trice %{adding_user} a ajouté votre pseudo %{pseud} + en tant que co-créateur-trice pour la série suivante :' + subject: "[%{app_name}] Notification de Co-création" + text: + creation: "%{title} (%{url}) par %{pseuds}" + remove_chapter: 'Si votre nom a été ajouté par erreur ou si vous ne souhaitez + pas figurer en tant que créateur-trice, vous pouvez modifier le chapitre + et en retirer votre nom : %{url}' + remove_series: 'Si votre nom a été ajouté par erreur ou si vous ne souhaitez + pas figurer en tant que créateur-trice, vous pouvez modifier la série et + en retirer votre nom : %{url}' + creatorship_notification_archivist: + explanation: L'utilisateur-trice, en sa qualité d'archiviste officiel-le d'Open + Doors (Portes Ouvertes), a la possibilité de vous ajouter sans vous le demander, + même si vous avez désactivé la co-création. + html: + creation: "%{creation_link} de %{pseud_links}" + edit_chapter: modifier le chapitre + edit_series: modifier la série + edit_work: modifier l'œuvre + remove_chapter: Si vous avez été ajouté-e par erreur ou ne souhaitez pas apparaître + comme créateur-trice, vous pouvez %{edit_chapter_link} pour retirer votre + pseudo. + remove_series: Si vous avez été ajouté-e par erreur ou ne souhaitez pas apparaître + comme créateur-trice, vous pouvez %{edit_series_link} pour retirer votre + pseudo. + remove_work: Si vous avez été ajouté-e par erreur ou ne souhaitez pas apparaître + comme créateur-trice, vous pouvez %{edit_work_link} pour retirer votre pseudo. + intro_chapter: 'L''utilisateur-trice %{archivist} a ajouté votre pseudo %{pseud} + en tant que co-créateur-trice du chapitre suivant :' + intro_series: 'L''utilisateur-trice %{archivist} a ajouté votre pseudo %{pseud} + en tant que co-créateur-trice de la série suivante :' + intro_work: 'L''utilisateur-trice %{archivist} a ajouté votre pseudo %{pseud} + en tant que co-créateur-trice de l''œuvre suivante :' + subject: "[%{app_name}] Notification d'ajout en tant que co-créateur-trice" + text: + creation: "%{title} (%{url}) de %{pseuds}" + remove_chapter: 'Si vous avez été ajouté-e par erreur ou ne souhaitez pas + apparaître comme créateur-trice, vous pouvez modifier le chapitre pour retirer + votre pseudo : %{url}' + remove_series: 'Si vous avez été ajouté-e par erreur ou ne souhaitez pas apparaître + comme créateur-trice, vous pouvez modifier la série pour retirer votre pseudo + : %{url}' + remove_work: 'Si vous avez été ajouté-e par erreur ou ne souhaitez pas apparaître + comme co-créateur-trice, vous pouvez modifier l''œuvre pour retirer votre + pseudo : %{url}' + creatorship_request: + html: + creation: "%{creation_link} par %{pseud_links}" + instructions: Vous pouvez accepter ou refuser cette demande sur la page %{page_name}. + page_name: Co-Creator Requests (Demandes de Co-création) + intro_chapter: 'L''utilisateur-trice %{inviting_user} a invité votre pseudo + %{pseud} à apparaître en co-création du chapitre suivant :' + intro_series: 'L''utilisateur-trice %{inviting_user} a invité votre pseudo %{pseud} + à apparaître en co-création de la série suivante :' + intro_work: 'L''utilisateur-trice %{inviting_user} a invité votre pseudo %{pseud} + à apparaître en co-création de l''œuvre suivante :' + subject: "[%{app_name}] Demande de Co-création" + text: + creation: "%{title} (%{url}) par %{pseuds}" + instructions: 'Vous pouvez accepter ou refuser cette invitation sur la page + Co-Creator Requests (Demandes de Co-création) : %{url}' + delete_work_notification: + attachment: Ci-joint une copie de votre œuvre pour référence. + deleted_other: + html: Votre œuvre %{title} a été supprimée suite à la demande de %{pseud}. + text: Votre œuvre "%{title}" a été supprimée suite à la demande de %{pseud}. + deleted_yourself: + html: Votre œuvre %{title} a été supprimée suite à votre demande. + text: Votre œuvre "%{title}" a été supprimée suite à votre demande. + questions: + html: Si vous avez des questions, veuillez %{support}. + text: Si vous avez des questions, veuillez %{support} (%{url}). + subject: "[%{app_name}] Votre œuvre a été supprimée" + support: contacter le Support Technique + invitation: + been_invited: Vous avez été invité-e à rejoindre notre version bêta ! + has_invited: "%{user_name} vous a invité-e à rejoindre notre version bêta !" + html: + faq_link_text: notre FAQ + subject: "[%{app_name}] Invitation" + invitation_to_claim: + access: + text: En fonction de l’archive, il se peut que vos œuvres aient été importées + de façon à n’être accessibles qu’aux utilisateur-trice-s enregistré-e-s + (afin qu’elles n’apparaissent pas parmi les résultats de recherche Google). + Si c’est le cas, les œuvres seront restreintes aux utilisateur-trice-s connecté-e-s, + à moins que vous ne les rendiez accessibles à tous/toutes. Si vous avez + besoin d’aide pour cela, pour rendre orphelines ou supprimer vos œuvres, + veuillez contacter le Comité Support Technique d’AO3. + claim_or_remove: + html: Vous pouvez revendiquer ou supprimer vos œuvres ici. + text: 'Vous pouvez revendiquer ou supprimer vos œuvres ici : %{claim_url}.' + email_tips: Si vous nous contactez, veuillez autoriser les e-mails provenant + de @transformativeworks.org et vérifiez que notre réponse n’arrive pas dans + votre courrier indésirable. + html: + ao3_news: les actualités d’AO3 + contact_open_doors: contacter Open Doors + contact_support: contacter le Comité Support Technique d’AO3 + faq_page: FAQ + tutorial_page: tutoriels + introduction: + text: Vous recevez cet e-mail car une archive a récemment été importée par + Open Doors (%{open_doors_link}) sur %{app_name} (%{app_short_name} - %{app_url}), + et il nous semble que les œuvres de fans listées ci-après vous appartiennent. + Nous aimerions vous donner l’occasion de revendiquer ces œuvres (ou de les + supprimer, ou encore de les rendre orphelines, c’est-à-dire de rompre la + relation entre elles et vous) si vous le souhaitez. Et si vous n’avez pas + encore de compte AO3 sous une adresse différente, nous voudrions vous convier + à bord ! + mistake: + text: S’il y a erreur et que ces œuvres ne vous appartiennent pas, ne les + supprimez pas ! Merci de simplement contacter Open Doors (%{open_doors_link}) + et nous reprendrons la main. + more_info: + text: 'Vous pouvez consulter les dernières annonces d’importation d’archives + grâce aux actualités d’AO3 (%{news_link}), et trouver des informations complémentaires + dans la FAQ d’Open Doors (%{open_doors_faq_link}) ou dans les tutoriels + (%{open_doors_tutorial_link}). Si la réponse à vos questions ne se trouve + pas à ces endroits, ou dans cet email, veuillez contacter le Comité Support + Technique ici : %{support_link}.' + other_works: + text: Si certaines de vos œuvres de l’archive importée étaient associées à + une adresse e-mail à laquelle vous n’avez plus accès, veuillez contacter + Open Doors en mentionnant toute information susceptible de contribuer à + confirmer votre identité. + questions: + text: 'Pour toute autre demande, veuillez contacter le Comité Support Technique + ici : %{support_link}.' + redirects: Afin de préserver les listes de recommandations et les marque-pages, + les adresses web de l’archive importée sont susceptibles de renvoyer vers + la copie importée de ces œuvres pendant une durée limitée (consultez le billet + d’actualités concernant votre archive pour vous en assurer). Si vous avez + déjà mis en ligne une copie de ces œuvres et que vous n’avez PAS utilisé la + fonctionnalité permettant d’importer à partir d’une URL, il y aura deux copies + d’une même œuvre sur l’archive. + subject: "[%{app_name}] Invitation à revendiquer vos œuvres" + unwanted: + text: 'Si ces œuvres vous appartiennent bien mais que vous ne souhaitez pas + les revendiquer, vous pouvez les rendre orphelines (afin qu’elles restent + sur AO3 sans que votre nom y soit associé) ou les supprimer (afin qu’elles + disparaissent entièrement d’AO3). Il n’est pas nécessaire d’ajouter ces + œuvres à un compte pour les rendre orphelines ou les supprimer, vous pouvez + le faire directement en suivant le lien de revendication plus haut. (Si + vous avez besoin d’aide, veuillez contacter le Comité Support Technique + ici : %{support_link}.)' + update_redirect: + text: 'Si vous aimeriez qu’Open Doors mette à jour le lien de redirection + afin qu’il renvoie vers votre œuvre préexistante, veuillez supprimer la + copie importée et contacter Open Doors ici : %{open_doors_link}, en précisant + le nom de votre compte AO3, le nom de votre compte sur l’archive importée, + ainsi que le titre et l’URL de l’œuvre vers laquelle vous aimeriez que le + lien redirige. (Si vous souhaitez changer le lien de redirection de plusieurs + œuvres, vous pouvez rassembler tous les renseignements dans un seul e-mail.)' + uploaded_list: 'Les œuvres suivantes ont été mises en ligne :' + invite_increase_notification: + html: + body: + one: 'Nous vous envoyons ce message pour vous informer que vous possédez + %{count} nouvelle invitation, permettant de créer un nouveau compte sur + AO3. Vous pouvez aussi inviter un-e ami-e à l''adresse suivante : %{invitation_page_link}.' + other: 'Nous vous envoyons ce message pour vous informer que vous possédez + %{count} nouvelles invitations, permettant de créer de nouveaux comptes + sur AO3. Vous pouvez aussi inviter un-e ami-e à l''adresse suivante : + %{invitation_page_link}.' + invitation_page_link_text: votre page d'invitations + subject: "[%{app_name}] Nouvelles Invitations" + text: + body: + one: Nous vous envoyons ce message pour vous informer que vous possédez + %{count} nouvelle invitation, permettant de créer un nouveau compte sur + AO3. Vous pouvez aussi inviter un-e ami-e sur votre page d'invitations + (%{invitation_page_url}). + other: Nous vous envoyons ce message pour vous informer que vous possédez + %{count} nouvelles invitations, permettant de créer de nouveaux comptes + sur AO3. Vous pouvez aussi inviter un-e ami-e sur votre page d'invitations + (%{invitation_page_url}). + invite_request_declined: + main: + one: Nous sommes au regret de vous informer que votre demande de nouvelle + invitation ne peut être satisfaite pour le moment. + other: Nous sommes au regret de vous informer que votre demande de %{count} + nouvelles invitations ne peut être satisfaite pour le moment. + reason: 'Votre demande était la suivante :' + subject: "[%{app_name}] Demande de Code d'Invitation Supplémentaire Rejetée" + recipient_notification: + html: + collection: Une œuvre cadeau a été publiée pour vous dans la collection %{collection_link} + sur AO3 ! + no_collection: Une œuvre cadeau a été publiée pour vous sur AO3 ! + subject: + collection: "[%{app_name}][%{collection_title}] Une œuvre cadeau pour vous + dans %{collection_title}" + no_collection: "[%{app_name}] Une œuvre cadeau pour vous" + text: + collection: Une œuvre cadeau a été publiée pour vous dans la collection "%{collection_title}" + (%{collection_url}) sur AO3 ! + signup_notification: + activate: + html: Veuillez %{activate_account_link}. + text: 'Veuillez suivre ce lien pour activer votre compte : %{activate_account_url}' + activate_your_account: suivez ce lien pour activer votre compte + admin_posts: Actualités d’AO3 + bye: Nous espérons que vous vous plairez sur AO3. + contact_support: contacter notre Support Technique + faq: FAQ + features: + html: Une fois que votre compte est activé, vous pouvez notamment publier + vos œuvres de fans, paramétrer les abonnements par e-mail pour être averti-e + des mises à jour de vos créateur-trice-s et œuvres préféré-e-s, définir + vos préférences pour personnaliser l’apparence et l’interface du site, garder + une trace des œuvres que vous avez consultées sur l’Archive grâce à votre + historique, et bien plus encore. + text: Une fois que votre compte est activé, vous pouvez notamment publier + vos œuvres de fans, paramétrer les abonnements par e-mail pour être averti-e + des mises à jour de vos créateur-trice-s et œuvres préféré-e-s, définir + vos préférences pour personnaliser l’apparence et l’interface du site, garder + une trace des œuvres que vous avez consultées sur l’Archive grâce à votre + historique, et bien plus encore. + information: + html: Vous trouverez une multitude d’informations et de conseils sur l’utilisation + de l’Archive sur notre %{faq_link}. Vous pouvez trouver les dernières actualités + concernant le développement du site grâce aux %{admin_posts_link}. Si vous + avez besoin d’aide, faites face à un bug, souhaitez nous poser des questions + ou nous faire part de vos commentaires, veuillez %{contact_support_link}, + qui est toujours ravi d’aider. + text: 'Vous trouverez une multitude d’informations et de conseils sur l’utilisation + d’AO3 sur notre FAQ à l’adresse suivante : %{faq_url}. Vous pouvez trouver + les dernières actualités publiées par les admins et concernant le développement + du site à l’adresse suivante : %{admin_posts_url}. Si vous avez besoin d’aide, + trouvez un bug, souhaitez nous poser des questions ou nous faire part de + vos commentaires, veuillez contacter notre équipe du Support Technique, + qui est toujours ravie d’aider : %{contact_support_url}. + + ' + welcome: Bienvenue sur Archive of Our Own, %{login} ! diff --git a/config/locales/phrase-exports/he.yml b/config/locales/phrase-exports/he.yml new file mode 100755 index 0000000..7383196 --- /dev/null +++ b/config/locales/phrase-exports/he.yml @@ -0,0 +1,471 @@ +--- +he: + activerecord: + attributes: + archive_warning: + name_with_colon: + many: 'אזהרות ארכיון:' + one: 'אזהרת ארכיון:' + other: 'אזהרות ארכיון:' + two: 'אזהרות ארכיון:' + category: + name_with_colon: + many: 'קטגוריות:' + one: 'קטגוריה:' + other: 'קטגוריות:' + two: 'קטגוריות:' + character: + name_with_colon: + many: 'דמויות:' + one: 'דמות:' + other: 'דמויות:' + two: 'דמויות:' + fandom: + name_with_colon: + many: 'פאנדומים:' + one: 'פאנדום:' + other: 'פאנדומים:' + two: 'פאנדומים:' + freeform: + name_with_colon: + many: 'תגיות נוספות:' + one: 'תגית נוספת:' + other: 'תגיות נוספות:' + two: 'תגיות נוספות:' + rating: + name_with_colon: 'סיווג:' + relationship: + name_with_colon: + many: 'מערכות יחסים:' + one: 'מערכת יחסים:' + other: 'מערכות יחסים:' + two: 'מערכות יחסים:' + work: + chapter_total_display: פרקים + summary: תקציר + models: + archive_warning: + many: אזהרות ארכיון + one: אזהרת ארכיון + other: אזהרות ארכיון + two: אזהרות ארכיון + category: + many: קטגוריות + one: קטגוריה + other: קטגוריות + two: קטגוריות + chapter: + many: פרקים + one: פרק + other: פרקים + two: פרקים + character: + many: דמויות + one: דמות + other: דמויות + two: דמויות + fandom: + many: פאנדומים + one: פאנדום + other: פאנדומים + two: פאנדומים + freeform: + many: תגיות נוספות + one: תגית נוספת + other: תגיות נוספות + two: תגיות נוספות + rating: + many: סיווגים + one: סיווג + other: סיווגים + two: סיווגים + relationship: + many: מערכות יחסים + one: מערכת יחסים + other: מערכות יחסים + two: מערכות יחסים + series: + many: סדרות + one: סדרה + other: סדרות + two: סדרות + kudo_mailer: + batch_kudo_notification: + guest: + many: "%{count} אורחות" + one: אורחת + other: "%{count} אורחות" + two: "%{count} אורחות" + left_kudos: + html: + one: "%{givers_list} השאירה קודוס על %{commentable_link}." + other: "%{givers_list} השאירו קודוס על %{commentable_link}." + text: + one: "%{givers_list} השאירה קודוס על %{commentable_title} (%{commentable_url})." + other: "%{givers_list} השאירו קודוס על %{commentable_title} (%{commentable_url})." + single_guest: + giver: אורחת + html: "%{giver} השאירה קודוס על %{commentable_link}." + text: אורחת השאירה קודוס על %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] קיבלת קודוס!" + mailer: + general: + closing: + formal: בברכה, + informal: בברכה, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: פרק %{position} של היצירה %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + many: "%{count} מילים" + one: מילה אחת + other: "%{count} מילים" + two: "%{count} מילים" + footer: + general: + about: + html: AO3 הוא ארכיון המנוהל ונתמך על ידי מעריצים ומעריצות ונסמך על %{donate_link}. + text: 'AO3 הוא ארכיון המנוהל ונתמך על ידי מעריצים ומעריצות ונסמך על תרומות: + %{donate_url}.' + html: + donate_link_text: תרומות + support_link_text: צרו קשר עם צוות התמיכה שלנו + unwanted_email: + html: אם קיבלת הודעה זו בטעות, אנא %{support_link}. + text: אם קיבלת הודעה זו בטעות, אנא צרו קשר עם צוות התמיכה שלנו בכתובת + %{support_url}. + sent_at: נשלח בשעה %{sent_at}. + greeting: + formal_html: "%{name} שלום," + informal: + addressed_html: היי, %{name}! + unaddressed: היי! + introductory: שלום מ-Archive of Our Own – AO3 (ארכיון משלנו)! + metadata_label_indicator: ":" + signature: + abuse_team: צוות מדיניות ושימוש לרעה של AO3 + app_short_name: AO3 + open_doors: צוות Open Doors (דלתות פתוחות) + parent_org: Organization for Transformative Works – OTW (ארגון למען יצירות + טרנספורמטיביות) + support: צוות התמיכה של AO3 + users: + mailer: + reset_password_instructions: + expiration: אם לא תשתמשו בקישור לאיפוס הסיסמה בתוך שבוע, יפוג תוקף הקישור + ותצטרכו לשלוח בקשה חדשה לאיפוס סיסמה. + intro: 'קיבלנו בקשה לאיפוס סיסמה בחשבונך. באפשרותך לשנות את הסיסמה על ידי + כניסה לקישור הבא והזנת הסיסמה החדשה:' + link_title: שינוי סיסמה. + subject: "[%{app_name}] איפוס סיסמה" + unrequested: אם לא ביקשת לשנות את סיסמתך, התעלמו מדוא"ל זה והסיסמה הנוכחית + שלך תמשיך לשמש אותך כמקודם. + user_mailer: + admin_deleted_work_notification: + bye: לנוחיותך, מצורף בזאת עותק של יצירתך. + contact_abuse: צרו קשר עם ועדת מדיניות ושימוש לרעה + deleted: + html: יצירתך %{title} נמחקה מהארכיון על ידי אדמינית. + text: יצירתך "%{title}" נמחקה מהארכיון על ידי אדמינית. + html: + tos_violation: אם ייתכן שיצירתך הפרה את תנאי השימוש של הארכיון, אנא %{contact_abuse_link}. + import_project: + html: אם יצירתך הייתה שייכת למיזם שיובא לארכיון על ידי Open Doors (דלתות פתוחות), + ניתן %{opendoors_link}. + text: אם יצירתך הייתה שייכת למיזם שיובא לארכיון על ידי Open Doors (דלתות פתוחות), + ניתן להפנות שאלות נוספות לצוות דלתות פתוחות (%{opendoors_link}). + opendoors: להפנות שאלות נוספות לצוות דלתות פתוחות + subject: "[%{app_name}] יצירתך נמחקה על ידי אדמינית" + text: + tos_violation: אם ייתכן שיצירתך הפרה את תנאי השימוש של הארכיון, אנא צרו קשר + עם ועדת מדיניות ושימוש לרעה (%{contact_abuse_url}). + admin_hidden_work_notification: + access: כל עוד היצירה מוסתרת, באפשרותך לגשת אליה באמצעות הקישור שצורף לעיל, + אך היא לא תופיע ברשימת היצירות שלך, ומשתמשות אחרות ב-AO3 לא יוכלו למצוא אותה. + check_email: נבקשך לבדוק בתיבת הדוא"ל שלך, כולל בתיקיית הספאם, אם קיבלת הודעה + מוועדת מדיניות ושימוש לרעה. ייתכן שהצוות כבר ניסה ליצור איתך קשר ולהסביר מדוע + היצירה הוסתרה. + contact_abuse: ליצור קשר עם ועדת מדיניות ושימוש לרעה + html: + help: אם לא ברור לך מדוע היצירה הוסתרה, ולא קיבלת הודעות נוספות כלשהן בנושא, + תוכלו %{contact_abuse_link} באופן ישיר. + hidden: צוות מדיניות ושימוש לרעה הסתיר את יצירתך %{title} ואין לציבור אפשרות + לגשת אליה כעת. + tos_violation: אם היצירה הוסתרה משום שהיא מפרה את %{tos_link} של AO3, תצטרכו + לשנות את היצירה כך שתעמוד בתנאי השימוש. אם לא יתוקנו ההפרות, היצירה עלולה + להימחק מ-AO3. + subject: "[%{app_name}] צוות מדיניות ושימוש לרעה הסתיר את יצירתך" + text: + help: 'אם לא ברור לך מדוע היצירה הוסתרה, ולא קיבלת הודעות נוספות כלשהן בנושא, + תוכלו ליצור קשר עם מדיניות ושימוש לרעה באופן ישיר: %{contact_abuse_url}.' + hidden: צוות מדיניות ושימוש לרעה הסתיר את יצירתך "%{title}" (%{work_url}) + ואין לציבור אפשרות לגשת אליה כעת. + tos_violation: אם היצירה שלך הוסתרה משום שהיא מפרה את תנאי השימוש של AO3, + (%{tos_url}), יהיה תצטרכו לשנות את היצירה כך שתעמוד בתנאי השימוש. אם לא + יתוקנו ההפרות, היצירה עלולה להימחק מ-AO3. + tos: תנאי השימוש + anonymous_or_unrevealed_notification: + anonymous_info: יצירות אנונימיות נכללות ברשימות התגיות, אך לא בדף היצירות שלך. + ביצירה עצמה, שם המשתמש/ת שלך יוחלף ב-"Anonymous" (אנונימי/ת). + anonymous_unrevealed_info: ייתכן שמנהלות האוסף יחשפו את היצירה שלך, אך ישאירו + אותה כאנונימית. משתמשות הרשומות לקבלת עדכונים מחשבונך לא יקבלו עדכון על שינוי + זה. ברגע שהיצירה תיחשף היא תיכלל ברשימות התגיות, אך לא בדף היצירות שלך. בדף + היצירה עצמה, שם המשתמש/ת שלך יוחלף ב-"Anonymous" (אנונימי/ת). + changed_status: + anonymous: + html: מנהלות האוסף %{collection_link} הפכו את היצירה שלך %{work_link} לאנונימית. + text: מנהלות האוסף "%{collection_title}" (%{collection_url}) הפכו את היצירה + שלך "%{work_title}" (%{work_url}) ליצירה אנונימית. + anonymous_unrevealed: + html: מנהלות האוסף %{collection_link} הפכו את היצירה שלך %{work_link} לאנונימית + ושטרם נחשפה. + text: מנהלות האוסף "%{collection_title}" (%{collection_url}) הפכו את היצירה + שלך "%{work_title}" (%{work_url}) ליצירה אנונימית ושטרם נחשפה. + unrevealed: + html: מנהלות האוסף %{collection_link} הפכו את היצירה שלך %{work_link} ליצירה + שטרם נחשפה. + text: מנהלות האוסף "%{collection_title}" (%{collection_url}) הפכו את היצירה + שלך "%{work_title}" (%{work_url}) ליצירה שטרם נחשפה. + collection_items_link_text: דף ה-Approved Collection Items (יצירות מאושרות באוספים) + do_not_want: + anonymous: + html: אם אין ברצונך שהיצירה תהייה אנונימית, יש לבקר ב %{collection_items_link} + שלך כדי להסיר את היצירה מאוסף זה. + text: 'אם אין ברצונך שהיצירה שלך תהפוך לאנונימית, יש לבקר בדף Approved Collection + Items (יצירות מאושרות באוספים) שלך כדי להסיר אותה מאוסף זה: %{collection_items_url}' + anonymous_unrevealed: + html: אם אין ברצונך שהיצירה שלך תהיה אנונימית ורשומה כיצירה שטרם נחשפה, + יש לבקר ב%{collection_items_link} שלך כדי להסיר אותה מאוסף זה. + text: 'אם אין ברצונך שהיצירה שלך תהיה אנונימית ורשומה כיצירה שטרם נחשפה, + יש לבקר בדף Approved Collection Items (יצירות מאושרות מאוספים) שלך כדי + להסיר אותה מאוסף זה: %{collection_items_url}' + unrevealed: + html: אם אין ברצונך שהיצירה שלך תירשם כיצירה שטרם נחשפה, יש לבקר ב%{collection_items_link} + שלך כדי להסיר אותה מאוסף זה. + text: 'אם אין ברצונך שהיצירה שלך תירשם כיצירה שטרם נחשפה, יש לבקר בדף Approved + Collection Items (יצירות מאושרות באוספים) שלך כדי להסיר אותה מאוסף זה: + %{collection_items_url}' + faq_link_text: שאלות נפוצות – אוספים + more_info: + html: למידע נוסף, בקרו בדף %{faq_link}. + text: 'למידע נוסף, אנא בקרו בדף שאלות נפוצות – אוספים: %{faq_url}' + subject: + anonymous: "[%{app_name}] היצירה שלך הפכה לאנונימית" + anonymous_unrevealed: "[%{app_name}] היצירה שלך שונתה לאנונימית, והמעמד שלה + שונה ליצירה שטרם נחשפה." + unrevealed: "[%{app_name}] מעמד היצירה שלך שונה ליצירה שטרם נחשפה" + unrevealed_info: יצירות שטרם נחשפו לא יופיעו ברשימת התגיות או בדף היצירות שלך. + שימוש בקישור לדף היצירה יוביל להודעה שהיצירה טרם נחשפה, ולא יהיה ניתן לגשת + לתוכן שלה. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (פריטים שאושרו לאוספים) + archivist_notice: כיוון שמנהלות האוסף פועלות במסגרת תפקידן כארכיונאיות של Open + Doors (דלתות פתוחות), הן רשאיות להוסיף את היצירה שלך לאוסף זה גם אם השבתת + את האפשרות להזמין אותך לאוספים. ארכיונאיות מוסיפות יצירה לאוסף רק אם היא הייתה + חלק מארכיון מיובא. + removal_instructions: + html: אם ברצונך להסיר את יצירתך מאוסף זה, עליך להיכנס לדף %{approved_items_link} + שלך. + text: 'אם ברצונך להסיר את יצירתך מאוסף זה, עליך להיכנס לדף Approved Collection + Items (פריטים שאושרו לאוספים) שלך: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] ארכיונאי/ת של Open Doors (דלתות + פתוחות) הוסיף/ה את היצירה שלך לאוסף" + work_added: + html: מנהלות האוסף %{collection_link} הוסיפו את היצירה שלך %{work_link} לאוסף! + text: מנהלות האוסף "%{collection_title}" (%{collection_url}) הוסיפו את היצירה + שלך "%{work_title}" (%{work_url}) לאוסף! + challenge_assignment_notification: + any: הכול + assignment: + html: קיבלת את הבקשה הבאה באתגר %{link} בארכיון משלנו! + description: 'תיאור:' + due: 'תאריך ההגשה של המשימה:' + html: + footer: קיבלת דוא"ל זה כיוון שנרשמת לאתגר %{title}. מידע נוסף על אתגר זה ופרטי + יצירת קשר עם המנהלות שלו זמינים ב%{footer_link}. + footer_link: עמוד הפרופיל של האתגר + look_up: ניתן למצוא משימה זו ב%{link}. + look_up_link: עמוד ה-Assignments (משימות) שלך + optional_tags: 'תגיות אפשריות:' + prompts: 'פרומפטים:' + prompt_url: 'כתובת האתר (URL) של הפרומפט:' + recipient: 'מקבלת:' + recipient_missing: 'ללא: יש לפנות למנהלת האתגר לקבלת סיוע!' + subject: "[%{app_name}][%{collection_title}] המשימה שלך!" + text: + assignment: קיבלת את הבקשה הבאה באתגר "%{collection_title}" (%{collection_url}) + בארכיון משלנו! + footer: קיבלת דוא"ל זה כיוון שנרשמת לאתגר %{title} (%{url}). מידע נוסף על + אתגר זה ופרטי יצירת קשר עם המנהלות שלו זמינים בכתובת %{profile_url}. + look_up: ניתן למצוא משימה זו בעמוד ה-Assignments (משימות) שלך בכתובת %{link}. + change_email: + changed: + html: '%{login}, כתובת הדוא"ל המשויכת לחשבונך שונתה ל-%{email}' + text: '%{login}, כתובת הדוא"ל המשויכת לחשבונך שונתה ל-%{email}' + subject: '[%{app_name}] כתובת הדוא"ל שלך שונתה' + collection_notification: + assignments_sent: + complete: כל המטלות נשלחו כעת. + subject: המטלות נשלחו + html: + received_message: 'קיבלת הודעה לגבי האוסף שלך %{collection_link}:' + text: + received_message: 'קיבלת הודעה לגבי האוסף שלך "%{collection_title}" (%{collection_url}):' + creatorship_notification: + explanation: כיוצר/ת שותף/ה ליצירה, ניתן להוסיפך לפרקים חדשים, ללא תלות בהגדרות + היוצר/ת השותף/ה שלך. כמו כן, תוסף/י לכל סדרה אליה תתווסף היצירה. + html: + creation: "%{creation_link} מאת %{pseud_links}" + edit_chapter: לערוך את הפרק + edit_series: לערוך את הסדרה + remove_chapter: אם הוספת בטעות, או שאינך רוצה להיות רשום/ה כיוצר/ת, באפשרותך + %{edit_chapter_link} על מנת להסיר את עצמך כיוצר/ת. + remove_series: אם הוספת בטעות, או שאינך רוצה להיות רשום/ה כיוצר/ת, באפשרותך + %{edit_series_link} על מנת להסיר את עצמך כיוצר/ת. + intro_chapter: 'המשתמש/ת %{adding_user} רשם/ה את שם העט שלך %{pseud} כיוצר/ת + שותף/ה לפרק הבא:' + intro_series: 'המשתמש/ת %{adding_user} רשם/ה את שם העט שלך %{pseud} כיוצר/ת + שותף/ה לסדרה הבאה:' + subject: "[%{app_name}] התראת יוצר/ת שותף/ה" + text: + creation: "%{title} (%{url}) מאת %{pseuds}" + remove_chapter: 'אם הוספת בטעות, או שאינך רוצה להיות רשום/ה כיוצר/ת, באפשרותך + לערוך את הפרק על מנת להסיר את עצמך כיוצר/ת: %{url}' + remove_series: 'אם הוספת בטעות, או שאינך רוצה להיות רשום/ה כיוצר/ת, באפשרותך + לערוך את הסדרה על מנת להסיר את עצמך כיוצר/ת: %{url}' + creatorship_notification_archivist: + explanation: כיוון שהארכיונאית פועלת במסגרת תפקידה במיזם Open Doors (דלתות פתוחות), + יש ביכולתה לשייך את שם העט שלך ללא שליחת בקשה, גם אם ביטלת את האפשרות להגדירך + כיוצר/ת שותף/ה. + html: + creation: "%{creation_link} מאת %{pseud_links}" + edit_chapter: לערוך את הפרק + edit_series: לערוך את הסדרה + edit_work: לערוך את היצירה + remove_chapter: אם נוספות בטעות, או אם אינך רוצה להופיע כיוצר/ת, באפשרותך + %{edit_chapter_link} על מנת להסיר את עצמך. + remove_series: אם נוספות בטעות, או אם אינך רוצה להופיע כיוצר/ת, באפשרותך %{edit_series_link} + על מנת להסיר את עצמך. + remove_work: אם נוספות בטעות, או אם אינך רוצה להופיע כיוצר/ת, באפשרותך %{edit_work_link} + על מנת להסיר את עצמך. + intro_chapter: 'המשתמשת %{archivist} הוסיפה את שם העט שלך %{pseud} בתור יוצר/ת + שותף/ה של הפרק הבא:' + intro_series: 'המשתמשת %{archivist} הוסיפה את שם העט שלך %{pseud} בתור יוצר/ת + שותף/ה של הסדרה הבאה:' + intro_work: 'המשתמשת %{archivist} הוסיפה את שם העט שלך %{pseud} בתור יוצר/ת + שותף/ה של היצירה הבאה:' + subject: "[%{app_name}] התראה על הוספתך כיוצר/ת שותף/ה על ידי ארכיונאית" + text: + creation: "%{title} (%{url}) מאת %{pseuds}" + remove_chapter: 'אם נוספות בטעות, או אם אינך רוצה להופיע כיוצר/ת, באפשרותך + לערוך את הפרק על מנת להסיר את עצמך: %{url}' + remove_series: 'אם נוספות בטעות, או אם אינך רוצה להופיע כיוצר/ת, באפשרותך + לערוך את הסדרה על מנת להסיר את עצמך: %{url}' + remove_work: 'אם נוספת בטעות, או אם אינך רוצה להופיע כיוצר/ת, באפשרותך לערוך + את היצירה על מנת להסיר את עצמך: %{url}' + creatorship_request: + html: + creation: "%{creation_link} מאת %{pseud_links}" + instructions: את ההזמנה ניתן לקבל או לדחות בדף %{page_name} שלך. + page_name: Co-Creator Requests (בקשות להוספת יוצר/ת שותף/ה) + intro_chapter: 'המשתמש/ת %{inviting_user} הזמין/ה את שם העט שלך %{pseud} להירשם + כיוצר/ת שותף/ה של הפרק:' + intro_series: 'המשתמש/ת %{inviting_user} הזמין/ה את שם העט שלך %{pseud} להירשם + כיוצר/ת שותף/ה של הסדרה:' + intro_work: 'המשתמש/ת %{inviting_user} הזמין/ה את שם העט שלך %{pseud} להירשם + כיוצר/ת שותף/ה של היצירה:' + subject: "[%{app_name}] בקשה להוספתך כיוצר/ת שותף/ה" + text: + creation: "%{title} (%{url}) מאת %{pseuds}" + instructions: 'את ההזמנה ניתן לקבל או לדחות בדף Co-Creator Requests (בקשות + להוספת יוצר/ת שותף/ה) שלך: %{url}' + delete_work_notification: + attachment: לנוחיותך, מצורף בזאת עותק של יצירתך. + deleted_other: + html: יצירתך %{title} נמחקה לבקשת %{pseud}. + text: יצירתך "%{title}" נמחקה לבקשת %{pseud}. + deleted_yourself: + html: יצירתך %{title} נמחקה על פי בקשתך. + text: יצירתך "%{title}" נמחקה על פי בקשתך. + questions: + html: אם יש לך שאלות, אנא %{support} + text: אם יש לך שאלות, אנא %{support} (%{url}). + subject: "[%{app_name}] יצירתך נמחקה" + support: פנו לצוות התמיכה + invite_increase_notification: + html: + body: + many: רק רצינו ליידע אותך שקיבלת %{count} הזמנות חדשות, בהן ניתן להשתמש + על מנת ליצור חשבון חדש בארכיון. באפשרותך להזמין חבר/ה דרך %{invitation_page_link}. + one: רק רצינו ליידע אותך שקיבלת הזמנה חדשה, בה ניתן להשתמש על מנת ליצור + חשבון חדש בארכיון. באפשרותך להזמין חבר/ה דרך %{invitation_page_link}. + other: רק רצינו ליידע אותך שקיבלת %{count} הזמנות חדשות, בהן ניתן להשתמש + על מנת ליצור חשבון חדש בארכיון. באפשרותך להזמין חבר/ה דרך %{invitation_page_link}. + two: רק רצינו ליידע אותך שקיבלת %{count} הזמנות חדשות, בהן ניתן להשתמש על + מנת ליצור חשבון חדש בארכיון. באפשרותך להזמין חבר/ה דרך %{invitation_page_link}. + invitation_page_link_text: דף ההזמנות שלך + subject: "[%{app_name}] הזמנות חדשות" + text: + body: + many: רק רצינו ליידע אותך שקיבלת %{count} הזמנות חדשות, בהן ניתן להשתמש + על מנת ליצור חשבון חדש בארכיון. באפשרותך להזמין חבר/ה דרך דף Invitations + (הזמנות), %{invitation_page_url}. + one: רק רצינו ליידע אותך שקיבלת הזמנה חדשה, בה ניתן להשתמש על מנת ליצור + חשבון חדש בארכיון. באפשרותך להזמין חבר/ה דרך דף Invitations (הזמנות), + %{invitation_page_url}. + other: רק רצינו ליידע אותך שקיבלת %{count} הזמנות חדשות, בהן ניתן להשתמש + על מנת ליצור חשבון חדש בארכיון. באפשרותך להזמין חבר/ה דרך דף Invitations + (הזמנות), %{invitation_page_url}. + two: רק רצינו ליידע אותך שקיבלת %{count} הזמנות חדשות, בהן ניתן להשתמש על + מנת ליצור חשבון חדש בארכיון. באפשרותך להזמין חבר/ה דרך דף Invitations + (הזמנות), %{invitation_page_url}. + invite_request_declined: + main: + many: צר לנו לבשר לך כי אין באפשרותנו להיענות לבקשתך ל-%{count} הזמנות חדשות + כעת. + one: צר לנו לבשר לך כי אין באפשרותנו להיענות לבקשתך להזמנה חדשה כעת. + other: צר לנו לבשר לך כי אין באפשרותנו להיענות לבקשתך ל-%{count} הזמנות חדשות + כעת. + two: צר לנו לבשר לך כי אין באפשרותנו להיענות לבקשתך ל-%{count} הזמנות חדשות + כעת. + reason: 'תוכן בקשתך:' + subject: "[%{app_name}] בקשתך לקוד הזמנה נוסף נדחתה" + recipient_notification: + html: + collection: יצירה הוקדשה לך במתנה באוסף %{collection_link} ב-AO3! + no_collection: יצירה הוקדשה לך במתנה ב-AO3! + subject: + collection: "[%{app_name}][%{collection_title}] קיבלת יצירה במתנה מ- %{collection_title}" + no_collection: "[%{app_name}] קיבלת יצירה במתנה" + text: + collection: יצירה הוקדשה לך במתנה באוסף "%{collection_title}" (%{collection_url}) + ב-AO3! + signup_notification: + activate: + html: אנא %{activate_account_link}. + text: 'אנא לחץ/י על קישור זה כדי להפעיל את חשבונך: %{activate_account_url}' + activate_your_account: לחץ/י על קישור זה כדי להפעיל את חשבונך + admin_posts: חדשות AO3 + bye: כולנו תקווה שתהנה/י מהשימוש באתר. + contact_support: צרו קשר עם התמיכה + faq: שאלות נפוצות + features: + html: ברגע שחשבונך יופעל, תוכל/י לפרסם יצירות, להגדיר רישומים לקבלת עדכונים + בדוא"ל כדי לקבל הודעה כאשר חשבונות או יצירות מועדפים מתעדכנים, להגדיר + העדפות כדי להתאים באופן אישי את אופן ההצגה של האתר, לעקוב אחר היצירות אליהן + ניגשת בעבר באמצעות ההיסטוריה, ודברים רבים נוספים. + text: ברגע שחשבונך יופעל, תוכל/י לפרסם יצירות, להגדיר רישומים לקבלת עדכונים + בדוא"ל כדי לקבל הודעה כאשר חשבונות או יצירות מועדפים מתעדכנים, להגדיר + העדפות כדי להתאים באופן אישי את אופן ההצגה של האתר, לעקוב אחר היצירות אליהן + ניגשת בעבר באמצעות ההיסטוריה, ודברים רבים נוספים. + information: + html: מידע ועצות בנוגע לשימוש בארכיון זמינים ב%{faq_link}. את החדשות האחרונות + אודות פיתוח האתר ניתן למצוא ב%{admin_posts_link}. אם דרושה לך עזרה נוספת, + אם נתקלת בבעייה באתר או אם יש לך שאלות או הערות, אנא %{contact_support_link}, + שתמיד שמח לעזור. + text: 'מידע ועצות בנוגע לשימוש בארכיון זמינים בשאלות הנפוצות שלנו ב-%{faq_url}. + את החדשות האחרונות אודות פיתוח האתר ניתן למצוא בחדשות AO3 %{admin_posts_url}. + אם דרושה לך עזרה נוספת, אם נתקלת בבעייה באתר או אם יש לך שאלות או הערות, + אנא צור/צרי קשר עם צוות התמיכה שלנו, שתמיד שמח לעזור: %{contact_support_url}' + welcome: ברוכים הבאים לארכיון משלנו, %{login}! diff --git a/config/locales/phrase-exports/hi.yml b/config/locales/phrase-exports/hi.yml new file mode 100755 index 0000000..0e37e95 --- /dev/null +++ b/config/locales/phrase-exports/hi.yml @@ -0,0 +1,532 @@ +--- +hi: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'चेतावनी:' + other: 'चेतावनियाँ:' + category: + name_with_colon: + one: 'वर्ग:' + other: 'वर्ग:' + character: + name_with_colon: + one: 'पात्र:' + other: 'पात्र:' + fandom: + name_with_colon: + one: 'प्रशंसक समूह:' + other: 'प्रशंसक समूह:' + freeform: + name_with_colon: + one: 'अतिरिक्त टैग:' + other: 'अतिरिक्त टैग्स:' + rating: + name_with_colon: 'रेटिंग:' + relationship: + name_with_colon: + one: 'संबंध:' + other: 'संबंध:' + work: + chapter_total_display: अध्याय + summary: सारांश + models: + archive_warning: + one: चेतावनी + other: चेतावनियाँ + category: + one: वर्ग + other: वर्ग + chapter: + one: अध्याय + other: अध्याय + character: + one: पात्र + other: पात्र + fandom: + one: प्रशंसक समूह + other: प्रशंसक समूह + freeform: + one: अतिरिक्त टैग + other: अतिरिक्त टैग्स + rating: + one: रेटिंग + other: रेटिंग्स + relationship: + one: संबंध + other: संबंध + series: + one: श्रृंखला + other: श्रृंखला + kudo_mailer: + batch_kudo_notification: + guest: + one: अतिथि + other: "%{count} अतिथिगण" + left_kudos: + html: + one: "%{givers_list} ने %{commentable_link} पर कुङोस दिया है।" + other: "%{givers_list} ने %{commentable_link} पर कुङोस दिए हैं।" + text: + one: "%{givers_list} ने %{commentable_title} (%{commentable_url}) पर कुङोस + दिया है।" + other: "%{givers_list} ने %{commentable_title} (%{commentable_url}) पर कुङोस + दिए हैं।" + single_guest: + giver: एक अतिथि + html: "%{giver} ने %{commentable_link} पर कुङोस दिया है।" + text: एक अतिथि ने %{commentable_title} (%{commentable_url}) पर कुङोस दिया + है। + subject: "[%{app_name}] आपको कुङोस मिला हैं!" + mailer: + general: + closing: + formal: निष्ठा से, + informal: उत्तम, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: अध्याय %{position} का %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} शब्द" + other: "%{count} शब्द" + footer: + about: + html: AO3 एक प्रशंसकों द्वारा संचालित और फैन-समर्थित संग्रह है जो %{your_donations_link} पर निर्भर करता है। + text: 'AO3 एक प्रशंसकों द्वारा संचालित और फैन-समर्थित संग्रह है जो आपके दान: %{your_donations_url} पर निर्भर करता है।' + your_donations: आपके दान + sent_at: "%{sent_at} पर भेजा गया।" + why_policy_abuse: + contact_policy_abuse: नीति और दुरुपयोग से संपर्क करें। + html: यदि आपको नही समझ रहा है कि आपको यह ईमेल क्यों भेजा गया है, तो कृपया नीति और दुरुपयोग से संपर्क करें %{contact_policy_abuse_link}। + text: यदि आपको नही समझ रहा है कि आपको यह ईमेल क्यों भेजा गया है, तो कृपया नीति और दुरुपयोग से संपर्क करें %{contact_policy_abuse_url}। + why_support: + contact_support: सहायता से सम्पर्क करें + html: यदि आपको नही समझ रहा है कि आपको यह ईमेल क्यों भेजा गया है, तो कृपया सहायता से संपर्क करें %{contact_support_link}। + text: यदि आपको नही समझ रहा है कि आपको यह ईमेल क्यों भेजा गया है, तो कृपया सहायता से संपर्क करें %{contact_support_url}। + greeting: + formal: + addressed_html: नमस्कार %{name}, + unaddressed: नमस्कार! + informal: + addressed_html: नमस्कार, %{name}! + unaddressed: नमस्कार! + introductory: Archive of Our Own AO3 (हमारा अपना संग्रह) – से नमस्कार! + metadata_label_indicator: ":" + signature: + abuse_team: AO3 नीति और दुरुपयोग समिति + app_short_name: AO3 + open_doors: Open Doors (खुले दरवाज़े) समिति + parent_org: Organization for Transformative Works – OTW (परिवर्तनकारी कार्य हेतु संगठन) + support: AO3 सहायता समिति + users: + mailer: + reset_password_instructions: + expiration: अगर आप इस लिंक को एक हफ्ते में आपने पासवर्ड को बदलने के लिए इस्तेमाल + नहीं करेंगे, तो उसकि समय सीमा समाप्त हो जाएगी और आपको नयी लिंक मांगनी होगी। + intro: किसी ने आपके खाते के पासवर्ड को रिसेट करने का अनुरोध किया है। आप अपने + खाते के पासवर्ड को दी हुई लिंक पे जाकर, नया पासवर्ड ङालकर बदल सकते हैं। + link_title: मेरे पासवर्ड कि बदली। + subject: "[%{app_name}] पासवर्ड को रीसेट करें।" + unrequested: अगर आपने इस पासवर्ड रिसेट का अनुरोध नहीं किया है, आप इस ईमेल + को नज़रअंदाज़ कर सकते हैं और आपका पुराना पासवर्ड चलता रहेगा। + user_mailer: + admin_deleted_work_notification: + bye: आपके संदर्भ के लिए आपके कार्य की एक कॉपी जोड़ी गयी है। + contact_abuse: हमारी नीति और दुरुपयोग को संपर्क कीजिये + deleted: + html: आपके कार्य %{title} को AO3 से एक साइट प्रशासक द्वारा मिटाया गया है। + text: आपका कार्य "%{title}" को एक साइट प्रशासक द्वारा मिटा दिया है। + html: + tos_violation: अगर सम्भव है की आपके कार्य ने AO3 की सेवा की शर्तों का उल्लधन + किया है, कृपया %{contact_abuse_link}। + import_project: + html: अगर आपका कार्य किसी आयात परियोजना जिसे हमारी Open Doors (खुले दरवाज़े) + टीम संभाल रही है, तो कृपया %{opendoors_link} आपके प्रश्नो के लिए। + text: अगर आपका कार्य किसी आयात परियोजना जिसे हमारी Open Doors (खुले दरवाज़े) + टीम संभाल रही है, तो कृपया खुले दरवाज़े को संपर्क कीजिये (%{opendoors_link}) + आपके प्रश्नो के लिए। + opendoors: खुले दरवाज़े को संपर्क कीजिये + subject: "[%{app_name}] आपके कार्य को एक प्रशासक द्वारा मिटा दिया गया है।" + text: + tos_violation: अगर सक्य है की आपके कार्य ने AO3 की सेवा की शर्तों का उल्लधन + किया है, कृपया हमारी नीति और दुरुपयोग को संपर्क कीजिये (%{contact_abuse_url})। + admin_hidden_work_notification: + access: जब तक आपका कार्य छुपा हुआ है, आप उसे ऊपर दी हुई लिंक से उपलब्ध कर सकेंगे, + पर वह आपके कार्य पेज पर नहीं सूचित किया जाएगा, और वह AO3 के बाकी उपयोगकर्ताओं + को उपलब्ध नहीं होगा। + check_email: कृपया आपके ईमेल को देखिये, आपके स्पैम फ़ोल्डर सहित , क्योकि शायद + नीति और दुरुपयोग टीम आपको पहले से संपर्क कर दिया होगा आपके कार्य को क्यों + छुपाया गया है वह समजाते हुए। + contact_abuse: नीति और दुरुपयोग को संपर्क + html: + help: अगर आप पक्का नहीं है आपके कार्य को क्यों छुपाया गया था, और आपको इस मामले + सम्बंधित और कोई संपर्क नहीं मिला है, कृपया सीधे %{contact_abuse_link} कीजिये। + hidden: आपके कार्य %{title} को नीति और दुरुपयोग टीम के द्वारा छुपाया गया है + और अब वह सार्वजनिक रूप से सुलभ अब नहीं है। + tos_violation: अगर आपके कार्य को छुपाया गया था क्योंकि वह AO3 की %{tos_link} + का उल्लंघन कर रहा है, तो आपको कार्रवाई करनी होगी उल्लंधन को सही करने के + लिए। आपके कार्य को सेवा की शर्तों के अनुपालन में लाने में असफलता आपके कार्य + को AO3 से हटा सकती है। + subject: "[%{app_name}] आपके कार्य को नीति और दुरुपयोग टीम के द्वारा छुपाया + गया है।" + text: + help: 'अगर आप पक्का नहीं है आपके कार्य को क्यों छुपाया गया था, और आपको इस + मामले सम्बंधित और कोई संपर्क नहीं मिला है, कृपया सीधे नीति और दुरुपयोग को + संपर्क कीजिये: %{contact_abuse_url}।' + hidden: आपके कार्य "%{title}" (%{work_url}) को नीति और दुरुपयोग टीम के द्वारा + छुपाया गया है और वह अब सार्वजनिक रूप से सुलभ नहीं है। + tos_violation: अगर आपके कार्य को छुपाया गया था क्योंकि वह AO3 की सेवा की शर्तें + (%{tos_url}) का उल्लंघन कर रहा है, तो आपको कार्रवाई करनी होगी उल्लंधन को + सही करने के लिए। आपके कार्य को सेवा की शर्तों के अनुपालन में लाने में असफलता + आपके कार्य को AO3 से हटा सकती है। + tos: सेवा की शर्तें + anonymous_or_unrevealed_notification: + anonymous_info: अज्ञात कार्य हमरे टैग सूचीकरण में शामिल होते है पर आप के कार्य + पेज पर नहीं। कार्य पर आपका उपयोगकर्ता नाम को "Anonymous" (अज्ञात) के साथ बदला + जाएगा। + anonymous_unrevealed_info: संग्रह की देखरेख करने वाले लोग आपके कार्य को शायद + प्रकाशित करे पर उसे अज्ञात रखे। जिन लोगों ने आपको सब्सक्राइब किया हैं उन्हें + इस बदलाव के बारे में सुचना नहीं मिलेगी। प्रकाशित हुए बाद आपका टैग सूचियों + में शामिल हो जाएगा, पर आपके कार्य पेज पर नहीं। कार्य पर आपका उपयोगकर्ता नाम + को "Anonymous" (अज्ञात) के साथ बदला जाएगा। + changed_status: + anonymous: + html: जो लोग %{collection_link} संग्रह की देखरेख करते हैं उन्होंने आपके + %{work_link} कार्य की अवस्था को अज्ञात स्थिति में बदल दिया है । + text: जो लोग “%{collection_title}” संग्रह (%{collection_url}) की देखरेख + करते हैं उन्होंने आपके “%{work_title}” (%{work_url}) कार्य की अवस्था को + अज्ञात स्थिति में बदल दिया है । + anonymous_unrevealed: + html: जो लोग %{collection_link} संग्रह की देखरेख करते हैं उन्होंने आपके + %{work_link} कार्य की अवस्था को अज्ञात और अप्रकाशित स्थिति में बदल दिया + है । + text: जो लोग "%{collection_title}" (%{collection_url}) संग्रह की देखरेख + करते हैं उन्होंने आपके "%{work_title}" (%{work_url}) कार्य की अवस्था को + अज्ञात और अप्रकाशित स्थिति में बदल दिया है । + unrevealed: + html: जो लोग %{collection_link} संग्रह की देखरेख करते हैं उन्होंने आपके + %{work_link} कार्य की अवस्था को अप्रकाशित स्थिति में बदल दिया है । + text: जो लोग "%{collection_title}" (%{collection_url}) संग्रह की देखरेख + करते हैं उन्होंने आपके "%{work_title}" (%{work_url}) कार्य की अवस्था को + अप्रकाशित स्थिति में बदल दिया है । + collection_items_link_text: Approved Collection Items (स्वीकृत संग्रह वस्तु) + पेज। + do_not_want: + anonymous: + html: अगर आप आपके कार्य को अज्ञात करना नहीं चाहते है, कृपया %{collection_items_link} + पर जाइये कार्य को संग्रह से निकालने के लिए। + text: अगर आप आपके कार्य को अज्ञात करना नहीं चाहते है, कृपया Approved Collection + Items (स्वीकृत संग्रह वस्तु) पेज पर जाइये कार्य को इस संग्रह (%{collection_items_url}) + से निकालने के लिए। + anonymous_unrevealed: + html: अगर आप आपके कार्य को अज्ञात और अप्रकाशित करना नहीं चाहते है, कृपया + %{collection_items_link} पर जाइये आपके कार्य को संग्रह से निकालने के लिए। + text: अगर आप आपके कार्य को अज्ञात और अप्रकाशित करना नहीं चाहते है, कृपया + Approved Collection Items (स्वीकृत संग्रह वस्तु) पेज पर जाइये कार्य को + इस संग्रह (%{collection_items_url}) से निकालने के लिए। + unrevealed: + html: अगर आप आपके कार्य को अप्रकाशित करना नहीं चाहते है, कृपया %{collection_items_link} + पर जाइये आपके कार्य को संग्रह से निकालने के लिए। + text: अगर आप आपके कार्य को अप्रकाशित करना नहीं चाहते है, कृपया Approved + Collection Items (स्वीकृत संग्रह वस्तु) पेज पर जाइये कार्य को इस संग्रह + (%{collection_items_url}) से निकालने के लिए। + faq_link_text: संग्रह FAQ + more_info: + html: अधिक जानकारी के लिए, कृपया हमारे %{faq_link} को देखिये। + text: 'ज्यादा जानकारी के लिए, कृपया हमारे संग्रह FAQ: %{faq_url} को देखिये।' + subject: + anonymous: "[%{app_name}] आपके कार्य को अज्ञात किया गया हैं।" + anonymous_unrevealed: "[%{app_name}] आपके कार्य को अज्ञात और अप्रकाशित किया + गया हैं।" + unrevealed: "[%{app_name}] आपके कार्य को अप्रकाशित किया गया हैं।" + unrevealed_info: अप्रकाशित कार्य हमरे टैग सूचीकरण में या आप के कार्य पेज पर + शामिल नहीं होते है। जो भी आपके कार्य तक एक लिंक से आएँगे, उन्हें एक सूचना + मिलेगी की वह अभी अप्रकाशित है और वह उसके अंदर के विषय को अभिगम नहीं कर पाएंगे। + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (स्वीकृत संग्रह वस्तुएँ)' + पृष्ठ + archivist_notice: क्योंकि संग्रह अनुरक्षक अपने Open Doors (खुले दरवाज़े) संग्राहकों + के पद पर अपनी आधिकारिक क्षमता में कार्य कर रहे हैं, उन्हें आपके कार्य को इस + संग्रह में जोड़ने की अनुमति है, यद्यपि आपने संग्रह आमंत्रण अक्षम किए हों। + संग्राहक एक कार्य को केवल तब संग्रह में जोड़ेंगे यदि उसे एक आयातित संग्रह + पर होस्ट किया गया था। + removal_instructions: + html: अगर आप अपना कार्य इस संग्रह से हटाना चाहते हैं, कृपया अपने %{approved_items_link} + पर जाएँ। + text: 'अगर आप अपना कार्य इस संग्रह से हटाना चाहते हैं, कृपया अपने Approved + Collection Items (स्वीकृत संग्रह वस्तुएँ) पृष्ठ पर जाएँ: %{approved_items_url}।' + subject: "[%{app_name}][%{collection_title}] एक Open Doors (खुले दरवाज़े) संग्राहक + ने आपके कार्य को एक संग्रह में जोड़ा है।" + work_added: + html: "%{collection_link} के संग्रह अनुरक्षकों ने आपका कार्य %{work_link} + अपने संग्रह में जोड़ा है!" + text: '"%{collection_title}" (%{collection_url}) के संग्रह अनुरक्षकों ने आपका + कार्य "%{work_title}" (%{work_url}) अपने संग्रह में जोड़ा है!' + challenge_assignment_notification: + any: कोई भी + assignment: + html: आपको AO3 पर %{link} चुनौती में निम्नलिखित अनुरोध सौंपा गया है! + description: 'विवरण:' + due: 'यह कार्यभार देय है:' + html: + footer: आपको यह ईमेल इसलिए मिल रहा है क्योंकि आपने %{title} चुनौती के लिए + साइन-अप किया है। इस चुनौती के बारे में अधिक जानकारी और मंदकों की संपर्क + जानकारी के लिए, कृपया %{footer_link} पर जाएँ। + footer_link: चुनौती प्रोफ़ाइल पृष्ठ + look_up: आप इस कार्यभार को %{link} पर देख सकते हैं। + look_up_link: आपका Assignments (कार्यभार) पृष्ठ + optional_tags: 'वैकल्पिक टैग:' + prompts: 'प्रॉम्प्ट:' + prompt_url: 'प्रॉम्प्ट URL:' + recipient: 'प्राप्तकर्ता:' + recipient_missing: 'कोई नहीं: मदद के लिए मंदक से संपर्क करें!' + subject: "[%{app_name}][%{collection_title}] आपका कार्यभार!" + text: + assignment: आपको AO3 पर "%{collection_title}" (%{collection_url}) चुनौती में + निम्नलिखित अनुरोध सौंपा गया है! + footer: आपको यह ईमेल इसलिए मिल रहा है क्योंकि आपने %{title} चुनौती (%{url}) + के लिए साइन-अप किया है। इस चुनौती के बारे में अधिक जानकारी और मंदकों के + संपर्क की जानकारी के लिए, कृपया %{profile_url} पर जाएँ। + look_up: आप इस कार्यभार को %{link} पर आपके Assignments (कार्यभार) पृष्ठ से + देख सकते हैं। + change_email: + changed: + html: "%{login}, आपके खाते से संबंधित ईमेल को %{email} से बदल दिया गया है।" + text: "%{login}, आपके खाते से संबंधित ईमेल को %{email} से बदल दिया गया है।" + subject: "[%{app_name}] ईमेल में बदलाव" + claim_notification: + access: + contact_support: AO3 सहायता से सम्पर्क करें + html: संग्रह के आधार पर, हो सकता है कि आपके कार्यों को केवल पंजीकृत उपयोगकर्ताओं + तक ही सीमित रखा गया हो (उन्हें Google खोजों से बाहर रखने के लिए)। यदि यह + मामला है, तो कार्य केवल लॉग-इन उपयोगकर्ताओं द्वारा ही पहुंच योग्य होंगे + जब तक कि आप उन्हें पूरी तरह से दृश्यमान बनाना नहीं चुनते। अपने कार्यों को + अनलॉक करने, अनाथ करने या हटाने में सहायता के लिए, कृपया %{contact_support_link}। + text: संग्रह के आधार पर, हो सकता है कि आपके कार्यों को केवल पंजीकृत उपयोगकर्ताओं + तक ही सीमित रखा गया हो (उन्हें Google खोजों से बाहर रखने के लिए)। यदि यह + मामला है, तो कार्य केवल लॉग-इन उपयोगकर्ताओं द्वारा ही पहुंच योग्य होंगे + जब तक कि आप उन्हें पूरी तरह से दृश्यमान बनाना नहीं चुनते। अपने कार्यों को + अनलॉक करने, अनाथ करने या हटाने में सहायता के लिए, कृपया %{support_url} पर + AO3 सहायता से संपर्क करें। + email_tips: यदि आप हमसे संपर्क कर रहे हैं, तो कृपया अपने सुरक्षित संपर्कों की + सूची में @transformativeworks.org से ईमेल पते जोड़ें और हमारे उत्तर के लिए + अपने स्पैम फ़ोल्डर्स की जांच करें। + introduction: + ao3_name: Archive of Our Own – AO3 (हमारा अपना संग्रह) + html: आपको यह ई-मेल इसलिए प्राप्त हो रहा है क्योंकि आपके पास एक फैनवर्क्स + संग्रह में काम था जिसे %{open_doors_name_link} द्वारा %{app_link} में आयात + किया गया है। क्योंकि यह ई-मेल पता आयातित संग्रह पर पंजीकृत पते से जुड़ा + हुआ है, संबंधित फैनवर्क्स (नीचे सूचीबद्ध) स्वचालित रूप से आपके AO3 खाते + में जोड़ दिए गए हैं। + open_doors_name: Open Doors (खुले दरवाज़े) + text: 'आपको यह ई-मेल इसलिए प्राप्त हो रहा है क्योंकि आपके पास एक फैनवर्क्स + संग्रह में काम था जिसे Open Doors (खुले दरवाज़े)(%{open_doors_url}) द्वारा + Archive of Our Own – AO3 (हमरा अपना संग्रह): %{app_url} में आयात किया गया + है। क्योंकि यह ई-मेल पता आयातित संग्रह पर पंजीकृत पते से जुड़ा हुआ है, संबंधित + फैनवर्क्स (नीचे सूचीबद्ध) स्वचालित रूप से आपके AO3 खाते में जोड़ दिए गए + हैं।' + mistake: + contact_open_doors: खुले दरवाज़े से सम्पर्क करें + html: यदि यह एक गलती है और ये आपके कार्य नहीं हैं, तो कृपया इन्हें न हटाएं! + कृपया केवल %{contact_open_doors_link} और हम इसे सुलझा लेंगे। + text: यदि यह एक गलती है और ये आपके कार्य नहीं हैं, तो कृपया इन्हें न हटाएं! + कृपया केवल खुले दरवाज़े से सम्पर्क करें (%{open_doors_url}) और हम इसे सुलझा + लेंगे। + more_info: + ao3_news: AO3 न्यूज़ + contact_support: AO3 सहायता से सम्पर्क करें + faq_page: FAQ (अक्सर पूछे जाने वाले प्रश्न) पृष्ठ + html: आप %{ao3_news_link} पर हालिया संग्रह चालों के बारे में घोषणाएं पढ़ सकते + हैं, और खुले दरवाज़े के %{faq_page_link} या %{tutorial_page_link} पर अतिरिक्त + जानकारी पा सकते हैं। ऐसे किसी भी प्रश्न के लिए जिसका उत्तर FAQ, ट्यूटोरियल + या इस ई-मेल में नहीं दिया गया है, कृपया %{contact_support_link}। + text: आप AO3 न्यूज़ (%{news_url}) पर हालिया संग्रह चालों के बारे में घोषणाएँ + पढ़ सकते हैं, और खुले दरवाज़े के FAQ पेज (%{open_doors_faq_url}) या ट्यूटोरियल + पेज (%{open_doors_tutorial_url}) पर अतिरिक्त जानकारी पा सकते हैं। FAQ, ट्यूटोरियल + या इस ई-मेल में उत्तर न दिए गए किसी भी प्रश्न के लिए, कृपया %{support_url} + पर सहायता से संपर्क करें। + tutorial_page: ट्यूटोरियल पृष्ठ + other_works: + contact_open_doors: खुले दरवाज़े से सम्पर्क करें + html: यदि आपके पास किसी ई-मेल पते के तहत आयातित संग्रह पर अन्य कार्य हैं, + जिन्हें आप अब एक्सेस नहीं कर सकते हैं, तो कृपया %{contact_open_doors_link} + किसी भी जानकारी के साथ जो आपकी पहचान को सत्यापित करने में मदद कर सके। + text: यदि आपके पास किसी ई-मेल पते के तहत आयातित संग्रह पर अन्य कार्य हैं, + जिन्हें आप अब एक्सेस नहीं कर सकते हैं, तो कृपया किसी भी जानकारी के लिए खुले + दरवाज़े से संपर्क करें किसी भी जानकारी के साथ जो आपकी पहचान को सत्यापित करने + में मदद कर सकती है। + questions: + contact_support: AO3 सहायता से सम्पर्क करें + html: अन्य पूछताछ के लिए, कृपया %{contact_support_link} + text: अन्य पूछताछ के लिए, कृपया %{support_url} पर AO3 सहायता से संपर्क करें। + redirects: + html: रेक सूचियों और बुकमार्क को संरक्षित करने के लिए, आयातित संग्रह के वेब + पते सीमित समय के लिए इन कार्यों की आयातित प्रतिलिपि पर रीडायरेक्ट कर सकते + हैं (सुनिश्चित करने के लिए अपने संग्रह के लिए घोषणा पोस्ट की जांच करें)। + यदि आपने पहले ही इन कार्यों की एक प्रति अपलोड कर दी है और आपने यूआरएल से + आयात सुविधा का %{negation} उपयोग किया है, तो AO3 पर एक ही कार्य की दो प्रतियां + होंगी। + subject: "[%{app_name}] अपलोड किए गए कार्य" + update_redirect: + contact_open_doors: खुले दरवाज़े से सम्पर्क करें + html: 'यदि आप चाहते हैं कि खुले दरवाज़े आपके पहले से मौजूद कार्य को इंगित करने + के लिए पुन: निर्देशित को अद्यतन करे, तो कृपया आयातित प्रतिलिपि हटा दें, + और %{contact_open_doors_link} अपने AO3 खाते के नाम के साथ, आयातित संग्रह + पर अपने खाते का नाम, और उस फैनवर्क का शीर्षक और URL जिस पर आप पुन: निर्देशित + करना चाहेंगे। (यदि आपके पास कई कार्य हैं जिनके लिए आप पुन: निर्देश बदलना + चाहेंगे, तो आप उन्हें एक ईमेल में सूचीबद्ध कर सकते हैं।)' + text: 'यदि आप चाहते हैं कि खुले दरवाज़े आपके पहले से मौजूद काम को इंगित करने + के लिए पुन: निर्देशित को अद्यतन करे, तो कृपया आयातित प्रतिलिपि हटा दें, + और %{open_doors_url} अपने AO3 खाते के नाम के साथ, आयातित संग्रह पर अपने + खाते का नाम, और उस फैनवर्क का शीर्षक और URL जिस पर आप पुन: निर्देशित करना + चाहेंगे। (यदि आपके पास कई कार्य हैं जिनके लिए आप पुन: निर्देश बदलना चाहेंगे, + तो आप उन्हें एक ईमेल में सूचीबद्ध कर सकते हैं।)' + works_by: 'ये कार्य ई-मेल के अंतर्गत लिखी गईं हैं: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: अब सभी असाइनमेंट्स भेज दिए गए हैं। + subject: भेजे गए असाइनमेंट्स + html: + received_message: 'आपको अपने संग्रह के बारे में एक संदेश प्राप्त हुआ है %{collection_link}:' + text: + received_message: 'आपको अपने संग्रह के बारे में एक संदेश प्राप्त हुआ है "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: जब आप किसी काम के सह-निर्माता होते हैं, तो आपकी सह-निर्माण सेटिंग + पर ध्यान दिए बिना आपको नए अध्यायों में जोड़ा जा सकता है। आपको किसी भी श्रृंखला + में भी जोड़ा जाएगा जिसमें काम जोड़ा गया है। + html: + creation: "%{creation_link} द्वारा %{pseud_links}" + edit_chapter: अध्याय संपादित करें + edit_series: श्रृंखला संपादित करें + remove_chapter: अगर आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में + सूचीबद्ध नहीं होना चाहते हैं, तो आप खुद को निर्माता के रूप में हटाने के + लिए %{edit_chapter_link} कर सकते हैं। + remove_series: अगर आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में + सूचीबद्ध नहीं होना चाहते हैं, तो आप खुद को निर्माता के रूप में हटाने के + लिए %{edit_series_link} कर सकते हैं। + intro_chapter: 'उपयोगकर्ता %{adding_user} ने आपके छद्म %{pseud} को निम्नलिखित + अध्याय में सह-निर्माता के रूप में सूचीबद्ध किया है:' + intro_series: 'प्रयोक्ता %{adding_user} ने आपके उपनाम %{pseud} को निम्नलिखित + श्रृंखला में सह-निर्माता के रूप में सूचीबद्ध किया है:' + subject: "[%{app_name}] सह-निर्माता सूचना" + text: + creation: "%{title} (%{url}) %{pseuds} द्वारा" + remove_chapter: 'यदि आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में + सूचीबद्ध नहीं होना चाहते हैं, तो आप खुद को निर्माता के रूप में हटाने के + लिए अध्याय को संपादित कर सकते हैं: %{url}' + remove_series: 'यदि आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में + सूचीबद्ध नहीं होना चाहते हैं, तो आप खुद को निर्माता के रूप में हटाने के + लिए श्रृंखला को संपादित कर सकते हैं: %{url}' + creatorship_notification_archivist: + explanation: क्योंकि वे अपने Open Doors (खुले दरवाज़े) संग्राहकों के पद पर अपनी + आधिकारिक क्षमता में कार्य कर रहे हैं, उन्हें - बिना किसी आमंत्रण के - आपको + जोड़ने की अनुमति है, यद्यपि आपने सह-निर्माण अक्षम किए हों। + html: + creation: "%{pseud_links} द्वारा %{creation_link}" + edit_chapter: अध्याय संपादित करें + edit_series: शृंखला संपादित करें + edit_work: कार्य संपादित करें + remove_chapter: यदि आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में + सूचीबद्ध नहीं होना चाहते हैं, तो आप खुद को निर्माता के रूप से हटाने के लिए + %{edit_chapter_link} कर सकते हैं। + remove_series: यदि आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में + सूचीबद्ध नहीं होना चाहते हैं, तो आप खुद को निर्माता के रूप से हटाने के लिए + %{edit_series_link} कर सकते हैं। + remove_work: यदि आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में सूचीबद्ध + नहीं होना चाहते हैं, तो आप खुद को निर्माता के रूप में हटाने के लिए %{edit_work_link} + कर सकते हैं। + intro_chapter: 'प्रयोक्ता %{archivist} ने आपके उपनाम %{pseud} को निम्नलिखित + अध्याय में सह-निर्माता के रूप में जोड़ा है:' + intro_series: 'प्रयोक्ता %{archivist} ने आपके उपनाम %{pseud} को निम्नलिखित शृंखला + में सह-निर्माता के रूप में जोड़ा है:' + intro_work: 'प्रयोक्ता %{archivist} ने आपके उपनाम %{pseud} को निम्नलिखित कार्य + में सह-निर्माता के रूप में जोड़ा है:' + subject: "[%{app_name}] संग्राहक सह-निर्माता अधिसूचना" + text: + creation: "%{pseuds} द्वारा %{title} (%{url})" + remove_chapter: 'यदि आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में + सूचीबद्ध नहीं होना चाहते हैं, तो आप स्वयं को निर्माता के रूप से हटाने के + लिए अध्याय को संपादित कर सकते हैं: %{url}' + remove_series: 'यदि आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में + सूचीबद्ध नहीं होना चाहते हैं, तो आप स्वयं को निर्माता के रूप से हटाने के + लिए शृंखला को संपादित कर सकते हैं: %{url}' + remove_work: 'यदि आपको गलती से जोड़ा गया है या आप एक निर्माता के रूप में सूचीबद्ध + नहीं होना चाहते हैं, तो आप स्वयं को निर्माता के रूप से हटाने के लिए कार्य + संपादित कर सकते हैं: %{url}' + creatorship_request: + html: + creation: "%{creation_link} जो %{pseud_links} के द्वारा रुचित है" + instructions: आप इस अनुरोध को अपने %{page_name} पेज पर स्वीकार या इंकार कर + सकते है। + page_name: Co-Creator Requests (सह-निर्माता अनुरोध) + intro_chapter: 'उपयोगकर्ता %{inviting_user} ने आपके उपनाम %{pseud} को निम्नलिखित + अध्याय पर सह-निर्माता के रूप में सूचीबद्ध होने के लिए आमंत्रित किया है:' + intro_series: 'उपयोगकर्ता %{inviting_user} ने आपके उपनाम %{pseud} को निम्नलिखित + श्रृंखला पर सह-निर्माता के रूप में सूचीबद्ध होने के लिए आमंत्रित किया है:' + intro_work: 'उपयोगकर्ता %{inviting_user} ने आपके उपनाम %{pseud} को निम्नलिखित + कार्य पर सह-निर्माता के रूप में सूचीबद्ध होने के लिए आमंत्रित किया है:' + subject: "[%{app_name}] सह-निर्माता अनुरोध" + text: + creation: "%{title} (%{url}), %{pseuds} के द्वारा रचित" + instructions: 'आप इस अनुरोध को अपने Co-Creator Requests (सह-निर्माता अनुरोध) + पेज पर स्वीकार या इंकार कर सकते है: %{url}' + delete_work_notification: + attachment: आपके कार्य का नकल, संदर्भ हेतु जुड़ा हुआ है। + deleted_other: + html: आपका कार्य %{title}, %{pseud} के अनुरोध पर मिटा दिया गया था। + text: आपका कार्य "%{title}", %{pseud} के अनुरोध पर मिटा दिया गया था। + deleted_yourself: + html: आपका कार्य %{title}, आपके अनुरोध पर मिटा दिया गया था। + text: आपका कार्य "%{title}", आपके अनुरोध पर मिटा दिया गया था। + questions: + html: यदि आपके कोई प्रश्न हैं, तो कृपया %{support}। + text: यदि आपके कोई प्रश्न हैं, तो कृपया %{support} (%{url})। + subject: "[%{app_name}] आपका कार्य मिटा दिया गया है" + support: सहयोग टीम से संपर्क करें + invite_increase_notification: + html: + body: + one: हम सिर्फ आपको यह बताना चाहते हैं कि आपके पास %{count} नया आमंत्रण है, + जिसका उपयोग AO3 पर एक नया खाता बनाने के लिए किया जा सकता है। आप %{invitation_page_link} + से किसी मित्र को आमंत्रित कर सकते हैं। + other: हम सिर्फ आपको यह बताना चाहते हैं कि आपके पास %{count} नए आमंत्रण + हैं, जिनका उपयोग AO3 पर नए खाते बनाने के लिए किया जा सकता है। आप %{invitation_page_link} + से किसी मित्र को आमंत्रित कर सकते हैं। + invitation_page_link_text: आपका Invitations (आमंत्रण) पृष्ठ + subject: "[%{app_name}] नये आमंत्रण" + text: + body: + one: |- + हम सिर्फ आपको यह बताना चाहते हैं कि आपके पास %{count} नया आमंत्रण है, जिसका उपयोग AO3 पर एक नया खाता बनाने के लिए किया जा सकता है। आप आपने Invitations (आमंत्रण) पृष्ठ + (%{invitation_page_url}) से किसी मित्र को आमंत्रित कर सकते हैं। + other: |- + हम सिर्फ आपको यह बताना चाहते हैं कि आपके पास %{count} नए आमंत्रण हैं, जिनका उपयोग AO3 पर नए खाते बनाने के लिए किया जा सकता है। आप आपने Invitations (आमंत्रण) पृष्ठ + (%{invitation_page_url}) से किसी मित्र को आमंत्रित कर सकते हैं। + invite_request_declined: + main: + one: हमें आपको यह सूचित करते हुए खेद हो रहा है कि नए आमंत्रण के लिए आपका अनुरोध + इस समय पूरा नहीं किया जा सकता है। + other: हमें आपको यह सूचित करते हुए खेद हो रहा है कि %{count} नए आमंत्रणों + के लिए आपका अनुरोध इस समय पूरा नहीं किया जा सकता है। + reason: 'आपका अनुरोध था:' + subject: "[%{app_name}] अतिरिक्त आमंत्रण अनुरोध अस्वीकृत किया गया" + recipient_notification: + html: + collection: आप के लिए एक उपहार कार्य AO3 पर %{collection_link} संग्रह में + पोस्ट किया गया है! + no_collection: आप के लिए एक उपहार कार्य AO3 पर पोस्ट किया गया है! + subject: + collection: "[%{app_name}][%{collection_title}] आप के लिए एक उपहार कार्य %{collection_title} + से।" + no_collection: "[%{app_name}] आप के लिए एक उपहार कार्य" + text: + collection: आप के लिए एक उपहार कार्य AO3 पर "%{collection_title}" संग्रह (%{collection_url}) + में पोस्ट किया गया है! diff --git a/config/locales/phrase-exports/hr.yml b/config/locales/phrase-exports/hr.yml new file mode 100755 index 0000000..52c46ba --- /dev/null +++ b/config/locales/phrase-exports/hr.yml @@ -0,0 +1,631 @@ +--- +hr: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Upozorenja:' + one: 'Upozorenje:' + other: 'Upozorenja:' + category: + name_with_colon: + few: 'Kategorije:' + one: 'Kategorija:' + other: 'Kategorija:' + character: + name_with_colon: + few: 'Lika:' + one: 'Lik:' + other: 'Likova:' + fandom: + name_with_colon: + few: 'Fandoma:' + one: 'Fandom:' + other: 'Fandoma:' + freeform: + name_with_colon: + few: 'Dodatne oznake:' + one: 'Dodatna oznaka:' + other: 'Dodatnih oznaka:' + rating: + name_with_colon: 'Ocjena:' + relationship: + name_with_colon: + few: 'Veze:' + one: 'Veza:' + other: 'Veza:' + work: + chapter_total_display: Poglavlja + summary: Sažetak + models: + archive_warning: + few: Upozorenja + one: Upozorenje + other: Upozorenja + category: + few: Kategorije + one: Kategorija + other: Kategorija + chapter: + few: Poglavlja + one: Poglavlje + other: Poglavlja + character: + few: Lika + one: Lik + other: Likova + fandom: + few: Fandoma + one: Fandom + other: Fandoma + freeform: + few: Dodatne oznake + one: Dodatna oznaka + other: Dodatnih oznaka + rating: + few: Ocjene + one: Ocjena + other: Ocjena + relationship: + few: Veze + one: Veza + other: Veza + series: + few: Serijala + one: Serijal + other: Serijala + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} gosta" + one: "%{count} gost" + other: "%{count} gostiju" + left_kudos: + html: + few: "%{givers_list} ostavili su kudos na %{commentable_link}." + one: "%{givers_list} ostavio/la je kudos na %{commentable_link}." + other: "%{givers_list} ostavilo je kudos na %{commentable_link}." + text: + few: "%{givers_list} ostavili su kudos na %{commentable_title} (%{commentable_url})." + one: "%{givers_list} ostavio/la je kudos na %{commentable_title} (%{commentable_url})." + other: "%{givers_list} ostavilo je kudos na %{commentable_title} (%{commentable_url})." + single_guest: + giver: Gost + html: "%{giver} ostavio/la je kudos na %{commentable_link}." + text: Gost je ostavio/la kudos na %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Dobili ste kudos!" + mailer: + general: + closing: + formal: Srdačno, + informal: Lijep pozdrav, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Poglavlje %{position} djela "%{title}" + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} riječi" + one: "%{count} riječ" + other: "%{count} riječi" + footer: + general: + about: + html: AO3 je arhiv od fanova za fanove, te ovisi o %{donate_link}. + text: 'AO3 je arhiv od fanova za fanove, te ovisi o vašim donacijama: + %{donate_url}.' + html: + donate_link_text: vaših donacija + support_link_text: kontaktirajte korisničku podršku + unwanted_email: + html: Ako ste ovu poruku primili pogreškom, molimo vas %{support_link}. + text: Ako ste ovu poruku primili pogreškom, molimo vas, javite se korisničkoj + podršci na %{support_url}. + sent_at: Poslano na %{sent_at}. + greeting: + formal_html: Dragi %{name}, + informal: + addressed_html: Bok, %{name}! + unaddressed: Bok! + introductory: Pozdrav od Archive of Our Own – AO3 (Našeg vlastitog arhiva)! + metadata_label_indicator: ":" + signature: + abuse_team: AO3 tim za pravila i zloupotrebu + app_short_name: AO3 + open_doors: Tim Open Doors (Otvorenih vrata) + parent_org: Organization for Transformative Works – OTW (Organizacija za transformativna + djela) + support: AO3 korisnička podrška + users: + mailer: + reset_password_instructions: + expiration: Ako ne iskoristite ovu poveznicu za resetiranje lozinke unutar + tjedan dana, isteći će i morati ćete zatražiti novu poveznicu. + intro: 'Netko je zatražio resetiranje lozinke za Vaš korisnički račun. Svoju + lozinku možete promijeniti tako da pratite poveznicu ispod i unesete Vašu + novu lozinku:' + link_title: Promijeni moju lozinku. + subject: "[%{app_name}] Resetirajte svoju lozinku" + unrequested: Ako Vi niste zatražili resetiranje lozinke, možete ignorirati + ovaj email i Vaša će prijašnja lozinka nastaviti funkcionirati. + user_mailer: + admin_deleted_work_notification: + bye: Priložena je kopija vašeg djela za vašu referencu. + contact_abuse: kontaktirajte naše vijeće za Zloupotrebu + deleted: + html: Vaše djelo %{title} je izbrisano sa Arhive od strane administratora. + text: Vaše djelo "%{title}" je izbrisano sa Arhive od strane administratora. + html: + tos_violation: Ako je moguće da je vaše djelo prekršilo Uvjete korištenja + Arhive, molimo %{contact_abuse_link}. + import_project: + html: Ako je vaše djelo bilo dio uvoznog projekta kojim upravlja naš tim Otvorenih + vrata, molimo %{opendoors_link} za sva daljnja pitanja. + text: Ako je vaše djelo bilo dio uvoznog projekta kojim upravlja Open Doors + (Otvorena vrata), molimo kontaktirajte Otvorena vrata (%{opendoors_link}) + za sva daljnja pitanja. + opendoors: kontaktirajte Otvorena vrata + subject: "[%{app_name}] Vaše djelo je izbrisano od strane administratora" + text: + tos_violation: Ako je moguće da je vaše djelo prekršilo Uvjete korištenja + Arhive, molimo kontaktirajte vijeće za Zloupotrebu (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Dok je vaše djelo skriveno, još uvijek mu možete pristupiti preko gornjeg + linka, ali neće biti prikazano na vašoj stranici djela, i neće biti dostupno + drugim AO3 korisnicima. + check_email: Molimo provjerite vaš mail, uključujući vašu spam mapu, jer tim + za Pravila & zlouporabu vas je možda već kontaktirao objašnjavajući zašto + je vaše djelo skriveno. + contact_abuse: kontaktirajte Pravila & zlouporabu + html: + help: Ako niste sigurni zašto je vaše djelo skriveno, i niste dobili daljnje + informacije o tome, molimo %{contact_abuse_link} direktno. + hidden: Vaše djelo %{title} je sakrio tim za Pravila & zlouporabu i više nije + javno dostupno. + tos_violation: Ako je vaše djelo skriveno jer krši AO3 %{tos_link}, morati + ćete poduzeti mjere kako bi ispravili prekršaj. Neuspjeh dovođenja vašeg + djela u sklad sa Uvjetima korištenja može dovesti do brisanja vašeg djela + sa AO3. + subject: "[%{app_name}] Vaše djelo je sakrio tim za Pravila & zlouporabu" + text: + help: 'Ako niste sigurni zašto je vaše djelo skriveno, i niste dobili daljnje + informacije o tome, molimo kontaktirajte Pravila & zlouporabu direktno: + %{contact_abuse_url}.' + hidden: Vaše djelo "%{title}" (%{work_url}) je sakrio tim za Pravila & zlouporabu + i više nije javno dostupno. + tos_violation: Ako je vaše djelo skriveno zbog toga što krši AO3 Uvjete korištenja + (%{tos_url}), morati ćete poduzeti mjere kako bi ispravili prekršaj. Neuspjeh + dovođenja vašeg djela u sklad sa Uvjetima korištenja može dovesti do brisanja + vašeg djela sa AO3. + tos: Uvjete korištenja + anonymous_or_unrevealed_notification: + anonymous_info: Anonimna djela uključena su u popis oznaka, ali ne i na vašoj + stranici djela. Na djelu će vaše korisničko ime biti zamijenjeno s "Anonymous" + (anonimno). + anonymous_unrevealed_info: Održavači kolekcije mogu kasnije otkriti vaše djelo, + ali ga ostaviti anonimno. Osobe koje imaju pretplatu na vas bit će obaviještene + o tome. Jednom otkriveno, vaše djelo bit će uključeno na popisu oznaka, ali + ne na popisu djela. Na djelu,vaše će ime biti zamijenjeno s "Anonymous" (anonimno). + changed_status: + anonymous: + html: Održavači kolekcije %{collection_link} promijenili su status vašeg + djela %{work_link} u anonimno. + text: Održavači kolekcije "%{collection_title}" (%{collection_url}) promijenili + su status vašeg djela "%{work_title}" (%{work_url}) u anonimno. + anonymous_unrevealed: + html: Održavači kolekcije %{collection_link} promijenili su status Vašeg + djela %{work_link} u anonimno i skriveno. + text: Održavači kolekcije "%{collection_title}" (%{collection_url}) promijenili + su status vašeg djela "%{work_title}" (%{work_url}) u anonimno i skriveno. + unrevealed: + html: Održavači kolekcije %{collection_link} će promijeniti status vašeg + djela %{work_link} u skriveno. + text: Održavači kolekcije "%{collection_title}" (%{collection_url}) promijenili + su status vašeg djela "%{work_title}" (%{work_url}) u skriveno. + collection_items_link_text: Approved Collection Items (odobrene stavke kolekcije) + do_not_want: + anonymous: + html: Ako ne želite da vaše djelo bude anonimno, molimo posjetite %{collection_items_link} + kako biste ga maknuli iz kolekcije. + text: 'Ako ne želite da vaše djelo bude anonimno, molimo posjetite Approved + Collection Items (odobrene stavke kolekcije) kako biste ga maknuli iz + te kolekcije: %{collection_items_url}' + anonymous_unrevealed: + html: Ako ne želite da vaše djelo bude anonimno i skriveno, molimo posjetite + %{collection_items_link} kako biste ga maknuli iz te kolekcije. + text: 'Ako ne želite da vaše djelo bude anonimno i skriveno, molimo posjetite + Approved Collection Items (odobrene stavke kolekcije) kako biste ga maknuli + iz te kolekcije: %{collection_items_url}' + unrevealed: + html: Ako ne želite da vaše djelo bude skriveno, molimo posjetite %{collection_items_link} + kako biste ga maknuli iz te kolekcije. + text: 'Ako ne želite da vaše djelo bude skriveno, molimo posjetite Approved + Collection Items (odobrene stavke kolekcije) kako biste ga maknuli iz + te kolekcije: %{collection_items_url}' + faq_link_text: Kolekcije - najčešća pitanja i odgovori + more_info: + html: Za više informacija, posjetite %{faq_link}. + text: 'Za više informacija, posjetite Kolekcije - najčešća pitanja i odgovori: + %{faq_url}' + subject: + anonymous: "[%{app_name}] Vaše djelo je anonimno" + anonymous_unrevealed: "[%{app_name}] Vaše djelo je anonimno i skriveno" + unrevealed: "[%{app_name}] Vaše je djelo skriveno" + unrevealed_info: Skrivena djela nisu uključena u popise oznaka ili na vašoj + stranici. Tko god slijedi link na djelo, primit će poruku da je privremeno + nedostupno, i tom sadržaju neće biti dozvoljen pristup. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Stavke odobrene za + kolekcije) + archivist_notice: Zato što održavatelji kolekcije djeluju u službenom kapacitetu + kao Open Doors (Otvorena vrata) arhivisti, dopušteno im je dodati vaše djelo + u ovu kolekciju, čak i ako ste onemogućili dodavanje djela u kolekcije. Arhivisti + će dodati djelo u kolekciju samo ako je bilo hostano na uvezenom arhivu. + removal_instructions: + html: Ako želite ukloniti vaše djelo iz ove kolekcije, molimo posjetite vašu + %{approved_items_link}. + text: 'Ako želite ukloniti vaše djelo iz ove kolekcije, molimo posjetite stranicu + Approved Collection Items (Stavke odobrene za kolekcije): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Open Doors (Otvorena vrata) arhivist + je dodao vaše djelo u kolekciju" + work_added: + html: Održavatelji kolekcije %{collection_link} su dodali vaše djelo %{work_link} + u svoju kolekciju! + text: Održavatelji kolekcije "%{collection_title}" (%{collection_url}) su + dodali vaše djelo "%{work_title}" (%{work_url}) u svoju kolekciju! + challenge_assignment_notification: + any: Bilo koji + assignment: + html: Dobili ste sljedeći zahtjev na %{link} za izazov Archive of Our Own + – AO3 (Našeg vlastitog ariva)! + description: 'Opis:' + due: 'Rok za ovaj zadatak je:' + html: + footer: Dobili ste ovaj email jer ste se prijavili na %{title} izazov. Za + više informacija o ovom izazovu i kontaktne informacije za moderatore, molimo + vas da posjetite %{footer_link} + footer_link: profilna stranica izazova + look_up: Možete pogledati ovaj zadatak na %{link}. + look_up_link: vaša Assignments (Zadaci) stranica + optional_tags: 'Neobavezne oznake:' + prompts: 'Promptovi:' + prompt_url: 'URL prompta:' + recipient: 'Primatelj:' + recipient_missing: 'Ne postoji: kontaktirajte moderatora za pomoć!' + subject: "[%{app_name}][%{collection_title}] Tvoj zadatak!" + text: + assignment: Dobili ste sljedeću molbu u "%{collection_title}" (%{collection_url}) + izazovu kod Archive of Our Own – AO3 (Našeg vlastitog arhiva)! + footer: Dobili ste ovaj email jer ste se prijavili za %{title} izazov (%{url}). + Za više informacija o ovom izazovu i kontaktne informacije za moderatore, + molimo vas da posjetite %{profile_url}. + look_up: Možete pogledati svoje zadatke s vaše Assignments (Zadaci) stranice + na %{link}. + change_email: + changed: + html: "%{login}, e-mail povezan s vašim računom je promijenjen u %{email}" + text: "%{login}, e-mail povezan s vašim računom je promijenjen u %{email}" + subject: "[%{app_name}] Promijenjen e-mail" + claim_notification: + access: + contact_support: kontaktirajte AO3 podršku + html: Ovisno o arhivi, vaša su djela možda uvezena s ograničenjem samo na + registrirane korisnike (kako bi ih zadržali izvan Google pretraživanja). + Ako je to slučaj, djelima će moći pristupiti samo prijavljeni korisnici + osim ako ih ne odlučite učiniti potpuno vidljivima. Za pomoć pri otključavanju, + napuštanju ili brisanju vaših djela, molimo %{contact_support_link}. + text: Ovisno o arhivi, vaša su djela možda uvezena s ograničenjem samo na + registrirane korisnike (kako bi ih zadržali izvan Google pretraživanja). + Ako je to slučaj, djelima će moći pristupiti samo prijavljeni korisnici + osim ako ih ne odlučite učiniti potpuno vidljivima. Za pomoć pri otključavanju, + napuštanju ili brisanju vaših djela, molimo kontaktirajte podršku na %{support_url}. + email_tips: Ako nas kontaktirate, dodajte adrese s @transformativeworks.org + na svoj popis sigurnih kontakata i provjerite svoje mape neželjene pošte za + naš odgovor. + introduction: + ao3_name: Archive of Our Own – AO3 (Naš vlastiti arhiv) + html: Primili ste ovu poruku jer ste imali djela u fan arhivi koja je uvezena + od strane %{open_doors_name_link} u %{app_link}. Budući da je ova adresa + povezana s jednom već registriranom u uvezenoj arhivi, pridružena fan djela + (navedena u nastavku) automatski su dodana vašem AO3 računu. + open_doors_name: Open Doors (Otvorena vrata) + text: 'Primili ste ovu poruku jer ste imali djela u arhivi fan djela koja + je uvezena od strane Open Doors (Otvorenih vrata) (%{open_doors_url}) u + Archive of Our Own – AO3 (Naš vlastiti arhiv): %{app_url}. Budući da je + ova adresa povezana s jednom registriranom u uvezenoj arhivi, pridružena + fan djela (navedena u nastavku) automatski su dodana vašem AO3 računu.' + mistake: + contact_open_doors: kontaktirate Otvorena vrata + html: Ako je ovo greška i ovo nisu vaša djela, nemojte ih brisati! Molimo + vas da %{contact_open_doors_link} i mi ćemo to srediti. + text: Ako je ovo greška i ovo nisu vaša djela, nemojte ih brisati! Molimo + vas da kontaktirate Otvorena vrata (%{open_doors_url}) i mi ćemo to srediti. + more_info: + ao3_news: AO3 vijesti + contact_support: kontaktirate AO3 podršku + faq_page: Najčešća pitanja + html: Možete pročitati najave o nedavnim premještajima arhiva na%{ao3_news_link}, + i pronaći dodatne informacije na Otvorenim vratima %{faq_page_link} ili + %{tutorial_page_link}. Za sva pitanja na koja nema odgovora u najčešćim + pitanjima, uputama ili ovoj poruci, molimo %{contact_support_link}. + text: Možete pročitati najave o nedavnim premještajima arhiva na AO3 vijestima(%{news_url}) + i pronaći dodatne informacije na najčešćim pitanjima Otvorenih vrata (%{open_doors_faq_url}) + ili na stranici s uputama (%{open_doors_tutorial_url}). Za sva pitanja na + koja nema odgovora u najčešćim pitanjima, uputama ili ovoj poruci, molimo + kontaktirajte podršku na %{support_url}. + tutorial_page: stranica s uputama + other_works: + contact_open_doors: kontaktirajte Otvorena vrata + html: Ako ste imali druga djela na uvezenoj arhivi pod adresom kojoj više + ne možete pristupiti, molimo %{contact_open_doors_link} sa svim informacijama + koje mogu pomoći u potvrdi vašeg identiteta. + text: Ako ste imali druga djela na uvezenoj arhivi pod adresom kojoj više + ne možete pristupiti, molimo kontaktirajte Otvorena vrata sa svim informacijama + koje mogu pomoći u potvrdi vašeg identiteta. + questions: + contact_support: kontaktirajte AO3 podršku + html: Za druge upite, molimo %{contact_support_link}. + text: Za druge upite, molimo kontaktirajte podršku na %{support_url}. + redirects: + html: Kako bi se sačuvali popisi fic preporuka i bookmarkovi, web-adrese uvezene + arhive mogu preusmjeravati na uvezenu kopiju ovih djela na ograničeno vrijeme + (provjerite objavu za svoju arhivu kako biste bili sigurni). Ako ste već + učitali kopiju ovih djela i %{negation} koristili značajku uvoza s URL-a, + postojat će dvije kopije istog djela na AO3-u. + subject: "[%{app_name}] Uvezena djela" + update_redirect: + contact_open_doors: kontaktirajte Otvorena vrata + html: Ako želite da Otvorena vrata ažuriraju preusmjeravanje kako bi upućivalo + na vaše već postojeće djelo, izbrišite uvezenu kopiju i %{contact_open_doors_link} + s imenom vašeg AO3 računa, nazivom vašeg računa u uvezenoj arhivi, te naslovom + i URL-om djela na koji želite da bude preusmjereno. (Ako imate više djela + za koja želite promijeniti preusmjeravanja, možete ih navesti u jednoj poruci.) + text: Ako želite da Otvorena vrata ažuriraju preusmjeravanje kako bi upućivalo + na vaše već postojeće djelo, izbrišite uvezenu kopiju i kontaktirajte Otvorena + vrata %{open_doors_url} s imenom vašeg AO3 računa, nazivom vašeg računa + u uvezenoj arhivi, te naslovom i URL-om djela na koji želite da bude preusmjereno. + (Ako imate više djela za koja želite promijeniti preusmjeravanja, možete + ih navesti u jednoj poruci.) + works_by: 'Djela su napisana pod ovom adresom: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Poslani su svi zadaci. + subject: Zadaci poslani + html: + received_message: 'Dobili ste poruku o vašoj kolekciji %{collection_link}:' + text: + received_message: 'Dobili ste poruku o vašoj kolekciji "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Kada ste sukreator nekog djela, možete biti dodani novim poglavljima + bez obzira na vaše postavke. Također ćete biti dodani serijalu kojem je dodano + djelo. + html: + creation: "%{creation_link} od %{pseud_links}" + edit_chapter: Uredite poglavlje + edit_series: Uredite serijal + remove_chapter: Ako ste pogreškom dodani ili ne želite biti navedeni kao kreator, + možete se %{edit_chapter_link} maknuti kao kreator. + remove_series: Ako ste pogreškom dodani ili ne želite biti navedeni kao kreator, + možete %{edit_series_link} kako biste maknuli sebe kao kreatora. + intro_chapter: 'Korisnik %{adding_user} je naveo vaš pseudonim %{pseud} kao + sukreatora na sljedećem poglavlju:' + intro_series: 'Korisnik %{adding_user} dodao je vaš pseudonim %{pseud} kao sukreatora + na sljedećem serijalu:' + subject: "[%{app_name}] Obavijest sukreatora" + text: + creation: "%{title} (%{url}) od %{pseuds}" + remove_chapter: 'Ako ste pogreškom dodani ili ne želite biti navedeni kao + kreator, možete urediti poglavlje kako biste maknuli sebe kao kreatora: + %{url}' + remove_series: 'Ako ste pogreškom dodani ili ne želite biti navedeni kao kreator,možete + urediti serijal kako biste maknuli sebe kao kreatora: %{url}' + creatorship_notification_archivist: + explanation: Budući da djeluju po službenoj dužnosti kao Open Doors arhivisti + (Otvorenih vrata), dozvoljeno im je dodavati Vas bez zahtjeva, čak i ako imate + onemogućeno sukreatorstvo. + html: + creation: "%{creation_link} od %{pseud_links}" + edit_chapter: uredi poglavlje + edit_series: uredi serijale + edit_work: uredi djelo + remove_chapter: Ako ste dodani greškom ili ne želite biti navedeni kao kreator, + možete se %{edit_chapter_link} ukloniti s popisa kreatora. + remove_series: Ako ste dodani greškom ili ne želite biti navedeni kao kreator, + možete se %{edit_series_link} ukloniti s popisa kreatora. + remove_work: Ako ste dodani greškom ili ne želite biti navedeni kao kreator, + možete se %{edit_work_link} ukloniti s popisa kreatora. + intro_chapter: 'Korisnik %{archivist} je dodao Vaš pseud %{pseud} kao sukreatora + sljedećih poglavlja:' + intro_series: 'Korisnik %{archivist} je dodao Vaš pseud %{pseud} kao sukreatora + sljedećih serijala:' + intro_work: 'Korisnik %{archivist} označio je Vaš pseudonim %{pseud} kao sukreatora + na sljedećem djelu:' + subject: "[%{app_name}] Obavijest arhivista o dodavanju sukreatora" + text: + creation: "%{title} (%{url}) od %{pseuds}" + remove_chapter: 'Ako ste dodani greškom ili ne želite biti navedeni kao kreator, + možete urediti poglavlje kako biste se uklonili s popisa kreatora: %{url}' + remove_series: 'Ako ste dodani greškom ili ne želite biti navedeni kao kreator, + možete urediti serijale kako biste se uklonili s popisa kreatora: %{url}' + remove_work: 'Ako ste dodani greškom ili ne želite biti navedeni kao kreator, + možete urediti djelo kako biste se uklonili s popisa kreatora: %{url}' + creatorship_request: + html: + creation: "%{creation_link} od %{pseud_links}" + instructions: Možete prihvatiti ili odbiti ovaj zahtjev na svojoj %{page_name} + stranici. + page_name: Co-Creator Requests (Zahtjevi sukreatora) + intro_chapter: 'Korisnik %{inviting_user} je pozvao Vaš pseud %{pseud} da bude + dodan kao sukreator na sljedećem poglavlju:' + intro_series: 'Korisnik %{inviting_user} je pozvao Vaš pseud %{pseud} da bude + dodan kao sukreator na sljedećem serijalu:' + intro_work: 'Korisnik %{inviting_user} je pozvao Vaš pseud %{pseud} da bude + dodan kao sukreator na sljedećem djelu:' + subject: "[%{app_name}] Zahtjev sukreatora" + text: + creation: "%{title} (%{url}) od %{pseuds}" + instructions: 'Možete prihvatiti ili odbiti ovaj zahtjev na svojoj Co-Creator + Requests (Zahtjevi sukreatora) stranici: %{url}' + delete_work_notification: + attachment: U prilogu se nalazi kopija vašeg djela za referencu. + deleted_other: + html: Vaše djelo %{title} je izbrisano na zahtjev %{pseud}. + text: Vaše djelo "%{title}" je izbrisano na zahtjev %{pseud}. + deleted_yourself: + html: Vaše djelo %{title} je izbrisano na vaš zahtjev. + text: Vaše djelo "%{title}" je izbrisano na vaš zahtjev. + questions: + html: Ako imate pitanja, molimo %{support}. + text: Ako imate pitanja, molimo %{support} (%{url}). + subject: "[%{app_name}] Vaše djelo je izbrisano" + support: kontaktirajte Korisničku podršku + invitation: + been_invited: Pozvani ste da se pridružite našoj otvorenoj beti! + has_invited: "%{user_name} Vas je pozvao da se pridružite našoj beti!" + html: + faq_link_text: naša najčešća pitanja + subject: "[%{app_name}] הזמנה" + invitation_to_claim: + access: + text: Ovisno o arhivi, moguće je da su vaša djela uvezena samo za registrirane + korisnike (kako se ne bi pojavili na Google pretrazi). Ako je to slučaj, + djela će biti dostupna samo prijavljenim korisnicima, osim ako se ne odlučite + da budu potpuno vidljiva. Za pomoć s otključavanjem, napuštanjem ili brisanjem + vaših djela, molimo kontaktirajte AO3 Podršku. + claim_or_remove: + html: Položite prava na ili uklonite svoja djela ovdje. + text: 'Položite prava na ili uklonite svoja djela ovdje: %{claim_url}' + email_tips: Ako nas kontaktirate, molimo stavite @transformativeworks.org na + listu prihvaćenih adresa i provjerite mapu s neželjenom poštom za naš odgovor. + html: + ao3_news: AO3 Vijesti + contact_open_doors: kontaktiraj Otvorena vrata + contact_support: kontaktiraj AO3 korisničku podršku + faq_page: stranica najčešćih pitanja + tutorial_page: uputstva + introduction: + text: Primili ste ovaj e-mail jer su Otvorena vrata (%{open_doors_link}) nedavno + uvezla arhiv u %{app_name} (%{app_short_name} - %{app_url}), i vjerujemo + da sljedeća djela pripadaju vama. Želimo vam pružiti priliku da položite + prava na (ili izbrišete/napustite) njih, ako želite. Ako već nemate račun + pod drugim e-mailom, ovim vas putem želimo pozvati da nam se pridružite! + mistake: + text: Ako je ovo greška i to nisu vaša djela, molimo vas da ih ne izbrišete! + Samo kontaktirajte Otvorena vrata (%{open_doors_link}) i mi ćemo se pobrinuti + oko toga. + more_info: + text: Nove obavijesti o nedavnim potezima arhiva možete pročitati na AO3 Vijestima + (%{news_link}), te pronaći dodatne informacije na najčešćim pitanjima Otvorenih + vrata (%{open_doors_faq_link}) ili na stranici s uputstvima (%{open_doors_tutorial_link}). + Za svaka pitanja koja nisu odgovorena ovdje ili u uputstvima, molimo kontaktirajte + Podršku na %{support_link}. + other_works: + text: Ako ste na uvezenoj arhivi imali djela pod e-mail adresom kojoj više + nemate pristup, molimo kontaktirajte Otvorena vrata s informacijama koje + mogu pomoći u potvrdi vašeg identiteta. + questions: + text: Za druga pitanja, molimo kontaktirajte AO3 Podršku na %{support_link}. + redirects: Kako bi sačuvali liste i bookmarkove, uvezene web adrese arhiva će + vas neko vrijeme možda preusmjeravati na uvezenu kopiju djela (provjerite + objave svoje arhive, kako biste bili sigurni). Ako ste već učitali kopiju + tih djela i NISTE koristili opciju URL uvoza, imat ćete dvije kopije istog + djela u arhivi. + subject: "[%{app_name}] Poziv na polaganje prava na djelo" + unwanted: + text: Ako djela pripadaju vama, al ih ne želite, možete ih napustiti (tako + da ostanu na AO3-u bez vašeg imena) ili izbrisati (potpuno ih ukloniti s + AO3-a). Ne morate ih dodati na bilo koji račun kako biste ih napustili ili + izbrisali--možete učiniti to direktno preko linka gore. (Za pomoć, molimo + kontaktirajte Podršku na %{support_link}.) + update_redirect: + text: Ako želite da Otvorena vrata preusmjeruju na vaše već postojeće djelo, + molimo izbrišite učitanu kopiju i kontaktirajte Otvorena vrata na %{open_doors_link} + s vašim AO3 korisničkim imenom, imenom računa s uvezene arhive, te naslovom + i URL-om fan djela na koje želite biti preusmjereni. (Ako imate više djela + koja želite da budu preusmjerena, možete ih sva navesti u jednom mailu.) + uploaded_list: 'Učitana djela sadrže:' + invite_increase_notification: + html: + body: + few: Želimo vas obavijestiti da imate %{count} nove pozivnice, koje se mogu + koristiti za izradu novih računa na AO3. Možete pozvati prijatelje na + %{invitation_page_link}. + one: Želimo vas obavijestiti da imate %{count} novu pozivnicu, koje se mogu + koristiti za izradu novih računa na AO3. Možete pozvati prijatelje na + %{invitation_page_link}. + other: Želimo vas obavijestiti da imate %{count} novih pozivnica, koje se + mogu koristiti za izradu novih računa na AO3. Možete pozvati prijatelje + na %{invitation_page_link}. + invitation_page_link_text: stranica Your Invitations (tvoje pozivnice) + subject: "[%{app_name}] Nove pozivnice" + text: + body: + few: Želimo vas obavijestiti da imate %{count} nove pozivnice, koje se mogu + koristiti za izradu novih računa na AO3. Možete pozvati prijatelje na + %{invitation_page_url}. + one: Želimo vas obavijestiti da imate %{count} novu pozivnicu, koje se mogu + koristiti za izradu novih računa na AO3. Možete pozvati prijatelje na + %{invitation_page_url}. + other: Želimo vas obavijestiti da imate %{count} novih pozivnica, koje se + mogu koristiti za izradu novih računa na AO3. Možete pozvati prijatelje + na %{invitation_page_url}. + invite_request_declined: + main: + few: Žao nam je što vas moramo obavijestiti da vaš zahtjev za %{count} nova + poziva trenutno ne može biti odobren. + one: Žao nam je što vas moramo obavijestiti da vaš zahtjev za novim pozivom + trenutno ne može biti odobren. + other: Žao nam je što vas moramo obavijestiti da vaš zahtjev za %{count} novih + poziva trenutno ne može biti odobren. + reason: 'Vaš zahtjev je bio:' + subject: "[%{app_name}] Zahtjev za dodatnim pozivnim kodom odbijen" + recipient_notification: + html: + collection: Poklon za Vas je objavljen u %{collection_link} AO3 kolekciji! + no_collection: Na AO3-u je objavljen poklon za Vas! + subject: + collection: "[%{app_name}][%{collection_title}] Poklon za Vas od %{collection_title}" + no_collection: "[%{app_name}] Poklon za Vas" + text: + collection: Poklon za Vas je objavljen u "%{collection_title}" kolekciji (%{collection_url}) + na AO3-u! + signup_notification: + activate: + html: Molimo %{activate_account_link}. + text: 'Molimo slijedite ovu poveznicu kako bi aktivirali svoj račun: %{activate_account_url}' + activate_your_account: Slijedite ovu poveznicu kako bi aktivirali svoj korisnički + račun + admin_posts: AO3 News + bye: Nadamo se da uživate u korištenju Arhiva. + contact_support: kontaktirajte naš tim za Korisničku podršku + faq: Najčešća pitanja + features: + html: Nakon što je vaš račun otvoren i aktiviran, možete objaviti svoja fan + djela, napraviti preplate putem e-maila kako biste bili obaviješteni kada + vaši omiljeni autori učitaju novo djelo ili ažuriraju već postojeće, postavite + postavke da biste prilagodili način na koji stranica izgleda i radi za vas, + pratite djela kojima ste pristupilii na Arhivu putem svoje povijesti i još + mnogo toga. + text: Nakon što je vaš račun otvoren i aktiviran, možete objaviti svoja fan + djela, napraviti preplate putem e-maila kako biste bili obaviješteni kada + vaši omiljeni autori učitaju novo djelo ili ažuriraju već postojeće, postavite + postavke da biste prilagodili način na koji stranica izgleda i radi za vas, + pratite djela kojem ste pristupili na Arhivu putem svoje povijesti i još + mnogo toga. + information: + html: Postoji puno informacija i savjeta o tome kako koristiti Arhiv putem + stranice %{faq_link}. Naći ćete najnovije vijesti o razvoju web lokacije + putem stranice %{admin_posts_link}. Ako vam je potrebna dodatna pomoć, naišli + ste na bug ili imate pitanja ili komentare, molimo %{contact_support_link}, + koji su uvijek spremni pomoći. + text: 'Postoji puno informacija i savjeta o tome kako koristiti Arhivu putem + stranice %{faq_url}. Naći ćete najnovije vijesti o razvoju web lokacije + na AO3 Vijestima na %{admin_posts_url}. Ako vam je potrebna dodatna pomoć, + naletili ste na bug ili imate pitanja ili komentare, molimo kontaktirajte + naš tim za korisničku podršku, koji su uvijek spremni pomoći: %{contact_support_url}.' + welcome: Dobrodošli u Naš vlastiti arhiv, %{login}! diff --git a/config/locales/phrase-exports/hu.yml b/config/locales/phrase-exports/hu.yml new file mode 100755 index 0000000..a77ed95 --- /dev/null +++ b/config/locales/phrase-exports/hu.yml @@ -0,0 +1,534 @@ +--- +hu: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Figyelmeztetés:' + other: 'Figyelmeztetések:' + category: + name_with_colon: + one: 'Kategória:' + other: 'Kategóriák:' + character: + name_with_colon: + one: 'Szereplő:' + other: 'Szereplők:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandomok:' + freeform: + name_with_colon: + one: 'További kulcsszó:' + other: 'További kulcsszavak:' + rating: + name_with_colon: 'Besorolás:' + relationship: + name_with_colon: + one: 'Kapcsolat:' + other: 'Kapcsolatok:' + work: + chapter_total_display: Fejezetek + summary: Összefoglaló + models: + archive_warning: + one: Figyelmeztetés + other: Figyelmeztetések + category: + one: Kategória + other: Kategóriák + chapter: + one: Fejezet + other: Fejezetek + character: + one: Szereplő + other: Szereplők + fandom: + one: Fandom + other: Fandomok + freeform: + one: További kulcsszó + other: További kulcsszavak + rating: + one: Besorolás + other: Besorolások + relationship: + one: Kapcsolat + other: Kapcsolatok + series: + one: Sorozat + other: Sorozatok + kudo_mailer: + batch_kudo_notification: + guest: + one: egy vendég + other: "%{count} vendég" + left_kudos: + html: + one: "%{givers_list} kudost hagyott itt: %{commentable_link}." + other: "%{givers_list} kudost hagyott itt: %{commentable_link}." + text: + one: "%{givers_list} kudost hagyott itt: %{commentable_title} (%{commentable_url})." + other: "%{givers_list} kudost hagyott itt: %{commentable_title} (%{commentable_url})." + single_guest: + giver: Egy vendég + html: "%{giver} kudost hagyott itt: %{commentable_link}." + text: 'Egy vendég kudost hagyott itt: %{commentable_title} (%{commentable_url}).' + subject: "​[%{app_name}]​​ ​Kudost kaptál!" + mailer: + general: + closing: + formal: Üdvözlettel, + informal: Üdv, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: "%{title} %{position}. fejezet" + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} szó" + other: "%{count} szó" + footer: + general: + about: + html: Az AO3 egy rajongók által működtetett és támogatott archívum, amely + a %{donate_link} épül. + text: 'Az AO3 egy rajongók által működtetett és támogatott archívum, amely + a Ti adományaitokból épül: %{donate_url}.' + html: + donate_link_text: Ti adományaitokból + support_link_text: lépj kapcsolatba a Támogatással + unwanted_email: + html: Ha tévedésből kaptad ezt az emailt, %{support_link}. + text: 'Ha tévedésből kaptad ezt az emailt, lépj kapcsolatba a Támogatással: + %{support_url}.' + sent_at: 'Dátum: %{sent_at}' + greeting: + formal_html: Kedves %{name}, + informal: + addressed_html: Szia %{name}! + unaddressed: Szia! + introductory: Üdvözlet az Archive of Our Own – AO3-tól (A Mi Archívumunk)! + metadata_label_indicator: ":" + signature: + abuse_team: Az AO3 Szabályzat és Visszaélés csapata + app_short_name: AO3 + open_doors: Az Open Doors (Nyitott Ajtók) csapata + parent_org: Organization for Transformative Works – OTW (Szervezet a Transzformatív + Munkákért) + support: Az AO3 Támogatás csapata + users: + mailer: + reset_password_instructions: + expiration: Ha egy héten belül nem használod ezt a linket a jelszavad visszaállításához, + a link érvényét veszti és egy újat kell majd igényelned. + intro: 'Valaki a fiókod jelszavának visszaállítását kérte. Az alábbi linkre + kattintva és az új jelszó megadásával módosíthatod a fiókod jelszavát:' + link_title: Jelszavam megváltoztatása. + subject: "[%{app_name}] Jelszó visszaállítása" + unrequested: Ha nem Te kérted jelszavad visszaállítását, hagyd figyelmen kívül + ezt az emailt, így korábbi jelszavad továbbra is működni fog. + user_mailer: + admin_deleted_work_notification: + bye: Csatoltuk a munkád másolatát. + contact_abuse: lépj kapcsolatba a Szabályzat & Visszaélés bizottsággal + deleted: + html: A munkád, %{title} törölve lett az Archívumból egy admin által. + text: A munkád, "%{title}" törölve lett az Archívumból egy oldal admin által. + html: + tos_violation: Ha előfordulhat, hogy a munkád megsértette az Archívum Szolgáltatási + Feltételeit, %{contact_abuse_link}. + import_project: + html: Ha a munkád része volt az Open Doors (Nyitott Ajtók) egyik importálási + projektjének, további kérdéseiddel %{opendoors_link}. + text: Ha a munkád része volt az Open Doors (Nyitott Ajtók) egyik importálási + projektjének, további kérdéseiddel lépj kapcsolatba a Nyitott Ajtók (%{opendoors_link}) + bizottsággal. + opendoors: lépj kapcsolatba a Nyitott Ajtók bizottsággal + subject: "[%{app_name}] A munkádat törölte egy admin" + text: + tos_violation: Ha előfordulhat, hogy a munkád megsértette az Archívum Szolgáltatási + Feltételeit, lépj kapcsolatba a Szabályzat & Visszaélés bizottsággal (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Amíg el van rejtve a munkád, továbbra is el tudod érni a fent megadott + linken, de nem lesz listázva a munkák oldaladon, és az AO3 többi felhasználója + számára sem lesz elérhető. + check_email: Kérjük, ellenőrizd az emailed, beleértve a spam mappádat is, mivel + a Szabályzat és Visszaélés csapat már lehet, hogy kapcsolatba lépett veled, + hogy elmagyarázza, miért rejtette el a munkádat. + contact_abuse: lépj közvetlen kapcsolatba a Szabályzat és Visszaélés bizottsággal + html: + help: Ha nem vagy biztos abban, miért lett elrejtve a munkád, és nem kaptál + további tájékoztatást ezzel kapcsolatban, kérjük, %{contact_abuse_link}. + hidden: A(z) %{title} munkádat elrejtette a Szabályzat és Visszaélés csapat + és nem érhető el nyilvánosan. + tos_violation: Ha a munkád azért lett elrejtve, mert megsértette az AO3-mat + %{tos_link}, köteles leszel intézkedni a szabálysértés megszüntetése érdekében. + Ha nem hozod összhangba munkád a Szolgáltatási Feltételekkel, ez a munkád + törléséhez vezethet. + subject: "[%{app_name}] A munkádat elrejtette a Szabályzat és Visszaélés csapat" + text: + help: 'Ha nem vagy biztos, miért lett elrejtve a munkád, és nem kaptál további + tájékoztatást ezzel kapcsolatban, kérjük, lépj közvetlen kapcsolatba a Szabályzat + és Visszaélés bizottsággal: %{contact_abuse_url}.' + hidden: A(z) "%{title}" (%{work_url}) munkádat elrejtette a Szabályzat és + Visszaélés csapat és nem érhető el nyilvánosan. + tos_violation: Ha a munkád azért lett elrejtve, mert megsértette az AO3 Szolgáltatási + Feltételeit (%{tos_url}), köteles leszel intézkedni a szabálysértés megszüntetése + érdekében. Ha nem hozod összhangba munkád a Szolgáltatási Feltételekkel, + ez a munkád törléséhez vezethet. + tos: Szolgáltatási Feltételek + anonymous_or_unrevealed_notification: + anonymous_info: A névtelen munkák rajta vannak a kulcsszó listákon, de nem jelennek + meg a munkáid között. A munkán a felhasználó neved “Anonymous”-ra (Névtelen) + lesz cserélve. + anonymous_unrevealed_info: A gyűjtemény karbantartói a későbbiekben nyilvánossá, + de névtelenné tehetik a munkád. Nem fognak értesítést kapni erről az emberek, + akik követnek téged. Miután újra nyilvános a munkád, rajta lesz a kulcsszó + listákon, de a munkáid között nem fog megjelenni. A munkán a felhasználó neved + “Anonymous”-ra (Névtelen) lesz cserélve. + changed_status: + anonymous: + html: 'A(z) %{collection_link} gyűjtemény kezelői névtelenné változtatták + az alábbi munkád státuszát: %{work_link}.' + text: A(z) "%{collection_title}" (%{collection_url}) karbantartói névtelenné + változtatták a munkád "%{work_title}" (%{work_url}) állapotát. + anonymous_unrevealed: + html: A(z) %{collection_link} karbantartói névtelenné és nem nyilvánossá + változtatták a munkád %{work_link} állapotát. + text: A(z) "%{collection_title}" (%{collection_url}) karbantartói névtelenné + és nem nyilvánossá változtatták a munkád "%{work_title}" (%{work_url}) + állapotát. + unrevealed: + html: A(z) %{collection_link} karbantartói nem nyilvánossá változtatták + a munkád %{work_link} állapotát. + text: A(z) "%{collection_title}" (%{collection_url}) karbantartói nem nyilvánossá + változtatták a munkád "%{work_title}" (%{work_url}) állapotát. + collection_items_link_text: Approved Collection Items (Elfogadott Gyűjtemény + Tételek) oldal + do_not_want: + anonymous: + html: Ha nem szeretnéd, hogy a munkád névtelenné váljon, kérlek, látogass + el az %{collection_items_link} oldalra, hogy eltávolíthasd ebből a gyűjteményből. + text: 'Ha nem szeretnéd, hogy a munkád névtelenné váljon, kérlek, látogass + el az Approved Collection Items (Elfogadott Gyűjtemény Tételek) oldalra, + hogy eltávolíthasd ebből a gyűjteményből: %{collection_items_url}' + anonymous_unrevealed: + html: Ha szeretnéd, hogy a munkád továbbra is nyilvános legyen, és ne váljon + névtelenné, kérlek, látogass el az %{collection_items_link} oldalra, hogy + eltávolíthasd ebből a gyűjteményből. + text: 'Ha szeretnéd, hogy a munkád továbbra is nyilvános legyen, és ne váljon + névtelenné, kérlek, látogass el az Approved Collection Items (Elfogadott + Gyűjtemény Tételek) oldalra, hogy eltávolíthasd ebből a gyűjteményből: + %{collection_items_url}' + unrevealed: + html: Ha szeretnéd, hogy a munkád továbbra is nyilvános legyen, kérlek, + látogass el az %{collection_items_link} oldalra, hogy eltávolíthasd ebből + a gyűjteményből. + text: 'Ha szeretnéd, hogy a munkád továbbra az nyilvános legyen, kérlek, + látogass el az Approved Collection Items (Elfogadott Gyűjtemény Tételek) + oldalra, hogy eltávolíthasd ebből a gyűjteményből: %{collection_items_url}' + faq_link_text: Gyűjtemények GyIK + more_info: + html: További információkért látogass el a %{faq_link} oldalra. + text: 'További információkért látogass el a Gyűjtemények GyIK oldalára: %{faq_url}' + subject: + anonymous: "[%{app_name}] A munkádat névtelenné tettük" + anonymous_unrevealed: "[%{app_name}] A munkád mostantól névtelen és nem nyilvános." + unrevealed: "[%{app_name}] A munkád mostantól nem nyilvános." + unrevealed_info: A nem nyilvános munkák nem jelennek meg sem a kulcsszó listákon, + sem a munkáid között. Ha bárki megpróbálja elérni a linket, üzenetet fog kapni, + miszerint a munka jelenleg nem nyilvános, és így nem fog hozzáférni a tartalomhoz. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Engedélyezett Gyűjtemények) + oldaladat + archivist_notice: Mivel a gyűjtemény karbantartói hivatalos, Open Doors (Nyitott + Ajtók) archivista szerepükben járnak el, hozzáadhatják a munkádat ehhez a + gyűjteményhez akkor is, ha a gyűjteménymeghívásaid ki vannak kapcsolva. Az + archivisták csak akkor adnak hozzá egy munkát egy adott gyűjteményhez, ha + az megjelent egy importált archívumon. + removal_instructions: + html: Ha szeretnéd eltávolítani a munkádat a gyűjteményből, látogasd meg az + %{approved_items_link}. + text: 'Ha szeretnéd eltávolítani a munkádat a gyűjteményből, látogasd meg + az Approved Collection Items (Engedélyezett Gyűjtemények) oldaladat: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Egy Open Doors (Nyitott Ajtók) + archivista hozzáadta a munkádat egy gyűjteményhez" + work_added: + html: A %{collection_link} gyűjtemény karbantartói hozzáadták „%{work_link}" + munkádat a gyűjteményhez! + text: A „%{collection_title}" (%{collection_url}) gyűjtemény karbantartói + hozzáadták „%{work_title}" (%{work_url}) munkádat a gyűjteményhez! + challenge_assignment_notification: + any: Bármi + assignment: + html: A következő kérést kaptad feladatként a(z) %{link} kihívásban az Archive + of Our Own oldalon! + description: 'Leírás:' + due: 'A feladat határideje:' + html: + footer: Azért kaptad ezt az emailt, mert feliratkoztál a(z) %{title} kihívásra. + További információért erről a kihívásról és a moderátorok elérhetőségéért, + kérjük, látogasd meg %{footer_link}. + footer_link: a kihívás profilját + look_up: Megtekintheted a feladatot %{link}. + look_up_link: a te Assignments (Feladatok) oldaladon. + optional_tags: 'Választható kulcsszavak:' + prompts: 'Ötletek:' + prompt_url: 'Ötlet URL-je:' + recipient: 'Ajándékozott:' + recipient_missing: 'Nincs: segítségért lépj kapcsolatba egy moderátorral!' + subject: "[%{app_name}][%{collection_title}] A feladatod!" + text: + assignment: A következő kérést kaptad feladatként a(z) "%{collection_title}" + kihívásban (%{collection_url}) az Archive of Our Own oldalon! + footer: Azért kaptad ezt az emailt, mert feliratkoztál a(z) %{title} kihívásra + (%{url}). További információért erről a kihívásról és a moderátorok elérhetőségéért, + kérjük, látogasd meg %{profile_url}. + look_up: 'Megtekintheted a feladatot a te Assignments (Feladatok) oldaladon: + %{link}.' + change_email: + changed: + html: "%{login}, a fiókodhoz tartozó email cím a következőre változott: %{email}" + text: "%{login}, a fiókodhoz tartozó email cím a következőre változott: %{email}" + subject: "[%{app_name}] Megváltozott email cím" + collection_notification: + assignments_sent: + complete: Minden feladat kiküldésre került. + subject: Feladatok kiküldve + html: + received_message: 'Üzeneted érkezett a(z) %{collection_link} gyűjteményed + kapcsán:' + text: + received_message: 'Üzeneted érkezett a(z) "%{collection_title}" (%{collection_url}) + gyűjteményed kapcsán:' + creatorship_notification: + explanation: Ha egy mű társalkotója vagy, akkor új fejezetekhez adhatnak hozzá + függetlenül a társalkotói beállításaidtól. Minden olyan sorozathoz is hozzá + fognak adni, amelyhez a művet hozzáadják. + html: + creation: "%{pseud_links}: %{creation_link}" + edit_chapter: a fejezet szerkesztésével + edit_series: a sorozat szerkesztésével + remove_chapter: Ha tévedésből adtak hozzá, vagy nem akarod, hogy alkotóként + szerepelj, akkor %{edit_chapter_link} eltávolíthatod magad az alkotók közül. + remove_series: Ha tévedésből adtak hozzá, vagy nem akarod, hogy alkotóként + szerepelj, akkor %{edit_series_link} eltávolíthatod magad az alkotók közül. + intro_chapter: 'Egy %{adding_user} nevű felhasználó társalkotóként tüntette + fel %{pseud} pszeudódat az alábbi fejezeten:' + intro_series: 'Egy %{adding_user} nevű felhasználó társalkotóként tüntette fel + %{pseud} pszeudódat az alábbi sorozaton:' + subject: "[%{app_name}] Társalkotói értesítés" + text: + creation: "%{pseuds}: %{title} (%{url})" + remove_chapter: 'Ha tévedésből adtak hozzá, vagy nem akarod, hogy alkotóként + szerepelj, akkor a fejezet szerkesztésével eltávolíthatod magad az alkotók + közül: %{url}' + remove_series: 'Ha tévedésből adtak hozzá, vagy nem akarod, hogy alkotóként + szerepelj, akkor a sorozat szerkesztésével eltávolíthatod magad az alkotók + közül: %{url}' + creatorship_notification_archivist: + explanation: Mivel az Open Doors (Nyitott Ajtók) archiválójaként járnak el, + felkérés nélkül hozzáadhatnak téged, mint társalkotót, még ha a beállításaidban + ez ki is van kapcsolva. + html: + creation: "%{creation_link} - %{pseud_links}" + edit_chapter: a fejezet szerkesztésével + edit_series: a sorozat szerkesztésével + edit_work: a munka szerkesztésével + remove_chapter: Ha tévedésből lettél megjelölve vagy nem szeretnél alkotóként + szerepelni, %{edit_chapter_link} törölheted magad az alkotók közül. + remove_series: Ha tévedésből lettél megjelölve vagy nem szeretnél alkotóként + szerepelni, %{edit_series_link} törölheted magad az alkotók közül. + remove_work: Ha tévedésből lettél megjelölve vagy nem szeretnél alkotóként + szerepelni, %{edit_work_link} törölheted magad az alkotók közül. + intro_chapter: "%{archivist} felhasználó társalkotónak jelölte %{pseud} pszeudódat + az alábbi fejezeten:" + intro_series: "%{archivist} felhasználó társalkotónak jelölte %{pseud} pszeudódat + az alábbi sorozaton:" + intro_work: "%{archivist} felhasználó társalkotónak jelölte %{pseud} pszeudódat + az alábbi munkán:" + subject: "[%{app_name}] Archiváló társalkotói értesítés" + text: + creation: "%{title} (%{url}) - %{pseuds}" + remove_chapter: 'Ha tévedésből lettél megjelölve vagy nem szeretnél alkotóként + szerepelni, a fejezet szerkesztésével törölheted magad az alkotók közül: + %{url}' + remove_series: 'Ha tévedésből lettél megjelölve vagy nem szeretnél alkotóként + szerepelni, a sorozat szerkesztésével törölheted magad az alkotók közül: + %{url}' + remove_work: 'Ha tévedésből lettél megjelölve vagy nem szeretnél alkotóként + szerepelni, a munka szerkesztésével törölheted magad az alkotók közül: %{url}' + creatorship_request: + html: + creation: "%{pseud_links}: %{creation_link}" + instructions: Elfogadhatod vagy visszautasíthatod ezt a felkérést a %{page_name} + oldaladon. + page_name: Co-Creator Requests (Társalkotói felkérések) + intro_chapter: 'A(z) %{inviting_user} felhasználó meghívta a(z) %{pseud} pszeudódat, + hogy társalkotóként legyen feltüntetve a következő fejezeteken:' + intro_series: 'A(z) %{inviting_user} felhasználó meghívta a(z) %{pseud} pszeudódat, + hogy társalkotóként legyen feltüntetve a következő sorozaton:' + intro_work: 'A(z) %{inviting_user} felhasználó meghívta a(z) %{pseud} pszeudódat, + hogy társalkotóként legyen feltüntetve a következő munkán:' + subject: "[%{app_name}] Felkérés társalkotónak" + text: + creation: "%{pseuds}: %{title} (%{url})" + instructions: 'Elfogadhatod vagy visszautasíthatod ezt a felkérést a Co-Creator + Requests (Társalkotói felkérések) oldaladon: %{url}' + delete_work_notification: + attachment: A szóban forgó munkádat csatoltuk az e-mailhez. + deleted_other: + html: "%{pseud} kérésére töröltük %{title} című munkádat." + text: '%{pseud} kérésére töröltük "%{title}" című munkádat.' + deleted_yourself: + html: Kérésedre töröltük %{title} című munkádat. + text: Kérésedre töröltük "%{title}" című munkádat. + questions: + html: Ha kérdésed van, %{support}. + text: Ha kérdésed van, %{support} (%{url}). + subject: "[%{app_name}] Munkádat töröltük" + support: lépj kapcsolatba a Támogatással + invitation: + subject: "[%{app_name}] Pozivnica" + invitation_to_claim: + access: + text: Az archívumtól függően előfordulhat, hogy műveid csak regisztrált felhasználók + érhetik el (hogy ne kerüljenek a Google keresésekbe). Ebben az esetben a + munkákhoz csak bejelentkezett felhasználók férhetnek hozzá, hacsak nem döntesz + úgy, hogy teljesen láthatóvá teszed őket. Ha segítségre van szükséged munkáid + nyilvánossá tételében, elhagyásában vagy törlésében, lépj kapcsolatba az + AO3 Támogatással. + claim_or_remove: + html: Foglald le vagy töröld a munkáidat itt. + text: 'Foglald le vagy töröld a munkáidat itt: %{claim_url}' + email_tips: Ha kapcsolatba lépsz velünk, kérjük, engedélyezd a @transformativeworks.org + e-mail címeit, és ellenőrizd, hogy válaszunk nincs-e a spam mappában. + html: + ao3_news: AO3 Hírek + contact_open_doors: lépj kapcsolatba a Nyitott Ajtókkal + contact_support: lépj kapcsolatba az AO3 támogatással + faq_page: GyIK + tutorial_page: útmutató + introduction: + text: Azért kapod ezt az e-mailt, mert a Nyitott Ajtók (%{open_doors_link}) + a közelmúltban importált egy archívumot az %{app_name}ra (%{app_short_name} + - %{app_url}), és úgy gondoljuk, hogy az alábbi rajongói munkák hozzád tartoznak. + Szeretnénk neked esélyt adni arra, hogy lefoglald (vagy töröld/elhagyd) + ezeket a munkákat, ha úgy gondolod. Illetve ha még nem rendelkezel fiókkal + más e-mail cím alatt, szeretnénk meghívni! + mistake: + text: Ha tévedés történt és ezek nem a Te munkáid, kérjük, ne töröld őket! + Csak lépj kapcsolatba a Nyitott Ajtókkal (%{open_doors_link}) és mi mindent + elrendezünk. + more_info: + text: 'A legfrissebb archívum költöztetésekről szóló bejelentéseket az AO3 + Hírek (%{news_link}) oldalán olvashatod, további információkat pedig a Nyitott + Ajtók GyIK (%{open_doors_faq_link}) vagy útmutatók oldalán (%{open_doors_tutorial_link}) + találhatsz. Ha olyan kérdésed van, amelyre a GYIK-ben, az útmutatókban vagy + ebben az e-mailben nem válaszoltunk, kérjük, lépj kapcsolatba az AO3 támogatással + az alábbi linken: %{support_link}.' + other_works: + text: Ha más munkáid is voltak az importált archívumon olyan e-mail cím alatt, + amelyhez már nem férsz hozzá, kérjük, lépj kapcsolatba a Nyitott Ajtókkal + bármilyen információval, amely segíthet személyazonosságod megerősítésében. + questions: + text: 'Ha más kérdésed lenne, kérjük, lépj kapcsolatba az AO3 Támogatással + az alábbi linken: %{support_link}.' + redirects: Az ajánlólisták és a könyvjelzők megőrzése érdekében az importált + archívum webcímei korlátozott ideig a munkák importált másolatára irányíthatnak + át (biztos információért ellenőrizd az archívum bejelentő posztját). Ha már + feltöltöttél egy példányt ezekből a munkákból és NEM használtad az URL-ből + történő importálás funkciót, akkor ugyanazon mű két másolata lesz az archívumon. + subject: "[%{app_name}] Meghívó munkák lefoglalására" + unwanted: + text: 'Ha ezek a munkák hozzád tartoznak, de nem szeretnéd már őket, lehetőséged + van őket elhagyni (így az AO3-on maradnak, de a neved el lesz távolítva + róluk), vagy törölni (így teljes mértékben eltávolítjuk őket az AO3-ról). + A munkák elhagyásához vagy törléséhez nem szükséges őket bármilyen fiókhoz + rendelni - ezt közvetlenül a fenti lefoglalási link segítségével is megteheted. + (További segítségért kérjük, lépj kapcsolatba a Támogatással az alábbi linken: + %{support_link}.)' + update_redirect: + text: Ha azt szeretnéd, hogy a Nyitott Ajtók frissítse az átirányítást, hogy + a már meglévő munkádra mutasson, kérjük, töröld az importált példányt, és + lépj kapcsolatba a Nyitott Ajtókkal (%{open_doors_link}) az AO3-fiókod nevével, + az importált archívumi fiókod nevével, illetve a rajongói munka címével + és URL-jével, amelyre az átirányítás mutasson. (Ha több munkád van, amelyeknél + meg szeretnéd változtatni az átirányításokat, akkor ezeket felsorolhatod + egy e-mailben.) + uploaded_list: 'A feltöltött munkák az alábbiak:' + invite_increase_notification: + html: + body: + one: 'Örömmel tudatjuk veled, hogy van %{count} új meghívód, amelyet új + fiók létrehozására használhatsz az AO3-on. Itt hívhatsz meg egy barátot: + %{invitation_page_link}.' + other: 'Örömmel tudatjuk veled, hogy van %{count} új meghívód, amelyeket + új fiókok létrehozására használhatsz az AO3-on. Itt hívhatsz meg barátokat: + %{invitation_page_link}.' + invitation_page_link_text: Invitations (Meghívók) oldalad + subject: "[%{app_name}] Új Meghívók" + text: + body: + one: Örömmel tudatjuk veled, hogy van %{count} új meghívód, amelyet új fiók + létrehozására használhatsz az AO3-on. Te is meghívhatod egy barátod az + Invitations (Meghívások) oldalon (%{invitation_page_url}). + other: Örömmel tudatjuk veled, hogy van %{count} új meghívód, amelyeket + új fiókok létrehozására használhatsz az AO3-on.Te is meghívhatod egy barátod + az Invitations (Meghívások) oldalon (%{invitation_page_url}). + invite_request_declined: + main: + one: Sajnálattal közöljük, hogy új meghívókra vonatkozó kérésed jelenleg nem + áll módunkban teljesíteni. + other: Sajnálattal közöljük, hogy %{count} új meghívóra vonatkozó kérésed + jelenleg nem áll módunkban teljesíteni. + reason: 'Kérésed a következő volt:' + subject: "[%{app_name}] További meghívó kódok kérése elutasítva" + recipient_notification: + html: + collection: Egy ajándék munkát posztoltak a számodra a(z) %{collection_link} + gyűjteményben az AO3-on! + no_collection: Egy ajándék munkát posztoltak a számodra az AO3-on! + subject: + collection: "[%{app_name}][%{collection_title}] Egy ajándék munka a számodra + a(z) %{collection_title} gyűjteményben" + no_collection: "[%{app_name}] Egy ajándék munka a számodra" + text: + collection: Egy ajándék munkát posztoltak a számodra a(z) "%{collection_title}" + gyűjteményben (%{collection_url}) az AO3-on! + signup_notification: + activate: + html: Kérjük, %{activate_account_link}. + text: 'Kérjük, kövesd ezt a linket a felhasználói fiókod aktiválásához: %{activate_account_url}' + activate_your_account: kövesd ezt a linket a felhasználói fiókod aktiválásához. + admin_posts: Archívum Hírek + bye: Reméljük, örömöd leled az Archívum használatában. + contact_support: lépj kapcsolatba a Támogatással + faq: GyIK + features: + html: Ha a felhasználói fiókod elkészült, közzé teheted rajongói munkáid, + beállíthatod az email feliratkozásaid, hogy értesítést kapj, amikor a kedvenc + alkotóid új munkát tettek közzé, vagy a kedvenc munkádat frissítették. Személyre + szabhatod az oldal működését és kinézetét, nyomon követheted az általad + az Archívumon megtekintett munkákat az előzményeidben, és még sok más funkciót + is elérhetsz. + text: Ha a felhasználói fiókod elkészült, közzé teheted rajongói munkáid, + beállíthatod az email feliratkozásaid, hogy értesítést kapj, amikor a kedvenc + alkotóid új munkát tettek közzé, vagy a kedvenc munkádat frissítették. Személyre + szabhatod az oldal működését és kinézetét, nyomon követheted az általad + az Archívumon megtekintett munkákat az előzményeidben, és még sok más funkciót + is elérhetsz. + information: + html: Sok információt és tanácsot találsz az Archívum használatával kapcsolatban + a %{faq_link} linken. Az oldal fejlesztésének legújabb híreit az %{admin_posts_link} + oldalon olvashatod. Ha több segítségre van szükséged, hibát fedeztél fel, + kérdéseid vagy megjegyzéseid vannak, %{contact_support_link}, akik mindig + szívesen rendelkezésedre állnak. + text: 'Sok információt és tanácsot találsz az Archívum használatával kapcsolatban + a GyIK-ben, a %{faq_url} oldalon. Az oldal fejlesztésének legújabb híreit + az Archívum Hírek oldalon, az %{admin_posts_url} linken olvashatod. Ha több + segítségre van szükséged, hibát fedeztél fel, kérdéseid vagy megjegyzéseid + vannak, lépj kapcsolatba a Támogatás csapattal, akik mindig szívesen rendelkezésedre + állnak: %{contact_support_url}.' + welcome: Üdvözlünk az Archive of Our Own-on (A Mi Archívumunkon), %{login}! diff --git a/config/locales/phrase-exports/id.yml b/config/locales/phrase-exports/id.yml new file mode 100755 index 0000000..c5a3e4b --- /dev/null +++ b/config/locales/phrase-exports/id.yml @@ -0,0 +1,630 @@ +--- +id: + activerecord: + attributes: + archive_warning: + name_with_colon: + other: 'Peringatan:' + category: + name_with_colon: + other: 'Kategori:' + character: + name_with_colon: + other: 'Karakter:' + fandom: + name_with_colon: + other: 'Fandom:' + freeform: + name_with_colon: + other: 'Label Tambahan:' + rating: + name_with_colon: 'Rating:' + relationship: + name_with_colon: + other: 'Pasangan:' + work: + chapter_total_display: Bab + summary: Sinopsis + models: + archive_warning: + other: Peringatan + category: + other: Kategori + chapter: + other: Bab + character: + other: Karakter + fandom: + other: Fandom + freeform: + other: Label Tambahan + rating: + other: Rating + relationship: + other: Pasangan + series: + other: Seri + kudo_mailer: + batch_kudo_notification: + guest: + other: "%{count} tamu" + left_kudos: + html: + other: "%{givers_list} telah memberikan kudos untuk %{commentable_link}." + text: + other: "%{givers_list} telah memberikan kudos untuk %{commentable_title} + (%{commentable_url})." + single_guest: + giver: Seorang tamu + html: "%{giver} telah memberikan kudos untuk %{commentable_link}." + text: Seorang tamu telah memberikan kudos untuk %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Anda telah menerima kudos!" + mailer: + general: + closing: + formal: Dengan hormat, + informal: Salam, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Bab %{position} pada %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + other: "%{count} kata" + footer: + general: + about: + html: AO3 adalah arsip yang dikelola dan didukung oleh sesama fan dan + bergantung pada %{donate_link}. + text: 'AO3 adalah arsip yang dikelola dan didukung oleh sesama fan dan + bergantung pada donasi Anda: %{donate_url}.' + html: + donate_link_text: donasi Anda + support_link_text: hubungi Komite Bantuan + unwanted_email: + html: Jika Anda tidak seharusnya menerima pesan ini, silakan %{support_link}. + text: Jika Anda tidak seharusnya menerima pesan ini, silakan hubungi Komite + Bantuan di %{support_url}. + sent_at: Dikirimkan pada %{sent_at}. + greeting: + formal_html: Halo %{name}, + informal: + addressed_html: Halo %{name}! + unaddressed: Halo! + introductory: Halo dari Archive of Our Own – AO3 (Arsip Milik Kita)! + metadata_label_indicator: ":" + signature: + abuse_team: Komite Kebijakan dan Pelanggaran AO3 + app_short_name: AO3 + open_doors: Tim Open Doors (Pintu Terbuka) + parent_org: Organization for Transformative Works – OTW (Organisasi untuk + Karya Transformatif) + support: Komite Bantuan AO3 + users: + mailer: + reset_password_instructions: + expiration: Tautan ini akan kadaluarsa jika tidak digunakan untuk mengubah + kata sandi Anda dalam satu minggu. Setelah itu, Anda perlu meminta tautan + baru. + intro: 'Terdapat permintaan pengaturan ulang kata sandi Anda. Kata sandi akun + Anda dapat diubah dengan mengikuti tautan berikut dan memasukkan kata sandi + yang baru:' + link_title: Ubah kata sandi saya. + subject: "[%{app_name}] Atur ulang kata sandi Anda" + unrequested: Jika Anda tidak pernah meminta pengaturan ulang kata sandi Anda, + silakan abaikan surel ini. Kata sandi lama Anda akan tetap berfungsi. + user_mailer: + admin_deleted_work_notification: + bye: Terlampir adalah salinan karya Anda sebagai referensi. + contact_abuse: hubungi Komite Kebijakan dan Pelanggaran kami + deleted: + html: Karya Anda, %{title}, telah dihapus dari AO3 oleh admin situs. + text: Karya Anda, "%{title}", telah dihapus dari AO3 oleh admin situs. + html: + tos_violation: Jika ada kemungkinan karya Anda melanggar Ketentuan Layanan + AO3, silakan %{contact_abuse_link}. + import_project: + html: Jika karya Anda merupakan bagian dari proyek impor yang diatur oleh + Komite Open Doors (Pintu Terbuka) kami, silakan %{opendoors_link} dengan + pertanyaan lebih lanjut. + text: Jika karya Anda merupakan bagian dari proyek impor yang diatur oleh + Komite Open Doors (Pintu Terbuka) kami, silakan hubungi Komite Pintu Terbuka + (%{opendoors_link}) dengan pertanyaan lebih lanjut. + opendoors: hubungi Komite Pintu Terbuka + subject: "[%{app_name}] Karya Anda telah dihapus oleh admin" + text: + tos_violation: Jika ada kemungkinan karya Anda melanggar Ketentuan Layanan + AO3, silakan hubungi Komite Kebijakan dan Pelanggaran kami (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Anda masih bisa mengakses karya tersebut melalui tautan di atas. Namun + karya tersebut tidak terdaftar dalam halaman karya Anda dan tidak tersedia + untuk pengguna AO3 lainnya. + check_email: Silakan periksa email Anda, termasuk kotak spam, karena Komite + Kebijakan dan Pelanggaran mungkin sudah mengirimkan alasan karya Anda disembunyikan. + contact_abuse: hubungi Komite Kebijakan dan Pelanggaran + html: + help: Jika Anda tidak yakin alasan karya Anda disembunyikan dan Anda belum + menerima komunikasi terkait hal ini, silakan %{contact_abuse_link} secara + langsung. + hidden: Karya Anda, %{title}, telah disembunyikan oleh Komite Kebijakan dan + Pelanggaran dan tidak dapat diakses publik lagi. + tos_violation: Jika karya Anda disembunyikan karena melanggar %{tos_link} + AO3, maka Anda harus melakukan tindakan untuk memperbaiki pelanggaran tersebut. + Karya Anda akan dihapus dari AO3 jika tidak mengikuti Ketentuan Layanan. + subject: "[%{app_name}] Karya Anda telah disembunyikan oleh Komite Kebijakan + dan Pelanggaran" + text: + help: 'Jika Anda tidak yakin alasan karya Anda disembunyikan dan Anda belum + menerima komunikasi terkait hal ini, silakan hubungi Komite Kebijakan dan + Pelanggaran secara langsung: %{contact_abuse_url}.' + hidden: Karya Anda, "%{title}" (%{work_url}), telah disembunyikan oleh Komite + Kebijakan dan Pelanggaran dan tidak dapat diakses publik lagi. + tos_violation: Jika karya Anda disembunyikan karena melanggar Ketentuan Layanan + AO3 (%{tos_url}), maka Anda harus melakukan tindakan untuk memperbaiki pelanggaran + tersebut. Karya Anda akan dihapus dari AO3 jika tidak mengikuti Ketentuan + Layanan. + tos: Ketentuan Layanan + anonymous_or_unrevealed_notification: + anonymous_info: Karya anonim tetap terlihat dalam daftar tag (label), namun + tidak dalam halaman karya Anda. Di karya tersebut, nama pengguna Anda akan + digantikan dengan "Anonymous" (Anonim). + anonymous_unrevealed_info: Moderator koleksi bisa saja akan membuka karya Anda + namun tetap membuatnya anonim. Akun yang berlangganan dengan Anda tidak akan + menerima notifikasi atas perubahan ini. Setelah dibuka, karya Anda akan termasuk + dalam daftar tag (label), tapi tidak dalam halaman karya Anda. Di karya tersebut, + nama pengguna Anda akan digantikan dengan "Anonymous" (Anonim). + changed_status: + anonymous: + html: Moderator koleksi %{collection_link} telah mengubah status karya Anda, + %{work_link}, menjadi anonim. + text: Moderator Koleksi "%{collection_title}" (%{collection_url}) telah + mengubah status karya anda "%{work_title}" (%{work_url}) menjadi anonim + anonymous_unrevealed: + html: Moderator koleksi %{collection_link} telah mengubah status karya Anda, + %{work_link}, menjadi anonim dan unrevealed (tersembunyi). + text: Moderator Koleksi "%{collection_title}" (%{collection_url}) telah + mengubah status karya anda "%{work_title}" (%{work_url}) menjadi anonim + dan unrevealed (tersembunyi) + unrevealed: + html: Moderator koleksi %{collection_link} telah mengubah status karya Anda, + %{work_link}, menjadi unrevealed (tersembunyi). + text: Moderator Koleksi "%{collection_title}" (%{collection_url}) telah + mengubah status karya anda "%{work_title}" (%{work_url}) menjadi unrevealed + (tersembunyi) + collection_items_link_text: halaman Approved Collection Items (Artikel Koleksi + yang Disetujui) + do_not_want: + anonymous: + html: Jika Anda tidak ingin karya Anda dibuat menjadi anonim, silakan kunjungi + %{collection_items_link} untuk menghapus karya tersebut dari koleksi ini. + text: 'Jika Anda tidak ingin karya Anda dibuat anonim, silakan kunjungi + halaman Approved Collection Items (Artikel Koleksi yang Disetujui) untuk + menghapus karya tersebut dari koleksi ini: %{collection_items_url}' + anonymous_unrevealed: + html: Jika Anda tidak ingin karya Anda dibuat anonim dan disembunyikan, + silakan kunjungi %{collection_items_link} untuk menghapus karya tersebut + dari koleksi ini. + text: 'Jika Anda tidak ingin karya Anda dibuat anonim dan disembunyikan, + silakan kunjungi halaman Approved Collection Items (Artikel Koleksi yang + Disetujui) untuk menghapus karya tersebut dari koleksi ini: %{collection_items_url}' + unrevealed: + html: Jika Anda tidak ingin karya Anda disembunyikan, silakan kunjungi %{collection_items_link} + untuk menghapus karya tersebut dari koleksi ini. + text: 'Jika Anda tidak ingin karya Anda disembunyikan, silakan kunjungi + halaman Approved Collection Items (Artikel Koleksi yang Disetujui) untuk + menghapus karya tersebut dari koleksi ini: %{collection_items_url}' + faq_link_text: Pertanyaan Umum tentang Koleksi + more_info: + html: Untuk informasi lebih lanjut, silakan kunjungi %{faq_link}. + text: 'Untuk informasi lebih lanjut, silakan kunjungi Pertanyaan Umum tentang + Koleksi: %{faq_url}' + subject: + anonymous: "[%{app_name}] Karya Anda telah dibuat anonim" + anonymous_unrevealed: "[%{app_name}] Karya Anda telah dibuat anonim dan disembunyikan" + unrevealed: "[%{app_name}] Karya Anda telah disembunyikan" + unrevealed_info: Karya tersembunyi tidak akan terlihat dalam daftar tag (label) + maupun halaman karya Anda. Semua orang yang membuka tautan ke karya tersebut + tidak akan dapat melihat kontennya dan akan menerima notifikasi bahwa karya + tersebut saat ini sedang disembunyikan. + archivist_added_to_collection_notification: + approved_collection_items_page: Laman Approved Collection Items (Barang Koleksi + yang Telah Disetujui) + archivist_notice: Karena pengelola koleksi bertindak sesuai dengan kewenangannya + sebagai admin arsip Open Doors (Pintu Terbuka), mereka diizinkan untuk menambahkan + karya Anda ke koleksi ini, meskipun Anda tidak mengizinkan undangan koleksi. + Admin arsip hanya akan menambahkan karya ke koleksi jika karya tersebut sebelumnya + berada di arsip yang diimpor. + removal_instructions: + html: Jika Anda ingin mengeluarkan karya Anda dari koleksi ini, mohon kunjungi + %{approved_items_link}. + text: 'Jika Anda ingin mengeluarkan karya Anda dari koleksi ini, mohon kunjungi + laman Approved Collection Items (Barang Koleksi yang Telah Disetujui) Anda: + %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Admin arsip Open Doors (Pintu Terbuka) + telah menambahkan karya Anda ke dalam sebuah koleksi" + work_added: + html: Pengelola koleksi dari %{collection_link} telah menambahkan karya Anda + %{work_link} ke dalam koleksi mereka! + text: Pengelola koleksi "%{collection_title}" (%{collection_url}) telah menambahkan + karya Anda "%{work_title}" (%{work_url}) ke koleksinya! + challenge_assignment_notification: + any: Apapun + assignment: + html: Anda ditugaskan untuk memenuhi permintaan dalam challenge (tantangan) + berikut %{link} di AO3! + description: 'Deskripsi:' + due: 'Tenggat waktu tugas ini adalah:' + html: + footer: Anda menerima surel ini karena Anda telah mendaftarkan diri untuk + mengikuti tantangan %{title}. Untuk informasi lebih lanjut terkait tantangan + ini atau untuk informasi kontak moderator, silakan kunjungi %{footer_link}. + footer_link: halaman profil tantangan + look_up: Anda dapat melihat tugas ini dari %{link}. + look_up_link: halaman Assignments (Tugas) Anda + optional_tags: 'Tag (Label) Opsional:' + prompts: 'Prompt (Ide Karya):' + prompt_url: 'URL Prompt (Ide Karya):' + recipient: 'Penerima:' + recipient_missing: 'Tidak tersedia: hubungi moderator untuk bantuan!' + subject: "[%{app_name}][%{collection_title}] Tugas Anda!" + text: + assignment: Anda telah diberikan tugas untuk memenuhi permintaan berikut dalam + challenge (tantangan) "%{collection_title}" (%{collection_url}) di AO3! + footer: Anda menerima surel ini karena Anda telah mendaftarkan diri untuk + mengikuti tantangan %{title} (%{url}). Untuk informasi lebih lanjut terkait + tantangan ini atau untuk informasi kontak moderator, silakan kunjungi %{profile_url}. + look_up: Anda dapat melihat tugas ini dari halaman Assignments (Tugas) di + %{link}. + change_email: + changed: + html: "%{login}, alamat surel yang diasosiasikan dengan akun Anda telah diganti + ke %{email}" + text: "%{login}, alamat surel yang diasosiasikan dengan akun Anda telah diganti + ke %{email}" + subject: "[%{app_name}] Alamat surel telah diganti" + claim_notification: + access: + contact_support: hubungi Komite Bantuan AO3 + html: Menyesuaikan dengan arsipnya, karya Anda mungkin telah diimpor secara + terbatas hanya untuk pengguna yang terdaftar (untuk mencegah agar tidak + muncul di pencarian Google). Jika demikian, maka karya-karya tersebut hanya + dapat diakses oleh pengguna yang sudah masuk ke akun AO3, kecuali jika Anda + memilih untuk membuatnya terbuka untuk umum. Untuk bantuan dalam mengubah + pengaturan karya menjadi terbuka untuk umum, orphaning (meninggalkan karya), + atau menghapus karya, silakan %{contact_support_link}. + text: Menyesuaikan dengan arsipnya, karya Anda mungkin telah diimpor secara + terbatas hanya untuk pengguna yang terdaftar (untuk mencegah agar tidak + muncul di pencarian Google). Jika demikian, maka karya-karya tersebut hanya + dapat diakses oleh pengguna yang sudah masuk ke akun AO3, kecuali jika Anda + memilih untuk membuatnya terbuka untuk umum. Untuk bantuan dalam mengubah + pengaturan karya menjadi terbuka untuk umum, orphaning (meninggalkan karya), + atau menghapus karya, silakan hubungi Komite Bantuan AO3 di %{support_url}. + email_tips: Jika Anda menghubungi kami, harap tambahkan alamat surel dari @transformativeworks.org + ke dalam daftar pengirim aman dan periksa folder spam Anda untuk menemukan + balasan dari kami. + introduction: + ao3_name: Archive of Our Own - AO3 (Arsip Milik Kita) + html: Anda menerima surel ini karena Anda memiliki karya di arsip karya fan + yang telah diimpor oleh %{open_doors_name_link} ke %{app_link}. Karena alamat + surel ini terhubung dengan alamat surel yang terdaftar di arsip yang diimpor, + maka karya fan terkait (tercantum di bawah ini) telah secara otomatis ditambahkan + ke akun AO3 Anda. + open_doors_name: Open Doors (Pintu Terbuka) + text: 'Anda menerima surel ini karena Anda memiliki karya di arsip karya fan + yang telah diimpor oleh Open Doors (Pintu Terbuka) (%{open_doors_url}) ke + Archive of Our Own – AO3 (Arsip Milik Kita): %{app_url}. Karena alamat surel + ini terhubung dengan alamat surel yang terdaftar di arsip yang diimpor, + maka karya fan terkait (tercantum di bawah ini) telah secara otomatis ditambahkan + ke akun AO3 Anda.' + mistake: + contact_open_doors: hubungi Pintu Terbuka + html: Jika hal ini merupakan sebuah kesalahan dan karya-karya tersebut bukan + milik Anda, harap jangan dihapus! Harap %{contact_open_doors_link} dan kami + akan menyelesaikan masalah ini. + text: Jika ini merupakan sebuah kesalahan dan karya-karya ini bukan karya + Anda, harap jangan dihapus! Harap hubungi Pintu Terbuka (%{open_doors_url}) + dan kami akan menyelesaikan masalah ini. + more_info: + ao3_news: Berita AO3 + contact_support: hubungi Komite Bantuan AO3 + faq_page: laman Pertanyaan Umum + html: Anda dapat membaca pengumuman mengenai pemindahan arsip terbaru di %{ao3_news_link}, + dan menemukan informasi tambahan di %{faq_page_link} atau %{tutorial_page_link} + milik Pintu Terbuka. Untuk pertanyaan yang tidak terjawab dalam Pertanyaan + Umum, tutorial, atau surel ini, silakan %{contact_support_link}. + text: Anda dapat membaca pengumuman mengenai pemindahan arsip terbaru di Berita + AO3 (%{news_url}), dan menemukan informasi tambahan di halaman Pertanyaan + Umum (%{open_doors_faq_url}) atau halaman tutorial (%{open_doors_tutorial_url}) + milik Pintu Terbuka. Untuk pertanyaan yang tidak terjawab dalam Pertanyaan + Umum, tutorial, atau surel ini, silakan hubungi Komite Bantuan AO3 di %{support_url}. + tutorial_page: laman tutorial + other_works: + contact_open_doors: hubungi Pintu Terbuka + html: Jika Anda memiliki karya-karya lain pada arsip yang diimpor yang ditulis + atas nama alamat surel yang tidak dapat Anda akses lagi, silakan %{contact_open_doors_link} + dengan informasi apa saja yang dapat membantu memverifikasi identitas Anda. + text: Jika Anda memiliki karya lain pada arsip yang diimpor yang ditulis atas + nama alamat surel yang tidak dapat Anda akses lagi, silakan hubungi Pintu + Terbuka dengan informasi apa saja yang dapat membantu memverifikasi identitas + Anda. + questions: + contact_support: hubungi Komite Bantuan AO3 + html: Untuk pertanyaan lainnya, silakan %{contact_support_link}. + text: Untuk pertanyaan lainnya, silakan hubungi Komite Bantuan AO3 di %{support_url}. + redirects: + html: Untuk melestarikan daftar rekomendasi dan markah buku, alamat web dari + arsip yang diimpor mungkin akan dialihkan ke salinan karya yang telah diimpor + selama waktu tertentu (periksa artikel pengumuman arsip Anda untuk memastikannya). + Jika Anda telah mengunggah salinan dari karya-karya ini dan Anda %{negation} + menggunakan fitur impor dari URL, maka akan ada dua salinan dari karya yang + sama di AO3. + subject: "[%{app_name}] Karya diunggah" + update_redirect: + contact_open_doors: hubungi Pintu Terbuka + html: Jika Anda ingin Open Doors (Pintu Terbuka) untuk memperbarui pengalihan + tautan ke karya Anda yang sudah ada sebelumnya, hapus salinan yang telah + diimpor, dan %{contact_open_doors_link} dengan nama akun AO3 Anda, nama + akun Anda di arsip yang telah diimpor, dan judul beserta URL dari karya + fan yang ingin Anda jadikan sebagai tujuan dari pengalihan tautan. (Jika + Anda memiliki lebih dari satu karya yang ingin Anda ubah pengalihan tautannya, + Anda dapat mencantumkan semuanya di dalam satu surel.) + text: Jika Anda ingin Pintu Terbuka memperbarui pengalihan tautan untuk mengarahkan + ke karya Anda yang sudah ada sebelumnya, hapus salinan yang telah diimpor, + dan hubungi Pintu Terbuka di %{open_doors_url} dengan nama akun AO3 Anda, + nama akun Anda di arsip yang telah diimpor, dan judul beserta URL dari karya + fan yang ingin Anda jadikan sebagai tujuan dari pengalihan tautan. (Jika + Anda memiliki lebih dari satu karya yang ingin Anda ubah pengalihan tautannya, + Anda dapat mencantumkan semuanya di dalam satu surel.) + works_by: 'Karya-karya berikut ditulis atas nama surel: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Seluruh Assignment (tugas) telah dikirimkan. + subject: Assignment (tugas) telah dikirim + html: + received_message: 'Anda menerima pesan tentang collection (koleksi) %{collection_link} + Anda:' + text: + received_message: 'Anda menerima pesan tentang collection (koleksi) "%{collection_title}" + (%{collection_url}) Anda:' + creatorship_notification: + explanation: Ketika Anda menjadi seorang rekan kreator sebuah karya, Anda dapat + ditambahkan pada bab-bab terbaru dalam karya terlepas dari pengaturan pembuatan + karya rekanan sebelumnya. Anda juga akan ditambahkan ke dalam seri manapun + tempat karya tersebut berada. + html: + creation: "%{creation_link} oleh %{pseud_links}" + edit_chapter: menyunting chapter tersebut + edit_series: menyunting series tersebut + remove_chapter: Jika Anda ditambahkan akibat kesalahan atau Anda tidak ingin + didaftarkan sebagai kreator, Anda dapat %{edit_chapter_link} untuk menghapus + status Anda sebagai kreator. + remove_series: Jika Anda ditambahkan akibat kesalahan atau Anda tidak ingin + didaftarkan sebagai kreator, Anda dapat %{edit_series_link} untuk menghapus + status Anda sebagai kreator. + intro_chapter: 'Pengguna %{adding_user} telah mendaftarkan nama pengguna Anda + %{pseud} sebagai rekan kreator pada chapter (bab) berikut:' + intro_series: 'Pengguna %{adding_user} telah mendaftarkan pseud (alias) %{pseud} + anda sebagai rekan kreator dalam series (seri) berikut:' + subject: "[%{app_name}] Notifikasi Rekan kreator" + text: + creation: "%{title} (%{url}) oleh %{pseuds}" + remove_chapter: 'Jika Anda ditambahkan akibat kesalahan atau tidak ingin didaftarkan + sebagai kreator, Anda dapat menyunting chapter untuk menghapus status Anda + sebagai kreator: %{url}' + remove_series: 'Jika Anda ditambahkan akibat kesalahan atau tidak ingin didaftarkan + sebagai kreator, Anda dapat menyunting series tersebut untuk menghapus status + Anda sebagai kreator: %{url}' + creatorship_notification_archivist: + explanation: Karena berlaku dalam kapasitas resmi sebagai pengarsip Open Doors, + ia diizinkan untuk menunjuk Anda sebagai rekan pencipta tanpa permintaan, + walaupun Anda telah mematikan opsi untuk menjadi rekan pencipta. + html: + creation: "%{creation_link} oleh %{pseud_links}" + edit_chapter: sunting bab + edit_series: sunting serial + edit_work: sunting karya + remove_chapter: Jika ada kesalahan dalam penunjukan ini atau Anda tidak ingin + ditunjuk sebagai pencipta, Anda dapat menghapus alias Anda sebagai pencipta + di %{edit_chapter_link}. + remove_series: Jika ada kesalahan dalam penunjukan ini atau Anda tidak ingin + ditunjuk sebagai pencipta, Anda dapat menghapus alias Anda sebagai pencipta + %{edit_series_link}. + remove_work: Jika ada kesalahan dalam penunjukan ini atau Anda tidak ingin + ditunjuk sebagai pencipta, Anda dapat %{edit_work_link} untuk menghapus + alias Anda sebagai pencipta. + intro_chapter: 'Pengguna %{archivist} telah menunjuk alias %{pseud} Anda sebagai + rekan pencipta untuk bab berikut:' + intro_series: 'Pengarsip %{archivist} telah menunjuk alias %{pseud} Anda sebagai + rekan pencipta untuk serial berikut:' + intro_work: 'Pengarsip %{archivist} telah menunjuk alias %{pseud} Anda sebagai + rekan pencipta untuk karya berikut:' + subject: "[%{app_name}] Notifikasi penunjukan sebagai rekan pencipta oleh pengarsip" + text: + creation: "%{title} (%{url}) oleh %{pseuds}" + remove_chapter: 'Jika ada kesalahan dalam penunjukan ini atau Anda tidak ingin + ditunjuk sebagai pencipta, Anda dapat menyunting bab ini untuk menghapus + alias Anda sebagai pencipta: %{url}' + remove_series: 'Jika ada kesalahan dalam penunjukan ini atau Anda tidak ingin + ditunjuk sebagai pencipta, Anda dapat menyunting serial ini untuk menghapus + alias Anda sebagai pencipta: %{url}' + remove_work: 'Jika ada kesalahan dalam penunjukan ini atau Anda tidak ingin + ditunjuk sebagai pencipta, Anda dapat menyunting karya ini untuk menghapus + alias Anda sebagai pencipta: %{url}' + creatorship_request: + html: + creation: "%{creation_link} oleh %{pseud_links}" + instructions: Anda dapat menerima atau menolak undangan ini di halaman %{page_name} + Anda. + page_name: Co-Creator Requests (Undangan Rekan Kreator) + intro_chapter: 'Pengguna %{inviting_user} mengundang Pseud (alias) Anda %{pseud} + untuk didaftarkan sebagai rekan kreator di chapter (bab) berikut:' + intro_series: 'Pengguna %{inviting_user} mengundang Pseud (alias) Anda %{pseud} + untuk didaftarkan sebagai rekan kreator di series (seri) berikut:' + intro_work: 'Pengguna %{inviting_user} mengundang Pseud (alias) Anda %{pseud} + untuk didaftarkan sebagai rekan kreator di karya berikut:' + subject: "[%{app_name}] Undangan rekan kreator" + text: + creation: "%{title} (%{url}) oleh %{pseuds}" + instructions: 'Anda dapat menerima atau menolak undangan ini di halaman Co-Creator + Requests (Undangan Rekan Kreator) Anda: %{url}' + delete_work_notification: + attachment: Terlampir salinan karya Anda sebagai referensi. + deleted_other: + html: Karya Anda, %{title}, telah dihapus atas permintaan %{pseud}. + text: Karya Anda, "%{title}", telah dihapus atas permintaan %{pseud}. + deleted_yourself: + html: Karya Anda, %{title}, telah dihapus atas permintaan Anda. + text: Karya Anda, "%{title}", telah dihapus atas permintaan Anda. + questions: + html: Jika Anda memiliki pertanyaan, silakan %{support}. + text: Jika Anda memiliki pertanyaan, silakan %{support} (%{url}). + subject: "[%{app_name}] Karya Anda telah dihapus" + support: hubungi Komite Bantuan + invitation: + been_invited: Kamu telah diundang untuk menjadi beta kami! + has_invited: "%{user_name} telah mengundangmu untuk bergabung menjadi beta kami!" + html: + faq_link_text: Pertanyaan umum kami + subject: Undangan [%{app_name}] + invitation_to_claim: + access: + text: Tergantung pada arsip asalnya, karya-karya Anda mungkin saja telah diimpor + dan hanya dapat dilihat oleh pengguna yang terdaftar saja (untuk mencegah + pencarian karya tersebut melalui Google). Jika hal ini terjadi, karya-karya + tersebut hanya dapat diakses oleh pengguna yang telah tercatat masuk, kecuali + Anda memutuskan untuk membuka akses terhadap karya Anda. Untuk bantuan membuka + karya, meninggalkan karya, atau menghapus karya, silakan hubungi tim Dukungan + AO3. + claim_or_remove: + html: Klaim atau hapus karya Anda di sini. + text: 'Klaim atau hapus karya Anda di sini: %{claim_url}' + email_tips: Jika Anda ingin menghubungi kami, harap masukkan alamat-alamat surel + dari @transformativeworks.org ke daftar putih kontak Anda dan cek folder spam + Anda untuk memastikan Anda menerima balasan kami. + html: + ao3_news: Berita AO3 + contact_open_doors: hubungi tim Open Doors + contact_support: hubungi tim Dukungan AO3 + faq_page: halaman Pertanyaan Umum + tutorial_page: halaman tutorial + introduction: + text: Anda menerima surel ini karena baru-baru ini ada arsip yang telah diimpor + oleh tim Open Doors (Pintu Terbuka) (%{open_doors_link}) ke %{app_name} + (%{app_short_name} - %{app_url}), dan berdasarkan informasi yang kami miliki, + karya fan berikut ini adalah milik Anda. Kami memberikan Anda kesempatan + untuk mengklaim (atau menghapus/meninggalkan) karya-karya ini jika Anda + ingin. Jika Anda belum mempunyai akun AO3 dengan alamat surel yang berbeda, + kami mengundang Anda untuk bergabung dengan kami! + mistake: + text: Jika ini adalah sebuah kesalahan dan karya-karya ini bukan milik Anda, + mohon jangan hapus karya-karya ini! Tolong hubungi tim Open Doors (%{open_doors_link}) + dan kami akan menanganinya. + more_info: + text: 'Anda dapat membaca pengumuman tentang kegiatan pengarsipan terbaru + di Berita AO3 (%{news_link}), serta mendapat informasi tambahan di halaman + Pertanyaan Umum tentang Open Doors (%{open_doors_faq_link}) atau di halaman + tutorial (%{open_doors_tutorial_link}). Untuk pertanyaan-pertanyaan yang + belum terjawab di halaman Pertanyaan Umum, tutorial, atau surel ini, silakan + hubungi Tim Dukungan AO3 di %{support_link}. + + ' + other_works: + text: Jika Anda memiliki karya-karya lain di arsip impor yang menggunakan + alamat surel yang sudah tidak dapat Anda akses, silakan hubungi tim Open + Doors dengan menyertakan informasi apapun yang dapat memverifikasi identitas + Anda. + questions: + text: Untuk pertanyaan-pertanyaan lain, silakan hubungi tim Dukungan AO3 di + %{support_link}. + redirects: Untuk mempertahankan daftar rekomendasi dan markah buku, alamat web + menuju arsip yang telah diimpor bisa saja telah dialihkan langsung ke salinan + karya yang telah diimpor ini selama jangka waktu tertentu (cek artikel pengumuman + arsip Anda untuk memastikannya). Jika Anda telah mengunggah salinan dari karya + ini dan Anda TIDAK menggunakan fitur impor dari URL, akan ada dua salinan + karya yang sama di AO3. + subject: "[%{app_name}] Undangan untuk mengklaim karya" + unwanted: + text: Jika karya-karya ini milik Anda, tapi Anda tidak menginginkannya lagi, + Anda dapat meninggalkan mereka (sehingga mereka dapat tetap berada di AO3, + tapi nama Anda akan terhapus) atau menghapus mereka (sehingga karya tersebut + akan dihilangkan dari AO3 seluruhnya). Untuk meninggalkan atau menghapus + karya, Anda tidak perlu menambahkannya ke akun manapun--Anda dapat melakukan + ini langsung melalui tautan klaim diatas. (Untuk bantuan, silakan hubungi + tim Dukungan di %{support_link}.) + update_redirect: + text: Jika Anda ingin tim Open Doors untuk memperbarui tautan pengalihan agar + mengarahkan ke karya yang Anda impor sendiri sebelumnya, harap hapus salinan + yang kami impor, lalu hubungi tim Open Doors di %{open_doors_link} menggunakan + nama akun AO3 Anda, nama akun Anda di arsip impor, dan judul serta URL karya + fan yang akan dituju oleh tautan pengalihan Anda. (Jika Anda memiliki beberapa + karya yang ingin Anda ganti tautan pengalihannya, Anda dapat menuliskan + semua tautan tersebut dalam satu surel.) + uploaded_list: 'Karya yang diunggah termasuk:' + invite_increase_notification: + html: + body: + other: Kami hanya ingin memberitahu bahwa Anda memiliki %{count} undangan + baru yang dapat digunakan untuk membuat akun baru di AO3. Anda dapat mengundang + teman Anda di %{invitation_page_link}. + invitation_page_link_text: halaman Invitations (Undangan) Anda + subject: "[%{app_name}] Undangan Baru" + text: + body: + other: Kami hanya ingin memberitahu bahwa Anda memiliki %{count} undangan + baru yang dapat digunakan untuk membuat akun baru di AO3. Anda dapat mengundang + teman Anda di halaman Invitations (Undangan) Anda (%{invitation_page_url}). + invite_request_declined: + main: + other: Kami mohon maaf karena permintaan Anda untuk %{count} undangan baru + tidak dapat kami penuhi saat ini. + reason: 'Permintaan Anda adalah:' + subject: "[%{app_name}] Permintaan kode undangan tambahan ditolak" + recipient_notification: + html: + collection: Sebuah karya hadiah telah diunggah ke koleksi %{collection_link} + di AO3 untuk Anda! + no_collection: Sebuah karya hadiah telah diunggah ke AO3 untuk Anda! + subject: + collection: "[%{app_name}][%{collection_title}] Karya hadiah untuk Anda dari + %{collection_title}" + no_collection: "[%{app_name}] Karya hadiah untuk Anda" + text: + collection: Sebuah karya hadiah telah diunggah ke koleksi "%{collection_title}" + di AO3 (%{collection_url}) untuk Anda! + signup_notification: + activate: + html: Mohon %{activate_account_link}. + text: 'Mohon ikuti tautan ini untuk mengaktifkan akun Anda: %{activate_account_url}' + activate_your_account: Ikuti tautan ini untuk mengaktifkan akun Anda. + admin_posts: Berita AO3 + bye: Kami harap Anda menikmati menggunakan AO3. + contact_support: Hubungi Dukungan + faq: Pertanyaan yang Sering Diajukan + features: + html: Setelah akun Anda tersedia dan aktif, Anda dapat memposting karya-karya + penggemar, mengatur layanan surel langganan untuk memberitahu Anda saat + pembuat konten favorit Anda memposting karya terbaru atau karya favorit + Anda diperbarui, mengatur tampilan situs, melacak karya-karya yang telah + Anda buka melalui riwayat, dan lain-lain. + text: Setelah akun Anda tersedia dan aktif, Anda dapat memposting karya-karya + penggemar, mengatur layanan surel langganan untuk memberitahu Anda saat + pembuat konten favorit Anda memposting karya terbaru atau karya favorit + Anda diperbarui, mengatur tampilan situs, melacak karya-karya yang telah + Anda buka melalui riwayat, dan lain-lain. + information: + html: Terdapat banyak informasi dan saran mengenai cara penggunaan AO3 yang + tersedia di %{faq_link} kami. Anda dapat menemukan berita terbaru mengenai + perkembangan situs di %{admin_posts_link} kami. Jika Anda membutuhkan bantuan, + menemukan bug, atau ingin mengajukan pertanyaan atau komentar, mohon + %{contact_support_link}, yang dengan senang hati akan membantu Anda. + text: 'Terdapat banyak informasi dan saran mengenai cara penggunaan AO3 yang + tersedia di Pertanyaan yang Sering Diajukan kami pada %{faq_url}. Anda dapat + menemukan berita terbaru mengenai perkembangan situs di Berita AO3 pada + %{admin_posts_url}. Jika Anda membutuhkan bantuan, menemukan bug, atau ingin + mengajukan pertanyaan atau komentar, mohon hubungi tim Dukungan kami, yang + dengan senang hati akan membantu Anda: %{contact_support_url}.' + welcome: Selamat datang di Archive of Our Own – AO3 (Arsip Milik Kita), %{login}! diff --git a/config/locales/phrase-exports/it.yml b/config/locales/phrase-exports/it.yml new file mode 100755 index 0000000..0e33626 --- /dev/null +++ b/config/locales/phrase-exports/it.yml @@ -0,0 +1,662 @@ +--- +it: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Avvertimento:' + other: 'Avvertimenti:' + category: + name_with_colon: + one: 'Categoria:' + other: 'Categorie:' + character: + name_with_colon: + one: 'Personaggio:' + other: 'Personaggi:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandom:' + freeform: + name_with_colon: + one: 'Tag Aggiuntiva:' + other: 'Tag Aggiuntive:' + rating: + name_with_colon: 'Rating:' + relationship: + name_with_colon: + one: 'Relazione:' + other: 'Relazioni:' + work: + chapter_total_display: Capitoli + summary: Riassunto + models: + archive_warning: + one: Avvertimento + other: Avvertimenti + category: + one: Categoria + other: Categorie + chapter: + one: Capitolo + other: Capitoli + character: + one: Personaggio + other: Personaggi + fandom: + one: Fandom + other: Fandom + freeform: + one: Tag Aggiuntiva + other: Tag Aggiuntive + rating: + one: Rating + other: Rating + relationship: + one: Relazione + other: Relazioni + series: + one: Serie + other: Serie + kudo_mailer: + batch_kudo_notification: + guest: + one: un ospite + other: "%{count} ospiti" + left_kudos: + html: + one: "%{givers_list} ha lasciato kudos per %{commentable_link}." + other: "%{givers_list} hanno lasciato kudos per %{commentable_link}." + text: + one: "%{givers_list} ha lasciato kudos per %{commentable_title} (%{commentable_url})." + other: "%{givers_list} hanno lasciato kudos per %{commentable_title} (%{commentable_url})." + single_guest: + giver: Un ospite + html: "%{giver} ha lasciato kudos per %{commentable_link}." + text: Un ospite ha lasciato kudos per %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Hai dei kudos!" + mailer: + general: + closing: + formal: Un saluto, + informal: Un saluto, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Capitolo %{position} di %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} parola" + other: "%{count} parole" + footer: + general: + about: + html: AO3 è un archivio supportato e gestito dai fan che dipende dalle + %{donate_link}. + text: 'AO3 è un archivio supportato e gestito dai fan che dipende dalle + vostre donazioni: %{donate_url}.' + html: + donate_link_text: vostre donazioni + support_link_text: contatta il Supporto + unwanted_email: + html: Se hai ricevuto questo messaggio per errore, per favore %{support_link}. + text: Se hai ricevuto questo messaggio per errore, contatta il Supporto + all'indirizzo %{support_url}. + sent_at: Inviato %{sent_at}. + greeting: + formal_html: Ciao %{name}, + informal: + addressed_html: Ciao, %{name}! + unaddressed: Ciao! + introductory: Ciao da Archive of Our Own – AO3 (Archivio Tutto Per Noi)! + metadata_label_indicator: ":" + signature: + abuse_team: Il team Norme & Violazioni di AO3 + app_short_name: AO3 + open_doors: Il team di Open Doors (Porte Aperte) + parent_org: Organization for Transformative Works – OTW (Organizzazione per + i Lavori Trasformativi) + support: Il team di Supporto di AO3 + users: + mailer: + reset_password_instructions: + expiration: Se non utilizzi questo link per reimpostare la tua password entro + una settimana, il link scadrà e dovrai richiederne uno nuovo. + intro: 'È stato richiesta la reimpostazione della password del tuo account. + Puoi cambiare la tua password accedendo al seguente link e immettendo la + tua nuova password:' + link_title: Cambia la mia password. + subject: "[%{app_name}] Reimposta la tua password" + unrequested: Se non hai richiesto di reimpostare la password, puoi ignorare + questa email; la tua password attuale continuerà a funzionare. + user_mailer: + admin_deleted_work_notification: + bye: In allegato puoi trovare una copia del tuo lavoro a cui fare riferimento. + contact_abuse: contatta il nostro Comitato Norme & Violazioni + deleted: + html: Il tuo lavoro %{title} è stato rimosso da AO3 da un amministratore del + sito. + text: Il tuo lavoro "%{title}" è stato rimosso da AO3 da un amministratore + del sito. + html: + tos_violation: Se ritieni possibile che il tuo lavoro abbia violato i Termini + di Servizio di AO3, per favore %{contact_abuse_link}. + import_project: + html: Se il tuo lavoro faceva parte di un progetto di importazione gestito + dal nostro team Open Doors (Porte Aperte), per favore %{opendoors_link} + per ulteriori domande. + text: Se il tuo lavoro faceva parte di un progetto di importazione gestito + dal nostro team Open Doors (Porte Aperte), per favore contatta Porte Aperte + (%{opendoors_link}) per ulteriori domande. + opendoors: contatta Porte Aperte + subject: "[%{app_name}] Il tuo lavoro è stato rimosso da un amministratore" + text: + tos_violation: Se ritieni possibile che il tuo lavoro abbia violato i Termini + di Servizio di AO3, per favore contatta il nostro Comitato Norme & Violazioni + (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Quando il tuo lavoro è nascosto, puoi comunque accedervi attraverso + il link fornito qui sopra, ma non viene elencato nella pagina dei tuoi lavori + e non risulta disponibile per gli altri utenti di AO3. + check_email: Ti invitiamo a controllare la tua email, compresa la cartella spam, + poiché il team Norme & Violazioni potrebbe averti già contattato per spiegarti + perché il tuo lavoro è stato nascosto. + contact_abuse: contatta Norme & Violazioni + html: + help: Se non hai certezza del perché il tuo lavoro sia stato nascosto e non + hai ricevuto ulteriori comunicazioni al riguardo, per favore %{contact_abuse_link} + direttamente. + hidden: Il tuo lavoro %{title} è stato nascosto dal team di Norme & Violazioni + e non è più accessibile al pubblico. + tos_violation: Se il tuo lavoro è stato nascosto perché viola i %{tos_link} + di AO3, ti verrà richiesto di intervenire per rettificare la violazione. + Se non provvederai ad apportare le opportune modifiche al tuo lavoro in + accordo con i Termini di Servizio, la conseguenza potrebbe essere la cancellazione + del tuo lavoro da AO3. + subject: "[%{app_name}] Il tuo lavoro è stato nascosto dal team di Norme & Violazioni" + text: + help: 'Se non hai certezza del perché il tuo lavoro sia stato nascosto e non + hai ricevuto ulteriori comunicazioni al riguardo, ti invitiamo a contattare + direttamente Norme & Violazioni: %{contact_abuse_url}.' + hidden: Il tuo lavoro "%{title}" (%{work_url}) è stato nascosto dal team di + Norme & Violazioni e non è più accessibile al pubblico. + tos_violation: Se il tuo lavoro è stato nascosto perché viola i Termini di + Servizio di AO3 (%{tos_url}), ti verrà richiesto di intervenire per rettificare + la violazione. Se non provvederai ad apportare le opportune modifiche al + tuo lavoro in accordo con i Termini di Servizio, la conseguenza potrebbe + essere la cancellazione del tuo lavoro da AO3. + tos: Termini di Servizio + anonymous_or_unrevealed_notification: + anonymous_info: I lavori anonimi sono inclusi negli elenchi di tag, ma non sulla + pagina dei tuoi lavori. Nella pagina del lavoro, il tuo nome utente sarà sostituito + da “Anonymous” (Anonimo). + anonymous_unrevealed_info: I manutentori della collezione potranno in seguito + rivelare il tuo lavoro ma lasciarlo anonimo. I tuoi iscritti non verranno + notificati di questo cambiamento. Una volta rivelato, il tuo lavoro sarà incluso + negli elenchi di tag, ma non sui lavori della tua pagina. Nella pagina del + lavoro, il tuo nome utente sarà sostituito da “Anonymous” (Anonimo). + changed_status: + anonymous: + html: I manutentori della collezione %{collection_link} hanno cambiato lo + stato del tuo lavoro %{work_link} in anonimo. + text: I manutentori della collezione "%{collection_title}" (%{collection_url}) + hanno cambiato lo stato del tuo lavoro "%{work_title}" (%{work_url}) in + anonimo. + anonymous_unrevealed: + html: I manutentori della collezione %{collection_link} hanno cambiato lo + stato del tuo lavoro %{work_link} in anonimo e nascosto. + text: I manutentori della collezione "%{collection_title}" (%{collection_url}) + hanno cambiato lo stato del tuo lavoro "%{work_title}" (%{work_url}) in + anonimo e nascosto. + unrevealed: + html: I manutentori della collezione %{collection_link} hanno cambiato lo + stato del tuo lavoro %{work_link} in nascosto. + text: I manutentori della collezione "%{collection_title}" (%{collection_url}) + hanno cambiato lo stato del tuo lavoro "%{work_title}" (%{work_url}) in + nascosto. + collection_items_link_text: pagina “Approved Collection Items” (Elementi approvati + della collezione) + do_not_want: + anonymous: + html: Se non vuoi che il tuo lavoro resti anonimo, per favore visita la + tua %{collection_items_link} per rimuoverlo da questa collezione. + text: 'Se non vuoi che il tuo lavoro sia anonimo, per favore visita la tua + pagina Approved Collection Items (Elementi approvati della collezione) + per rimuoverlo da questa collezione: %{collection_items_url}' + anonymous_unrevealed: + html: Se non vuoi che il tuo lavoro sia anonimo e nascosto, per favore visita + la tua %{collection_items_link} per rimuoverlo da questa collezione. + text: 'Se non vuoi che il tuo lavoro sia anonimo e nascosto, per favore + visita la tua pagina Approved Collection Items (Elementi approvati della + collezione) per rimuoverlo da questa collezione: %{collection_items_url}' + unrevealed: + html: Se non vuoi che il tuo lavoro sia nascosto, per favore visita la tua + %{collection_items_link} per rimuoverlo da questa collezione. + text: 'Se non vuoi che il tuo lavoro sia nascosto, per favore visita la + tua pagina Approved Collection Items (Elementi approvati della collezione) + per rimuoverlo da questa collezione: %{collection_items_url}' + faq_link_text: FAQ sulle Collezioni + more_info: + html: Per maggiori informazioni visita le nostre %{faq_link}. + text: 'Per maggiori informazioni, visita le nostre FAQ sulle Collezioni: %{faq_url}' + subject: + anonymous: "[%{app_name}] Il tuo lavoro è stato reso anonimo" + anonymous_unrevealed: "[%{app_name}] Il tuo lavoro è stato reso anonimo e + nascosto" + unrevealed: "[%{app_name}] Il tuo lavoro è stato reso nascosto" + unrevealed_info: I lavori nascosti non sono inclusi negli elenchi di tag o sulla + pagina dei tuoi lavori. Chiunque raggiunga il lavoro attraverso un link riceverà + una notifica che il lavoro è attualmente nascosto, e non saranno in grado + di accedere al suo contenuto. + archivist_added_to_collection_notification: + approved_collection_items_page: pagina Approved Collection Elements (Elementi + Approvati della Collezione) + archivist_notice: Poiché i gestori della collezione agiscono in veste ufficiale + come archivisti di Open Doors (Porte Aperte), possono aggiungere il tuo lavoro + a questa collezione, anche se hai disabilitato gli inviti alle collezioni. + Gli archivisti aggiungono un lavoro a una collezione solo nel caso in cui + fosse precedentemente ospitato in un archivio che è stato importato. + removal_instructions: + html: Se desideri rimuovere il tuo lavoro da questa collezione, per favore + visita la tua %{approved_items_link}. + text: 'Se desideri rimuovere il tuo lavoro dalla collezione, per favore visita + la tua pagina Approved Collection Items (Elementi Approvati della Collezione): + %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Un archivista di Open Doors (Porte + Aperte) ha aggiunto il tuo lavoro a una collezione" + work_added: + html: I gestori della collezione %{collection_link} hanno aggiunto il tuo + lavoro %{work_link} alla loro collezione! + text: I gestori della collezione "%{collection_title}" (%{collection_url}) + hanno aggiunto il tuo lavoro "%{work_title}" (%{work_url}) alla loro collezione! + challenge_assignment_notification: + any: Qualsiasi + assignment: + html: Ti è stata assegnata la seguente richiesta nella challenge %{link} su + AO3! + description: 'Descrizione:' + due: 'La scadenza è:' + html: + footer: Ricevi questa email perché hai effettuato l'iscrizione alla challenge + %{title}. Per altre informazioni su questa challenge e per visualizzare + i contatti dei moderatori, ti preghiamo di visitare %{footer_link}. + footer_link: la pagina profilo della challenge + look_up: Puoi vedere cosa ti è stato assegnato aprendo %{link}. + look_up_link: la pagina Assignments (Incarichi) + optional_tags: 'Tag facoltative:' + prompts: 'Prompt:' + prompt_url: 'URL del prompt:' + recipient: 'Destinatario:' + recipient_missing: 'Nessuno: contatta un moderatore per ricevere assistenza!' + subject: "[%{app_name}][%{collection_title}] Il tuo incarico!" + text: + assignment: Ti è stata assegnata la seguente richiesta nella challenge "%{collection_title}" + (%{collection_url}) su AO3! + footer: Ricevi questa email perché hai effettuato l'iscrizione alla challenge + %{title} (%{url}). Per altre informazioni sulla challenge e per visualizzare + i contatti dei moderatori ti preghiamo di visitare il link %{profile_url}. + look_up: Puoi trovare questo incarico nella tua pagina Assignments (Incarichi) + al link %{link}. + change_email: + changed: + html: "%{login}, l'indirizzo email associato al tuo account è stato modificato + in %{email}" + text: "%{login}, l'indirizzo email associato al tuo account è stato modificato + in %{email}" + subject: "[%{app_name}] Modifica indirizzo email" + claim_notification: + access: + contact_support: contatta il Supporto di AO3. + html: In base all'archivio di provenienza i tuoi lavori potrebbero essere + stati importati in modo tale da essere visibili solo agli utenti registrati + (per escluderli dalle ricerche via Google). In tal caso i tuoi lavori saranno + disponibili soltanto agli utenti che abbiano effettuato l'accesso, a meno + che tu non decida di renderli visibili a tutti. Se ti serve aiuto per sbloccare, + rendere orfani o eliminare i tuoi lavori, per favore %{contact_support_link}. + text: In base all'archivio di provenienza i tuoi lavori potrebbero essere + stati importati in modo tale da essere visibili solo agli utenti registrati + (per escluderli dalle ricerche via Google). In tal caso i tuoi lavori saranno + disponibili soltanto agli utenti che abbiano effettuato l'accesso, a meno + che tu non decida di renderli visibili a tutti. Se ti serve aiuto a sbloccare, + rendere orfani o eliminare i tuoi lavori, per favore contatta il supporto + di AO3 (%{support_url}). + email_tips: Nel caso tu decida di contattarci, ricordati per favore di aggiungere + alla tua whitelist gli indirizzi email con dominio @transformativeworks.org + e controlla che la nostra risposta non sia finita nella cartella di spam. + introduction: + ao3_name: Archive of Our Own – AO3 (Archivio Tutto Per Noi) + html: Hai ricevuto questa email perché avevi lavori presenti in un archivio + di fanwork che è stato importato da %{open_doors_name_link} su %{app_link}. + Poiché questo indirizzo email è connesso a un account sull'archivio importato, + i fanwork a esso associati (di cui sotto) sono stati aggiunti automaticamente + al tuo account su AO3. + open_doors_name: Open Doors (Porte Aperte) + text: 'Hai ricevuto questa email perché avevi lavori presenti in un archivio + di fanwork che è stato importato da Open Doors (Porte Aperte) (%{open_doors_url}) + su Archive of Our Own – AO3 (Archivio Tutto Per Noi): %{app_url}. Poiché + questo indirizzo email è connesso a un account sull''archivio importato, + i fanwork a esso associati (di cui sotto) sono stati aggiunti automaticamente + al tuo account su AO3.' + mistake: + contact_open_doors: Contatta Porte Aperte + html: Se si tratta di un errore e questi non sono i tuoi lavori, per favore + non eliminarli! %{contact_open_doors_link} e risolveremo il problema. + text: Se si tratta di un errore e questi non sono i tuoi lavori, per favore + non eliminarli! Contatta Porte Aperte (%{open_doors_url}) e risolveremo + il problema. + more_info: + ao3_news: AO3 News + contact_support: contatta il Supporto di AO3 + faq_page: pagina delle FAQ + html: Puoi leggere gli annunci riguardanti i trasferimenti di archivi più + recenti su %{ao3_news_link} e troverai ulteriori informazioni sulla %{faq_page_link} + di Porte Aperte o sulla %{tutorial_page_link}. Se non trovi risposta alla + tua domanda nelle FAQ, nei tutorial o in questa email, per favore %{contact_support_link}. + text: Puoi leggere gli annunci riguardanti i trasferimenti di archivi più + recenti su AO3 News (%{news_url}) e troverai ulteriori informazioni sulla + pagine delle FAQ di Porte Aperte (%{open_doors_faq_url}) o sulla pagina + dei tutorial (%{open_doors_tutorial_url}). Se non trovi risposta alla tua + domanda nelle FAQ, nei tutorial o in questa email, per favore contatta il + Supporto di AO3 (%{support_url}). + tutorial_page: pagina dei tutorial + other_works: + contact_open_doors: contatta Porte Aperte + html: Se nell'archivio importato avevi altri lavori legati a un altro indirizzo + email a cui non hai più accesso, per favore %{contact_open_doors_link} fornendo + qualsiasi informazione che permetta di verificare la tua identità come autore + dei lavori in oggetto. + text: Se nell’archivio importato avevi altri lavori legati a un altro indirizzo + email a cui non hai più accesso, per favore contatta Porte Aperte fornendo + qualsiasi informazione che permetta di verificare la tua identità come autore + dei lavori in oggetto. + questions: + contact_support: contatta il Supporto di AO3 + html: Se hai ulteriori domande, per favore %{contact_support_link}. + text: Se hai ulteriori domande, per favore contatta il Supporto di AO3 (%{support_url}). + redirects: + html: Per conservare le liste di fanfic consigliate e i preferiti gli URL + dell'archivio importato potrebbero reindirizzare alla copia importata dei + lavori per un periodo di tempo limitato (controlla il post riguardante il + trasferimento del tuo archivio per averne certezza). Se hai già caricato + una copia di un lavoro e %{negation} hai usato la funzione "import from + URL" (importa da URL), su AO3 saranno presenti due copie dello stesso lavoro. + subject: "[%{app_name}] Lavori caricati" + update_redirect: + contact_open_doors: contatta Porte Aperte + html: Se desideri che Porte Aperte aggiorni il reindirizzamento perché si + riferisca a un tuo lavoro preesistente, per favore elimina la copia importata + e %{contact_open_doors_link} con il nome del tuo account di AO3, il nome + del tuo account sull'archivio importato, il titolo e URL del fanwork a cui + vorresti far riferire il reindirizzamento. (Se si tratta di più di un lavoro, + puoi elencarli tutti in una singola email). + text: Se desideri che Porte Aperte aggiorni il reindirizzamento perché si + riferisca a un tuo lavoro preesistente, per favore elimina la copia importata + e contatta Porte Aperte (%{open_doors_url}) con il nome del tuo account + di AO3, il nome del tuo account sull'archivio importato, il titolo e URL + del fanwork a cui vorresti far riferire il reindirizzamento. (Se si tratta + di più di un lavoro, puoi elencarli tutti in una singola email). + works_by: 'I seguenti lavori sono legati a questo indirizzo email: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Tutti gli incarichi sono stati inviati. + subject: Incarichi inviati + html: + received_message: 'Hai ricevuto un messaggio riguardo la tua collezione %{collection_link}:' + text: + received_message: 'Hai ricevuto un messaggio riguardo la tua collezione "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Quando sei coautore di un lavoro, puoi essere aggiunt@ a nuovi + capitoli indipendentemente dalle tue impostazioni riguardanti le creazioni + congiunte. Sarai altresì aggiunt@ a qualsiasi serie cui venga aggiunto il + lavoro in questione. + html: + creation: "%{creation_link} di %{pseud_links}" + edit_chapter: modificare il capitolo + edit_series: modificare la serie + remove_chapter: Se pensi ci sia un errore o se non desideri essere elencat@ + come autore, puoi %{edit_chapter_link} per rimuovere il tuo pseudonimo come + autore. + remove_series: Se pensi ci sia un errore o se non desideri apparire come autore, + puoi %{edit_series_link} per rimuovere il tuo pseudonimo dall'elenco degli + autori. + intro_chapter: 'L’utente %{adding_user} ha indicato il tuo pseudonimo %{pseud} + come coautore del seguente capitolo:' + intro_series: 'L’utente %{adding_user} ha indicato il tuo pseudonimo %{pseud} + come coautore della seguente serie:' + subject: "[%{app_name}] Notifica di coautore" + text: + creation: "%{title} (%{url}) di %{pseuds}" + remove_chapter: 'Se il tuo pseudonimo è stato aggiunto per errore o se non + desideri apparire come autore, puoi modificare il capitolo e rimuovere il + tuo pseudonimo dall''elenco degli autori: %{url}' + remove_series: 'Se pensi ci sia un errore o se non desideri apparire come + autore, puoi modificare la serie per rimuovere il tuo pseudonimo dall''elenco + degli autori: %{url}' + creatorship_notification_archivist: + explanation: Poiché questo utente agisce nel suo ruolo ufficiale di archivista + di Open Doors (Porte Aperte), ha l'autorizzazione ad aggiungerti senza una + richiesta, anche se hai la cocreazione disabilitata. + html: + creation: "%{creation_link} di %{pseud_links}" + edit_chapter: modificare il capitolo + edit_series: modificare la serie + edit_work: modificare il lavoro + remove_chapter: Se ritieni che questa modifica sia avvenuta per errore e non + desideri che il tuo pseudonimo venga indicato come autore, puoi %{edit_chapter_link} + per rimuoverti dalla lista degli autori. + remove_series: Se ritieni che questa modifica sia avvenuta per errore e non + desideri che il tuo pseudonimo venga indicato come autore, puoi %{edit_series_link} + per rimuoverti dalla lista degli autori. + remove_work: Se ritieni che questa modifica sia avvenuta per errore e non + desideri che il tuo pseudonimo venga indicato come autore, puoi %{edit_work_link} + per rimuoverti dalla lista degli autori. + intro_chapter: 'L''utente %{archivist} ha aggiunto il tuo pseudonimo %{pseud} + come coautore del seguente capitolo:' + intro_series: 'L''utente %{archivist} ha aggiunto il tuo pseudonimo %{pseud} + come coautore della seguente serie:' + intro_work: 'L''utente %{archivist} ha aggiunto il tuo pseudonimo %{pseud} come + coautore del seguente lavoro:' + subject: "[%{app_name}] Notifica di coautore da parte di un archivista" + text: + creation: "%{title} (%{url}) di %{pseuds}" + remove_chapter: 'Se ritieni che questa modifica sia avvenuta per errore e + non desideri che il tuo pseudonimo venga indicato come autore, puoi modificare + il capitolo e rimuoverti dalla lista degli autori: %{url}' + remove_series: 'Se ritieni che questa modifica sia avvenuta per errore e non + desideri che il tuo pseudonimo venga indicato come autore, puoi modificare + la serie e rimuoverti dalla lista degli autori: %{url}' + remove_work: 'Se ritieni che questa modifica sia avvenuta per errore e non + desideri che il tuo pseudonimo venga indicato come autore, puoi modificare + il lavoro e rimuoverti dalla lista degli autori: %{url}' + creatorship_request: + html: + creation: "%{creation_link} di %{pseud_links}" + instructions: Puoi accettare o rifiutare questa richiesta sulla tua pagina + %{page_name}. + page_name: Co-Creator Requests (Richieste di coautore) + intro_chapter: 'L''utente %{inviting_user} ha invitato il tuo pseudonimo %{pseud} + ad essere elencato come coautore del seguente capitolo:' + intro_series: 'L''utente %{inviting_user} ha invitato il tuo pseudonimo %{pseud} + ad essere elencato come coautore della seguente serie:' + intro_work: 'L''utente %{inviting_user} ha invitato il tuo pseudonimo %{pseud} + ad essere elencato come coautore del seguente lavoro:' + subject: "[%{app_name}] Richiesta di coautore" + text: + creation: "%{title} (%{url}) di %{pseuds}" + instructions: 'Puoi accettare o rifiutare questa richiesta sulla tua pagina + Co-Creator Requests (Richieste di coautore): %{url}' + delete_work_notification: + attachment: In allegato trovi una copia del tuo lavoro da poter consultare. + deleted_other: + html: Il tuo lavoro %{title} è stato cancellato come richiesto da %{pseud}. + text: Il tuo lavoro "%{title}" è stato cancellato come richiesto da %{pseud}. + deleted_yourself: + html: Il tuo lavoro %{title} è stato cancellato come da tua richiesta. + text: Il tuo lavoro "%{title}" è stato cancellato come da tua richiesta. + questions: + html: Se dovessi avere dei dubbi, per favore %{support}. + text: Se dovessi avere dei dubbi, per favore %{support} (%{url}). + subject: "[%{app_name}] Il tuo lavoro è stato cancellato" + support: contatta il Supporto + invitation: + been_invited: Hai ricevuto un invito ad unirti alla nostra versione beta! + has_invited: "%{user_name} ti ha chiesto di unirti alla nostra versione beta!" + html: + faq_link_text: le nostre FAQ + subject: "[%{app_name}] Invito" + invitation_to_claim: + access: + html: A seconda dell’archivio, i tuoi lavori potrebbero essere stati importati + in modo da essere visibili solo agli utenti registrati (in modo da escluderli + dalle ricerche via Google). In tal caso, i lavori saranno accessibili solo + da utenti che abbiano effettuato l'accesso, a meno che tu non scelga di + renderli visibili a tutti. Se ti serve aiuto su come sbloccare, rendere + orfani o cancellare i tuoi lavori, per favore %{contact_support_link}. + text: A seconda dell’archivio, i tuoi lavori potrebbero essere stati importati + in modo da essere solo visibili agli utenti registrati (ed esclusi dalle + ricerche via Google). In tal caso, i lavori saranno accessibili solo da + utenti che abbiano effettuato l’accesso, a meno che tu non scelga di renderli + visibili a tutti. Se ti serve aiuto su come sbloccare, rendere orfani o + cancellare i tuoi lavori, per favore contatta il Supporto di AO3. + claim_or_remove: + html: Qui puoi rivendicare o cancellare i tuoi lavori. + text: 'Qui puoi rivendicare o cancellare i tuoi lavori: %{claim_url}' + email_tips: Nel caso tu decida di contattarci, ricordati per favore di aggiungere + alla tua whitelist gli indirizzi email provenienti da @transformativeworks.org + e controlla che la nostra risposta non sia finita nella cartella di spam. + html: + ao3_news: AO3 News + contact_open_doors: contatta Porte Aperte + contact_support: contatta il Supporto di AO3 + faq_page: pagina delle FAQ + tutorial_page: guida + introduction: + text: Stai ricevendo questa email perché un archivio è stato di recente importato + da Open Doors (Porte Aperte) (%{open_doors_link}) in %{app_name} (%{app_short_name} + - %{app_url}), e crediamo che tu sia l’autore dei seguenti lavori. Vorremmo + darti la possibilità di rivendicarli (o cancellarli/renderli orfani). E, + se non hai già un account con un altro indirizzo email, ci piacerebbe invitarti! + mistake: + html: Se si tratta di un errore e questi non sono i tuoi lavori, per favore + non cancellarli! Semplicemente %{contact_open_doors_link} e risolveremo + il problema. + text: Se si tratta di un errore e questi non sono i tuoi lavori, per favore + non cancellarli! Semplicemente contatta Porte Aperte (%{open_doors_link}) + e risolveremo il problema. + other_works: + html: Se hai altri lavori nell’archivio importato sotto un diverso indirizzo + email a cui non hai più accesso, %{contact_open_doors_link} con qualunque + informazione che possa aiutare a verificare la tua identità di autore di + tali lavori. + text: Se hai altri lavori nell’archivio importato collegati a un diverso indirizzo + email a cui non hai più accesso, contatta Porte Aperte con qualunque informazione + che possa aiutare a verificare la tua identità di autore di tali lavori. + questions: + html: Per altre domande, per favore %{contact_support_link}. + redirects: Per mantenere intatte le rec list e i preferiti, l’indirizzo web + dell’archivio importato potrebbe - per un breve periodo - reindirizzare alle + copie importate di questi lavori (per essere sicur@, controlla l’annuncio + relativo al tuo archivio). Se hai già pubblicato una copia di questi lavori + e NON hai usato la funzione per importare automaticamente dall’URL, ci saranno + due copie dello stesso lavoro nell’archivio. + subject: "[%{app_name}] Invito a rivendicare i tuoi lavori" + unwanted: + html: 'Se sei l’autore di questi lavori, ma non li vuoi più, li puoi rendere + orfani (così che rimangano su AO3 ma senza il tuo nome) o puoi cancellarli + (verranno in tal caso completamente rimossi da AO3). Non c’è bisogno di + aggiungerli a un account per renderli orfani o cancellarli: puoi farlo direttamente + dal link qui sopra. (Se hai bisogno di aiuto, per favore %{contact_support_link}.)' + update_redirect: + html: Se desideri che Porte Aperte aggiorni il reindirizzamento per puntare + al tuo lavoro pre-esistente, cancella la copia importata e %{contact_open_doors_link} + specificando il nome del tuo profilo su AO3, quello sull’archivio importato + e il titolo e URL del lavoro al quale vuoi che punti il reindirizzamento. + (Se vuoi cambiare il reindirizzamento di più lavori, puoi elencarli tutti + in una singola email.) + text: Se desideri che Porte Aperte aggiorni il reindirizzamento per puntare + al tuo lavoro pre-esistente, cancella la copia importata e contatta Porte + Aperte (%{open_doors_link}) specificando il nome del tuo profilo su AO3, + quello sull’archivio importato e titolo e URL del lavoro al quale vuoi che + punti il reindirizzamento. (Se vuoi cambiare il reindirizzamento di più + lavori, puoi elencarli tutti in una singola email.) + uploaded_list: 'I lavori pubblicati comprendono:' + invite_increase_notification: + html: + body: + one: Volevamo farti sapere che hai %{count} nuovo invito che può essere + usato per creare un nuovo account su AO3. Puoi invitare un amico recandoti + %{invitation_page_link}. + other: Volevamo farti sapere che hai %{count} nuovi inviti che possono essere + usati per creare nuovi account su AO3. Puoi invitare i tuoi amici recandoti + %{invitation_page_link}. + invitation_page_link_text: sulla tua pagina degli inviti + subject: "[%{app_name}] Nuovi inviti" + text: + body: + one: Volevamo farti sapere che hai %{count} nuovo invito che può essere + usato per creare un nuovo account su AO3. Puoi invitare un amico recandoti + alla tua pagina Invitations (inviti) (%{invitation_page_url}). + other: Volevamo farti sapere che hai %{count} nuovi inviti che possono essere + usati per creare nuovi account su AO3. Puoi invitare i tuoi amici recandoti + alla tua pagina Invitations (inviti) (%{invitation_page_url}). + invite_request_declined: + main: + one: Ci dispiace doverti informare che al momento la tua richiesta per un + ulteriore codice invito non può essere accettata. + other: Ci dispiace doverti informare che al momento la tua richiesta per %{count} + nuovi inviti non può essere accettata. + reason: 'La tua richiesta è stata:' + subject: "[%{app_name}] Richiesta per un Codice Invito aggiuntivo rifiutata" + recipient_notification: + html: + collection: All'interno della collezione %{collection_link} su AO3 è stato + pubblicato un fanwork regalo per te! + no_collection: Su AO3 è stato pubblicato un fanwork regalo per te! + subject: + collection: "[%{app_name}][%{collection_title}] Un fanwork regalo per te su + %{collection_title}" + no_collection: "[%{app_name}] Hai ricevuto un fanwork regalo" + text: + collection: All'interno della collezione "%{collection_title}" (%{collection_url}) + su AO3 è stato pubblicato un fanwork regalo per te! + signup_notification: + activate: + html: Per favore %{activate_account_link}. + text: 'Per favore segui questo link per attivare il tuo account: %{activate_account_url}' + activate_your_account: segui questo link per attivare il tuo account + admin_posts: News di AO3 + bye: Speriamo ti divertirai a usare AO3. + contact_support: contatta il Supporto + faq: FAQ + features: + html: Non appena il tuo account sarà attivo e funzionante, potrai postare + i tuoi fanwork, impostare le iscrizioni via email che ti permetteranno di + sapere quando i tuoi autori preferiti pubblicano del materiale o quando + i tuoi lavori preferiti vengono aggiornati, scegliere come preferisci che + il sito ti appaia e funzioni, tenere traccia dei fanwork che hai visualizzato + su AO3 attraverso la tua cronologia e molto altro ancora. + text: Non appena il tuo account sarà attivo e funzionante, potrai postare + i tuoi fanwork, impostare le iscrizioni via email che ti permetteranno di + sapere quando i tuoi autori preferiti pubblicano del materiale o quando + i tuoi lavori preferiti vengono aggiornati, scegliere come preferisci che + il sito ti appaia e funzioni, tenere traccia dei fanwork che hai visualizzato + su AO3 attraverso la tua cronologia, e molto altro ancora. + information: + html: Ci sono molte informazioni e suggerimenti su come usare AO3 nelle nostre + %{faq_link}. Troverai le ultime notizie riguardo agli sviluppi del sito + nelle nostre %{admin_posts_link}. Se hai bisogno di aiuto, incontri un bug, + o hai altre domande o commenti, per favore %{contact_support_link}, che + sarà sempre felice di aiutarti. + text: 'Ci sono molte informazioni e suggerimenti su come usare AO3 nelle nostre + FAQ su %{faq_url}. Troverai le ultime notizie riguardo agli sviluppi del + sito su News di AO3 su %{admin_posts_url}. Se hai bisogno di aiuto, incontri + un bug, o hai altre domande o commenti, per favore mettiti in contatto con + il team di Supporto, che sarà sempre felice di aiutarti: %{contact_support_url}.' + subject: "[%{app_name}] Attiva il tuo account" + welcome: Benvenut@ su AO3, %{login}! diff --git a/config/locales/phrase-exports/ja.yml b/config/locales/phrase-exports/ja.yml new file mode 100755 index 0000000..18071ae --- /dev/null +++ b/config/locales/phrase-exports/ja.yml @@ -0,0 +1,404 @@ +--- +ja: + activerecord: + attributes: + archive_warning: + name_with_colon: + other: 警告: + category: + name_with_colon: + other: カテゴリー: + character: + name_with_colon: + other: キャラクター: + fandom: + name_with_colon: + other: ジャンル: + freeform: + name_with_colon: + other: その他のタグ: + rating: + name_with_colon: レイティング: + relationship: + name_with_colon: + other: カップリング: + work: + chapter_total_display: 章 + summary: あらすじ + models: + archive_warning: + other: 警告 + category: + other: カテゴリー + chapter: + other: 章 + character: + other: キャラクター + fandom: + other: ジャンル + freeform: + other: その他のタグ + rating: + other: レイティング + relationship: + other: カップリング + series: + other: シリーズ + kudo_mailer: + batch_kudo_notification: + guest: + other: ゲスト%{count}名 + left_kudos: + html: + other: "%{givers_list}があなたの作品 %{commentable_link}にいいねを送りました。" + text: + other: "%{givers_list} があなたの作品 %{commentable_title} (%{commentable_url})にいいねを送りました。" + single_guest: + giver: ゲスト1名 + html: "%{giver}があなたの作品 %{commentable_link}にいいねを送りました。" + text: ゲスト1名があなたの作品 %{commentable_title} (%{commentable_url})にいいねを送りました。 + subject: "[%{app_name}] あなたにいいねが届きました!" + mailer: + general: + closing: + formal: 敬具、 + informal: 以上、 + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: "『 %{title}』の %{position} 章" + title_with_word_count: "『%{creation_title}』(%{word_count})" + word_count: + other: "%{count} 語" + footer: + general: + about: + html: みんなのアーカイブ(AO3)はファンによって運営され、ファンに支えられているアーカイブです。AO3は%{donate_link}に頼っています。 + text: みんなのアーカイブ(AO3)はファンによって運営され、ファンに支えられているアーカイブです。AO3は皆様からのご寄付に頼っています:%{donate_url}. + html: + donate_link_text: 皆様からのご寄付 + support_link_text: ユーザーサポートまでご連絡ください + unwanted_email: + html: エラーにてこのメッセージを受けた場合は%{support_link}。 + text: 間違ってこのメッセージを受けた場合はユーザーサポート(%{support_url})までご連絡ください。 + sent_at: "%{sent_at}に送信されました。" + greeting: + formal_html: "%{name}さん、" + informal: + addressed_html: こんにちは、%{name}さん! + unaddressed: こんにちは! + introductory: みんなのアーカイブ(AO3)から、こんにちは! + metadata_label_indicator: ":" + signature: + abuse_team: 迷惑・不正行為対策チーム + app_short_name: AO3 + open_doors: The Open Doors (オープンドア) チーム + parent_org: Organization for Transformative Works ー OTW(変形的作品のためのNPO) + support: AO3ユーザーサポートチーム + users: + mailer: + reset_password_instructions: + expiration: 1週間以内にこのリンクからパスワード再設定をしない場合、リンクの有効期限が切れるため、新たなリンクをリクエストする必要があります。 + intro: あなたのアカウントのパスワード再設定がリクエストされました。下記のリンクから新しいパスワードを入力することで、アカウントのパスワードを変更できます。 + link_title: パスワードを変更する + subject: "[%{app_name}] パスワードの再設定" + unrequested: もしあなたがパスワード再設定をリクエストしなかった場合は、このメールを無視しても、元のパスワードを引き続きお使い頂けます。 + user_mailer: + admin_deleted_work_notification: + bye: ご参考のために、あなたの作品のコピーを添付しました。 + contact_abuse: 迷惑・不正行為対策委員会にご連絡ください + deleted: + html: あなたの作品 %{title} はサイト管理者によってAO3から削除されました。 + text: あなたの作品「%{title}」はサイト管理者によってAO3から削除されました。 + html: + tos_violation: あなたの作品がAO3のサービス利用規約を違反している可能性がある場合は、%{contact_abuse_link}。 + import_project: + html: あなたの作品がOpen Doors(オープンドア)チームによって管理されているインポート企画の一部であった場合は、%{opendoors_link}。 + text: あなたの作品がOpen Doors(オープンドア)チームによって管理されているインポート企画の一部であった場合は、オープンドアプロジェクト(%{opendoors_link})にご連絡ください。 + opendoors: オープンドアプロジェクトにご連絡ください + subject: "[%{app_name}] あなたの作品は管理者によって削除されました" + text: + tos_violation: あなたの作品がAO3のサービス利用規約を違反している可能性がある場合は、迷惑・不正行為対策委員会(%{contact_abuse_url})にご連絡ください。 + admin_hidden_work_notification: + access: 作品が非表示されている間も、上記のリンクから作品にアクセスできますが、あなたの投稿作品ページには掲載されず、他のAO3のユーザーが閲覧することはできません。 + check_email: すでに迷惑・不正行為対策委員会からあなたの作品が非表示となった理由を連絡している可能性がありますので、迷惑メールフォルダも含めてメールをご確認ください。 + contact_abuse: 迷惑・不正行為対策委員会をご連絡ください + html: + help: もし作品が非表示となった理由が確認できない、そしてこの件に関する連絡を受けていない場合は、直接に%{contact_abuse_link}。 + hidden: あなたの作品%{title}は迷惑・不正行為対策委員会によって隠され、非表示状態になっております。 + tos_violation: あなたの作品がAO3の%{tos_link}に違反しているために非表示となった場合、違反を修正するための措置が求められます。利用規約に従わない場合、あなたの作品はAO3から削除されることがあります。 + subject: "[%{app_name}] あなたの作品は迷惑・不正行為対策委員会によって非表示とされました。" + text: + help: もし作品が非表示となった理由が確認できない、そしてこの件に関する連絡を受けていない場合は、直接に迷惑・不正行為対策委員会へご連絡ください:%{contact_abuse_url}。 + hidden: あなたの作品「%{title}」(%{work_url})は迷惑・不正行為対策委員会によって隠され、非表示状態になっております。 + tos_violation: あなたの作品がAO3の( %{tos_url})に違反しているために非表示となった場合、違反を修正するための措置が求められます。利用規約に従わない場合、あなたの作品はAO3から削除されることがあります。 + tos: サービス利用規約 + anonymous_or_unrevealed_notification: + anonymous_info: 匿名化された作品はタグリストに含まれますが、あなたの投稿作品ページには表示されません。該当作品の作者欄にはあなたのユーザー名の代わりに「Anonymous」(匿名)と表示されます。 + anonymous_unrevealed_info: コレクション管理者は、後であなたの作品を公開するかもしれませんが、匿名化はされません。この変更は、あなたのフォロワーには通知されません。あなたの作品は公開した後にタグリストに含まれますが、あなたの投稿作品ページには表示されません。該当作品の作者欄にはあなたのユーザー名の代わりに「Anonymous」(匿名)と表示されます。 + changed_status: + anonymous: + html: "%{collection_link}のコレクション管理者はあなたの作品「%{work_link}」を匿名化しました。" + text: '"%{collection_title}" (%{collection_url}) のコレクション管理者は、あなたの作品 "%{work_title}" + (%{work_url}) のステータスを匿名に変更しました。' + anonymous_unrevealed: + html: "%{collection_link}のコレクション管理者はあなたの作品「%{work_link}」の状況を匿名・未公開に変更しました。" + text: '"%{collection_title}" (%{collection_url}) のコレクション管理者は、あなたの作品 "%{work_title}" + (%{work_url}) のステータスを匿名・未公開に変更しました。' + unrevealed: + html: "%{collection_link}のコレクション管理者はあなたの作品「%{work_link}」の状況を未公開に変更しました。" + text: '"%{collection_title}" (%{collection_url}) のコレクション管理者は、あなたの作品 "%{work_title}" + (%{work_url}) のステータスを未公開に変更しました。' + collection_items_link_text: Approved Collection Items(承認済みのコレクション作品)のページ + do_not_want: + anonymous: + html: 作品を匿名化したくない場合は、あなたの%{collection_items_link}ページで作品をコレクションから削除してください。 + text: 作品を匿名化したくない場合は、あなたのApproved Collection Items(承認済みのコレクション作品)ページで作品をコレクションから削除してください:%{collection_items_url} + anonymous_unrevealed: + html: 作品の状況を匿名・未公開に変更したくない場合は、あなたの%{collection_items_link}ページで作品をコレクションから削除してください。 + text: 作品の状況を匿名・未公開に変更したくない場合は、あなたのApproved Collection Items(承認済みのコレクション作品)ページで作品をコレクションから削除してください:%{collection_items_url} + unrevealed: + html: 作品の状況を未公開に変更したくない場合は、あなたの%{collection_items_link}ページで作品をコレクションから削除してください。 + text: 作品の状況を未公開に変更したくない場合は、あなたのApproved Collection Items(承認済みのコレクション作品)ページで作品をコレクションから削除してください:%{collection_items_url} + faq_link_text: コレクションFAQ + more_info: + html: 詳しくは、%{faq_link}をご覧ください。 + text: 詳しくは、コレクションFAQをご覧ください:%{faq_url} + subject: + anonymous: "[%{app_name}] あなたの作品は匿名化されました" + anonymous_unrevealed: "[%{app_name}] あなたの作品は匿名・未公開化されました" + unrevealed: "[%{app_name}] あなたの作品は未公開化されました" + unrevealed_info: 未公開作品はタグリストにも、あなたの投稿作品ページにも表示されません。リンクで作品にアクセスしたいユーザーには、作品は未公開とのお知らせが表示され、作品にアクセスできません。 + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (承認済みコレクションアイテム) ページ + archivist_notice: コレクションメンテナーはOpen Doors(オープンドアプロジェクト)の公式管理人として行動しているため、あなたがコレクションへの招待を無効にした場合でも、作品をコレクションに追加することができます。ただし管理人はインポートされたアーカイブでホストされている作品のみ、コレクションに追加します。 + removal_instructions: + html: このコレクションから作品を削除したい場合は、%{approved_items_link}をご覧ください。 + text: このコレクションから作品を削除したい場合は、Approved Collection Items(承認済みコレクションアイテム)ページをご覧ください: + %{approved_items_url}。 + subject: "[%{app_name}][%{collection_title}] Open Doors(オープンドアプロジェクト)の管理人が、あなたの作品をコレクションに追加しました" + work_added: + html: "%{collection_link}のコレクションメンテナーは、%{work_link}をコレクションに追加しました!" + text: コレクション「"%{collection_title}」 (%{collection_url})のコレクションメンテナーは、「"%{work_title}」 + (%{work_url})をコレクションに追加しました! + challenge_assignment_notification: + any: 何でも + assignment: + html: Archive of Our Own – AO3(みんなのアーカイブ)の %{link}チャレンジで、あなたは次のリクエストに割り当てられました。 + description: 概要: + due: 課題の締め切り: + html: + footer: あなたは%{title}チャレンジに登録したため、このメールを受信しています。このチャレンジの詳細と課題管理者の連絡先情報については、%{footer_link}にてご確認ください。 + footer_link: チャレンジのプロフィールページ + look_up: この課題は%{link}からご確認いただけます。 + look_up_link: あなたのAssignments(課題)ページ + optional_tags: タグ(必須ではありません): + prompts: お題: + prompt_url: お題URL: + recipient: 受信者: + recipient_missing: 受信者なし:課題管理者にお問い合わせください! + subject: "[%{app_name}][%{collection_title}]あなたへの課題です!" + text: + assignment: Archive of Our Own – AO3(みんなのアーカイブ)の %{collection_title} チャレンジ(%{collection_url}) + で、次のリクエストがあなたの課題として割り当てられました。 + footer: あなたは%{title}チャレンジ(%{url})に登録したため、このメールを受信しています。このチャレンジの詳細と課題管理者の連絡先情報については、%{profile_url}にてご確認ください。 + look_up: この課題については、Assignments(課題)のページ %{link}からご確認いただけます。 + change_email: + changed: + html: "%{login}さん、あなたのアカウントのメールアドレスは%{email}に変更されました。" + text: "%{login}さん、あなたのアカウントのメールアドレスは%{email}に変更されました。" + subject: "[%{app_name}] メールアドレス変更のお知らせ" + claim_notification: + access: + contact_support: AO3サポートまでお問い合わせ + html: アーカイブによっては、あなたの作品がGoogle検索から除外され、AO3の登録ユーザーのみに公開されます。あなたが作品の公開範囲を変更しない限り、あなたの作品にはログインしたユーザーのみがアクセスできます。作品の公開範囲変更・所有権放棄・削除については、%{contact_support_link}ください。 + text: アーカイブによっては、あなたの作品がGoogle検索から除外され、AO3の登録ユーザーのみに公開されます。あなたが作品の公開範囲を変更しない限り、あなたの作品にはログインしたユーザーのみがアクセスできます。作品の公開範囲変更・所有権放棄・削除については、以下のリンクでAO3サポートまでご連絡ください:%{support_url}。 + email_tips: お問い合わせの際は、@transformativeworks.orgを安全な連絡先リストに追加し、迷惑メールフォルダをチェックして返信をお待ちください。 + introduction: + ao3_name: Archive of Our Own – AO3(みんなのアーカイブ) + html: あなたの作品は%{open_doors_name_link}により、別のファン作品アーカイブから%{app_link}にインポートされました。このメールアドレスはインポートされたアーカイブに登録されているため、あなたのアカウントに関連する作品は自動的にあなたのAO3アカウントに追加されました。(作品について詳しくは、以下のリストを参照してください。) + open_doors_name: Open Doors(オープンドアプロジェクト) + text: あなたの作品はOpen Doors(オープンドアプロジェクト)(%{open_doors_url})により、別のファン作品アーカイブからArchive + of Our Own – AO3(みんなのアーカイブ)(%{app_url})にインポートされました。このメールアドレスはインポートされたアーカイブに登録されているため、あなたのアカウントに関連する作品は自動的にあなたのAO3アカウントに追加されました。(作品について詳しくは、以下のリストを参照してください。) + mistake: + contact_open_doors: Open Doorsに連絡して + html: もしこれが間違いであり、追加されたのがあなたの作品でない場合、どうか作品を削除しないでください! %{contact_open_doors_link}いただければ、私たちが対処いたします。 + text: もしこれが間違いであり、追加されたのがあなたの作品でない場合、どうか作品を削除しないでください!Open Doors (%{open_doors_url})に連絡していただければ、私たちが対処いたします。 + more_info: + ao3_news: AO3ニュース + contact_support: AO3サポートまでご連絡 + faq_page: よくある質問ページ + html: アーカイブのインポートに関するニュース記事やお知らせは%{ao3_news_link}で読むことができます。Open Doors(オープンドアプロジェクト)についての情報は%{faq_page_link}や + %{tutorial_page_link}で掲載されています。これらをご覧いただき、まだ質問がある場合は、%{contact_support_link}ください。 + text: アーカイブのインポートに関するニュース記事やお知らせはAO3ニュース(%{news_url})で読むことができます。Open Doors + (オープンドアプロジェクト) についての情報はよくある質問ページ(%{open_doors_faq_url})やチュートリアルページ (%{open_doors_tutorial_url})で掲載されています。これらをご覧いただき、まだ質問がある場合は、以下のリンクでAO3サポートまでご連絡ください:%{support_url}。 + tutorial_page: チュートリアルページ + other_works: + contact_open_doors: Open Doorsまでご連絡 + html: インポートされたアーカイブに、アクセスできなくなったメールアドレスで他の作品を投稿した場合は、本人確認に役立つ情報を%{contact_open_doors_link}ください。 + text: インポートされたアーカイブに、アクセスできなくなったメールアドレスで他の作品を投稿した場合は、本人確認に役立つ情報をOpen Doorsまでご連絡ください。 + questions: + contact_support: AO3サポートまでご連絡 + html: その他のお問い合わせは、%{contact_support_link}ください。 + text: その他のお問い合わせは、以下のリンクでAO3サポートまでご連絡ください:%{support_url}。 + redirects: + html: おすすめリストやブックマークを保存するため、インポートされたアーカイブの作品ページは、短期間でAO3のコピーまでリダイレクトされる可能性があります(詳細はニュース記事をご確認ください)。もし、あなたはすでに自分の作品のコピーをURLインポート機能を%{negation}にAO3に投稿した場合、同じ作品が2つあることになります。 + subject: "[%{app_name}] アップロードされた作品について" + update_redirect: + contact_open_doors: Open Doorsまでご連絡 + html: リダイレクト先を既存の作品ページにしたい場合、まずはインポートされたコピーを削除し、そして%{contact_open_doors_link}ください。連絡する際に、AO3と元のアーカイブ両方のアカウント名、作品タイトルとリダイレクトしたいURLを明記してください。(複数作品のリダイレクトを変更したい場合は、1通のメールにまとめてもいいです)。 + text: リダイレクト先を既存の作品ページにしたい場合、先ずはインポートされたコピーを削除し、そして以下のリンクでOpen Doorsまでご連絡ください:%{open_doors_url}。連絡する際に、AO3と元のアーカイブ両方のアカウント名、作品タイトルとリダイレクトしたいURLを明記してください。(複数作品のリダイレクトを変更したい場合は、1通のメールにまとめてもいいです。) + works_by: 下記の作品はこのメールアドレスで書かれました:%{email} + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: すべての課題が割り当てられ、各参加者に送信されました。 + subject: 課題が送信されました + html: + received_message: あなたのコレクション %{collection_link} に関するメッセージが届いています。 + text: + received_message: あなたのコレクション「%{collection_title}」(%{collection_url})に関するメッセージが届いています。 + creatorship_notification: + explanation: あなたが作品の合作者の場合は、あなたの共同制作の設定に関わらず、新しいチャプターにあなたのペンネームが合作者として追加されます。また、作品が加えられたシリーズにも追加されます。 + html: + creation: "%{creation_link} 作者:%{pseud_links}" + edit_chapter: 章を編集して + edit_series: シリーズを編集して + remove_chapter: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、%{edit_chapter_link}合作者から自分を削除できます。 + remove_series: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、%{edit_series_link}合作者として自身を削除することができます。 + intro_chapter: "%{adding_user}さんは以下の章の合作者として、あなたのペンネーム%{pseud}を追加しました:" + intro_series: "%{adding_user}さんは以下のシリーズの合作者としてあなたのペンネーム%{pseud} を追加しました:" + subject: "[%{app_name}] 合作者のお知らせ" + text: + creation: "%{title} (%{url}) 作者:%{pseuds}" + remove_chapter: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、章を編集して自身を合作者から削除することができます: + %{url} + remove_series: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、シリーズを編集して自身を合作者から削除することができます: + %{url} + creatorship_notification_archivist: + explanation: Open Doors(オープンドアプロジェクト)の公式な権限を持つ管理人は、あなたが合作者機能を無効化している場合でも、リクエストを送ることなくあなたを合作者として追加することがあります。 + html: + creation: "%{creation_link} 作者:%{pseud_links}" + edit_chapter: 章を編集して + edit_series: シリーズを編集して + edit_work: 作品を編集して + remove_chapter: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、%{edit_chapter_link}合作者として自身を削除することができます。 + remove_series: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、%{edit_series_link}合作者として自身を削除することができます。 + remove_work: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、%{edit_work_link}合作者として自身を削除することができます。 + intro_chapter: "%{archivist}さんはあなたのペンネーム%{pseud}を以下の章の合作者として追加しました:" + intro_series: "%{archivist}さんはあなたのペンネーム%{pseud}を以下のシリーズの合作者として追加しました:" + intro_work: "%{archivist}さんはあなたのペンネーム%{pseud}を以下の作品の合作者として追加しました:" + subject: "[%{app_name}]管理人による合作者追加のお知らせ" + text: + creation: "%{title} (%{url}) 作者: %{pseuds}" + remove_chapter: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、章を編集して合作者として自身を削除することができます:%{url} + remove_series: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、シリーズを編集して合作者として自身を削除することができます:%{url} + remove_work: 間違って合作者に追加された場合や、合作者としてリストに追加されたくない場合は、作品を編集して合作者として自身を削除することができます:%{url} + creatorship_request: + html: + creation: "%{creation_link} 作者:%{pseud_links}" + instructions: "%{page_name}ページでこのリクエストを承認または拒否することができます。" + page_name: Co-Creator Requests(合作者リクエスト) + intro_chapter: "%{inviting_user} さんはあなた(ペンネーム%{pseud})を以下の章の合作者として招待しました:" + intro_series: "%{inviting_user} さんはあなた(ペンネーム%{pseud})を以下のシリーズの合作者として招待しました:" + intro_work: "%{inviting_user} さんはあなた(ペンネーム%{pseud})を以下の作品の合作者として招待しました:" + subject: "[%{app_name}] 合作者リクエスト" + text: + creation: "%{title}(%{url}) 作者:%{pseuds}" + instructions: Co-Creator Requests(合作者リクエスト)ページでこのリクエストを承認または拒否することができます:%{url} + delete_work_notification: + attachment: ご参考までに、当該作品のコピーを添付にてお送りいたします。 + deleted_other: + html: "%{pseud}からの要望により、あなたの作品 %{title} が削除されました。" + text: "%{pseud}からの要望により、あなたの作品 %{title} が削除されました。" + deleted_yourself: + html: ご要望通りに、あなたの作品 %{title} が削除されました。 + text: ご要望通りに、あなたの作品 %{title} が削除されました。 + questions: + html: ご質問がございましたら、 %{support} + text: ご質問がございましたら %{support} (%{url}) + subject: "[%{app_name}] あなたの作品が削除されました" + support: ユーザーサポートまでお問い合わせください。 + invitation: + been_invited: あなたは私たちのβ版に招待されました! + has_invited: "%{user_name}さんはあなたを私たちのβ版に招待しました!" + html: + faq_link_text: 私たちのFAQ + subject: "[%{app_name}] 招待状" + invitation_to_claim: + access: + text: アーカイブによっては、インポートされた作品が登録ユーザーにしか閲覧できない場合があります(作品がグーグル検索結果に表示されないようにするためです)。 + この場合、 全体公開に設定しない限り、作品はログイン済みのユーザーにのみアクセス可能となります。作品のアンロック・匿名化・削除に関しては、 AO3サポートまでご連絡ください。 + claim_or_remove: + html: こちらから作品の担当表明や削除を行えます。 + text: 'こちらから作品の担当表明や削除を行えます: %{claim_url}' + email_tips: お問い合わせの際はメールアドレス@transformativeworks.orgをホワイトリストへ追加の上、こちらからの返信が迷惑メールに送信されていないかご確認ください。 + html: + ao3_news: AO3ニュース + contact_open_doors: オープンドアまでご連絡ください + contact_support: AO3サポートまでご連絡ください + faq_page: FAQページ + tutorial_page: チュートリアルページ + introduction: + text: アーカイブが%{open_doors_link} より%{app_name}(%{app_short_name} - %{app_url})へインポートされました件でメールを送らせていただいています。下記には作品の一覧が載せられていますが、ご希望の場合は、作品の担当表明(または削除・匿名化)が可能です。また、アカウントをお持ちでない場合は、ぜひアカウント登録をお願いします! + mistake: + text: アーカイブ情報に間違いがある場合、また下記の作品がご自身の作品でない場合は作品を削除しないようにお願いいたします! こちらが改めて整理できますようオープンドア(%{open_doors_link})までご連絡ください。 + more_info: + text: アーカイブに関する最新動向についてはAO3ニュース(%{news_link})からご覧できます。また、オープンドアの関連情報についてはFAQページ(%{open_doors_faq_link}) + かチュートリアルページ (%{open_doors_tutorial_link})をご参照ください。 FAQやチュートリアルに記載されていないご質問またはこのメールに関するご質問がある場合は、%{support_link}でAO3サポートまでご連絡ください。 + other_works: + text: アーカイブのインポート時に利用したメールアドレスにアクセスできなくなり、そのアーカイブにまだ他の作品がある場合は、ご身分を証明できる情報をオープンドアまでご連絡ください。 + questions: + text: その他のご質問に関しては%{support_link}でAO3サポートまでご連絡ください。 + redirects: オススメリスト及びブックマークを保存するために、インポートされたアーカイブ内のWebアドレスは一定期間作品のコピーまでリダイレクトされます(詳しくはご自身のアーカイブの告知ポストをご確認ください)。作品のコピーをアップロード済みであり、かつURLインポート機能をご利用でない場合、アーカイブの同じ作品のコピーが2つ作成されます。 + subject: "[%{app_name}]作品担当表明へのご招待" + unwanted: + text: ご自身の作品ではありますが公表したくない場合は作品を匿名化(作品はAO3に保存されますが、作者名は表示されません)または削除(作品は AO3から完全削除されます)できます。上記の担当表明リンクからそのまま作品の匿名化と削除ができますので、匿名化と削除のために作品を特定のアカウント下に置く必要はありません。(協力が必要な場合は%{support_link}でAO3サポートまでご連絡ください。) + update_redirect: + text: オープンドアに既存の作品までのリダイレクトを依頼する場合は、インポートされたコピーを削除し、AO3アカウント名・インポートされたアーカイブにおけるアカウント名・リダイレクト先の作品名とURLをオープンドア%{open_doors_link}までご連絡ください(複数の作品のリダイレクト先を変更したい場合は、作品リストをメールでお知らせください)。 + uploaded_list: 'アップロードされた作品は以下の通りです:' + invite_increase_notification: + html: + body: + other: 新しい招待状が%{count}枚あなたに届いていることをお知らせいたします。招待状はアーカイブで新しいアカウントを作成するために使えます。%{invitation_page_link}にて友達を招待することもできます。 + invitation_page_link_text: 招待管理ページ + subject: "[%{app_name}] 新しい招待状" + text: + body: + other: 新しい招待状が%{count}枚あなたに届いていることをお知らせいたします。招待状はアーカイブで新しいアカウントを作成するために使えます。Invitations(招待状)ページ(%{invitation_page_url})で友達を招待することができます。 + invite_request_declined: + main: + other: 申し訳ございませんが、あなたのリクエストされた%{count} 件の新しい招待コードは、今回は承認できませんでした。 + reason: あなたのリクエストは以下の通りでした。 + subject: "[%{app_name}]追加招待コードのリクエストが拒否されました" + recipient_notification: + html: + collection: あなたへのプレゼント作品が、AO3の%{collection_link} コレクションに投稿されました! + no_collection: あなたへのプレゼント作品がAO3に投稿されました! + subject: + collection: "[%{app_name}][%{collection_title}] %{collection_title} からあなたへのプレゼント作品が届きました" + no_collection: "[%{app_name}] あなたへのプレゼント作品が届きました" + text: + collection: あなたへのプレゼント作品が、AO3の 「 %{collection_title} 」コレクション(%{collection_url})に投稿されました! + signup_notification: + activate: + html: こちらよりどうぞ %{activate_account_link}。 + text: 'このリンクに従いアカウントを有効化してください: %{activate_account_url}' + activate_your_account: このリンクに従いアアカウントを有効化してください + admin_posts: AO3ニュース + bye: AO3の利用が楽しいものとなりますよう願っております。 + contact_support: ユーザーサポートまでご連絡ください + faq: FAQ + features: + html: アカウントが有効化されると、ファン作品を投稿したり、お気に入りの作者や作品が更新された時にメール通知するフォローを設定したり、サイトの見た目や機能が自分好みになるよう設定からカスタマイズしたり、AO3でアクセスした作品を確認したり、他にも沢山のことができるようになります。 + text: 'アカウントが有効化されると、ファン作品を投稿したり、お気に入りの作者や作品が更新された時にメール通知するフォローを設定したり、サイトの見た目や機能が自分好みになるよう設定からカスタマイズしたり、AO3でアクセスした作品を確認したり、他にも沢山のことができるようになります。 ' + information: + html: 私たちの %{faq_link} には、AO3の使い方に関する沢山の情報やアドバイスが掲載されています。 サイトの最新の更新状況は %{admin_posts_link} + にて確認できます。サポートが必要な場合、バグを見つけた場合、またはご質問やコメントがある場合は、%{contact_support_link} + へご連絡下さいましたら喜んでお手伝いいたします。 + text: 私たちの %{faq_url} には、AO3の使い方に関する沢山の情報やアドバイスが掲載されています。 サイトの最新の更新状況は %{admin_posts_url} + にて確認できます。サポートが必要な場合、バグを見つけた場合、またはご質問やコメントがある場合は、%{contact_support_url} へご連絡下さいましたら喜んでお手伝いいたします。 + welcome: Archive of Our Own – AO3(みんなのアーカイブ)へようこそ、 %{login} さん! diff --git a/config/locales/phrase-exports/ko.yml b/config/locales/phrase-exports/ko.yml new file mode 100755 index 0000000..d5d55ab --- /dev/null +++ b/config/locales/phrase-exports/ko.yml @@ -0,0 +1,490 @@ +--- +ko: + activerecord: + attributes: + archive_warning: + name_with_colon: + other: '주의 사항:' + category: + name_with_colon: + other: '카테고리:' + character: + name_with_colon: + other: '여러 등장인물들:' + fandom: + name_with_colon: + other: '팬덤:' + freeform: + name_with_colon: + other: '기타 태그:' + rating: + name_with_colon: '등급:' + relationship: + name_with_colon: + other: '관계성:' + work: + chapter_total_display: 챕터 + summary: 줄거리 + models: + archive_warning: + other: 주의 사항 + category: + other: 카테고리 + chapter: + other: 챕터 + character: + other: 등장인물 + fandom: + other: 팬덤 + freeform: + other: 기타 태그 + rating: + other: 등급 + relationship: + other: 관계성 + series: + other: 시리즈 + kudo_mailer: + batch_kudo_notification: + guest: + other: "%{count} 손님들" + left_kudos: + html: + other: "%{commentable_link}에 %{givers_list}이(가) 좋아요(kudos)를 남겼습니다." + text: + other: "%{commentable_title} (%{commentable_url})에 %{givers_list}이(가) 좋아요(kudos)를 + 남겼습니다." + single_guest: + giver: 손님 + html: "%{commentable_link}에 %{giver}이(가) 좋아요(kudos)를 남겼습니다." + text: "%{commentable_title} (%{commentable_url})에 손님이 좋아요(kudos)를 남겼습니다." + subject: "[%{app_name}] 회원님의 게시물에 좋아요(kudos)가 있습니다!" + mailer: + general: + closing: + formal: 드림 + informal: 드림 + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: 작품 %{title}의 챕터 %{position} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + other: "%{count} 단어" + footer: + general: + about: + html: AO3는 팬이 직접 운영 및 지원하는 아카이브로 %{donate_link}에 의존하고 있습니다. + text: 'AO3는 팬이 직접 운영 및 지원하는 아카이브로 여러분의 기부금에 의존하고 있습니다. 기부 링크: %{donate_url}' + html: + donate_link_text: 여러분의 기부금 + support_link_text: 지원 위원회에 연락 + unwanted_email: + html: 이 메시지를 오류로 받으신 경우, %{support_link}해 주세요. + text: 이 메시지를 오류로 받으신 경우, 다음 링크로 지원 위원회에 문의해 주세요. %{support_url} + sent_at: "%{sent_at}에 전송됨." + greeting: + formal_html: "%{name} 님," + informal: + addressed_html: 안녕하세요, %{name} 님! + unaddressed: 안녕하세요! + introductory: Archive of Our Own – AO3 (우리만의 아카이브)에서 인사드립니다! + metadata_label_indicator: ":" + signature: + abuse_team: AO3 정책관리 위원회 드림 + app_short_name: AO3 + open_doors: The Open Doors (오픈 도어 프로젝트) 팀 드림 + parent_org: Organization for Transformative Works – OTW (변형적 작품 단체) 드림 + support: AO3 지원 위원회 드림 + users: + mailer: + reset_password_instructions: + expiration: 일주일 안에 링크를 통해 비밀번호를 재설정하지 않을시, 현재 링크가 만료되며 새로운 링크를 요청하셔야 합니다. + intro: 누군가가 회원님 계정의 비밀번호 재설정을 요청하였습니다. 아래 링크에서 새로운 비밀번호를 입력하여 비밀번호를 변경하실 수 + 있습니다. + link_title: 비밀번호 변경하기 + subject: "[%{app_name}] 비밀번호 재설정" + unrequested: 비밀번호 재설정을 요청하지 않으셨다면 이 이메일을 무시하셔도 됩니다. 비밀번호가 변경되지 않습니다. + user_mailer: + admin_deleted_work_notification: + bye: 회원님을 위해 작품의 복사본이 첨부되어 있습니다. + contact_abuse: 정책관리 위원회에 연락하기 + deleted: + html: 회원님의 %{title} 작품이 사이트 관리자에 의해 Archive of Our Own - AO3(우리만의 아카이브)에서 + 삭제되었습니다. + text: 회원님의 “%{title}” 작품이 사이트 관리자에 의해 Archive of Our Own - AO3(우리만의 아카이브)에서 + 삭제되었습니다. + html: + tos_violation: 만약 회원님의 작품이 AO3의 이용약관을 어겼을 가능성이 있다면, %{contact_abuse_link}를 + 통해 문의해 주십시오. + import_project: + html: 만약 회원님의 작품이 Open Doors(오픈 도어 프로젝트) 팀이 관리하는 반입 프로젝트에 속해있었다면, %{opendoors_link}를 + 통해 문의해 주십시오. + text: 만약 회원님의 작품이 Open Doors(오픈 도어 프로젝트) 팀이 관리하는 반입 프로젝트에 속해있었다면, (%{opendoors_link})를 + 통해 오픈 도어 프로젝트에 문의해 주십시오. + opendoors: 오픈 도어 프로젝트에 연락하기 + subject: "[%{app_name}]님의 작품이 관리자에 의해 삭제되었습니다" + text: + tos_violation: 만약 회원님의 작품이 AO3의 이용약관을 어겼을 가능성이 있다면, (%{contact_abuse_url})를 + 통해 정책관리 위원회에 문의해 주십시오. + admin_hidden_work_notification: + access: 작품이 비공개인 동안에는 위에 제공된 링크를 통해 조회하실 수는 있으나 회원님의 작품 페이지 목록에는 포함되지 않고 AO3 + 내 다른 사용자에게 공개되지 않습니다. + check_email: 정책 관리 위원회에서 회원님의 작품을 비공개한 사유를 설명하는 메일을 발송했을 수도 있으니 회원님의 메일함 및 스팸 + 보관함을 확인해 주시기 바랍니다. + contact_abuse: 정책 관리 위원회에 문의 + html: + help: 회원님의 작품이 비공개 전환된 사유를 알 수 없거나 해당 사항에 대한 상세 연락을 받지 못하셨다면 직접 %{contact_abuse_link}해 + 주시기 바랍니다. + hidden: 정책 관리 위원회에서 회원님의 작품 %{title}을(를) 비공개로 전환하여 더 이상 공개적으로 조회할 수 없습니다. + tos_violation: AO3 내 %{tos_link} 규정 위반으로 작품이 비공개 되었다면 해당 위반사항을 시정하셔야 합니다. + 작품이 이용 약관을 준수하도록 조치를 취하지 않으신다면 작품이 AO3에서 삭제될 수도 있습니다. + subject: "[%{app_name}] 정책 관리 위원회에서 회원님의 작품을 비공개 처리하였습니다" + text: + help: '회원님의 작품이 비공개 전환된 사유를 알 수 없거나 해당 사항에 대한 상세 연락을 받지 못하셨다면 직접 정책 관리 위원회에 + 문의해 주시기 바랍니다: %{contact_abuse_url}' + hidden: 정책 관리 위원회에서 회원님의 작품 "%{title}" (%{work_url})을(를) 비공개 전환하여 더 이상 공개적으로 + 조회할 수 없습니다. + tos_violation: AO3 내 %{tos_url} 규정 위반으로 작품이 비공개 되었다면 해당 위반사항을 시정하셔야 합니다. 작품이 + 이용 약관을 준수하도록 조치를 취하지 않으신다면 작품이 AO3에서 삭제될 수도 있습니다. + tos: 이용 약관 + anonymous_or_unrevealed_notification: + anonymous_info: 익명 작품들은 태그 목록에 포함되지만 회원님의 작품 페이지에는 포함되지 않습니다. 작품 페이지에서 회원님의 + 이름이 "Anonymous" (익명)으로 대체됩니다. + anonymous_unrevealed_info: 추후 관리자가 회원님의 작품을 익명 작품으로써 공개할 수도 있습니다. 회원님을 구독하고 + 있는 사용자들에게는 해당 변경사항이 알려지지 않습니다. 공개 시에는 회원님의 작품이 태그 목록에 포함되나 회원님의 작품 페이지에는 나타나지 + 않습니다. 작품상에서는 회원님의 유저 이름이 "Anonymous" (익명)로 표기됩니다. + changed_status: + anonymous: + html: "%{collection_link} 컬렉션 관리자가 회원님의 작품 %{work_link}을(를) 익명 작품으로 전환했습니다." + text: '"%{collection_title}" (%{collection_url}) 콜렉션 관리자가 회원님의 작품 "%{work_title}" + (%{work_url}) 를/을 익명으로 처리했습니다.' + anonymous_unrevealed: + html: "%{collection_link} 컬렉션 관리자가 회원님의 작품을 %{work_link} 을(를) 익명 및 비공개로 + 전환했습니다." + text: '"%{collection_title}" (%{collection_url}) 콜렉션 관리자가 회원님의 작품 "%{work_title}" + (%{work_url}) 를/을 익명이자 비공개 등록으로 처리했습니다.' + unrevealed: + html: "%{collection_link} 컬렉션 관리자가 회원님의 작품 %{work_link}을(를) 비공개로 전환했습니다." + text: '"%{collection_title}" (%{collection_url}) 콜렉션 관리자가 회원님의 작품 "%{work_title}" + (%{work_url}) 를/을 비공개 등록으로 처리했습니다.' + collection_items_link_text: Approved Collection Items (등록된 컬렉션 작품 목록) 페이지 + do_not_want: + anonymous: + html: 작품의 익명 처리를 원치 않으신다면 회원님의 컬렉션 목록 링크 %{collection_items_link} 에 접속하여 + 해당 컬렉션에서 작품을 제외해 주시기 바랍니다. + text: '작품 익명 처리를 원치 않으신다면 회원님의 Approved Collection Items (승인된 컬렉션 목록) 페이지에 + 접속하셔서 해당 컬렉션에서 작품을 제외해 주시기 바랍니다: %{collection_items_url}' + anonymous_unrevealed: + html: 작품 익명 및 비공개 처리를 원치 않으신다면 회원님의 컬렉션 목록 링크 %{collection_items_link} 에 + 접속하여 해당 컬렉션에서 작품을 제외해 주시기 바랍니다. + text: '작품 익명 및 비공개 처리를 원치 않으신다면 회원님의 Approved Collection Items (승인된 컬렉션 + 목록) 페이지에 접속하셔서 해당 컬렉션에서 작품을 제외해 주시기 바랍니다: %{collection_items_url}' + unrevealed: + html: 작품 비공개를 원치 않으시다면 회원님의 컬렉션 목록 링크 %{collection_items_link} 에 접속하여 해당 + 컬렉션에서 작품을 제외해 주시기 바랍니다. + text: '작품 비공개 처리를 원치 않으신다면 회원님의 Approved Collection Items (승인된 컬렉션 목록) 페이지에 + 접속하셔서 해당 컬렉션에서 작품을 제외해 주시기 바랍니다: %{collection_items_url}' + faq_link_text: 컬렉션 FAQ 페이지 + more_info: + html: 더 자세한 사항은 %{faq_link}를 참고해 주세요. + text: '더 자세한 사항은 컬렉션 FAQ를 참고해 주세요: %{faq_url}' + subject: + anonymous: "[%{app_name}] 회원님의 작품이 익명 처리되었습니다." + anonymous_unrevealed: "[%{app_name}] 회원님의 작품이 익명 및 비공개 처리되었습니다." + unrevealed: "[%{app_name}] 회원님의 작품이 비공개 처리되었습니다" + unrevealed_info: 비공개 작품은 태그 목록 및 회원님의 작품 페이지에 나타나지 않습니다. 해당 작품 링크로 접속하는 모든 이용자에게는 + 작품이 비공개임을 알리는 공지가 뜨며 작품 내용을 조회할 수 없습니다. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (승인된 컬렉션 항목) 페이지 + archivist_notice: 컬렉션 관리자는 Open Doors (오픈 도어 프로젝트) 아키비스트로서 공식 자격으로 활동하기 때문에 + 회원님께서 컬렉션 초대를 비활성화한 경우에도 이 컬렉션에 작품을 추가할 수 있습니다. 아키비스트는 가져온 아카이브에서 호스팅된 작품인 + 경우에만 작품을 컬렉션에 추가합니다. + removal_instructions: + html: 이 컬렉션에서 작품을 제외하려면 회원님의 %{approved_items_link}를 방문하세요. + text: '이 컬렉션에서 작품을 제외하려면 회원님의 Approved Collection Items (승인된 컬렉션 항목) 페이지를 + 방문하세요. 링크: %{approved_items_url}' + subject: "[%{app_name}][%{collection_title}] Open Doors (오픈 도어 프로젝트) 아키비스트가 + 회원님의 작품을 컬렉션에 추가했습니다" + work_added: + html: "%{collection_link} 컬렉션 관리자가 회원님의 %{work_link} 작품을 컬렉션에 추가했습니다!" + text: '"%{collection_title}" (%{collection_url}) 컬렉션 관리자가 회원님의 "%{work_title}" + (%{work_url}) 작품을 컬렉션에 추가했습니다!' + challenge_assignment_notification: + any: "'모든' 태그 포함" + assignment: + html: 회원님께서는 AO3 %{link} 챌린지에서 다음과 같은 리퀘를 맡게 되셨습니다! + description: '설명:' + due: '이 챌린지 과제의 마감일:' + html: + footer: "%{title} 챌린지에 등록했기 때문에 이 이메일을 받으셨습니다. 이 챌린지에 대한 자세한 내용과 진행자의 연락처는 + %{footer_link}에서 확인할 수 있습니다." + footer_link: 챌린지 프로필 페이지 + look_up: 이 챌린지 과제는 %{link}에서 확인할 수 있습니다. + look_up_link: 회원님의 Assignments (챌린지 과제) 페이지 + optional_tags: '선택적 태그:' + prompts: '소재:' + prompt_url: '소재 URL:' + recipient: '받는 사람:' + recipient_missing: '없음: 관리자에게 도움을 요청하세요!' + subject: "[%{app_name}][%{collection_title}] 회원님의 챌린지 과제입니다!" + text: + assignment: 다음은 회원님이 맡게 되신 AO3 "%{collection_title}" 챌린지 (%{collection_url}) + 리퀘입니다! + footer: "%{title} 챌린지(%{url})에 등록했기 때문에 이 이메일을 받으셨습니다. 이 챌린지에 대한 자세한 내용과 진행자의 + 연락처는 %{profile_url}에서 확인할 수 있습니다." + look_up: 이 챌린지 과제는 회원님의 Assignments (챌린지 과제) 페이지 링크 %{link}에서 확인할 수 있습니다. + change_email: + changed: + html: "%{login}님, 회원님의 계정과 연계된 이메일 주소가 %{email}으로 변경되었습니다." + text: "%{login}님, 회원님의 계정과 연계된 이메일 주소가 %{email}으로 변경되었습니다." + subject: "[%{app_name}] 이메일 주소 변경" + claim_notification: + access: + contact_support: AO3 지원 위원회에 문의 + html: 아카이브에 따라서는 통합 이전 시 회원님의 작품이 (구글 검색을 방지하기 위해) 등록된 회원에게만 보이도록 설정되는 경우가 + 있습니다. 이때는 전체 공개로 설정을 변경하지 않으면 작품은 로그인한 회원들만 조회할 수 있습니다. 작품을 전체 공개하거나, 버리기, + 또는 삭제하는 데 도움이 필요하시면 %{contact_support_link}해 주시기 바랍니다. + text: '아카이브에 따라서는 통합 이전 시 회원님의 작품이 (구글 검색을 방지하기 위해) 등록된 회원에게만 보이도록 설정되는 경우가 + 있습니다. 이 때는 전체 공개로 설정을 변경하지 않으면 작품은 로그인을 한 회원들만 조회할 수 있습니다. 작품을 전체 공개하거나, + 버리기, 또는 삭제하는 데 도움이 필요하시면 다음 링크를 통해 AO3 지원 위원해에 문의해 주시기 바랍니다: %{support_url}' + email_tips: 저희에게 문의를 주실 경우 @transformativeworks.org를 회원님의 안전 연락처에 추가해 주시고 저희의 + 답변이 회원님의 스팸 폴더로 들어가 있지는 않은지 확인해 주시기 바랍니다. + introduction: + ao3_name: Archive of Our Own – AO3 (우리만의 아카이브) + html: 이 이메일은 %{open_doors_name_link}를 통해 %{app_link}으로 통합 이전된 팬작품 아카이브가 회원님의 + 작품을 포함하고 있음을 알리기 위해 보내 드립니다. 본 이메일 주소가 이번에 이전된 아카이브에 등록된 계정과 연결되어 있어 관련된 + 팬작품(아래 목록에서 확인하실 수 있습니다)은 자동으로 회원님의 AO3 계정에 추가되었습니다. + open_doors_name: Open Doors (오픈 도어 프로젝트) + text: '이 이메일은 Open Doors (오픈 도어 위원회) (%{open_doors_url})를 통해 Archive of Our + Own – AO3 (우리만의 아카이브): %{app_url}으로 통합 이전된 팬작품 아카이브가 회원님의 작품을 포함하고 있음을 알리기 + 위해 보내드립니다.본 이메일 주소가 이번에 이전된 아카이브에 등록되어 있어 관련된 팬작품(아래 목록에서 확인하실 수 있습니다)은 + 자동으로 회원님의 AO3 계정에 추가되었습니다.' + mistake: + contact_open_doors: 오픈 도어 프로젝트에 문의 + html: 이 작품이 회원님의 작품이 아니라면 해당 작품을 삭제하지 말아 주세요! %{contact_open_doors_link}해서 + 알려 주시면 저희가 해결해 드리겠습니다. + text: 만약 이 작품들이 귀하의 작품이 아니라면, 해당 작품을 삭제하지 말아주세요! 오픈 도어 위원회(%{open_doors_url})에 + 문의해서 알려 주시면 저희가 해결해 드리겠습니다. + more_info: + ao3_news: AO3 소식 + contact_support: AO3 지원 위원회에 문의 + faq_page: FAQ 페이지 + html: 최근 아카이브 이전에 대한 소식은 %{ao3_news_link}에서, 오픈 도어 프로젝트에 대한 추가 정보는 %{faq_page_link} + 또는 %{tutorial_page_link}에서 확인하실 수 있습니다. FAQ, 튜토리얼, 이메일 등으로 해결되지 못한 질문은 %{contact_support_link}해 + 주시기 바랍니다. + text: '최근 아카이브 이전에 대한 정보는 AO3 뉴스 (%{news_url})에서, 오픈 도어 프로젝트에 대한 추가 정보는 오픈 + 도어 FAQ 페이지 (%{open_doors_faq_url}) 또는 튜토리얼 페이지(%{open_doors_tutorial_url})에서 + 확인하실 수 있습니다. FAQ, 튜토리얼, 이메일 등으로 해결하지 못한 질문은 다음 링크를 통해 지원 위원회에 문의해 주시기 바랍니다: + %{support_url}' + tutorial_page: 튜토리얼 페이지 + other_works: + contact_open_doors: 오픈도어 프로젝트에 문의 + html: 이전해 온 아카이브의 다른 작품들이 회원님이 현시점 사용할 수 없는 이메일 주소로 등록되어 있는 경우 무엇이든 회원님의 신원을 + 확인할 수 있는 정보를 넣어 %{contact_open_doors_link}해 주시기 바랍니다. + text: 이전해온 아카이브의 다른 작품들이 회원님이 현 시점 사용할 수 없는 이메일 주소로 등록되어 있는 경우 무엇이든 회원님의 신원을 + 확인할 수 있는 정보를 넣어 오픈 도어 위원회에 문의해 주시기 바랍니다. + questions: + contact_support: AO3 지원 위원회에 문의 + html: 그 의 질문은 %{contact_support_link}해 주세요. + text: '그 의 질문은 다음 링크를 통해 AO3 지원 위원회에 문의해 주세요: %{support_url}' + redirects: + html: 추천 리스트와 책갈피를 보존하시려는 경우 이전된 아카이브의 웹주소는 일정 기간 이전해 온 해당 작품의 주소로 자동 리디렉팅이 + 되기도 합니다(정확한 사항은 해당하는 아카이브에 관한 공지를 통해 확인해 주세요). 해당 작품의 사본을 이미 게시하고 URL을 통해 + 불러오기 기능을 사용하지 %{negation}셨다면 AO3에는 동일한 작품이 두 개 게시물로 존재하게 됩니다. + subject: "[%{app_name}] 작품이 게시되었습니다" + update_redirect: + contact_open_doors: 오픈 도어 프로젝트에 문의 + html: 리디렉팅 주소가 회원님의 기존 작품으로 이어지도록 오픈 도어 위원회에서 업데이트를 진행하기를 원하신다면 이전해 온 사본을 + 삭제한 뒤 AO3 계정 이름, 이전한 아카이브 내 계정 이름, 리디렉팅으로 이동하게 될 팬작품의 제목과 URL을 담아 %{contact_open_doors_link}해 + 주시기 바랍니다. (여러 작품의 라디렉팅 주소를 변경하기를 원하시면 한 통의 이메일 안에 모두 담으셔도 됩니다.) + text: 리디렉팅 주소가 회원님의 기존 작품으로 이어지도록 오픈 도어 위원회에서 업데이트를 진행하기를 원하신다면 이전해 온 사본을 + 삭제한 뒤 AO3 계정 이름, 이전한 아카이브 내 계정 이름, 리디렉팅으로 이동하게 될 팬작품의 제목과 URL을 담아 %{open_doors_url}를 + 통해 오픈 도어 위원회에 문의해 주시기 바랍니다. (여러 작품의 라디렉팅 주소를 변경하기 원하시면 한 통의 이메일 안에 모두 담으셔도 + 됩니다.) + works_by: '해당 작품은 다음 이메일 주소로 작성되었습니다: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: 모든 챌린지 과제가 발송 완료되었습니다. + subject: 챌린지 과제 발송 완료 + html: + received_message: '회원님의 컬렉션 %{collection_link}에 관한 메시지가 도착했습니다:' + text: + received_message: 회원님의 컬렉션 "%{collection_title}" (%{collection_url})에 관한 메시지가 + 도착했습니다. + creatorship_notification: + explanation: 어떤 작품의 공동 창작자가 되면 회원님의 공동 창작 설정과 관계 없이 신규 챕터에 공동 창작자로 추가됩니다. 또한 + 해당 작품을 포함하는 모든 시리즈에도 등록됩니다. + html: + creation: "%{creation_link}, %{pseud_links} 작(作)" + edit_chapter: 챕터 수정하기 + edit_series: 시리즈 수정하기 + remove_chapter: 의도치 않게 등록 되었거나 등록을 희망하지 않으신다면 %{edit_chapter_link}를 통해 회원님을 + 창작자에서 제외하실 수 있습니다. + remove_series: 의도치 않게 등록되었거나 등록을 원치 않으신다면 %{edit_series_link}를 통해 회원님을 창작자에서 + 제외할 수 있습니다. + intro_chapter: "%{adding_user} 님이 회원님의 필명 %{pseud}을(를) 다음 작품 챕터의 공동 창작자로 등록했습니다:" + intro_series: "%{adding_user} 님이 회원님의 필명 %{pseud}을(를) 다음 시리즈의 공동 창작자로 등록했습니다:" + subject: "[%{app_name}] 공동 창작자 알림" + text: + creation: "%{title} (%{url}), %{pseuds} 작(作)" + remove_chapter: '의도치 않게 등록 되었거나 등록을 원치 않으신다면 챕터를 수정하여 회원님을 창작자에서 제외할 수 있습니다 + : %{url}' + remove_series: '의도치 않게 등록 되었거나 등록을 원치 않으신다면 시리즈를 수정하여 회원님을 창작자에서 제외할 수 있습니다r: + %{url}' + creatorship_notification_archivist: + explanation: Open Doors (오픈 도어)의 공식적인 임무를 진행하는 아키비스트는 사용자님이 '나를 공동 창작자로 추가' + 설정을 비활성화 시켰더라도 요청 없이 추가할 수 있습니다. + html: + creation: "%{pseud_links}의 %{creation_link}" + edit_chapter: 챕터 수정하기 + edit_series: 시리즈 수정하기 + edit_work: 작품 수정하기 + remove_chapter: 회원님의 공동 창작자 등록이 오류로 인한 것이라면 %{edit_chapter_link} 링크를 통해 회원님의 + 창작자 등록을 취소하실 수 있습니다. + remove_series: 회원님의 공동 창작자 등록이 오류로 인한 것이라면 %{edit_series_link} 링크를 통해 창작자 + 등록을 취소하실 수 있습니다. + remove_work: 회원님의 공동 창작자 등록이 오류로 인한 것이라면 %{edit_work_link}링크를 통해 창작자 등록을 취소하실 + 수 있습니다. + intro_chapter: "%{archivist} 님이 회원님의 필명 %{pseud}을(를) 다음 작품 챕터의 공동 창작자로 등록했습니다:" + intro_series: "%{archivist} 님이 회원님의 필명 %{pseud}을(를) 다음 시리즈의 공동 창작자로 추가했습니다:" + intro_work: '아카이브 관리자 %{archivist} 님이 회원님의 필명 %{pseud}을(를) 다음 작품의 공동 창작자로 추가하였습니다:' + subject: "[%{app_name}] 아키비스트 공동 창작자 알림" + text: + creation: "%{pseuds}의 %{title} (%{url})" + remove_chapter: '실수로 또는 원치 않게 창작자로 추가되었을 경우 챕터 수정을 통해 회원님의 필명을 창작자 명단에서 삭제할 + 수 있습니다: %{url}' + remove_series: '실수로 또는 원치 않게 창작자로 추가되었을 경우 시리즈 수정을 통해 회원님의 필명을 창작자 명단에서 삭제할 + 수 있습니다: %{url}' + remove_work: '실수로 또는 원치 않게 창작자로 추가됐을 경우 작품 수정을 통해 회원님의 필명을 작품 창작자 명단에서 삭제할 + 수 있습니다: %{url}' + creatorship_request: + html: + creation: "%{pseud_links}의 %{creation_link}" + instructions: 회원님의 %{page_name} 페이지에서 본 요청을 수락 또는 거절할 수 있습니다. + page_name: Co-Creator Requests (공동 창작자 요청) + intro_chapter: "%{inviting_user} 회원님이 회원님의 창작자명 %{pseud} 을(를) 다음 챕터의 공동 창작자로 + 등록하기를 요청했습니다:" + intro_series: "%{inviting_user} 회원님이 회원님의 창작자명 %{pseud}을(를) 다음 시리즈의 공동 창작자로 + 등록하기를 요청했습니다:" + intro_work: "%{inviting_user} 회원님이 회원님의 창작자명 %{pseud}을(를) 다음 작품의 공동 창작자로 등록하기를 + 요청했습니다:" + subject: "[%{app_name}] 공동 창작자 등록 요청" + text: + creation: "%{pseuds}의; %{title} (%{url})" + instructions: '회원님의 Co-Creator Requests (공동 창작자 요청) 페이지에서 본 요청을 수락 또는 거절할 + 수 있습니다: %{url}' + delete_work_notification: + attachment: 참고를 위해 작품의 복사본을 첨부해 드립니다. + deleted_other: + html: "%{pseud} 의 요청으로 회원님의 작품 %{title}이 삭제되었습니다." + text: '%{pseud}의 요청으로 회원님의 작품 "%{title}"이 삭제되었습니다.' + deleted_yourself: + html: 회원님의 요청으로 회원님의 작품 %{title}이 삭제되었습니다. + text: 회원님의 요청으로 회원님의 작품 "%{title}"이 삭제되었습니다. + questions: + html: 질문이 있으시다면, %{support}에 연락해 주세요. + text: 질문이 있으시다면, %{support}(%{url})에 연락해 주세요. + subject: "[%{app_name}] 회원님의 작품이 삭제되었습니다" + support: 지원 위원회에 연락해 주세요 + invitation_to_claim: + access: + text: 아카이브에 따라, 작품이 (구글 검색을 피하기 위해)등록된 회원에게만 공개된 경우도 있습니다. 만약 그런 상황이라면, 작품의 + 전면 공개를 하지 않는 이상 작품은 계속해서 로그인 된 회원에게만 공개됩니다. 작품의 전면공개, 고립하기, 삭제하기 등에 도움이 + 필요하시다면 AO3 지원 위원회로 연락주십시오. + claim_or_remove: + html: 작품 소유권을 되찾거나 포기하는 법. + text: '작품 창작자로 등록하거나 삭제하는 링크: %{claim_url}' + email_tips: 만약 저희와 연락하고 싶으시다면, @transformativeworks.org의 이메일 주소를 스팸이 아닌 것으로 + 분류하신 뒤 저희 답변을 스팸 폴더에서 찾아봐 주세요. + html: + ao3_news: AO3 뉴스 + contact_open_doors: 오픈 도어 연락하기 + contact_support: AO3 지원 연락하기 + faq_page: 자주 묻는 질문답변 + tutorial_page: 튜토리얼 페이지 + introduction: + text: 최근 Open Doors (오픈 도어 프로젝트) (%{open_doors_link})를 통해 이전된 아카이브 %{app_name}(%{app_short_name} + - %{app_url})에서 다음 작품들이 회원님의 작품인 것으로 추측되어 이메일 드립니다. 원하신다면 작품의 소유권을 회복(또는 + 삭제/고립)할 기회를 드리고 싶습니다. 그리고 만약 이미 아카이브에 다른 이메일 주소로 회원이 아니시라면, 저희 아카이브에 초대하고 + 싶습니다! + mistake: + text: 만약 본 메일이 실수이고 작품의 창작자가 아니시라면, 부디 삭제하지 말아주십시오! 오픈 도어 프로젝트(%{open_doors_link})로 + 연락주시면 저희가 해결하겠습니다. + more_info: + text: 최근의 아카이브 뉴스에 관해 AO3 뉴스(%{news_link})에서 읽으실 수 있으며, 오픈 도어 FAQ 페이지(%{open_doors_faq_link}) + 나 튜토리얼 메뉴(%{open_doors_tutorial_link})를 통해 추가적인 정보를 얻으실 수 있습니다. FAQ, 튜토리얼, + 그리고 본 이메일에 답이 없는 질문이 있을 경우, %{support_link}로 통해서 지원 위원회로 연락 주십시오. + other_works: + text: 만약 이전된 아카이브에 접속할 수 없는 이메일 계정으로 여러 작품이 있으실 경우, 창작자 증명이 가능한 자료와 함께 오픈 + 도어로 연락 주십시오. + questions: + text: 그 외 다른 도움이 필요하신 경우, %{support_link} 통해서 AO3 서포트로 연락 주십시오. + redirects: 추천 목록과 북마크를 저장하기 위해, 이전된 아카이브의 웹주소는 이전된 작품 복사본의 주소로 당분간 연결됩니다(아카이브의 + 공지사항을 확인해주세요). 만약 이미 작품의 복사본을 등록했고 URL의 이전 기능을 사용하지 않았을 경우, 아카이브에 작품의 복사본 + 2개가 있을 것입니다. + subject: "[%{app_name}] 작품 등록하기에 초대합니다" + unwanted: + text: 만약 이 작품의 창작자면서도 소유권을 포기하고 싶으실 경우, 작품을 고립(작품은 AO3에 남지만, 작가 이름이 익명으로 처리)할 + 수 있고 또는 삭제(작품이 AO3에 남지 않고 완전히 삭제)할 수도 있습니다. 작품을 고립하거나 삭제하기 위해 계정에 등록할 필요 + 없습니다-- 위의 링크를 통해 하실 수 있습니다. (도움이 필요하신 경우, %{support_link} 서포트로 연락 주십시오.) + update_redirect: + text: 만약 오픈 도어에서 기존 작품으로 연결되는 링크를 업데이트 하길 원하신 다면, 이전된 작품 복사본을 지우시고, %{open_doors_link}로 + 통해서 오픈 도어에게 연락해 AO3 계정 이름, 이전된 아카이브의 계정 이름, 그리고 작품의 제목과 URL 주소를 알려주세요. (만약 + 링크할 작품이 여러개라도, 한 이메일로 목록을 주시면 됩니다.) + uploaded_list: '게시한 작품은 다음을 포함합니다:' + invite_increase_notification: + html: + body: + other: 회원님께서 %{count} 개의 새 초대장을 받으셨으며 이를 사용해 AO3 아카이브에서 새로운 계정을 만들 수 있다는 + 것을 알려드립니다. %{invitation_page_link}를 통해 친구를 초대할 수 있습니다. + invitation_page_link_text: Invitations (초대) 페이지 + subject: "[%{app_name}] 새로운 초대장" + text: + body: + other: 회원님께서 %{count} 개의 새 초대장을 받으셨으며, 이를 통해 새로운 AO3 계정을 만들 수 있다는 것을 알려드립니다. + Invitations (초대) 페이지에서 친구를 초대할 수 있습니다 (%{invitation_page_url}). + invite_request_declined: + main: + other: 안타깝게도 회원님이 요청하신 추가 초청 코드 %{count} 개는 현재 발급해 드리기 어렵습니다. + reason: '회원님의 요청:' + subject: "[%{app_name}] 추가 초청 코드 요청이 거부되었습니다" + recipient_notification: + html: + collection: AO3 내 %{collection_link} 컬렉션에 회원님을 위한 선물 작품이 게시되었습니다! + no_collection: 회원님을 위한 선물 작품이 AO3에 게시되었습니다! + subject: + collection: "[%{app_name}][%{collection_title}] %{collection_title} 내 회원님을 + 위한 선물 작품이 있습니다" + no_collection: "[%{app_name}] 회원님을 위한 선물 작품이 있습니다" + text: + collection: AO3 내 "%{collection_title}" 컬렉션(%{collection_url})에 회원님을 위한 선물 + 작품이 게시되었습니다! + signup_notification: + activate: + html: "%{activate_account_link} 해주세요." + text: '당신의 계정을 활성화하려면 다음 링크를 눌러주세요: %{activate_account_url}' + activate_your_account: 계정 활성화를 위해 링크를 눌러주세요 + admin_posts: AO3 뉴스 + bye: 아카이브 사용하시면서 즐겁기 바랍니다. + contact_support: 서포트 팀과 연락하기 + faq: FAQ + features: + html: 일단 계정이 활성화된 후, 회원님은 팬작품을 게시할 수 있고, 이메일을 통해 좋아하는 작가나 작품의 업데이트를 알림받을 수 + 있고, 사이트 사용화면을 마음에 들게 꾸밀 수 있고, 히스토리를 통해 과거에 열람한 아카이브의 작품을 확인할 수 있고, 그 밖에도 + 많은 것을 할 수 있습니다. + text: 일단 계정이 활성화된 후, 회원님은 팬작품을 게시할 수 있고, 이메일을 통해 좋아하는 작가나 작품의 업데이트를 알림받을 수 + 있고, 사이트 사용화면을 마음에 들게 꾸밀 수 있고, 히스토리를 통해 과거에 열람한 아카이브의 작품을 확인할 수 있고, 그 밖에도 + 많은 것을 할 수 있습니다. + information: + html: "%{faq_link}에는 아카이브를 어떻게 활용할 수 있는지 도와드리는 정보가 가득합니다. 사이트의 발달 상황에 대한 가장 + 최신의 소식은 %{admin_posts_link}를 통해 접할 수 있습니다. 만약 더 많은 도움이 필요하신 경우 또는 질문이나 제안이 + 있으실 경우에는 %{contact_support_link}를 이용해 주세요. 언제나 도와드릴 준비가 되어있습니다." + text: " %{faq_url}에는 아카이브를 어떻게 활용할 수 있는지 도와드리는 정보가 가득합니다. 사이트의 발달 상황에 대한 가장 + 최신 소식, AO3 뉴스는 %{admin_posts_url}를 통해 접할 수 있습니다. 만약 더 많은 도움이 필요하신 경우 또는 + 질문이나 제안이 있으실 경우에는 %{contact_support_url}를 이용해 주세요. 언제나 도와드릴 준비가 되어있습니다." + welcome: 우리만의 아카이브에 오신 것을 환영합니다, %{login}님! diff --git a/config/locales/phrase-exports/lt.yml b/config/locales/phrase-exports/lt.yml new file mode 100755 index 0000000..8e81ada --- /dev/null +++ b/config/locales/phrase-exports/lt.yml @@ -0,0 +1,2 @@ +--- +lt: {} diff --git a/config/locales/phrase-exports/lv.yml b/config/locales/phrase-exports/lv.yml new file mode 100755 index 0000000..c16692e --- /dev/null +++ b/config/locales/phrase-exports/lv.yml @@ -0,0 +1,288 @@ +--- +lv: + mailer: + general: + creation: + title_with_chapter_number: "%{title} %{position} nodaļa" + users: + mailer: + reset_password_instructions: + expiration: Ja Tu nedēļas laikā neizmantosi šo saiti, lai nomainītu paroli, + beigsies tās derīguma termiņš, un Tev vajadzēs to pieprasīt atkārtoti. + intro: 'Kāds ir pieprasījis paroles nomaiņu Tavam kontam. Tu vari nomainīt + sava konta paroli sekojot norādītajai saitei un ievadot savu jauno paroli:' + link_title: Mainīt manu paroli. + subject: "[%{app_name}] Atiestati savu paroli" + unrequested: Ja Tu nepieprasīji šo paroles nomaiņu, Tu vari ignorēt šo epastu + un Tava iepriekšējā parole turpinās darboties. + user_mailer: + admin_hidden_work_notification: + access: Kamēr Tavs darbs ir slēpts, Tu joprojām spēsi tam piekļūt, izmantojot + augstāk norādīto saiti, bet tas nebūs redzams Tavu darbu lapā, un tas nebūs + pieejams citiem AO3 lietotājiem. + check_email: Lūdzu, pārbaudi savu epasta adresi, ieskaitot spama sadaļu, jo + Pārkāpumu risināšanas komanda, iespējams, jau ir ar Tevi sazinājusies, lai + paskaidrotu, kāpēc Tavs darbs ir ticis paslēpts. + contact_abuse: sazinies ar Pārkāpumu risināšanas komandu + html: + help: Ja Tu neesi pārliecināts, kāpēc Tavs darbs ir ticis paslēpts un Tu neesi + saņēmis papildus informāciju, lūdzu, %{contact_abuse_link}. + hidden: Tavu darbu %{title} ir paslēpusi Pārkāpumu risināšanas komanda, un + tas vairs nav publiski pieejams. + tos_violation: Ja Tavs darbs tika paslēpts, jo tas pārkāpa AO3 %{tos_link}, + Tev būs jānovērš pārkāpums. Ja tas netiks izdarīts, un darbs neatbildīs + Pakalpojumu sniegšanas noteikumiem, tas tiks dzēsts. + subject: "[%{app_name}] Tavu darbu ir paslēpusi Pārkāpumu risināšanas komanda" + text: + help: 'Ja Tu neesi pārliecināts par darba paslē''pšanas iemeslu un neesi saņēmis + papildus informāciju, lūdzu, sazinies ar Pārkāpumu risināšanas komandu: + %{contact_abuse_url}.' + hidden: Tavu darbu "%{title}" (%{work_url}) ir paslēpusi Pārkāpumu risināšanas + komanda, un tas vairs nav publiski pieejams. + tos_violation: Ja Tavs darbs tika paslēpts, jo tas neatbilst AO3 Pakalpojumu + sniegšanas noteikumiem (%{tos_url}), Tev nāksies veikt darba labojumus. + Ja darbu nepārveidosi, lai tas atbilstu Pakalpojumu sniegšanas noteikumiem. + Tavs darbs tiks dzēsts no AO3. + tos: Pakalpojumu sniegšanas noteikumi + anonymous_or_unrevealed_notification: + anonymous_info: Anonīmi darbi ir iekļauti birku sarakstos, bet ne Tavā publisko + darbu sarakstā. Darbā Tavs lietotājvārds tiks aizstāts ar "Anonīms" (Tulkošana). + anonymous_unrevealed_info: Kolekcijas uzturētāji var vēlāk padarīt Tavu darbu + par atklātu, bet atstāt to anonīmu. Cilvēki, kuri seko Tavam profilam, netiks + informēti par šīm izmaiņām. Kad tas tiek padarīts par atklātu, Tavs darbs + tiks iekļauts birku sarakstos, bet ne Tavu darbu sarakstos. Darba autora vārds + tiks mainīts uz ''Anonīms'' (Tulkošana). + changed_status: + anonymous: + html: "%{collection_link} kolekcijas uzturētāji ir padarījuši tavu darbu + %{work_link} anonīmu." + text: '"%{collection_title}" (%{collection_url}) kolekcijas uzturētāji ir + nomainījuši Tava darba "%{work_title}" (%{work_url}) statusu uz anonīmu.' + anonymous_unrevealed: + html: "%{collection_link} kolekcijas uzturētāji ir nomainījuši Tava darba + %{work_link} statusu uz anonīmu un slēptu." + text: '"%{collection_title}" (%{collection_url}) kolekcijas uzturētāji ir + nomainījuši Tava darba "%{work_title}" (%{work_url}) statusu uz anonīmu + un slēptu.' + unrevealed: + html: "%{collection_link} kolekcijas uzturētāji ir mainījuši Tava darba + %{work_link} statusu, un ir padarījuši to par slēptu." + text: '"%{collection_title}" (%{collection_url}) kolekcijas uzturētāji ir + nomainījuši Tava darba "%{work_title}" (%{work_url}) statusu uz slēptu.' + collection_items_link_text: Apstiprināto Kolekcijas vienumu (Tulkošana) lapa + do_not_want: + anonymous: + html: Ja Tu nevēlies, lai Tavs darbs ir anonīms, lūdzu apmeklē %{collection_items_link}, + lai to noņemtu no šī saraksta. + text: 'Ja Tu nevēlies, lai Tavs darbs ir anonīms, apmeklē savu Apstirpināto + Kolekcijas Vienumu (Tulkošana) lapu, lai to noņemtu no šīs kolekcijas: + %{collection_items_url}' + anonymous_unrevealed: + html: Ja Tu nevēlies, lai Tavs darbs ir anonīms un slēpts, lūdzu, apmeklē + %{collection_items_link}, lai to noņemtu no šīs kolekcijas. + text: 'Ja Tu nevēlies, lai Tavs darbs ir anonīms un slēpts, apmeklē savu + Apstirpināto Kolekcijas Vienumu (Tulkošana) lapu, lai to noņemtu no šīs + kolekcijas: %{collection_items_url}' + unrevealed: + html: Ja Tu nevēlies, lai Tavs darbs ir slēpts, apmeklē savu %{collection_items_link}, + lai to noņemtu no šīs kolekcijas. + text: 'Ja Tu nevēlies, lai Tavs darbs ir slēpts, apmeklē savu Apstirpināto + Kolekcijas Vienumu (Tulkošana) lapu, lai to noņemtu no šīs kolekcijas: + %{collection_items_url}' + faq_link_text: BUJ par kolekcijām + more_info: + html: Lai saņemtu papildus informāciju, apmeklē mūsu %{faq_link}. + text: 'Lai saņemtu papildus informāciju, apmeklē mūsu BUJ par kolekcijām: + %{faq_url}' + subject: + anonymous: "[%{app_name}] Tavs darbs tika padarīts anonīms" + anonymous_unrevealed: Tavs darbs [%{app_name}] tika padarīts par anonīmu un + slēptu. + unrevealed: Tavs darbs [%{app_name}] tika padarīts slēpts + unrevealed_info: Slēpti darbi nav iekļauti birku sarakstos un Tavu darbu sarakstā. + Ikviens, kurš izmanto saiti, lai apskatītu Tavu darbu, saņems paziņojumu, + ka tas pašlaik ir slēpts, un nespēs tam piekļūt. + archivist_added_to_collection_notification: + approved_collection_items_page: Apstiprinātās Kolekcijas (Tulkošana) lapa + archivist_notice: Kolekcijas uzturētāji darbojas viņu oficiālajā kapacitātē + kā Atvērto Durvju(Tulkošana) arhīvisti, tāpēc viņiem ir atļauts pievienot + Tavu darbu kolekcijai, arī tādos gadījumos, kad esi bloķējis ielūgumus uz + kolekcijām. Arhīvisti pievieno darbu kolekcijai tikai tad, ja ja tas tika + pievienots importētam arhīvam. + removal_instructions: + html: Ja Tu vēlies noņemt savu darbu no šīs kolekcijas, lūdzu, apmeklē %{approved_items_link}. + text: 'Ja Tu vēlies noņemt savu darbu no šīs kolekcijas, lūdzu, apmeklē savu + Apstiprināto kolekciju (Tulkošana) lapu: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}]Open Doors(Atvērtās Durvis (Tulkošana)) + arhīvists ir pievienojis Tavu darbu kolekcijai." + work_added: + html: "%{collection_link}Kolekcijas uzturētāji ir pievienojuši Tavu darbu + %{work_link} viņu kolekcijai!" + text: '"%{collection_title}" (%{collection_url})Kolekcijas uzturētāji ir pievienojuši + Tavu darbu "%{work_title}" (%{work_url}) viņu kolekcijai!' + challenge_assignment_notification: + any: Jebkurš un pēc izvēles + assignment: + html: Tev ir iedots sekojošs pieprasījums AO3 %{link} izaicinājumā. + description: 'Apraksts:' + due: 'Šī uzdevuma izpildes termiņš ir:' + html: + footer: Tu esi saņēmis šo e-pastu, jo Tu pieteicies %{title} izaicinājumam. + Lai uzzinātu vairāk par šo izaicinājumu un, lai saņemtu moderatoru kontaktinformāciju, + lūdzu, apmeklē %{footer_link}. + footer_link: izaicinājuma profila mājaslapu + look_up: Tu vari aplūkot uzdevumu Savā %{link}. + look_up_link: Assignments (Tulkošana) lapā + optional_tags: 'Tagi pēc izvēles:' + prompts: 'Prompti:' + prompt_url: 'Promptu URL:' + recipient: 'Saņēmējs:' + recipient_missing: 'Neviens: lūdz palīdzību moderatoram.' + subject: "[%{app_name}][%{collection_title}]Tavs uzdevums!" + text: + assignment: Tev ir piešķirts sekojošs pieprasījums "%{collection_title}" AO3 + izaicinājumā(%{collection_url})! + footer: Tu esi saņēmis šo e-pastu, jo Tu pieteicies %{title} izaicinājumam + (%{url}). Lai uzzinātu vairāk par šo izaicinājumu un, lai saņemtu moderatoru + kontaktinformāciju, lūdzu, apmeklē %{profile_url}. + look_up: Tu vari aplūkot savu izaicinājumu Savā Assignments (Tulkošana) lapā + %{link}. + change_email: + changed: + html: "%{login}, Epasta adrese, kura ir asociēta ar Tavu profilu, ir mainīta + uz %{email}" + text: Epasta adrese %{login}, kura ir asociēta ar Tavu profilu, ir nomainīta + uz %{email} + subject: "[%{app_name}] Epasta adrese ir mainīta" + claim_notification: + access: + contact_support: sazinies ar AO3 Support (Atbalsts) + html: Atkarībā no arhīva Tavi darbi var būt importēti un tos var redzēt tikai + reģistrēti lietotāji (Lai paslēptu tos no Google meklētāja). Ja tas ir tā, + darbi būs pieejami tikai reģistrētiem lietotājiem, izņemot gadījumus, kad + Tu izvēlies tos padarīt redzamus citiem. Lai saņemtu palīdzību šīs darbības + veikšanai vai savu darbu dzēšanai, lūdzu sazinies ar %{contact_support_link}. + text: Atkarībā no arhīva Tavi darbi var būt importēti un tos var redzēt tikai + reģistrēti lietotāji (Lai paslēptu tos no Google meklētāja). Ja tas ir tā, + darbi būs pieejami tikai reģistrētiem lietotājiem, izņemot gadījumus, kad + Tu izvēlies tos padarīt redzamus citiem. Lai saņemtu palīdzību šīs darbības + veikšanai vai savu darbu dzēšanai, lūdzu sazinies ar user_mailer.claim_notification.access.contact_support + Sazinies ar AO3 Support(Atbalsts)%{support_url}. + email_tips: Ja Tu sazinies ar Mums, lūdzu pievieno e-pasta adreses no @transformativeworks.org + uz savu drošo kontaktu sarakstu un pārbaudi savu spamu, lai redzētu Mūsu atbildi. + introduction: + ao3_name: Archive Of Our Own-AO3 (Tulkošana) (Mūsu pašu arhīvs) + html: Tu esi saņēmis šo e-pastu, jo Tavi darbi ir iekļauti fanworks arhīvā, + kurš tika importēts no %{open_doors_name_link} uz %{app_link}. Šī e-pasta + adrese ir saistīta ar to, kas ir reģistrēta importētajā arhīvā, asociētie + fanu darbi (minēti lejā) automātiski tika pievienoti Tavam AO3 kontam. + open_doors_name: "(Atvērtās Durvis (Tulkošana)" + text: Tu esi saņēmis šo e-pastu, jo Tavi darbi ir iekļauti fanworks arhīvā, + kurš tika importēts no Atvērtajām Durvīm(%{open_doors_url}) uz AO3 arhīvu.%{app_url}. + . Šī e-pasta adrese ir saistīta ar to, kas ir reģistrēta importētajā arhīvā, + asociētie fanu darbi( minēti lejā) automātiski tika pievienoti Tavam AO3 + kontam. + mistake: + contact_open_doors: sazinies ar Atvērtajām Durvīm (Open Doors) + html: Ja šī ir kļūda, un šie nav Tavi darbi, lūdzu, neizdēs tos! Lūdzu, sazinies + ar %{contact_open_doors_link} un Mēs to nokārtosim. + text: Ja šī ir kļūda, un šie nav Tavi darbi, lūdzu, neizdēs tos! Lūdzu, sazinies + ar (%{open_doors_url}) un Mēs to nokārtosim + more_info: + ao3_news: AO3 ziņas + contact_support: Sazinies ar AO3 Support (AO3 Atbalsts) + faq_page: BUJ lapa + html: Tu vari izlasīt paziņojumus par nesenām arhīva pārcelšanām %{ao3_news_link}, + un atrast papildus informāciju Open Doors (Atvērtās Durvis) %{faq_page_link} + vai%{tutorial_page_link}. Ja ir kādi jautājumi, kas nav atbildēti FAQ apmācībā, + vai šajā e-pastā, lūdzu %{contact_support_link}. + text: Tu vari izlasīt paziņojumus par nesenām arhīva pārcelšanām AO3 Ziņās + (%{news_url}), un atrast papildus informāciju Open Doors (Atvērtās Durvis)(%{open_doors_faq_url}) + vai apmācības lapā (%{open_doors_tutorial_url}). Ja ir kādi jautājumi, kas + nav atbildēti FAQ apmācība, vai šajā e-pastā, lūdzu%{support_url}. + tutorial_page: apmācības lapa + other_works: + contact_open_doors: sazinies ar Atvērtajām Durvīm + html: Ja ir bijuši citi darbi importētajā arhīvā zem e-pasta adreses, kurai + Tu vairs nevari piekļūt, lūdzu, sazinies %{contact_open_doors_link} ar jebkādu + informāciju, kas varētu palīdzēt vertificēt Tavu identitāti. + text: Ja ir bijuši citi darbi importētajā arhīvā zem e-pasta adreses, kurai + Tu vairs nevari piekļūt, lūdzu, sazinies ar jebkādu informāciju, kas varētu + palīdzēt vertificēt Tavu identitāti. + questions: + contact_support: sazinies ar AO3 Atbalstu + html: Citām nepieciešamībām, lūdzu,%{contact_support_link}. + text: Citām nepieciešamībām, lūdzu,%{support_url}. + redirects: + html: Lai saglabātu rec (rekomendāciju) sarakstu un grāmatzīmes, importēto + arhīvu mājaslapu adreses var norādit uz šo darbu importētajām kopijām uz + noteiktu laiku( pārbaudi sava arhīva paziņojumu, lai pārliecinātos). Ja + Tu jau esi lejupielādējis šo darbu kopiju un %{negation} izmantoji URL funkciju, + būs divas tāda paša darba kopijas AO3. + subject: "[%{app_name}] Darbi ir augšupielādēti" + update_redirect: + contact_open_doors: Sazinies ar Atvērtajām Durvīm + html: Ja Tu vēlies, lai Open Doors atjauninātu novirzījumu, lai tas norādītu + uz jau eksistējošu darbu, lūdzu,%{contact_open_doors_link} izdzēs importēto + kopiju ar savu AO3 vārdu, sava konta vārdu importētajā arhīvā un nosaukumu + un tā fanu darba URL, uz kuru tu gribi novirzīt. (Ja ir vairāki darbi, kurus + Tu vēlies novirzīt vai mainīt novirzījumu, Tu vari to pierakstīt vienā e-pastā.) + text: Ja Tu vēlies, lai Open Doors atjauninātu novirzījumu , lai tas norādītu + uz jau eksistējošu darbu un sazināties ar Open Doors %{open_doors_url} , + lūdzu, izdzēs importēto kopiju ar savu AO3 vārdu, sava konta vārdu importētajā + arhīvā un nosaukumu un tā fanu darba URL, uz kuru tu gribi novirzīt. (Ja + ir vairāki darbi, kurus Tu vēlies novirzīt vai mainīt novirzījumu, Tu vari + to pierakstīt vienā e-pastā.) + works_by: 'Šie darbi tika rakstīti izmantojot šo e-pasta adresi: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + creatorship_notification_archivist: + explanation: Viņi izmanto savas oficiālās iespējas kā Open Doors (Translation) + (Atvērtās Durvis (Tulkošana)), viņiem ir atļauts Tevi pievienot bez uzaicinājuma + arī tad, ja esi bloķējis ko-autora funkciju. + html: + creation: "%{creation_link} %{pseud_links}" + edit_chapter: Mainīt vai labot nodaļu + edit_series: Mainīt vai labot stāstu sērijas + edit_work: mainīt vai labot darbu. + remove_chapter: Ja Tu es pievienots klūdas dēļ vai nevēlies būt atzīmēts kā + autors, Tu vari noņemt sevi kā ko-autoru.%{edit_chapter_link} + remove_series: Ja Tu es pievienots klūdas dēļ, vai nevēlies būt atzīmēts kā + autors, Tu vari %{edit_series_link} noņemt sevi kā ko-autoru. + remove_work: Ja Tu es pievienots klūdas dēļ, vai nevēlies būt atzīmēts kā + autors, Tu vari %{edit_work_link} noņemt sevi kā ko-autoru. + intro_chapter: 'Lietotājs %{archivist} ir Tevi %{pseud} pievienojis kā ko- autoru + sekojošajā nodaļā:' + intro_series: 'Lietotājs %{archivist} ir Tevi pievienojis %{pseud} kā ko- autoru + sekojošajās stāstu sērijās:' + intro_work: 'Lietotājs %{archivist} ir pievienojis Tavu pseud %{pseud} kā ko-autoru + sekojošajā darbā:' + subject: "[%{app_name}] Arhīvista ko -autora (co-creator) ziņa" + text: + creation: "%{title} (%{url})%{pseuds}" + remove_chapter: Ja Tu es pievienots klūdas dēļ, vai nevēlies būt atzīmēts + kā autors, Tu vari labot nodaļu noņemt sevi kā ko-autoru.%{url} + remove_series: Ja Tu es pievienots klūdas dēļ, vai nevēlies būt atzīmēts kā + autors, Tu vari labot stāstu sērijas un noņemt sevi kā ko-autoru.%{url} + remove_work: 'Ja Tu es pievienots klūdas dēļ vai nevēlies būt atzīmēts kā + autors, Tu vari labot darbu un noņemt sevi kā ko-autoru: %{url}' + creatorship_request: + html: + creation: "%{creation_link} autors/i %{pseud_links}" + instructions: Tu vari apstiprināt vai noraidīt uzaicinājumu savā %{page_name} + lapā. + page_name: Līdzradītāja Uzaicinājums (Tulkošana) + intro_chapter: 'Lietotājs %{inviting_user} ir uzaicinājis Tavu pseidonīmu %{pseud} + norādīt kā līdzradītāju sekojošajai nodaļai:' + intro_series: 'Lietotājs %{inviting_user} ir uzaicinājis Tavu pseidonīmu %{pseud} + norādīt kā līdzradītāju sekojošajai sērijai:' + intro_work: 'Lietotājs %{inviting_user} ir uzaicinājis Tavu pseidonīmu %{pseud} + norādīt kā līdzradītāju sekojošajam darbam:' + subject: "[%{app_name}] Līdzradītāja pieprasījums" + text: + creation: Autora %{pseuds} %{title} (%{url}) + instructions: 'Tu vari apstiprināt vai noraidīt uzaicinājumu savā Līdzradītāja + Uzaicinājumu (Tulkošana) lapā: %{url}' diff --git a/config/locales/phrase-exports/mk.yml b/config/locales/phrase-exports/mk.yml new file mode 100755 index 0000000..a674574 --- /dev/null +++ b/config/locales/phrase-exports/mk.yml @@ -0,0 +1,2 @@ +--- +mk: {} diff --git a/config/locales/phrase-exports/mr.yml b/config/locales/phrase-exports/mr.yml new file mode 100755 index 0000000..4bbfc71 --- /dev/null +++ b/config/locales/phrase-exports/mr.yml @@ -0,0 +1,533 @@ +--- +mr: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'इशारा:' + other: 'इशारे:' + category: + name_with_colon: + one: 'प्रकार:' + other: 'प्रकार:' + character: + name_with_colon: + one: 'व्यक्तिरेखा:' + other: 'व्यक्तिरेखा:' + fandom: + name_with_colon: + one: 'रसिकगट:' + other: 'रसिकगट:' + freeform: + name_with_colon: + one: 'अतिरिक्त टाचणखूण:' + other: 'अतिरिक्त टाचणखूणा:' + rating: + name_with_colon: 'गुणांकन:' + relationship: + name_with_colon: + one: 'नाते:' + other: 'नाती:' + work: + chapter_total_display: प्रकरण + summary: सारांश + models: + archive_warning: + one: इशारा + other: इशारे + category: + one: प्रकार + other: प्रकार + chapter: + one: प्रकरण + other: प्रकरण + character: + one: व्यक्तिरेखा + other: व्यक्तिरेखा + fandom: + one: रसिकगट + other: रसिकगट + freeform: + one: अतिरिक्त टाचणखूण + other: अतिरिक्त टाचणखूणा + rating: + one: गुणांकन + other: गुणांकन + relationship: + one: नाते + other: नाती + series: + one: मालिका + other: मालिका + kudo_mailer: + batch_kudo_notification: + guest: + one: एक पाहुणा + other: "%{count} पाहुणे" + left_kudos: + html: + one: "%{givers_list} यांनी पुढील कार्यावर टाळ्या दिल्या आहेत %{commentable_link}." + other: "%{givers_list} यांनी पुढील कार्यावर टाळ्या दिल्या आहेत %{commentable_link}." + text: + one: "%{givers_list} यांनी पुढील कार्यावर टाळ्या दिल्या आहेत %{commentable_title} + (%{commentable_url})." + other: "%{givers_list} यांनी पुढील कार्यावर टाळ्या दिल्या आहेत %{commentable_title} + (%{commentable_url})." + single_guest: + giver: एक पाहुणा + html: "%{commentable_link} वर %{giver} या पाहुण्याने टाळ्या दिल्या आहेत." + text: "%{commentable_title} (%{commentable_url}) वर पाहुण्यांनी टाळ्या दिल्या + आहेत" + subject: "[%{app_name}] आपल्याला टाळ्या प्राप्त झाल्या आहेत!" + mailer: + general: + closing: + formal: मनःपूर्वक, + informal: शुभेच्छा, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: "%{title} चं %{position} प्रकरण" + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} शब्द" + other: "%{count} शब्द" + footer: + general: + about: + html: AO3 हे एक रसिक-चलित आणि रसिक-समर्थित संग्रह आहे जो %{donate_link}वर + अवलंबून आहे. + text: AO3 हे रसिक-चलित आणि रसिक-समर्थित संग्रह आहे जो आपल्या देणग्याः + %{donate_url} यांवर अवलंबून आहे. + html: + donate_link_text: आपल्या देणग्यां + support_link_text: समिती-संवाद समितीस संपर्क साधा + unwanted_email: + html: जर आपल्याला हा संदेश चुकुन पाठवला गेला असेल, तर कृपया %{support_link}. + text: जर आपल्याला हा संदेश चुकुन प्राप्त झाला असेल, तर कृपया समिती-संवाद + समितीस संपर्क साधा %{support_url}. + sent_at: "%{sent_at} ला पाठवलं गेलं." + greeting: + formal_html: प्रिय %{name}, + informal: + addressed_html: नमस्कार, %{name}! + unaddressed: नमस्कार! + introductory: Archive of Our Own – AO3 (आमचा स्वतःचा संग्रह) तर्फे नमस्कार! + metadata_label_indicator: ":" + signature: + abuse_team: AO3 नियम आणि तक्रारनिवारण समिती + app_short_name: AO3 + open_doors: The Open Doors (रसिक मुक्तद्वार समिती) + parent_org: Organization for Transformative Works – OTW (परिवर्तनात्मक रसिक-कला + मंडळी) + support: AO3 समिती-संवाद समिती + users: + mailer: + reset_password_instructions: + expiration: जर आपण ही दूवा वापरुन पुढच्या एका आठवड्यात आपले संकेतशब्द बदलले + नाही, तर विनंती कालबाह्य होईल, आणि आपल्याला एका नव्या दूव्याची विनंती करावी + लागेल. + intro: 'कोणीतरी आपल्या खात्याचा संकेतशब्द पुनःप्रस्थापित करण्याची विनंती केली + आहे. आपण आपल्या खात्याचा संकेतशब्द खाली दिलेल्या दूव्याचे अनुसरण करून मग + आपला नवा संकेतशब्द प्रविष्ट करून बदलू शकता:' + link_title: माझा संकेतशब्द बदला + subject: "[%{app_name}] आपला संकेतशब्द पुनःप्रस्थापित करा" + unrequested: जर आपण संकेतशब्द बदलण्याची विनंती नसेल केली, तर आपण ह्या ई-मेल + कडे दुर्लक्ष करू शकता आणि तुमचा पूर्वीचा संकेतशब्द काम करत राहील. + user_mailer: + admin_deleted_work_notification: + bye: आपल्या संदर्भासाठी आपल्या कार्याची कॉपी इथे संलग्न केलेली आहे. + contact_abuse: नियम आणि तक्रारनिवारण समिती ला संपर्क करा. + deleted: + html: आपले कार्य %{title} AO3 वरून एका साईट व्यवस्थापकाने काढून टाकले आहे. + text: आपले कार्य "%{title}" AO3 वरून एका साईट व्यवस्थापकाने काढून टाकले आहे. + html: + tos_violation: जर शक्यता असेल की आपल्या कार्याने AO3 च्या नियम आणि ध्येयधोरणेचे + उल्लंघन केले असेल तर कृपया %{contact_abuse_link} ला भेट द्या. + import_project: + html: जर आपले कार्य आयात केलेल्या प्रकल्पाचा भाग असेल जे Open Doors (रसिकमुक्तद्वार + प्रकल्प) सांभाळतात, तर कृपया इतर प्रश्नांच्या समाधानाकरीता %{opendoors_link} + ला भेट द्या. + text: जर आपले कार्य आयात केलेल्या प्रकल्पाचा भाग असेल जे Open Doors (रसिकमुक्तद्वार + प्रकल्प) सांभाळतात, तर कृपया इतर प्रश्नांच्या समाधानाकरीता Open Doors (%{opendoors_link}) + शी संपर्क करा. + opendoors: रसिकमुक्तद्वार प्रकल्पाला संपर्क करा. + subject: "[%{app_name}] आपले कार्य एका व्यवस्थापकाने काढून टाकले आहे." + text: + tos_violation: जर शक्यता असेल की आपल्या कार्याने AO3 च्या नियम आणि ध्येयधोरणेचे + उल्लंघन केले असेल तर कृपया आमच्या नियम आणि तक्रारनिवारण समिती (%{contact_abuse_url}) + ला संपर्क करा. + admin_hidden_work_notification: + access: तुमचे कार्य लपलेले असून, तुम्ही वर दिलेल्या दूवा द्वारे त्यात प्रवेश + करण्यात सक्षम असाल, परंतु ते तुमच्या कार्य पृष्ठावर सूचीबद्ध केले जाणार नाही + आणि ते AO3 च्या इतर वापरकर्त्यांसाठी उपलब्ध होणार नाही. + check_email: कृपया तुमचे ईमेल तपासा, तुमच्या स्पॅम फोल्डरसह, कारण तुमचे काम + का लपवले गेले हे स्पष्ट करण्यासाठी नियम आणि तक्रारनिवारण समिती ने तुमच्याशी + आधीच संपर्क साधला असेल. + contact_abuse: नियम आणि तक्रारनिवारण समिती ला संपर्क करा + html: + help: तुमचे काम का लपवले गेले आहे ह्याच्या बद्दल तुम्ही अनिश्चित असल्यास, + आणि तुम्हाला या प्रकरणाशी संबंधित अधिक संप्रेषण प्राप्त झाले नसेल, तर कृपया + थेट %{contact_abuse_link}. + hidden: तुमचे कार्य %{title} नियम आणि तक्रारनिवारण समिती ने लपवले आहे आणि + ते यापुढे सार्वजनिकपणे उपलब्ध असणार नाही. + tos_violation: AO3 च्या %{tos_link} चे उल्लंघन केल्यामुळे तुमचे कार्य लपवले + गेले असल्यास, तुम्हाला उल्लंघन दुरुस्त करण्यासाठी कारवाई करणे आवश्यक असेल. + तुम्ही तुमचे काम नियम आणि ध्येयधोरणे चे पालन करण्यात अयशस्वी झाल्यास तुमचे + काम AO3 मधून हटवले जाऊ शकते. + subject: "[%{app_name}] तुमचे कार्य नियम आणि तक्रारनिवारण समिती ने लपवले आहे" + text: + help: 'तुमचे काम का लपवले गेले आहे ह्याच्या बद्दल तुम्ही अनिश्चित असल्यास, + आणि तुम्हाला या प्रकरणाशी संबंधित अधिक संप्रेषण प्राप्त झाले नसेल, तर कृपया + थेट नियम आणि तक्रारनिवारण समिती ला संपर्क करा: %{contact_abuse_url}.' + hidden: तुमचे कार्य "%{title}" (%{work_url}) नियम आणि तक्रारनिवारण समिती ने + लपवले आहे आणि ते यापुढे सार्वजनिकपणे उपलब्ध असणार नाही. + tos_violation: AO3 च्या नियम आणि ध्येयधोरणे (%{tos_url}) चे उल्लंघन केल्यामुळे + तुमचे काम लपवले गेले असल्यास, तुम्हाला उल्लंघन दुरुस्त करण्यासाठी कारवाई + करणे आवश्यक असेल. तुम्ही तुमचे काम नियम आणि ध्येयधोरणे चे पालन करण्यात अयशस्वी + झाल्यास तुमचे काम AO3 मधून हटवले जाऊ शकते. + tos: नियम आणि ध्येयधोरणे + anonymous_or_unrevealed_notification: + anonymous_info: निनावी कार्ये टाचणखुणांच्या यादीत सामील केली जातात पण आपल्या + कार्यांच्या पृष्ठावर दिसत नाहीत. त्या कार्यावर आपले वापरकर्तानाम “Anonymous” + (निनावी) म्हणून पुनःस्थापित केले जाईल. + anonymous_unrevealed_info: संकलनाचे व्यवस्थापक काही काळा-नंतर आपले कार्य उघड + करूनही निनावी ठेऊ शकतात. आपल्या वर्गणीदारांना ह्या परिवर्तनाबद्दल कळवले जाणार + नाही. एकदा आपले कार्य उघड केले गेले कि ते टाचणखुणांच्या यादीत सामील केले जाईल + पण आपल्या कार्यांच्या पृष्ठावर दिसणार नाही. त्या कार्यावर आपले वापरकर्तानाम + “Anonymous” (निनावी) म्हणून पुनःस्थापित केले जाईल. + changed_status: + anonymous: + html: "%{collection_link} संकलनाच्या व्यवस्थापकांनी आपल्या कार्याची %{work_link} + स्थिती निनावी केली आहे." + text: '"%{collection_title}" (%{collection_url}) संकलनाच्या व्यवस्थापकांनी + आपल्या कार्याची "%{work_title}" (%{work_url}) स्थिती निनावी केली आहे.' + anonymous_unrevealed: + html: "%{collection_link} संकलनाच्या व्यवस्थापकांनी आपल्या कार्याची %{work_link} + स्थिती निनावी आणि अदृश्य केली आहे." + text: '"%{collection_title}" (%{collection_url}) संकलनाच्या व्यवस्थापकांनी + आपल्या कार्याची "%{work_title}" (%{work_url}) स्थिती निनावी आणि अदृश्य + केली आहे.' + unrevealed: + html: "%{collection_link} संकलनाच्या व्यवस्थापकांनी आपल्या कार्याची %{work_link} + स्थिती अदृश्य केली आहे." + text: '"%{collection_title}" (%{collection_url}) संकलनाच्या व्यवस्थापकांनी + आपल्या कार्याची "%{work_title}" (%{work_url}) स्थिती अदृश्य केली आहे.' + collection_items_link_text: Approved Collection Items (स्वीकृत संकलन बाब) पृष्ठ + do_not_want: + anonymous: + html: जर आपल्याला आपले कार्य निनावी करायचे नसेल तर कृपया %{collection_items_link} + ला भेट द्या आणि तुमचे कार्य ह्या संकलनातून काढा. + text: 'जर आपल्याला आपले कार्य निनावी करायचे नसेल तर कृपया Approved Collection + Items (स्वीकृत संकलन बाब) पृष्ठाला भेट द्या आणि आपले कार्य ह्या संकलनातून + काढा: %{collection_items_url}' + anonymous_unrevealed: + html: जर आपल्याला आपले कार्य निनावी आणि अदृश्य करायचे नसेल तर कृपया %{collection_items_link} + ला भेट द्या आणि आपले कार्य ह्या संकलनातून काढा. + text: 'जर आपल्याला आपले कार्य निनावी आणि अदृश्य करायचे नसेल तर कृपया Approved + Collection Items (स्वीकृत संकलन बाब) पृष्ठाला भेट द्या आणि आपले कार्य + ह्या संकलनातून काढा: %{collection_items_url}' + unrevealed: + html: जर आपल्याला आपले कार्य अदृश्य करायचे नसेल तर कृपया %{collection_items_link} + ला भेट द्या आणि आपले कार्य ह्या संकलनातून काढा. + text: 'जर आपल्याला आपले कार्य अदृश्य करायचे नसेल तर कृपया Approved Collection + Items (स्वीकृत संकलन बाब) पृष्ठाला भेट द्या आणि आपले कार्य ह्या संकलनातून + काढा: %{collection_items_url}' + faq_link_text: संकलन वाविप्र + more_info: + html: अधिक माहिती साठी आमच्या %{faq_link} ला भेट द्या. + text: 'अधिक माहिती साठी आमच्या संकलन वाविप्रला भेट द्या: %{faq_url}' + subject: + anonymous: "[%{app_name}] आपले कार्य निनावी केले गेले आहे." + anonymous_unrevealed: "[%{app_name}] आपले कार्य निनावी आणि अदृश्य केले गेले + आहे" + unrevealed: "[%{app_name}] आपले कार्य अदृश्य केले गेले आहे" + unrevealed_info: अदृश्य कार्य टाचणखुणांच्या यादीत किंवा आपल्या कार्यांच्या पृष्ठावर + दिसत नाहीत. जर कोणी त्या कार्याची लिंक वापरली तर त्यांना सूचित केले जाईल कि + ते कार्य अदृश्य आहे, आणि त्यांना त्याचा मजकूर दिसणार नाही. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (मान्य केलेल्या संग्रह + कृत्या) पृष्ठ + archivist_notice: जरी आपण संकलन आमंत्रणे अमान्य केले असतील तरीही संकलन व्यवस्थापक + त्यांच्या Open Doors रसिक-मुक्तद्वार प्रकल्प) संग्रहकाच्या अधिकृत भूमिकेत + काम करत असल्यामुळे, ते आपली कृती या संकलनेत सामील करू शकतात. संग्राहक एक कृती + संकलनेत फक्त तेव्हा सामील करतात जेव्हा ती कृती एका बाहेरून आणलेल्या संग्रहात + सादर केली गेली असेल. + removal_instructions: + html: जर आपण आपली कृती या संकलनेतून काढू इच्छिता, तर %{approved_items_link} + वर जा. + text: जर आपण आपली कृती या संकलनेतून काढू इच्छिता, तर Approved Collection Items + (मान्य केलेल्या संग्रह कृत्या) %{approved_items_url} पृष्ठावर जा. + subject: "[%{app_name}][%{collection_title}] Open Doors (रसिक-मुक्तद्वार प्रकल्प) + च्या एका संग्रहकाने आपली कृती एका संकलनात सामील केली आहे" + work_added: + html: "%{collection_link} च्या व्यवस्थापकांनी आपली कृती %{work_link} त्यांच्या + संकलनेत सामील केली आहे!" + text: '"%{collection_title}" %{collection_url} च्या व्यवस्थापकांनी आपली कृती + "%{work_title}" %{work_url} त्यांच्या संकलनेत सामील केली आहे!' + challenge_assignment_notification: + any: कोणतेही + assignment: + html: AO3 मधल्या %{link} आव्हाना मधून तुम्हाला ही विनंती सोपवली गेली आहे! + description: 'वर्णन:' + due: 'हे आव्हानासाठी लेखन द्यायची अपेक्षित वेळ:' + html: + footer: आपल्याला हा ई-मेल प्राप्त होत आहे कारण आपण %{title} आव्हानासाठी नोंद + केली आहे. ह्या आव्हानाबद्दल आणखी माहितीसाठी आणि संपादकांच्या संपर्क माहितीसाठी, + कृपया %{footer_link} ला भेट द्या. + footer_link: आव्हान खाते-रेखाचित्र पृष्ठ + look_up: आपण हे आव्हानासाठी लेखन %{link} इकडे बघू शकता. + look_up_link: आपले Assignments (आव्हानासाठी लेखन) पृष्ठ + optional_tags: 'ऐच्छिक टाचणखूणा:' + prompts: 'लेखनबीज:' + prompt_url: 'लेखन बीज URL:' + recipient: 'प्राप्तकरता:' + recipient_missing: 'कोणी नाही: मदतीसाठी एका संपादकाला संपर्क करा!' + subject: "[%{app_name}][%{collection_title}] आपले आव्हानासाठी लेखन!" + text: + assignment: AO3 मधल्या "%{collection_title}" (%{collection_url}) आव्हानामधून + आपल्याला ही विनंती सोपवली गेली आहे! + footer: आपल्याला हा ई-मेल प्राप्त होत आहे कारण आपण %{title} आव्हाना (%{url}) + साठी नोंद केली आहे. ह्या आव्हानाबद्दल आणखी माहितीसाठी आणि संपादकांच्या संपर्क + माहितीसाठी, कृपया %{profile_url} ला भेट द्या. + look_up: आपण हे आव्हानासाठी लेखन आपल्या Assignments (आव्हानासाठी लेखन) पृष्ठावर + %{link} बघू शकता. + change_email: + changed: + html: "%{login}, आपल्या खात्याशी संबंधित ईमेल %{email} मध्ये बदलला गेला आहे" + text: "%{login}, आपल्या खात्याशी संबंधित ईमेल %{email} मध्ये बदलला गेला आहे" + subject: "[%{app_name}] ईमेल बदलले गेले" + claim_notification: + access: + contact_support: AO3 समिती-संवाद समितीशी संपर्क साधा + html: संग्रहावर अवलंबित, आपल्या कृती फक्त नोंदवलेल्या वापरकर्त्यांना उपलब्ध + केले असू शकतात (ज्यानेकरून ते गूगल मध्ये शोधात येणार नाहीत). असे जर असेल, + तर आपण जोपर्यंत सगळ्यांसाठी हे कृती उपलब्ध करायचा निर्णय घेत नाही, तोपर्यंत + ते फक्त लॉग ईन केलेल्या वापरकर्त्यांना वाचता येतील. आपल्या कृती अनिर्बंधीत + किंवा मुक्त करण्यात किंवा हटवण्यात मदत हवी असल्यास, कृपया %{contact_support_link}. + text: संग्रहावर अवलंबित, आपल्या कृती फक्त नोंदवलेल्या वापरकर्त्यांना उपलब्ध + केले असू शकतात (ज्यानेकरून ते गूगल मध्ये शोधात येणार नाहीत). असे जर असेल, + तर आपण जोपर्यंत सगळ्यांसाठी हे कृती उपलब्ध करायचा निर्णय घेत नाही, तोपर्यंत + ते फक्त लॉग ईन केलेल्या वापरकर्त्यांना वाचता येतील. आपल्या कृती अनिर्बंधीत + किंवा मुक्त करण्यात किंवा हटवण्यात मदत हवी असल्यास, कृपया समिती-संवाद समितीशी + इथे %{support_url} संपर्क साधा. + email_tips: आपण आमच्या संपर्कात असाल तर कृपया @transformativeworks.orgचे ईमेल + आयडी आपल्या safe contact (सुरक्षित संपर्का)च्या यादीत घाला आणि आपले स्पॅम + फोल्डर बघत ऱ्हावा, आमचे उत्तर तिथे आले असू शकते. + introduction: + ao3_name: Archive of Our Own – AO3 (आमचा स्वतःचा संग्रह) + html: हा ईमेल आपल्याला पाठवण्यात आला आहे कारण आपल्या कृती एका रसिककृती संग्रहात + सामील होत्या जो %{open_doors_name_link} तर्फे %{app_link} मध्ये आयात केले + गेले आहेत. ही ईमेल आयडी त्या संग्रहावर नोंदवलेल्या आयडीशी जोडलेली असल्यामुळे, + सर्व संबंधित (खाली दिलेल्या) रसिककृती आपोआप आपल्या AO3 खात्याला जमा झाले + आहेत. + open_doors_name: Open Door (रसिकमुक्तद्वार प्रकल्प) + text: 'हा ईमेल आपल्याला पाठवण्यात आला आहे कारण आपल्या कृती एका रसिककृती संग्रहात + सामील होत्या जो (%{open_doors_url}) तर्फे Archive of Our Own – AO3 (आमचा + स्वतःचा संग्रह): %{app_url} मध्ये आयात केला गेला आहे. ही ईमेल आयडी त्या + संग्रहावर नोंदवलेल्या आयडीशी जोडलीला असल्यामुळे, सर्व संबंधित (खाली दिलेल्या) + रसिककृती आपोआप आपल्या AO3 खात्याला जमा झाले आहेत.' + mistake: + contact_open_doors: रसिकमुक्तद्वार प्रकल्पाशी संपर्क साधा + html: जर इथे चूक झाली असेल आणि ह्या कृती आपल्या नसतील तर कृपया त्यांना हटवू + नका! फक्त %{contact_open_doors_link} आणि आम्ही त्याची काळजी घेऊ. + text: जर इथे चूक झाली असेल आणि ह्या आपल्या कृती नसतील तर कृपया त्या हटवू नका! + फक्त रसिकमुक्तद्वार प्रकल्पाशी संपर्क साधा (%{open_doors_url}) आणि आम्ही + त्याची काळजी घेऊ. + more_info: + ao3_news: AO3 बातम्या + contact_support: AO3 समिती-संवाद समितीशी संपर्क साधा + faq_page: वाविप्र पृष्ठ + html: अलीकडे झालेल्या संग्रह स्थलांतरांबद्दलच्या घोषणा आपण %{ao3_news_link} + खाली वाचू शकता, आणि अधिक माहिती रसिकमुक्तद्वार प्रकल्पच्या %{faq_page_link} + किंवा %{tutorial_page_link} वर सापडेल. वाविप्र, शिकवणी, किंवा या ईमेल मध्ये + आपल्या कुठल्यापण प्रश्नाचे उत्तर नाही मिळाले तर कृपया %{contact_support_link}. + text: अलीकडे झालेल्या संग्रह स्थलांतरांबद्दलच्या घोषणा आपण AO3 बातमी (%{news_url}) + खाली वाचू शकता, आणि अधिक माहिती रसिकमुक्तद्वार प्रकल्पच्या वाविप्र पृष्ठ + (%{open_doors_faq_url}) किंवा शिकवणी पृष्ठा(%{open_doors_tutorial_url}) + वर सापडेल. वाविप्र, शिकवणी किंवा, ह्या ईमेल मध्ये आपल्या प्रश्नाचे उत्तर + नाही मिळाले तर कृपया समिती-संवाद समितीशी इथे %{support_url} संपर्क साधा. + tutorial_page: शिकवणी पृष्ठ + other_works: + contact_open_doors: रसिकमुक्तद्वार प्रकल्पाशी संपर्क साधा + html: जर आयात केलेल्या संग्रहावर आपल्या कुठल्यातर दुसऱ्या ईमेल आयडीखाली इतर + कृती होत्या पण आपण त्या ईमेल आयडी मध्ये आता प्रवेश नाही घेऊ शकत, तर आपल्या + ओळखीची खात्री करता येईल अशी कोणतीही माहिती घेऊन %{contact_open_doors_link}. + text: जर आयात केलेल्या संग्रहावर आपल्या कुठल्यातर दुसऱ्या ईमेल आयडीखाली इतर + कृती होत्या पण आपण त्या ईमेल आयडी मध्ये आता प्रवेश नाही घेऊ शकत, तर आपल्या + ओळखीची खात्री करता येईल अशी कोणतीही माहिती घेऊन कृपया रसिकमुक्तद्वार प्रकल्पाशी + संपर्क साधा. + questions: + contact_support: AO3 समिती-संवाद समितीशी संपर्क साधा + html: इतर प्रश्नांसाठी कृपया %{contact_support_link}. + text: इतर प्रश्नांसाठी कृपया %{support_url} खाली AO3 समिती-संवाद समितीशी संपर्क + साधा. + redirects: + html: सूचक यादी व वाचनखुणा जपवण्यासाठी आयात केलेल्या संग्रहाच्या दुवा कदाचित + थोड्या वेळासाठी आयात केलेल्या प्रतिकडे नेहतील (याची खात्री करायला आपल्या + संग्रहाची घोषणा बघा). जर आपण हे कृती आधीच अपलोड केल्या असतील आणि import + from URL (दुवेवरून आयात करा) हे साधन वापरले असेल %{negation}, तर AO3वरती + एकाच कृतीच्या दोन प्रती असतील. + subject: "[%{app_name}] कृती अपलोड केल्या आहेत" + update_redirect: + contact_open_doors: रसिकमुक्तद्वार प्रकल्पाशी संपर्क साधा + html: जर Open Doors मार्गदर्शनाचे अद्यतन आपल्या आधीच्या कृतीला न्हेण्यासाठी + करावे हे आपल्याला हवे असेल तर कृपया आयात केलेली कृती हटवा, आणि आपल्या AO3 + खात्याचे नाव, आयात केलेल्या संग्रहावरच्या आपल्या खात्याचे नाव, ज्या कृतीकडे + मार्गदर्शन जावे त्याचे नाव व त्याची दुवा, ह्या सर्व माहितीसकट %{contact_open_doors_link}. + (अनेक कृतींसाठी नवीन मार्गदर्शन हवे असल्यास आपण एका ईमेल मधे ती माहिती देऊ + शकता.) + text: जर Open Doors मार्गदर्शनाचे अद्यतन आपल्या आधीच्या कृतीला न्हेण्यासाठी + करावे हे आपल्याला हवे असेल तर कृपया आयात केलेली कृती हटवा, आणि आपल्या AO3 + खात्याचे नाव, आयात केलेल्या संग्रहावरच्या आपल्या खात्याचे नाव, ज्या कृतीकडे + मार्गदर्शन जावे त्याचे नाव व त्याची दुवा, ह्या सर्व माहितीसकट रसिकमुक्तद्वार + प्रकल्पाशी इथे %{open_doors_url} संपर्क साधा. (अनेक कृतींसाठी नवीन मार्गदर्शन + हवे असल्यास आपण एका ईमेल मधे ती माहिती देऊ शकता.) + works_by: 'हे सर्व कृती ह्या ईमेल खाली लिहिल्या गेल्या होत्या: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: सर्व आव्हानांसाठी लेखन आता पाठवले गेले आहेत. + subject: आव्हानासाठी लेखन पाठवले गेले आहे + html: + received_message: 'आपल्याला आपल्या संकलनाबद्दल एक निरोप मिळाला आहे %{collection_link}:' + text: + received_message: 'आपल्याला आपल्या संकलनाबद्दल एक निरोप मिळाला आहे "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: आपण जेव्हा एखाद्या कार्याचे सह-निर्माते असता तेव्हा नवीन अध्यायासाठी + आपण आपोआपच सामिल केले जाल, आपले सह-निर्माता सेटिंग्ज काहीही असोत. ते कार्य + ज्या मालिकेचा भाग होईल तिथेही आपल्याला सामिल केले जाईल. + html: + creation: "%{pseud_links} च्या तर्फे %{creation_link}" + edit_chapter: अध्यायामध्ये बदल करा + edit_series: मालिकेमध्ये बदल करा + remove_chapter: जर आपले नाव चुकुन सामिल झाले असेल किंवा आपल्याला सह-निर्मात्या + म्हणून नमुद व्हायचे नसेल तर आपण %{edit_chapter_link} हे करून स्वतःला हटवू + शकता. + remove_series: जर आपले नाव चुकुन सामिल झाले असेल किंवा आपल्याला सह-निर्मात्या + म्हणून नमुद व्हावयाचे नसेल तर आपण %{edit_series_link} हे करून स्वतःला हटवू + शकता. + intro_chapter: 'ह्या वापरकर्त्याने %{adding_user} आपला स्युडोआयडी %{pseud} खालील + अध्यायासाठी सह-निर्माता म्हणून नोंदविला आहे:' + intro_series: 'ह्या वापरकर्त्याने %{adding_user} आपला स्युडोआयडी %{pseud} खालील + मालिकेसाठी सह-निर्माता म्हणून नोंदविला आहे:' + subject: "[%{app_name}] सह-निर्माता सूचना" + text: + creation: "%{pseuds} च्या तर्फे %{title} (%{url})" + remove_chapter: जर आपले नाव चुकुन सामिल झाले असेल किंवा आपल्याला सह-निर्मात्या + म्हणून नमुद व्हायचे नसेल तर आपण अध्यायामध्ये बदल करून स्वतःला हटवू शकताः + %{url} + remove_series: 'जर आपले नाव चुकुन सामिल झाले असेल किंवा आपल्याला सह-निर्मात्या + म्हणून नमुद व्हायचे नसेल तर आपण मालिकेमध्ये बदल करून स्वतःला हटवू शकता: + %{url}' + creatorship_notification_archivist: + explanation: ते Open Doors (रसिकमुक्तद्वार संकल्पाचे) संग्राहक म्हणून त्यांच्या + अधिकृत क्षमतेअंतर्गत काम करत असल्यामुळे, ते आपल्याला निमंत्रणाशिवाय सामील + करू शकतात, जरी तुम्ही सहनिर्मिती अक्षम केली असेल तरी. + html: + creation: "%{pseud_links} द्वारे %{creation_link}" + edit_chapter: अध्यायाचे संपादन करा + edit_series: लेखमाला संपादित करा + edit_work: कार्याचे संपादन करा + remove_chapter: जर आपल्याला चुकून सामील केले गेले असेल किंवा आपल्याला निर्माते + म्हणून सामील व्हायचे नसेल, तर आपण निर्माते म्हणून स्वतःला काढायला %{edit_chapter_link} + वर जाऊ शकता. + remove_series: जर आपल्याला चुकून सामील केले गेले असेल किंवा आपल्याला निर्माते + म्हणून सामील व्हायचे नसेल, तर आपण निर्माते म्हणून स्वतःला काढायला %{edit_series_link} + वर जाऊ शकता. + remove_work: जर आपल्याला चुकून सामील केले गेले असेल किंवा आपल्याला निर्माते + म्हणून सामील व्हायचे नसेल, तर आपण निर्माते म्हणून स्वतःला काढायला %{edit_work_link} + वर जाऊ शकता. + intro_chapter: "%{archivist} वापरकर्त्याने आपला स्यूडोआयडी %{pseud} पुढील प्रकरणात + सह-निर्माते म्हणून सामील केला आहे:" + intro_series: "%{archivist} वापरकर्त्याने आपला स्यूडोआयडी %{pseud} पुढील लेखमालेत + सह-निर्माते म्हणून सामील केले आहे:" + intro_work: 'वापरकर्ता %{archivist} यांनी आपला स्यूडोआयडी %{pseud} पुढील कार्यात + सह-निर्माते म्हणून सामील केला आहे:' + subject: "[%{app_name}] संग्राहक सह-निर्माती अधिसूचना" + text: + creation: "%{pseuds} द्वारे %{title} (%{url})" + remove_chapter: 'जर आपल्याला चुकून सामील केले गेले असेल किंवा आपल्याला निर्माते + म्हणून सामील व्हायचे नसेल, तर आपण निर्माते म्हणून स्वतःला काढायला प्रकरण + संपादित करू शकता: %{url}' + remove_series: 'जर आपल्याला चुकून सामील केले गेले असेल किंवा आपल्याला निर्माते + म्हणून सामील व्हायचे नसेल, तर आपण निर्माते म्हणून स्वतःला काढायला लेखमाला + संपादित करू शकता: %{url}' + remove_work: 'जर आपल्याला चुकून सामील केले गेले असेल किंवा आपल्याला निर्माते + म्हणून सामील व्हायचे नसेल, तर आपण निर्माते म्हणून स्वतःला काढायला कार्य + संपादित करू शकता: %{url}.' + creatorship_request: + html: + creation: "%{creation_link} द्वारे %{pseud_links}" + instructions: तुम्ही %{page_name} पृष्ठावर जाऊन ही विनंती स्वीकारू किंवा नाकारू + शकता. + page_name: Co-Creator Requests (सहनिर्माती विनंत्या) + intro_chapter: "%{inviting_user} वापरकर्त्याने पुढील प्रकरणावर आपल्या स्यूडोआयडी + %{pseud} ला सहनिर्माते नेमण्यासाठी आमंत्रण दिले आहे:" + intro_series: "%{inviting_user} वापरकर्त्याने पुढील लेखमालेवर आपल्या स्यूडोआयडी + %{pseud} ला सहनिर्माते नेमण्यासाठी आमंत्रण दिले आहे:" + intro_work: "%{inviting_user} वापरकर्त्याने पुढील कार्यावर आपल्या स्यूडोआयडी + %{pseud} ला सहनिर्माते नेमण्यासाठी आमंत्रण दिले आहे:" + subject: "[%{app_name}] सहनिर्माती विनंती" + text: + creation: "%{title} (%{url}) द्वारे %{pseuds}" + instructions: 'तुम्ही Co-Creator Requests (सहनिर्माती विनंत्या) पृष्ठावर जाऊन + ही विनंती स्वीकारू किंवा नाकारू शकता: %{url}' + delete_work_notification: + attachment: आपल्या संदर्भाकरिता आपल्या कार्याची प्रत सोबत जोडण्यात आली आहे. + deleted_other: + html: आपले कार्य %{title}, %{pseud} यांच्या विनंतीमुळे हटविण्यात आले आहे. + text: आपले कार्य “%{title}”, %{pseud} यांच्या विनंतीमुळे हटविण्यात आले आहे. + deleted_yourself: + html: आपल्या विनंतीनुसार, आपले कार्य %{title} हटविण्यात आले आहे. + text: आपल्या विनंतीनुसार, आपले कार्य “%{title}” हटविण्यात आले आहे. + questions: + html: जर आपल्याला काही शंका असतील, तर कृपया %{support}. + text: जर आपल्याला काही शंका असतील, तर कृपया %{support} (%{url}). + subject: "[%{app_name}] आपले कार्य हटविण्यात आले आहे" + support: समिती-संवाद समितीस संपर्क साधा + invite_increase_notification: + html: + body: + one: आम्‍हाला आपल्याला कळवायचे आहे की आपल्याला %{count} नवीन आमंत्रण प्राप्त + झाले आहे, जे AO3 वर नवीन खाते तयार करण्‍यासाठी वापरले जाऊ शकते. आपण %{invitation_page_link} + वर एका मित्राला आमंत्रित करू शकता. + other: आम्‍हाला आपल्याला कळवायचे आहे की आपल्याला %{count} नवीन आमंत्रणे + प्राप्त झाली आहेत, जी AO3 वर नवीन खाते तयार करण्‍यासाठी वापरली जाऊ शकतात. + आपण %{invitation_page_link} वर एका मित्राला आमंत्रित करू शकता. + invitation_page_link_text: आपली Invitations (आमंत्रणे) पृष्ठ + subject: "[%{app_name}] नवीन आमंत्रणे" + text: + body: + one: आम्‍हाला आपल्याला कळवायचे आहे की आपल्याला %{count} नवीन आमंत्रण प्राप्त + झाले आहे, जे AO3 वर नवीन खाते तयार करण्‍यासाठी वापरले जाऊ शकते. आपण आपल्या + Invitations (आमंत्रणे) पृष्ठावर (%{invitation_page_url}) एका मित्राला + आमंत्रित करू शकता. + other: आम्‍हाला आपल्याला कळवायचे आहे की आपल्याला %{count} नवीन आमंत्रणे + प्राप्त झाली आहेत, जी AO3 वर नवीन खाते तयार करण्‍यासाठी वापरली जाऊ शकतात.आपण + आपल्या Invitations (आमंत्रणे) पृष्ठावर (%{invitation_page_url}) एका मित्राला + आमंत्रित करू शकता. + invite_request_declined: + main: + one: आम्‍हाला कळवण्‍यास खेद होत आहे की आपली नवीन आमंत्रणाची विनंती यावेळी + पूर्ण होऊ शकत नाही. + other: आम्‍हाला कळवण्‍यास खेद होत आहे की आपली %{count} नवीन आमंत्रणांची विनंती + यावेळी पूर्ण होऊ शकत नाही. + reason: 'आपली विनंती होती:' + subject: "[%{app_name}] अतिरिक्त आमंत्रण विनंतीला नकार" + recipient_notification: + html: + collection: "%{collection_link} हे AO3 वरती असलेल्या संकलनामध्ये आपल्यासाठी + एक भेट रसिककृती प्रकाशित केली गेली!" + no_collection: आपल्यासाठी एक भेट रसिककृती AO3 वर प्रकाशित केली गेली! + subject: + collection: "[%{app_name}][%{collection_title}] %{collection_title} कडून आपल्यासाठी + एक भेट रसिककृती" + no_collection: "[%{app_name}] आपल्यासाठी एक भेट रसिककृती" + text: + collection: '"%{collection_title}" हे AO3 वरती असलेल्या (%{collection_url}) + संकलनामध्ये तुमच्यासाठी एक भेट रसिककृती प्रकाशित केली गेली!' diff --git a/config/locales/phrase-exports/ms.yml b/config/locales/phrase-exports/ms.yml new file mode 100755 index 0000000..5af7ec8 --- /dev/null +++ b/config/locales/phrase-exports/ms.yml @@ -0,0 +1,615 @@ +--- +ms: + activerecord: + attributes: + archive_warning: + name_with_colon: + other: 'Amaran:' + category: + name_with_colon: + other: 'Kategori:' + character: + name_with_colon: + other: 'Watak:' + fandom: + name_with_colon: + other: 'Fandom:' + freeform: + name_with_colon: + other: 'Tag Tambahan:' + rating: + name_with_colon: 'Taraf:' + relationship: + name_with_colon: + other: 'Hubungan:' + work: + chapter_total_display: Bab + summary: Ringkasan + models: + archive_warning: + other: Amaran + category: + other: Kategori + chapter: + other: Bab + character: + other: Watak + fandom: + other: Fandom + freeform: + other: Tag Tambahan + rating: + other: Taraf + relationship: + other: Hubungan + series: + other: Siri + kudo_mailer: + batch_kudo_notification: + guest: + other: "%{count} tetamu" + left_kudos: + html: + other: "%{givers_list} telah meninggalkan kudos untuk %{commentable_link}." + text: + other: "%{givers_list} telah meninggalkan kudos untuk %{commentable_title} + (%{commentable_url})." + single_guest: + giver: Seorang tetamu + html: "%{giver} telah meninggalkan kudos untuk %{commentable_link}." + text: Seorang tetamu telah meninggalkan kudos untuk %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Anda telah menerima kudos!" + mailer: + general: + closing: + formal: Yang benar, + informal: Yang benar, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Bab %{position} daripada %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + other: "%{count} perkataan" + footer: + general: + about: + html: AO3 adalah arkib yang diurus dan disokong oleh peminat yang bergantung + pada %{donate_link}. + text: 'AO3 adalah arkib yang diurus dan disokong oleh peminat yang bergantung + pada sumbangan anda: %{donate_url}.' + html: + donate_link_text: sumbangan anda + support_link_text: hubungi Bantuan + unwanted_email: + html: Jika anda tidak sepatutnya menerima mesej ini, sila %{support_link}. + text: Jika anda tidak sepatutnya menerima mesej ini, sila hubungi Bantuan + di %{support_url}. + sent_at: Dihantar pada %{sent_at}. + greeting: + formal_html: "%{name}," + informal: + addressed_html: Hai, %{name}! + unaddressed: Hai! + introductory: Helo daripada Archive of Our Own – AO3 (Arkib Milik Kita)! + metadata_label_indicator: ":" + signature: + abuse_team: Pasukan Polisi & Aduan AO3 + app_short_name: AO3 + open_doors: Pasukan The Open Doors (Projek Pemeliharaan Bahan-Bahan Digital + dan Bukan Digital) + parent_org: Organization for Transformative Works – OTW (Organisasi Karya-Karya + Transformatif) + support: Pasukan Bantuan AO3 + users: + mailer: + reset_password_instructions: + expiration: Pautan ini akan dinyahaktifkan dalam masa seminggu sekiranya ia + tidak digunakan. Anda perlu meminta pautan yang baharu setelah tempoh tersebut + tamat. + intro: 'Sebuah permintaan untuk menetapkan semula kata laluan untuk akaun + anda telah dibuat. Anda boleh mengikuti pautan yang berikut untuk menetapkan + semula kata laluan anda:' + link_title: Tetapkan semula kata laluan saya. + subject: "[%{app_name}] Tetapkan semula kata laluan anda" + unrequested: Jika anda tidak memohon penetapan semula kata laluan, sila abaikan + e-mel ini. Kata laluan anda yang asal masih akan dapat digunakan. + user_mailer: + admin_deleted_work_notification: + bye: Salinan karya anda telah dilampirkan untuk rujukan anda. + contact_abuse: hubungi Jawatankuasa Polisi & Aduan kami + deleted: + html: Karya anda %{title} telah dipadam daripada AO3 oleh seorang admin laman + web berkenaan. + text: Karya anda "%{title}" telah dipadam daripada AO3 oleh seorang admin + laman web berkenaan. + html: + tos_violation: Jika terdapat kemungkinan karya anda telah melanggar Syarat-Syarat + Perkhidmatan AO3, sila %{contact_abuse_link}. + import_project: + html: Jika karya anda merupakan sebahagian daripada projek import yang diuruskan + oleh pasukan Open Doors (Projek Pemeliharaan Bahan-Bahan Digital dan Bukan + Digital) kami, sila %{opendoors_link} untuk sebarang persoalan. + text: Jika karya anda merupakan sebahagian daripada projek import yang diuruskan + oleh pasukan Open Doors (Projek Pemeliharaan Bahan-Bahan Digital dan Bukan + Digital) kami, sila hubungi Open Doors (%{opendoors_link}) untuk sebarang + persoalan. + opendoors: hubungi Open Doors + subject: "[%{app_name}] Karya anda telah dipadam oleh seorang admin" + text: + tos_violation: Jika terdapat kemungkinan karya anda telah melanggar Syarat-Syarat + Perkhidmatan AO3, sila hubungi Jawatankuasa Polisi & Aduan kami (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Ketika karya anda disembunyikan, anda masih boleh mengakses menerusi + capaian yang diberikan di atas, tetapi ia tidak akan disenaraikan di halaman + karya anda, dan tidak akan dipaparkan kepada pengguna AO3 yang lain. + check_email: Sila semak e-mel anda, termasuk folder spam, kerana pasukan Polisi + & Aduan mungkin telah menghubungi anda berkenaan mengapa karya anda disembunyikan. + contact_abuse: hubungi Polisi & Aduan + html: + help: Sekiranya anda tidak pasti mengapa karya anda disembunyikan dan anda + masih belum menerima hubungan lanjut tentang hal ini, sila hubungi %{contact_abuse_link} + secara langsung. + hidden: Karya anda %{title} telah disembunyikan oleh pasukan Polisi & Aduan + dan tidak dapat diakses oleh pihak umum lagi. + tos_violation: Sekiranya karya anda disembunyikan kerana melanggar %{tos_link} + AO3, anda akan perlu mengambil tindakan untuk membetulkan pelanggaran tersebut. + Kegagalan karya anda mematuhi Syarat-syarat Perkhidmatan mungkin akan menyebabkan + karya anda dipadam daripada AO3. + subject: "[%{app_name}] Karya anda telah disembunyikan oleh pasukan Polisi & + Aduan" + text: + help: 'Sekiranya anda tidak pasti mengapa karya anda disembunyikan dan anda + masih belum menerima hubungan lanjut tentang hal ini, sila hubungi Polisi + & Aduan secara langsung: %{contact_abuse_url}.' + hidden: Karya anda "%{title}" (%{work_url}) telah disembunyikan oleh pasukan + Polisi & Aduan dan tidak dapat diakses oleh umum lagi. + tos_violation: Sekiranya karya anda disembunyikan kerana melanggar Syarat-syarat + Perkhidmatan AO3 (%{tos_url}), anda akan perlu mengambil tindakan untuk + membetulkan pelanggaran tersebut. Kegagalan karya anda mematuhi Syarat-syarat + Perkhidmatan mungkin akan menyebabkan karya anda dipadam daripada AO3. + tos: Syarat-syarat Perkhidmatan + anonymous_or_unrevealed_notification: + anonymous_info: Karya tidak bernama termasuk dalam senarai tag, tetapi tidak + pada halaman karya anda. Pada karya tersebut, nama pengguna anda akan digantikan + dengan “Anonymous” (Tidak Bernama). + anonymous_unrevealed_info: Pengendali koleksi kemudiannya boleh mempamerkan + karya anda tetapi membiarkan ia tidak bernama. Sesiapa yang melanggan anda + tidak akan diberitahu mengenai perubahan ini. Setelah dipamerkan, karya anda + akan termasuk dalam senarai tag, tetapi bukan pada laman karya anda. Pada + karya tersebut, nama pengguna anda akan digantikan dengan “Anonymous” (Tidak + Bernama) + changed_status: + anonymous: + html: Pengendali koleksi %{collection_link} telah mengubah status karya + anda %{work_link} kepada tidak bernama. + text: Penyenggara koleksi "%{collection_title}" (%{collection_url}) telah + mengubah status karya anda "%{work_title}" (%{work_url}) kepada tanpa + nama. + anonymous_unrevealed: + html: Pengendali koleksi %{collection_link} telah mengubah status karya + anda %{work_link} kepada tidak bernama dan tidak dipamerkan. + text: Penyenggara koleksi "%{collection_title}" (%{collection_url}) telah + mengubah status karya anda "%{work_title}" (%{work_url}) kepada tanpa + nama dan belum dipamerkan. + unrevealed: + html: Pengendali koleksi %{collection_link} telah mengubah status karya + anda %{work_link} kepada tidak dipamerkan. + text: Penyenggara koleksi "%{collection_title}" (%{collection_url}) telah + mengubah status karya anda "%{work_title}" (%{work_url}) kepada belum + dipamerkan. + collection_items_link_text: Laman Approved Collection Items (Butiran Koleksi + Diluluskan) + do_not_want: + anonymous: + html: Jika anda tidak mahu karya anda menjad tidak bernama, sila lawati + %{collection_items_link} anda untuk mengeluarkannya daripada koleksi ini. + text: 'Jika anda tidak mahu karya anda sebagai tidak bernama, sila lawati + laman Approved Collection Items (Butiran Koleksi Diluluskan) anda untuk + mengeluarkannya daripada koleksi ini: %{collection_items_url}' + anonymous_unrevealed: + html: Jika anda tidak mahu karya anda sebagai tidak bernama dan tidak dipamerkan, + sila lawat %{collection_items_link} anda untuk mengeluarkannya daripada + koleksi ini. + text: 'Jika anda tidak mahu karya anda sebagai tidak bernama dan tidak dipamerkan, + sila lawat laman Approved Collection Items (Butiran Koleksi Diluluskan) + anda untuk mengeluarkannya daripada koleksi ini: %{collection_items_url}' + unrevealed: + html: Jika anda tidak mahu karya anda sebagai tidak dipamerkan, sila lawati + %{collection_items_link} anda untuk mengeluarkannya daripada koleksi ini. + text: 'Jika anda tidak mahu karya anda sebagai tidak dipamerkan, sila lawat + laman Approved Collection Items (Butiran Koleksi Diluluskan) anda untuk + mengeluarkannya daripada koleksi ini: %{collection_items_url}' + faq_link_text: FAQ Koleksi + more_info: + html: Untuk maklumat lebih anjut, sila lawat %{faq_link} kami. + text: 'Untuk maklumat lebih lanjut, sila lawati FAQ Koleksi kami: %{faq_url}' + subject: + anonymous: "[%{app_name}] Karya anda telah menjadi tidak bernama" + anonymous_unrevealed: "[%{app_name}] Karya anda telah dibuat tidak bernama + dan tidak dipamerkan" + unrevealed: "[%{app_name}] Karya anda tidak dipamerkan" + unrevealed_info: Karya yang tidak dipamerkan tidak termasuk dalam senarai tag + atau pada laman karya anda. Sesiapa yang mengikuti pautan ke karya tersebut + akan menerima notis bahawa karya tersebut tidak dipamerkan, dan mereka tidak + akan dapat mengakses kandungan tersebut. + archivist_added_to_collection_notification: + approved_collection_items_page: Halaman Approved Collection Items (Item Koleksi + yang Diluluskan) + archivist_notice: Oleh kerana penyelenggara koleksi bertindak dalam kapasiti + rasmi mereka sebagai ahli arkib Open Doors (Projek Pemeliharaan Bahan-Bahan + Digital dan Bukan Digital), mereka dibenarkan untuk menambah karya anda ke + koleksi ini, walaupun anda telah menutup jemputan koleksi. Ahli arkib hanya + akan menambah sesebuah karya ke koleksi jika ia dihoskan di arkib yang diimport. + removal_instructions: + html: Jika anda ingin mengalih keluar karya anda daripada koleksi ini, sila + lawati %{approved_items_link} anda. + text: 'Jika anda ingin mengalih keluar karya anda daripada koleksi ini, sila + lawati halaman Approved Collection Items (Item Koleksi yang Diluluskan) + anda: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Ahli arkib Open Doors (Projek Pemeliharaan + Bahan-Bahan Digital dan Bukan Digital) telah menambah karya anda ke koleksi" + work_added: + html: Penyelenggara koleksi %{collection_link} telah menambah karya anda %{work_link} + ke koleksi mereka! + text: Penyelenggara koleksi bagi "%{collection_title}" (%{collection_url}) + telah menambah karya anda "%{work_title}" (%{work_url}) ke koleksi mereka! + challenge_assignment_notification: + any: Mana-mana + assignment: + html: Anda telah ditugaskan dengan permintaan yang dinyatakan pada cabaran + %{link} di Arkib Milik Kita! + description: 'Penerangan:' + due: 'Tugasan ini akan berakhir pada:' + html: + footer: Anda menerima emel ini kerana anda telah mendaftar untuk cabaran %{title}. + Untuk maklumat lebih lanjut tentang cabaran ini dan maklumat untuk dihubungi + bagi moderator, sila lihat %{footer_link}. + footer_link: laman profil cabaran + look_up: Anda boleh melihat tugasan ini di %{link}. + look_up_link: halaman Assignments (Tugasan) anda + optional_tags: 'Tag Pilihan:' + prompts: 'Prompt:' + prompt_url: 'URL Prompt:' + recipient: 'Penerima:' + recipient_missing: 'Tiada: hubungi moderator untuk bantuan!' + subject: "[%{app_name}][%{collection_title}] Tugasan Anda!" + text: + assignment: Anda telah ditugaskan dengan permintaan yang dinyatakan pada cabaran + "%{collection_title}" (%{collection_url}) di Arkib Milik Kita! + footer: Anda menerima emel ini kerana anda telah mendaftar untuk cabaran %{title} + (%{url}). Untuk maklumat lebih lanjut mengenai cabaran ini maklumat untuk + dihubungi bagi moderator, sila lihat %{profile_url}. + look_up: Anda boleh mencari tugasan ini dari halaman Assignments (Tugasan) + anda di %{link}. + change_email: + changed: + html: "%{login}, emel yang dikaitkan dengan akaun anda kini telah diubah kepada + %{email}" + text: "%{login}, emel yang dikaitkan dengan akaun anda kini telah diubah kepada + %{email}" + subject: "[%{app_name}] Emel diubah" + claim_notification: + access: + contact_support: hubungi Bantuan AO3 + html: Bergantung kepada arkib, karya anda mungkin telah diimport dihadkan + kepada pengguna berdaftar sahaja (untuk tidak dijumpai dalam pencarian Google). + Jika ini berlaku, karya-karya tersebut akan hanya diakses oleh pengguna + yang telah log masuk melainkan anda memilih untuk membuat karya tersebut + dilihat sepenuhnya. Untuk bantuan membuka, meyatim, atau memadam karya-karya + anda, sila %{contact_support_link}. + text: Bergantung kepada arkib, karya anda mungkin telah diimport dihadkan + kepada pengguna berdaftar sahaja (untuk tidak dijumpai dalam pencarian Google). + Jika ini berlaku, karya-karya tersebut akan hanya diakses oleh pengguna + yang telah log masuk melainkan anda memilih untuk membuat karya tersebut + jelas sepenuhnya. Untuk bantuan membuka, meyatim, atau memadam karya-karya + anda, sila hubungi Bantuan AO3 di %{support_url}. + email_tips: Jika anda menghubungi kami, sila masukkan alamat e-mel dari @transformativeworks.org + ke dalam senarai hubungan selamat anda dan periksa folder spam untuk balasan + kami. + introduction: + ao3_name: Archive of Our Own - AO3 (Arkib Milik Kita) + html: Anda menerima e-mel ini kerana anda mempunyai karya-karya di dalam arkib + karya peminat yang telah diimport oleh %{open_doors_name_link} ke dalam + %{app_link}. Disebabkan alamat e-mel ini dihubungkan dengan e-mel berdaftar + pada arkib tersebut, mana-mana karya yang berkaitan (disenaraikan di bawah) + telah dimasukkan secara automatik ke akaun AO3 anda. + open_doors_name: Open Doors (Projek Pemeliharaan Bahan-Bahan Digital dan Bukan + Digital) + text: 'Anda menerima e-mel ini kerana anda mempunyai karya-karya di dalam + arkib karya peminat yang telah diimport oleh Open Doors (Projek Pemeliharaan + Bahan-Bahan Digital dan Bukan Digital) (%{open_doors_url}) ke dalam Archive + of Our Own – AO3 (Arkib Milik Kita): %{app_url}. Disebabkan alamat e-mel + ini dihubungkan dengan e-mel berdaftar pada arkib tersebut, mana-mana karya + yang berkaitan (disenaraikan di bawah) telah dimasukkan secara automatik + ke akaun AO3 anda.' + mistake: + contact_open_doors: hubungi Open Doors + html: Jika ini merupakan kesilapan dan karya-karya ini bukan milik anda, jangan + padam! Sila %{contact_open_doors_link} dan kami akan selesaikannya. + text: Jika ini merupakan kesilapan dan karya-karya ini bukan milik anda, jangan + padam! Sila hubungi Open Doors (%{open_doors_url}) dan kami akan selesaikannya. + more_info: + ao3_news: Berita AO3 + contact_support: hubungi Bantuan AO3 + faq_page: laman FAQ + html: Anda boleh membaca pengumuman mengenai pemindahan arkib terkini di %{ao3_news_link}, + serta mencari informasi tambahan di %{faq_page_link} atau %{tutorial_page_link} + Open Doors. Bagi sebarang pertanyaan yang tidak dijawab dalam FAQ, tutorial + atau e-mel ini, sila %{contact_support_link}. + text: Anda boleh membaca pengumuman mengenai pemindahan arkib terkini di Berita + AO3 (%{news_url}), serta mencari informasi tambahan di laman FAQ Open Doors + (%{open_doors_faq_url}) atau laman tutorial (%{open_doors_tutorial_url}). + Bagi sebarang pertanyaan yang tidak terjawab dalam FAQ, tutorial atau e-mel + ini, sila hubungi Bantuan di %{support_url}. + tutorial_page: laman tutorial + other_works: + contact_open_doors: hubungi Open Doors + html: Jika anda mempunyai karya-karya pada arkib import di bawah alamat e-mel + yang anda tidak lagi boleh akses, sila %{contact_open_doors_link} dengan + sebarang maklumat yang boleh membantu mengesahkan identiti anda. + text: Jika anda mempunyai karya-karya pada arkib import di bawah alamat e-mel + yang anda tidak lagi mampu akses, sila hubungi Open Doors dengan apa-apa + maklumat yang boleh membantu mengesahkan identiti anda. + questions: + contact_support: hubungi Bantuan AO3 + html: Untuk pertanyaan lanjut, sila %{contact_support_link}. + text: Untuk pertanyaan lanjut, sila hubungi Bantuan AO3 di %{support_url}. + redirects: + html: Untuk memelihara senarai cadangan dan menanda, alamat laman dari arkib + diimport mungkin mengubah hala ke salinan import karya-karya ini untuk masa + terhad (lihat pengumuman bagi arkib kita untuk kepastian). Jika anda sudah + memuat naik salinan karya tersebut dan anda %{negation} mengguna ciri import + dari URL, dua salinan karya yang sama akan terpapar pada AO3. + subject: "[%{app_name}] Karya yang dimuat naik" + update_redirect: + contact_open_doors: hubungi Open Doors + html: Jika anda ingin Open Doors untuk mengemas kini ubah hala ke karya anda + yang sedia ada, sila padamkan salinan import, dan %{contact_open_doors_link} + dengan nama akaun AO3 anda, nama akaun anda pada arkib import, dan tajuk + dan URL karya anda yang ingin dihalakan. (Jika anda mempunyai beberapa karya + yang anda ingin menukar ubah hala, anda boleh senaraikan dalam satu e-mel.) + text: Jika anda ingin Open Doors untuk mengemas kini ubah hala ke karya anda + yang sedia ada, sila padamkan salinan import, dan hubungi Open Doors di + %{open_doors_url} dengan nama akaun AO3 anda, nama akaun anda pada arkib + import, dan tajuk dan URL karya anda yang ingin dihalakan. (Jika anda mempunyai + beberapa karya yang anda ingin menukar ubah hala, anda boleh menyenaraikan + dalam satu e-mel.) + works_by: 'Karya-karya ini ditulis di bawah e-mel: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Semua tugasan telah dihantar + subject: Tugasan dihantar + html: + received_message: 'Anda telah menerima pesanan tentang koleksi anda %{collection_link}:' + text: + received_message: 'Anda telah menerima pesanan tentang koleksi anda "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Apabila anda menjadi seorang pereka bersama untuk sesebuah karya, + anda boleh dimasukkan pada bab-bab baru, tanpa mengira tetapan pereka bersama + anda. Anda juga akan ditambah ke mana-mana siri di mana karya tersebut akan + disertakan. + html: + creation: "%{creation_link} oleh %{pseud_links}" + edit_chapter: Edit bab + edit_series: olah siri + remove_chapter: Jika anda telah silap dimasukkan atau tidak mahu disenarai + sebagai pereka, anda boleh %{edit_chapter_link} untuk mengeluarkan diri + anda sebagai pereka. + remove_series: Jika anda telah silap dimasukkan atau tidak mahu disenarai + sebagai pereka, anda boleh %{edit_series_link} untuk mengeluarkan diri sebagai + pereka. + intro_chapter: 'Pengguna %{adding_user} telah menyenaraikan nama samaran anda + %{pseud} sebagai pereka bersama untuk bab yang berikut:' + intro_series: 'Pengguna %{adding_user} telah menyenaraikan nama samaran anda + %{pseud} sebagai pereka bersama bagi siri berikut:' + subject: "[%{app_name}] Pemberitahuan Pereka Bersama" + text: + creation: "%{title} (%{url}) oleh %{pseuds}" + remove_chapter: 'Jika anda telah silap dimasukkan atau tidak mahu disenarai + sebagai pereka, anda boleh mengedit bab ini untuk mengeluarkan diri sebagai + pereka: %{url}' + remove_series: 'Jika anda telah silap dimasukkan atau tidak mahu disenarai + sebagai pereka, anda boleh untuk mengeluarkan diri sebagai pereka: %{url}' + creatorship_notification_archivist: + explanation: Oleh sebab mereka bertindak melalui peranan rasmi mereka sebagai + ahli arkib Open Doors (Projek Pemeliharaan Bahan-Bahan Digital dan Bukan Digital), + mereka boleh menyertakan anda tanpa permintaan, walaupun anda memilih untuk + menolak perekaan bersama. + html: + creation: "%{creation_link} oleh %{pseud_links}" + edit_chapter: mengedit bab ini + edit_series: mengedit siri ini + edit_work: mengedit karya ini + remove_chapter: Jika anda telah disertakan secara tidak sengaja ataupun anda + tidak ingin disenaraikan sebagai pereka, anda boleh %{edit_chapter_link} + untuk membuang nama samaran anda sebagai pereka. + remove_series: Jika anda telah disertakan secara tidak sengaja ataupun anda + tidak ingin disenaraikan sebagai pereka, anda boleh %{edit_series_link} + untuk membuang nama samaran anda sebagai pereka. + remove_work: Jika anda telah disertakan secara tidak sengaja ataupun anda + tidak ingin disenaraikan sebagai pereka, anda boleh %{edit_work_link} untuk + membuang nama samaran anda sebagai pereka. + intro_chapter: 'Pengguna %{archivist} telah menyertakan nama samaran anda %{pseud} + sebagai pereka bersama untuk bab berikut:' + intro_series: 'Pengguna %{archivist} telah menyertakan nama samaran anda %{pseud} + sebagai pereka bersama berikut untuk siri berikut:' + intro_work: 'Pengguna %{archivist} telah menyertakan nama samaran anda %{pseud} + sebagai pereka bersama untuk karya berikut:' + subject: "[%{app_name}] Pemberitahuan pereka bersama ahli arkib" + text: + creation: "%{title} (%{url}) oleh %{pseuds}" + remove_chapter: 'Jika anda telah disertakan secara tidak sengaja ataupun anda + tidak ingin disenaraikan sebagai pereka, anda boleh mengedit bab ini untuk + membuang nama samaran anda sebagai pereka: %{url}' + remove_series: 'Jika anda telah disertakan secara tidak sengaja ataupun anda + tidak ingin disenaraikan sebagai pereka, anda boleh mengedit siri ini untuk + membuang nama samaran anda sebagai pereka: %{url}' + remove_work: 'Jika anda telah disertakan secara tidak sengaja ataupun anda + tidak ingin disenaraikan sebagai pereka, anda boleh mengedit karya ini untuk + membuang nama samaran anda sebagai pereka: %{url}' + creatorship_request: + html: + creation: "%{creation_link} oleh %{pseud_links}" + instructions: Anda boleh menerima atau menolak permintaan ini di halaman %{page_name} + anda. + page_name: Co-Creator Requests (Permintaan-Permintaan Pereka Bersama) + intro_chapter: 'Pengguna %{inviting_user} telah menjemput nama samaran anda + %{pseud} untuk disenaraikan sebagai pereka bersama bab di bawah:' + intro_series: 'Pengguna %{inviting_user} telah menjemput nama samaran anda %{pseud} + untuk disenaraikan sebagai pereka bersama di siri tersebut:' + intro_work: 'Pengguna %{inviting_user} telah menjemput nama samaran anda %{pseud} + untuk disenaraikan sebagai pereka bersama di karya tersebut:' + subject: "[%{app_name}] Permintaan pereka bersama" + text: + creation: "%{title} (%{url}) oleh %{pseuds}" + instructions: 'Anda boleh menerima atau menolak permintaan ini di halaman + Co-Creator Requests (Permintaan-Permintaan Pereka Bersama) anda: %{url}' + delete_work_notification: + attachment: Dilampirkan adalah sebuah salinan karya anda untuk rujukan. + deleted_other: + html: Karya anda %{title} telah dipadamkan atas permintaan %{pseud}. + text: Karya anda "%{title}" telah dipadamkan atas permintaan %{pseud}. + deleted_yourself: + html: Karya anda %{title} telah dipadamkan atas permintaan anda. + text: Karya anda "%{title}" telah dipadamkan atas permintaan anda. + questions: + html: Sekiranya anda mempunyai sebarang pertanyaan, sila %{support}. + text: Sekiranya anda mempunyai sebarang pertanyaan, sila %{support} (%{url}). + subject: "[%{app_name}] Karya anda telah dipadamkan" + support: hubungi Bantuan + invitation_to_claim: + access: + text: Bergantung kepada arkib, karya-karya anda yang diimport mungkin dihadkan + kepada pengguna berdaftar sahaja (supaya tidak termasuk ke dalam carian + Google). Jika berlaku sedemikian, karya-karya tersebut hanya boleh diakses + oleh pengguna yang log masuk, melainkan anda memilih untuk membuatkan karya-karya + boleh diakses oleh orang ramai. Untuk bantuan membebaskan, meyatimkan, atau + memadam karya-karya anda, sila hubungi Bantuan AO3. + claim_or_remove: + html: Tuntut atau padamkan karya-karya anda di sini. + text: 'Tuntut atau padam karya-karya anda di sini: %{claim_url}' + email_tips: Jika anda menghubungi kami, sila whitelist alamat-alamat e-mel daripada + @transformativeworks.org dan semak folder spam anda untuk balasan kami. + html: + ao3_news: Berita AO3 + contact_open_doors: hubungi Open Doors + contact_support: hubungi bantuan AO3 + faq_page: laman FAQ + tutorial_page: laman tutorial + introduction: + text: Anda menerima e-mel ini kerana sebuah arkib baru sahaja diimport oleh + Open Doors (%{open_doors_link}) ke dalam %{app_name} (%{app_short_name} + - %{app_url}), dan kami percaya bahawa hasil kerja peminat berikut adalah + milik anda. Kami ingin memberikan peluang kepada anda untuk menuntut (atau + memadam/menyatim) karya-karya tersebut jika anda mahu. Dan jika anda belum + lagi mempunyai akaun dengan e-mel berbeza, kami ingin menjemput anda untuk + menyertai kami! + mistake: + text: Jika ini merupakan suatu kesilapan dan karya-karya ini bukan milik anda, + sila jangan padamkannya! Sila hubungi sahaja Open Doors (%{open_doors_link}) + dan kami akan selesaikannya. + more_info: + text: Anda boleh membaca pengumuman mengenai pergerakan arkib terbaru di Berita + AO3 (%{news_link}), dan mencari maklumat tambahan tentang laman FAQ Open + Doors (%{open_doors_faq_link}) atau laman tutorial (%{open_doors_tutorial_link}). + Untuk sebarang soalan yang tidak dijawab di dalam FAQ, tutorial, atau e-mel + ini, sila hubungi Bantuan di %{support_link}. + other_works: + text: Jika anda mempunyai karya-karya lain pada arkib yang diimport dengan + alamat e-mel lain yang anda tidak dapat akses, sila hubungi Open Doors dengan + apa-apa maklumat yang boleh membantu mengesahkan identiti anda. + questions: + text: Untuk pertanyaan lanjut, sila hubungi Bantuan AO3 di %{support_link}. + redirects: Untuk memelihara senarai cadangan dan penanda laman, alamat-alamat + laman web dari arkib yang diimport mungkin akan berubah hala ke salinan untuk + karya-karya tersebut yang diimport untuk jangka masa yang terhad (semak artikel + pengumuman untuk arkib anda untuk kepastian). Jika anda telah memuat naik + salinan untuk karya-karya tersebut dan anda TIDAK menggunakan ciri import + daripada URL, akan terdapat dua salinan untuk karya yang sama di dalam arkib. + subject: "[%{app_name}] Jemputan untuk menuntut karya" + unwanted: + text: Jika karya-karya ini milik anda, tetapi anda tidak menyimpannya lagi, + anda boleh meyatimkan (supaya mereka kekal di dalam AO3, tetapi dengan nama + anda dibuang) atau memadamkan mereka (supaya mereka dibuang sepenuhnya dari + AO3). Anda tidak perlu menambahkan karya-karya tersebut ke mana-mana akaun + untuk meyatimkan atau memadamkan mereka--anda boleh lakukan terus daripada + pautan tuntut di atas. (Untuk bantuan, sila hubungi Bantuan di %{support_link}.) + update_redirect: + text: Jika anda ingin Open Doors untuk mengemas kini pengalihan untuk menuju + ke karya anda yang sedia ada, sila padamkan salinan yang telah dimuat naik, + dan hubungi Open Doors di %{open_doors_link} dengan akaun AO3 anda, nama + akaun anda pada arkib yang diimport, dan tajuk dan URL hasil kerja peminat + anda yang anda ingin tujukan pengalihan tersebut. (Jika anda mempunyai pelbagai + karya yang anda ingin ubah pengalihan, anda boleh senaraikannya dalam satu + e-mel.) + uploaded_list: 'Karya-karya yang dimuat naik termasuk:' + invite_increase_notification: + html: + body: + other: Kami ingin memaklumkan bahawa anda mempunyai %{count} jemputan baharu + yang boleh digunakan untuk membuat akaun baharu di AO3. Anda boleh menjemput + rakan anda di %{invitation_page_link}. + invitation_page_link_text: laman jemputan anda + subject: "[%{app_name}] Jemputan Baharu" + text: + body: + other: Kami ingin memaklumkan bahawa anda mempunyai %{count} jemputan baharu + yang boleh digunakan untuk membuat akaun baharu di AO3. Anda boleh menjemput + rakan anda di laman Invitations (Jemputan) anda (%{invitation_page_url}). + invite_request_declined: + main: + other: Dengan berat hati ingin kami maklumkan kepada anda bahawa permintaan + anda untuk %{count} jemputan baharu tidak dapat dipenuhi ketika ini. + reason: 'Berikut merupakan permintaan anda:' + subject: "[%{app_name}] Permintaan Kod Jemputan Tambahan Ditolak" + recipient_notification: + html: + collection: Karya hadiah telah disiarkan untuk anda dalam koleksi %{collection_link} + di AO3! + no_collection: Karya hadiah telah disiarkan untuk anda di AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Karya hadiah untuk anda dari + %{collection_title}" + no_collection: "[%{app_name}] Hadiah karya untuk anda" + text: + collection: Karya hadiah telah disiarkan untuk anda dalam koleksi "%{collection_title}" + (%{collection_url}) di AO3! + signup_notification: + activate: + html: Sila %{activate_account_link}. + text: 'Sila ikuti pautan ini untuk aktifkan akaun anda: %{activate_account_url}' + activate_your_account: Ikuti pautan ini untuk aktifkan akaun anda + admin_posts: Berita AO3 + bye: Kami harap anda memperolehi pengalaman baik menggunakan arkib ini. + contact_support: Hubungi Jawatankuasa Sokongan + faq: FAQ + features: + html: Setelah akaun anda diaktifkan, anda boleh menerbitkan hasil kerja peminat, + menetapkan langganan e-mel untuk memaklumkan anda jika pereka atau karya + kegemaran anda telah dikemaskini, menetapkan pilihan anda untuk mengubah + suai rupa atau bagaimana laman ini berfungsi kepada anda, mengikuti hasil + karya yang anda telah akses di arkib melalui sejarah anda dan banyak lagi. + text: Setelah akaun anda diaktifkan, anda boleh menerbitkan hasil kerja peminat, + menetapkan langganan e-mel untuk memaklumkan anda jika pereka atau karya + kegemaran anda telah dikemaskini, menetapkan pilihan anda untuk mengubah + suai rupa atau bagaimana laman ini berfungsi kepada anda, mengikuti hasil + karya yang anda telah akses di arkib melalui sejarah anda dan banyak lagi. + information: + html: Terdapat banyak maklumat dan nasihat tentang cara-cara menggunakan Arkib + di %{faq_link} kami. Anda akan menemui berita terkini tentang perkembangan + laman di %{admin_posts_link} kami. Jika anda memerlukan lebih pertolongan, + menghadapi ralat perisian dalaman atau mempunyai soalan atau komen, sila + %{contact_support_link}, yang sentiasa bersedia untuk menolong. + text: 'Terdapat banyak maklumat dan nasihat tentang cara-cara menggunakan + Arkib di FAQ kami di %{faq_url}. Anda akan menemui berita terkini tentang + perkembangan laman dalam Berita AO3 di %{admin_posts_url}. Jika anda memerlukan + lebih pertolongan, menghadapi ralat perisian dalaman atau mempunyai soalan + atau komen, sila berhubung dengan bahagian Bantuan kami, yang sentiasa + bersedia untuk menolong: %{contact_support_url}' + welcome: Selamat datang ke Arkib Milik Kita, %{login}! diff --git a/config/locales/phrase-exports/nb.yml b/config/locales/phrase-exports/nb.yml new file mode 100755 index 0000000..eb15a48 --- /dev/null +++ b/config/locales/phrase-exports/nb.yml @@ -0,0 +1,620 @@ +--- +nb: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Advarsel:' + other: 'Advarsler:' + category: + name_with_colon: + one: 'Kategori:' + other: 'Kategorier:' + character: + name_with_colon: + one: 'Karakter:' + other: 'Karakterer:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandommer:' + freeform: + name_with_colon: + one: 'Ytterligere tagg:' + other: 'Ytterligere tagger:' + rating: + name_with_colon: 'Aldersgrense:' + relationship: + name_with_colon: + one: 'Forhold:' + other: 'Forhold:' + work: + chapter_total_display: Kapitler + summary: Sammendrag + models: + archive_warning: + one: Advarsel + other: Advarsler + category: + one: Kategori + other: Kategorier + chapter: + one: Kapittel + other: Kapitler + character: + one: Karakter + other: Karakterer + fandom: + one: Fandom + other: Fandommer + freeform: + one: Ytterligere tagg + other: Ytterligere tagger + rating: + one: Aldersgrense + other: Aldersgrenser + relationship: + one: Forhold + other: Forhold + series: + one: Serie + other: Serier + kudo_mailer: + batch_kudo_notification: + guest: + one: en gjest + other: "%{count} gjester" + left_kudos: + html: + one: "%{givers_list} la igjen kudos på %{commentable_link}." + other: "%{givers_list} la igjen kudos på %{commentable_link}." + text: + one: "%{givers_list} la igjen kudos på %{commentable_title} (%{commentable_url})." + other: "%{givers_list} la igjen kudos på %{commentable_title} (%{commentable_url})." + single_guest: + giver: En gjest + html: "%{giver} la igjen kudos på %{commentable_link}." + text: En gjest la igjen kudos på %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Du har fått kudos!" + mailer: + general: + closing: + formal: Med vennlig hilsen + informal: Med vennlig hilsen + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Kapittel %{position} av %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} ord" + other: "%{count} ord" + footer: + general: + about: + html: Vårt eget arkiv er et fan-drevet og fan-støttet arkiv som avhenger + av %{donate_link}. + text: 'AO3 er et fan-drevet og fan-støttet arkiv som avhenger av dine + donasjoner: %{donate_url}.' + html: + donate_link_text: dine donasjoner + support_link_text: kontakte support + unwanted_email: + html: Dersom du feilaktig har mottatt denne beskjeden kan du %{support_link}. + text: 'Dersom du feilaktig har mottatt denne beskjeden, vennligst kontakt + support: %{support_url}.' + sent_at: Sendt %{sent_at}. + greeting: + formal_html: Kjære %{name} + informal: + addressed_html: Hei, %{name}! + unaddressed: Hei! + introductory: En hilsen fra Archive of Our Own – AO3 (Vårt eget arkiv)! + metadata_label_indicator: ":" + signature: + abuse_team: Teamet for retningslinjer og misbruk + app_short_name: AO3 + open_doors: Teamet for Open Doors (Åpne Dører) + parent_org: Organization for Transformative Works – OTW (Organisasjonen for + transformative verk) + support: Teamet for AO3 support + users: + mailer: + reset_password_instructions: + expiration: Hvis du ikke bruker denne lenken til å tilbakestille passordet + ditt innen en uke, vil lenken utløpe, og du må be om en ny en. + intro: 'Noen har bedt om å tilbakestille passordet til kontoen din. Du kan + endre passordet til kontoen din ved å følge lenken under og fylle inn det + nye passordet ditt:' + link_title: Endre passordet mitt. + subject: "[%{app_name}] Tilbakestill passordet ditt" + unrequested: Hvis du ikke ba om å tilbakestille passordet ditt, kan du ignorere + denne e-posten og det tidligere passordet ditt vil fortsette å fungere. + user_mailer: + admin_deleted_work_notification: + bye: Vedlagt ligger en kopi av verket for din referanse. + contact_abuse: kontakt vår komité for retningslinjer og misbruk + deleted: + html: Ditt verk %{title} ble slettet fra Arkivet av en sideadministrator. + text: Ditt verk "%{title}" ble slettet fra Arkivet av en sideadministrator. + html: + tos_violation: Hvis det er mulig at verket ditt brøt med Arkivets brukervilkår, + vennligst %{contact_abuse_link}. + import_project: + html: Hvis verket var en del av et importprosjekt administrert av vårt Åpne + Dører-team, vennligst %{opendoors_link} for eventuelle spørsmål. + text: Hvis verket var en del av et importprosjekt administrert av vårt Åpne + Dører-team, vennligst kontakt Åpne Dører (%{opendoors_link}) for eventuelle + spørsmål. + opendoors: kontakt Åpne Dører + subject: "[%{app_name}] Ditt verk har blitt slettet av en administrator" + text: + tos_violation: Hvis det er mulig at verket ditt brøt med Arkivets brukervilkår, + vennligst kontakt vår komité for retningslinjer og misbruk %{contact_abuse_url}. + admin_hidden_work_notification: + access: Mens verket ditt er skjult kan du fortsatt få tilgang til det gjennom + lenken ovenfor, men det vil ikke være synlig på siden med oversikt over dine + verk, og det vil heller ikke være tilgjengelig for andre brukere av AO3. + check_email: Vennligst sjekk e-posten din, inkludert spam innboksen ettersom + teamet for retningslinjer og misbruk allerede kan ha kontaktet deg for å forklare + hvorfor verket ditt har blitt skjult. + contact_abuse: kontakt retningslinjer og misbruk + html: + help: Hvis du er usikker på hvorfor verket ditt ble skjult og du ikke har + mottatt videre kommunikasjon angående dette, vennligst %{contact_abuse_link} + direkte. + hidden: Verket ditt %{title} har blitt skjult av teamet for retningslinjer + og misbruk og er ikke lenger offentlig tilgjengelig. + tos_violation: Hvis verket ditt ble skjult fordi det er i strid med AO3s %{tos_link} + blir du nødt til å gjøre endringer for å rette opp dette. Dersom du ikke + endrer verket ditt slik at det samsvarer med brukervilkårene, kan det føre + til at verket ditt blir slettet fra AO3. + subject: "[%{app_name}] Verket ditt har blitt skjult av teamet for retningslinjer + og misbruk" + text: + help: 'Hvis du er usikker på hvorfor verket ditt ble skjult og du ikke har + mottatt videre kommunikasjon angående dette, vennligst kontakt retningslinjer + og misbruk direkte: %{contact_abuse_url}.' + hidden: Verket ditt "%{title}" (%{work_url}) har blitt skjult av teamet for + retningslinjer og misbruk og er ikke lenger offentlig tilgjengelig. + tos_violation: Hvis verket ditt ble skjult fordi det er i strid med AO3s brukervilkår + (%{tos_url}) blir du nødt til å gjøre endringer for å rette opp dette. Dersom + du ikke endrer verket ditt slik at det samsvarer med brukervilkårene, kan + det føre til at verket ditt blir slettet fra AO3. + tos: Brukervilkår + anonymous_or_unrevealed_notification: + anonymous_info: Anonyme verk inkluderes i tagg-lister, men ikke på oversikten + over dine verk. På selve verket vil brukernavnet ditt erstattes med “Anonymous” + (Anonym). + anonymous_unrevealed_info: Samlingens administratorer kan ved en senere anledning + velge å offentliggjøre verket men holde det anonymt. Brukere som abonnerer + på dine verk vil ikke motta noen notifikasjon når dette skjer. Når verket + er offentliggjort vil det inkluderes i tagg-lister, men ikke på oversikten + over dine verk. På selve verket vil brukernavnet ditt erstattes med “Anonymous” + (Anonym). + changed_status: + anonymous: + html: Administratorene for %{collection_link} har gjort verket ditt %{work_link} + anonymt. + text: Administratorene for samlingen "%{collection_title}" (%{collection_url}) + har gjort verket ditt "%{work_title}" (%{work_url}) anonymt. + anonymous_unrevealed: + html: Administratorene for samlingen %{collection_link} har endret statusen + til verket ditt %{work_link} til skjult og anonymisert. + text: Administratorene for samlingen "%{collection_title}" (%{collection_url}) + har endret statusen til verket ditt "%{work_title}" (%{work_url}) til + anonymisert og skjult. + unrevealed: + html: Administratorene for samlingen %{collection_link} har endret statusen + til verket ditt %{work_link} til skjult. + text: Administratorene for samlingen "%{collection_title}" (%{collection_url}) + har endret statusen til verket ditt "%{work_title}" (%{work_url}) til + skjult. + collection_items_link_text: siden for Approved Collection Items (Godkjente samlingsverk) + do_not_want: + anonymous: + html: Dersom du ikke ønsker at verket ditt skal være anonymisert, vennligst + gå til %{collection_items_link} for å fjerne det fra det samlingen. + text: 'Dersom du ikke ønsker at verket ditt skal være anonymisert, vennligst + besøk din side for Approved Collection Items (Godkjente samlingsverk) + for å fjerne det fra denne samlingen: %{collection_items_url}' + anonymous_unrevealed: + html: Dersom du ikke ønsker at verket ditt skal være hverken skjult eller + anonymisert, vennligst besøk %{collection_items_link} for å fjerne det + fra denne samlingen. + text: 'Dersom du ikke ønsker at verket ditt skal være hverken skjult eller + anonymisert, vennligst besøk din side for Approved Collection Items (Godkjente + samlingsverk) for å fjerne det fra denne samlingen: %{collection_items_url}' + unrevealed: + html: Dersom du ikke ønsker at verket ditt skal være skjult, vennligst besøk + %{collection_items_link} for å fjerne det fra denne samlingen. + text: 'Dersom du ikke ønsker at verket ditt skal være skjult, vennligst + besøk din side for Approved Collection Items (Godkjente samlingsverk) + for å fjerne det fra denne samlingen: %{collection_items_url}' + faq_link_text: ofte stilte spørsmål om samlinger. + more_info: + html: For mer informasjon kan du besøke våre %{faq_link}. + text: 'For mer informasjon kan du besøke våre ofte stilte spørsmål om samlinger: + %{faq_url}' + subject: + anonymous: "[%{app_name}] Verket ditt har blitt anonymisert" + anonymous_unrevealed: "[%{app_name}] Verket ditt har blitt anonymisert og + skjult." + unrevealed: "[%{app_name}] Verket ditt er skjult" + unrevealed_info: Skjulte verk inkluderes ikke i tagg-lister, ei heller i oversikten + over dine verk. Alle som følger en link til verket ditt vil få en notifikasjon + om at verket for øyeblikket er skjult, og at de derfor ikke har tilgang. + archivist_added_to_collection_notification: + approved_collection_items_page: siden din for Approved Collection Items (godkjente + samlingselementer) + archivist_notice: Fordi samlingsadministratorene handler i kraft av å være arkivarer + for Open Doors (Åpne Dører), har de lov til å legge ditt verk inn i denne + samlingen, selv om du har samlingsinvitasjoner deaktivert. Arkivarer vil kun + legge til et verk i en samling dersom det var en del av et importert arkiv. + removal_instructions: + html: Om du ønsker å fjerne verket ditt fra denne samlingen, besøk %{approved_items_link}. + text: 'Om du ønsker å fjerne verket ditt fra denne samlingen, besøk siden + din for Approved Collection Items (godkjente samlingselementer): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] En arkivar fra Open Doors (Åpne + Dører) har lagt til verket ditt i en samling." + work_added: + html: Samlingsadministratorene til %{collection_link} har lagt ditt verk %{work_link} + inn i samlingen sin! + text: Samlingsadministratorene til "%{collection_title}" (%{collection_url}) + har lagt ditt verk "%{work_title}" (%{work_url}) inn i samlingen sin! + challenge_assignment_notification: + any: Uansett + assignment: + html: Du har fått følgende i oppdrag i %{link}-utfordringen på Archive of + Our Own (Vårt eget arkiv)! + description: 'Beskrivelse:' + due: 'Dette oppdraget har frist:' + html: + footer: Du mottar denne e-posten fordi du har svart på %{title}-utfordringen. + For mer informasjon om denne utfordringen og kontaktinformasjonen til moderatorene, + gå til %{footer_link}. + footer_link: utfordringens profilside + look_up: Du kan finne dette oppdraget på %{link}. + look_up_link: Assignments (oppdrag)-siden din + optional_tags: 'Valgfrie tagger:' + prompts: 'Inspirasjon:' + prompt_url: 'URL til inspirasjonen:' + recipient: 'Mottaker:' + recipient_missing: 'Ingen: kontakt en moderator for hjelp!' + subject: "[%{app_name}][%{collection_title}] Ditt oppdrag!" + text: + assignment: Du har fått følgende i oppdrag i "%{collection_title}"-utfordringen + (%{collection_url}) på Archive of Our Own (Vårt eget arkiv)! + footer: Du mottar denne e-posten fordi du har meldt deg på %{title}-utfordringen + (%{url}). For mer informasjon om denne utfordringen og kontaktinformasjonen + til moderatorene, gå til %{profile_url}. + look_up: Du kan finne dette oppdraget på Assignments (oppdrag)-siden din på + %{link}. + change_email: + changed: + html: "%{login}, e-posten knyttet til din konto har blitt endret til %{email}" + text: "%{login}, e-posten knyttet til din konto har blitt endret til %{email}" + subject: "[%{app_name}] E-post endret" + claim_notification: + access: + contact_support: kontakt AO3 support + html: Avhengig av arkivet, kan det hende verkene dine har blitt importert + som begrenset til kun registrerte brukere (for å unngå at de dukker opp + i Google-søk). Hvis dette er tilfellet, vil verkene kun være tilgjengelige + for brukere som er logget inn, med mindre du velger å gjøre dem helt synlige. + For hjelp med å åpne, si fra deg eller slette verkene dine, vennligst %{contact_support_link}. + text: 'Avhengig av arkivet, kan det hende verkene dine har blitt importert + som begrenset til kun registrerte brukere (for å unngå at de dukker opp + i Google-søk). Hvis dette er tilfellet, vil verkene kun være tilgjengelige + for brukere som er logget inn, med mindre du velger å gjøre dem helt synlige. + For hjelp med å åpne, si fra deg eller slette verkene dine, vennligst kontakt + AO3 support her: %{support_url}.' + email_tips: Hvis du kontakter oss, vennligst legg til e-postadresser fra @transformativeworks.org + til listen din over sikre kontakter og sjekk søppelpostmappene dine etter + svar fra oss. + introduction: + ao3_name: Archive of Our Own – AO3 (Vårt eget arkiv) + html: Du mottar denne e-posten fordi du hadde verk i et fanverkarkiv som har + blitt importert av %{open_doors_name_link} til %{app_link}. Fordi denne + e-postadressen er knyttet til en som er registrert hos det importerte arkivet, + har de tilhørende fanverkene (listet opp nedenfor) automatisk blitt lagt + til AO3-kontoen din. + open_doors_name: Open Doors (Åpne Dører) + text: 'Du mottar denne e-posten fordi du hadde verk i et fanverkarkiv som + har blitt importert av Open Doors (Åpne Dører) (%{open_doors_url}) til Archive + of Our Own – AO3 (Vårt eget arkiv): %{app_url}. Fordi denne e-postadressen + er knyttet til en som er registrert hos det importerte arkivet, har de tilhørende + fanverkene (listet opp nedenfor) automatisk blitt lagt til AO3-kontoen din.' + mistake: + contact_open_doors: kontakt Åpne Dører + html: Hvis dette er feil og disse verkene ikke tilhører deg, ikke slett dem! + Vennligst %{contact_open_doors_link}, så ordner vi det. + text: Hvis dette er feil og disse verkene ikke tilhører deg, ikke slett dem! + Vennligst kontakt Åpne Dører (%{open_doors_url}), så ordner vi det. + more_info: + ao3_news: AO3 Nyheter + contact_support: kontakt AO3 support + faq_page: ofte stilte spørsmål-side + html: Du kan lese kunngjøringer om nylige arkivforflyttninger på %{ao3_news_link}, + og finne ytterligere informasjon på Åpne Dører sin %{faq_page_link} eller + %{tutorial_page_link}. For spørsmål som ikke er besvart i ofte stilte spørsmål, + tutorialer, eller i denne e-posten, vennligst %{contact_support_link}. + text: 'Du kan lese kunngjøringer om nylige arkivforflyttninger på AO3 Nyheter + (%{news_url}) og finne ytterligere informasjon på Åpne Dører sin ofte stilte + spørsmål-side (%{open_doors_faq_url}) eller tutorial-side (%{open_doors_tutorial_url}). + For spørsmål som ikke er besvart i ofte stilte spørsmål, tutorialer, eller + i denne e-posten, vennligst kontakt support her: %{support_url}.' + tutorial_page: tutorial-side + other_works: + contact_open_doors: kontakt Åpne Dører + html: Hvis du hadde andre verk på det importerte arkivet under en e-postadresse + du ikke lenger har tilgang til, vennligst %{contact_open_doors_link} med + all informasjon som kan hjelpe med å verifisere identiteten din. + text: Hvis du hadde andre verk på det importerte arkivet under en e-postadresse + du ikke lenger har tilgang til, vennligst kontakt Åpne Dører med all informasjon + som kan hjelpe med å verifisere identiteten din. + questions: + contact_support: kontakt AO3 support + html: For andre henvendelser, vennligst %{contact_support_link}. + text: 'For andre henvendelser, vennligst kontakt AO3 support her: %{support_url}.' + redirects: + html: For å bevare anbefalingslister og bokmerker, kan nettadressen til det + importerte arkivet omdirigere til den importerte kopien av disse verkene + i en begrenset periode (sjekk kunngjøringsinnlegget til arkivet ditt for + å være sikker). Hvis du allerede har lastet opp en kopi av disse verkene + og du %{negation} brukte funksjonen hvor verket importeres fra URL-en, kommer + det til å være to kopier av samme verk på AO3. + subject: "[%{app_name}] Verk lastet opp" + update_redirect: + contact_open_doors: kontakt Åpne Dører + html: Hvis du ønsker at Åpne Dører skal oppdatere omdirigeringspunktet til + verket ditt som allerede eksisterer på AO3, vennligst slett den importerte + kopien og %{contact_open_doors_link} med navnet på AO3-kontoen din, navnet + på kontoen din fra det importerte arkivet, samt tittelen og URL-en til fanverket + du ønsker at omdirigeringen skal gå til. (Hvis du har flere verk du ønsker + å endre omdirigeringen til, kan du oppgi alle sammen i én e-post.) + text: 'Hvis du ønsker at Åpne Dører skal oppdatere omdirigeringspunktet til + verket ditt som allerede eksisterer på AO3, vennligst slett den importerte + kopien og kontakt Åpne Dører her: %{open_doors_url} med navnet på AO3-kontoen + din, navnet på kontoen din fra det importerte arkivet, samt tittelen og + URL-en til fanverket du ønsker at omdirigeringen skal gå til. (Hvis du har + flere verk du ønsker å endre omdirigeringen til, kan du oppgi alle sammen + i én e-post.)' + works_by: 'Disse verkene ble skrevet under e-posten: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Alle oppdrag er nå sendt ut. + subject: Oppdrag utsendt + html: + received_message: 'Du har fått en melding om samlingen din %{collection_link}:' + text: + received_message: 'Du har fått en melding om samlingen din "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Når du er medskaper på et verk kan du bli lagt til på nye kapitler + uavhengig av dine medskaper-innstillinger. Du blir også lagt til på alle serier + som verket tilhører. + html: + creation: "%{creation_link} av %{pseud_links}" + edit_chapter: redigere kapittelet + edit_series: redigere serien + remove_chapter: Dersom du har blitt lagt til ved en feiltakelse eller du ikke + ønsker å stå oppført som skaper, kan du %{edit_chapter_link} for å fjerne + deg selv som skaper. + remove_series: Dersom du har blitt lagt til ved en feiltakelse eller du ikke + ønsker å stå oppført som skaper, kan du %{edit_series_link} for å fjerne + deg selv som skaper. + intro_chapter: 'Brukeren %{adding_user} har lagt til pseudonymet ditt %{pseud} + som medskaper på følgende kapittel:' + intro_series: 'Brukeren %{adding_user} har lagt til pseudonymet ditt %{pseud} + som medskaper på følgende serie:' + subject: "[%{app_name}] Varsel om at du har blitt lagt til som medskaper" + text: + creation: "%{title} (%{url}) av %{pseuds}" + remove_chapter: 'Dersom du har blitt lagt til ved en feiltakelse eller ikke + ønsker å stå oppført som skaper, kan du redigere kapittelet for å fjerne + deg selv som skaper: %{url}' + remove_series: 'Dersom du har blitt lagt til ved en feiltakelse eller du ikke + ønsker å stå oppført som skaper, kan du redigere serien for å fjerne deg + selv som skaper: %{url}' + creatorship_notification_archivist: + explanation: Fordi hen er offisielt utstedt arkivar for Åpne Dører, har hen + lov til å legge deg til uten forespørsel, selv om du har slått av innstillingen + for å kunne legges til som medskaper. + html: + creation: "%{creation_link} av %{pseud_links}" + edit_chapter: redigere kapittelet + edit_series: redigere serien + edit_work: redigere arbeidet + remove_chapter: Dersom du har blitt lagt til ved en feil, eller ikke ønsker + å listes som skaper, så kan du %{edit_chapter_link} for å fjerne deg selv + som skaper. + remove_series: Dersom du har blitt lagt til ved en feil, eller ikke ønsker + å listes som skaper, så kan du %{edit_series_link} for å fjerne deg selv + som skaper. + remove_work: Dersom du har blitt lagt til ved en feiltakelse eller ikke ønsker + å stå oppført som skaper, kan du %{edit_work_link} for å fjerne deg selv + som skaper. + intro_chapter: 'Brukeren %{archivist} har lagt til pseudonymet ditt %{pseud} + som medskaper på følgende kapittel:' + intro_series: 'Brukeren %{archivist} har lagt til pseudonymet ditt %{pseud} + som medskaper på følgende serie:' + intro_work: 'Brukeren %{archivist} har lagt til pseudonymet ditt %{pseud} som + medskaper på følgende verk:' + subject: "[%{app_name}] En arkivar har lagt deg til som medskaper" + text: + creation: "%{title} (%{url}) av %{pseuds}" + remove_chapter: 'Dersom du har blitt lagt til ved en feiltakelse eller ikke + ønsker å stå oppført som skaper, kan du redigere kapittelet for å fjerne + deg selv som skaper: %{url}' + remove_series: 'Dersom du har blitt lagt til ved en feiltakelse eller ikke + ønsker å stå oppført som skaper, kan du redigere serien for å fjerne deg + selv som skaper: %{url}' + remove_work: 'Dersom du har blitt lagt til ved en feiltakelse eller ikke ønsker + å stå oppført som skaper, kan du redigere verket for å fjerne deg selv som + skaper: %{url}' + creatorship_request: + html: + creation: "%{creation_link} av %{pseud_links}" + instructions: Du kan godkjenne eller avvise denne forespørselen på siden din + for %{page_name}. + page_name: Co-Creator Requests (medskaperforespørsler) + intro_chapter: 'Brukeren %{inviting_user} har invitert pseudonymet ditt %{pseud} + til å bli lagt til som medskaper på følgende kapittel:' + intro_series: 'Brukeren %{inviting_user} har invitert pseudonymet ditt %{pseud} + til å bli lagt til som medskaper på følgende serie:' + intro_work: 'Brukeren %{inviting_user} har invitert pseudonymet ditt %{pseud} + til å bli lagt til som medskaper på følgende verk:' + subject: "[%{app_name}] Medskaperforespørsel" + text: + creation: "%{title} (%{url}) av %{pseuds}" + instructions: 'Du kan godkjenne eller avvise denne forespørselen på siden + din for Co-Creator Requests (medskaperforespørsler): %{url}' + delete_work_notification: + attachment: For videre referanse finner du en kopi at verket ditt vedlagt. + deleted_other: + html: Ditt verk %{title} ble slettet etter forespørsel fra %{pseud}. + text: Ditt verk “%{title}" ble slettet etter forespørsel fra %{pseud}. + deleted_yourself: + html: Ditt verk %{title} ble slettet per din forespørsel. + text: Ditt verk "%{title}" ble slettet per din forespørsel. + questions: + html: Dersom du har noen spørsmål, vennligst %{support}. + text: Dersom du har noen spørsmål, vennligst %{support} (%{url}). + subject: "[%{app_name}] Ditt verk har blitt slettet" + support: kontakt support + invitation_to_claim: + access: + text: Avhengig av arkivet, kan verkene dine ha blitt importert begrenset til + registrerte brukere (slik at de ikke vises i Google-søk). Om det er slik, + vil verkene kun være synlige for innloggede brukere med mindre du velger + å gjøre dem synlige. For hjelp med å låse opp, si i fra deg eller slette + verk, vennligst kontakt AO3 support. + claim_or_remove: + html: Gjør krav på eller fjern verk her. + text: 'Gjør krav på eller fjern verk her: %{claim_url}' + email_tips: 'Dersom du tar kontakt med oss, vennligst merk e-postadresser fra + @transformativeworks.org som trygge og sjekk spamfilteret. ' + html: + ao3_news: AO3 nyheter + contact_open_doors: kontakt Åpne Dører + contact_support: kontakt AO3 support + faq_page: FAQ-side + tutorial_page: tutorial-side + introduction: + text: Du mottar denne e-posten fordi et arkiv nylig har blitt importert av + Åpne Dører (%{open_doors_link}) inn på %{app_name} (%{app_short_name} - + %{app_url}), og vi tror at de følgende verkene tilhører deg. Vi vil gi deg + sjansen til å gjøre krav på (eller slette/si i fra deg) disse verkene om + du vil. Og om du ikke allerede har en konto under en annen e-postadresse, + vil vi gjerne invitere deg med! + mistake: + text: Om dette er en feil og disse verkene ikke tilhører deg, vær snill og + ikke slett dem! Vennligst kontakt Åpne Dører (%{open_doors_link}) og vi + vil ordne opp i det. + more_info: + text: 'Du kan lese kunngjøringene om nylige arkiv-flyttinger på AO3 nyheter + (%{news_link}), og du finner tilleggsinformasjon på Åpne Dørers FAQ-side + (%{open_doors_faq_link}) eller tutorial-siden (%{open_doors_tutorial_link}). + For spørsmål som ikke besvares i FAQ-en, tutorialen, eller denne e-posten, + vennligst kontakt support her: %{support_link}.' + other_works: + text: Om du hadde andre verk på det importerte arkivet under en e-postadresse + du ikke lenger har tilgang til, vennligst kontakt Åpne Dører med informasjon + som kan bekrefte din identitet. + questions: + text: 'For andre spørsmål, vennligst kontakt AO3 support her: %{support_link}.' + redirects: For å bevare anbefalingslister og bokmerker, vil det importerte arkivets + URL muligens viderekoble til den importerte versjonen av disse verkene i en + begrenset periode (sjekk innlegget med kunngjøringen for arkivet ditt for + å være sikker). Om du allerede har publisert noen av disse verkene og du IKKE + importerer fra URL, vil det eksistere to kopier av samme verk på arkivet. + subject: "[%{app_name}] Invitasjon til å gjøre krav på verk" + unwanted: + text: Om disse verkene tilhører deg men du ikke vil ha dem, kan du si dem + i fra deg (slik at de blir på AO3, men navnet ditt blir fjernet) eller slette + dem (slik at de blir fjernet helt fra AO3). Du behøver ikke å legge disse + verkene til en konto for å slette dem eller si dem i fra deg – du kan gjøre + det direkte fra krav-linken over. (Om du trenger hjelp med dette, vennligst + kontakt support på %{support_link}.) + update_redirect: + text: Om du vil at Åpne Dører skal oppdatere viderekoblingen til å vise til + et allerede eksisterende verk, vennligst slett den importerte versjonen, + og kontakt Åpne Dører på %{open_doors_link} med ditt AO3-brukernavn, brukernavnet + ditt på det importerte arkivet samt tittelen og URLen til det fanverket + du vil viderekoble til. (Om du har flere verk du vil endre viderekoblingen + til, kan du liste alle i samme e-post). + uploaded_list: 'Verkene det gjelder er:' + invite_increase_notification: + html: + body: + one: Vi ville bare informere deg om at du har %{count} ny invitasjon som + kan brukes til å lage en ny bruker på arkivet. Du kan invitere en venn + på %{invitation_page_link}. + other: Vi ville bare informere deg om at du har %{count} nye invitasjoner + som kan brukes til å lage nye brukere på arkivet. Du kan invitere en venn + på %{invitation_page_link}. + invitation_page_link_text: din Invitations (invitasjoner)-side + subject: "[%{app_name}] Nye invitasjoner" + text: + body: + one: Vi ville bare informere deg om at du har %{count} ny invitasjon som + kan brukes til å lage en ny bruker på arkivet. Du kan invitere en venn + på din Invitations (invitasjoner)-side (%{invitation_page_url}). + other: Vi ville bare informere deg om at du har %{count} nye invitasjoner + som kan brukes til å lage nye brukere på arkivet. Du kan invitere en venn + på din Invitations (invitasjoner)-side (%{invitation_page_url}). + invite_request_declined: + main: + one: Vi beklager å måtte informere deg om at din forespørsel om å få tilsendt + en ny invitasjon ikke kan innfris på dette tidspunktet. + other: Vi beklager å måtte informere deg om at din forespørsel om å få tilsendt + %{count} nye invitasjoner ikke kan innfris på dette tidspunktet. + reason: 'Din forespørsel var:' + subject: "[%{app_name}] Forespørsel om ekstra invitasjonskode avvist" + recipient_notification: + html: + collection: Et verk er publisert som en gave til deg i samlingen %{collection_link} + på AO3! + no_collection: Et verk er publisert på AO3 som en gave til deg! + subject: + collection: "[%{app_name}][%{collection_title}] Du har fått et verk fra %{collection_title}" + no_collection: "[%{app_name}] Du har fått et verk" + text: + collection: Et verk er publisert som en gave til deg i samlingen "%{collection_title}" + (%{collection_url}) på AO3! + signup_notification: + activate: + html: Vennligst %{activate_account_link}. + text: 'Vennligst følg denne lenken for å aktivere kontoen din: %{activate_account_url}' + activate_your_account: følg denne lenken for å aktivere kontoen din + admin_posts: AO3 nyheter + bye: Vi håper du vil trives med å bruke arkivet. + contact_support: kontakt vårt support team + faq: Ofte stilte spørsmål + features: + html: Så snart kontoen din er aktivert kan du publisere dine verk, lage e-post-abonnementer + slik at du får beskjed når dine favoritter har oppdatert, tilpasse dine + preferanser for hvordan siden ser ut og fungerer for deg, holde orden på + hvilke verk du har klikket på via loggen, og mye mer. + text: Så snart kontoen din er aktivert kan du publisere dine verk, lage e-post-abonnementer + slik at du får beskjed når dine favoritter har oppdatert, tilpasse dine + preferanser for hvordan siden ser ut og fungerer for deg, holde orden på + hvilke verk du har klikket på via loggen, og mye mer. + information: + html: Du kan finne mye informasjon og råd om hvordan du bruker arkivet under + %{faq_link}. Nyheter om nettstedets utvikling finner du her i %{admin_posts_link}. + Om du har behov for mer hjelp, støter på en feil eller har andre spørsmål + eller tilbakemeldinger, vennligst %{contact_support_link}, som alltid står + klare til å hjelpe. + text: 'Du kan finne mye informasjon og råd for hvordan du bruker arkivet i + vår FAQ (ofte stilte spørsmål) under %{faq_url}. Oppdateringer om nettstedets + utvikling finner du hos AO3 nyheter: %{admin_posts_url}. Om du har behov + for mer hjelp, støter på en feil eller har andre spørsmål eller tilbakemeldinger, + vennligst kontakt vårt support team, som alltid står klare til å hjelpe: + %{contact_support_url}.' + welcome: Velkommen til Archive of Our Own, %{login}! diff --git a/config/locales/phrase-exports/nl.yml b/config/locales/phrase-exports/nl.yml new file mode 100755 index 0000000..3aef3de --- /dev/null +++ b/config/locales/phrase-exports/nl.yml @@ -0,0 +1,563 @@ +--- +nl: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Waarschuwing:' + other: 'Waarschuwingen:' + category: + name_with_colon: + one: 'Categorie:' + other: 'Categorieën:' + character: + name_with_colon: + one: 'Personage:' + other: 'Personages:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandoms:' + freeform: + name_with_colon: + one: 'Extra Tag:' + other: 'Extra Tags:' + rating: + name_with_colon: 'Classificatie:' + relationship: + name_with_colon: + one: 'Relatie:' + other: 'Relaties:' + work: + chapter_total_display: Hoofdstukken + summary: Samenvatting + models: + archive_warning: + one: Waarschuwing + other: Waarschuwingen + category: + one: Categorie + other: Categorieën + chapter: + one: Hoofdstuk + other: Hoofdstukken + character: + one: Personage + other: Personages + fandom: + one: Fandom + other: Fandoms + freeform: + one: Extra Tag + other: Extra Tags + rating: + one: Classificatie + other: Classificaties + relationship: + one: Relatie + other: Relaties + series: + one: Serie + other: Series + kudo_mailer: + batch_kudo_notification: + guest: + one: een bezoeker + other: "%{count} bezoekers" + left_kudos: + html: + one: Je hebt kudos gekregen van %{givers_list} voor %{commentable_link}. + other: Je hebt kudos gekregen van %{givers_list} voor %{commentable_link}. + text: + one: Je hebt kudos gekregen van %{givers_list} voor %{commentable_title} + (%{commentable_url}). + other: Je hebt kudos gekregen van %{givers_list} voor %{commentable_title} + (%{commentable_url}). + single_guest: + giver: een bezoeker + html: Je hebt kudos gekregen van %{giver} voor %{commentable_link}. + text: Je hebt kudos gekregen van een bezoeker voor %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Kudos!" + mailer: + general: + closing: + formal: Met vriendelijke groeten, + informal: Groeten, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Hoofdstuk %{position} van %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} woord" + other: "%{count} woorden" + footer: + general: + about: + html: AO3 is een door fans beheerd en ondersteund archief dat afhankelijk + is van %{donate_link} + text: 'AO3 is een door fans beheerd en ondersteund archief dat afhankelijk + is van jouw donaties: %{donate_url}.' + html: + donate_link_text: jouw donaties + support_link_text: Neem contact op met Support + unwanted_email: + html: Is dit bericht niet voor jou bedoeld? %{support_link}. + text: Is dit bericht niet voor jou bedoeld? Neem dan contact op met Support + via %{support_url}. + sent_at: Verstuurd om %{sent_at}. + greeting: + formal_html: Beste %{name}, + informal: + addressed_html: Hallo, %{name}! + unaddressed: Hallo! + introductory: Hallo van Archive of Our Own – AO3 (Ons Eigen Archief)! + metadata_label_indicator: ":" + signature: + abuse_team: AO3 Beleids- en Misbruikcommissie + app_short_name: AO3 + open_doors: Open Doors (Open Deuren) + parent_org: Organization for Transformative Works – OTW (Organisatie voor + Transformatieve Werken) + support: AO3 Support + users: + mailer: + reset_password_instructions: + expiration: Als je deze link niet binnen een week gebruikt om je wachtwoord + opnieuw in te stellen, zal de link vervallen en moet je een nieuwe aanvragen. + intro: 'Er is een wachtwoordherstel voor je account aangevraagd. Je kan je + wachtwoord veranderen door de onderstaande link te volgen en een nieuw wachtwoord + te kiezen:' + link_title: Verander mijn wachtwoord. + subject: "[%{app_name}] Wijzig je wachtwoord" + unrequested: Als je geen wachtwoordherstel hebt aangevraagd, kan je deze e-mail + negeren en zal je vorige wachtwoord blijven werken. + user_mailer: + admin_deleted_work_notification: + bye: Een kopie van je werk is ter referentie bijgevoegd. + contact_abuse: neem dan contact op met Beleid & Misbruik + deleted: + html: Jouw werk %{title} is verwijderd uit AO3 door een site-admin. + text: Jouw werk "%{title}" is verwijderd uit AO3 door een site-admin. + html: + tos_violation: Als het mogelijk is dat jouw werk de servicevoorwaarden van + AO3 schond, %{contact_abuse_link}. + import_project: + html: Als jouw werk onderdeel was van een importproject beheerd door Open + Doors (Open Deuren) en je nog verdere vragen hebt, %{opendoors_link}. + text: Als jouw werk onderdeel was van een importproject beheerd door Open + Doors (Open Deuren) en je nog verdere vragen hebt, neem dan contact op met + Open Deuren (%{opendoors_link}). + opendoors: neem dan contact op met Open Deuren + subject: "[%{app_name}] Jouw werk is verwijderd door een admin" + text: + tos_violation: Als het mogelijk is dat jouw werk de servicevoorwaarden van + AO3 schond, neem dan contact op met Beleid & Misbruik (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Terwijl je werk verborgen is, is het voor jou toegankelijk via de bovenstaande + link maar het zal niet zichtbaar zijn op de pagina met jouw werken en niet + beschikbaar zijn voor andere gebruikers van AO3. + check_email: Controleer je e-mail, inclusief je spamfolder, want het Beleids- + en Misbruikteam kan al geprobeerd hebben om contact met je op te nemen om + uit te leggen waarom je werk is verborgen. + contact_abuse: neem dan contact op met het Beleids- en Misbruikteam + html: + help: Als je niet weet waarom je werk verborgen is en je hebt geen verdere + communicatie hierover ontvangen, %{contact_abuse_link}. + hidden: Jouw werk %{title} is verborgen door het Beleids- en Misbruikteam + en is niet meer publiek toegankelijk. + tos_violation: Als je werk verborgen is omdat het AO3's %{tos_link} overtreedt, + zal van jou verwacht worden dat je actie onderneemt om de overtreding te + corrigeren. Als je er niet in slaagt je werk inschikkelijk te maken met + de Servicevoorwaarden, kan dat ertoe leiden dat je werk verwijderd wordt + van AO3. + subject: "[%{app_name}] Jouw werk is verborgen door het Beleids- en Misbruikteam" + text: + help: 'Als je niet weet waarom je werk verborgen is en je hebt geen verdere + communicatie hierover ontvangen, neem dan rechtstreeks contact op met het + Beleids- en Misbruikteam: %{contact_abuse_url}.' + hidden: Jouw werk "%{title}" (%{work_url}) is verborgen door het Beleids- + en Misbruikteam en is niet meer publiek toegankelijk. + tos_violation: Als je werk verborgen is omdat het AO3's Servicevoorwaarden + (%{tos_url}) overtreedt, zal van jou verwacht worden dat je actie onderneemt + om de overtreding te corrigeren. Als je er niet in slaagt je werk inschikkelijk + te maken met de Servicevoorwaarden, kan dat ertoe leiden dat je werk verwijderd + wordt van AO3. + tos: Servicevoorwaarden + anonymous_or_unrevealed_notification: + anonymous_info: Anonieme werken worden wel weergegeven in taglijsten, maar niet + op de pagina met jouw werken. Op het werk wordt je gebruikersnaam vervangen + door “Anonymous” (Anoniem). + anonymous_unrevealed_info: De beheerders van de verzameling kunnen je werk later + onthullen maar het anoniem laten. Mensen die op jou geabonneerd zijn, zullen + niet van deze verandering op de hoogte gebracht worden. Als je werk onthuld + is, zal het wel in taglijsten weergegeven worden, maar niet op de pagina met + jouw werken. Op het werk zal je gebruikersnaam vervangen worden door “Anonymous” + (Anoniem). + changed_status: + anonymous: + html: De beheerders van de verzameling %{collection_link} hebben de status + van je werk %{work_link} veranderd naar anoniem. + text: De beheerders van de verzameling "%{collection_title}" (%{collection_url}) + hebben de status van je werk "%{work_title}" (%{work_url}) veranderd naar + anoniem. + anonymous_unrevealed: + html: De beheerders van de verzameling %{collection_link} hebben de status + van je werk %{work_link} veranderd naar anoniem en nog niet onthuld. + text: De beheerders van de verzameling "%{collection_title}" (%{collection_url}) + hebben de status van je werk "%{work_title}" (%{work_url}) veranderd naar + anoniem en nog niet onthuld. + unrevealed: + html: De beheerders van de verzameling %{collection_link} hebben de status + van je werk %{work_link} veranderd naar nog niet onthuld. + text: De beheerders van de verzameling "%{collection_title}" (%{collection_url}) + hebben de status van je werk "%{work_title}" (%{work_url}) veranderd naar + nog niet onthuld. + collection_items_link_text: Approved Collection Items (Goedgekeurde Verzamelde + Werken) pagina + do_not_want: + anonymous: + html: Als je niet wilt dat je werk anoniem wordt, ga dan naar je %{collection_items_link} + om het uit deze verzameling te verwijderen. + text: 'Als je niet wilt dat je werk anoniem gemaakt wordt, ga dan naar je + Approved Collection Items (Goedgekeurde Verzamelde Werken) pagina om het + uit deze verzameling te verwijderen: %{collection_items_url}' + anonymous_unrevealed: + html: Als je niet wilt dat je werk anoniem en niet onthuld blijft, ga dan + naar je %{collection_items_link} om het uit deze verzameling te verwijderen. + text: 'Als je niet wilt dat je werk anoniem gemaakt en niet onthuld blijft, + ga dan naar je Approved Collection Items (Goedgekeurde Verzamelde Werken) + pagina om het uit deze verzameling te verwijderen: %{collection_items_url}' + unrevealed: + html: Als je niet wilt dat je werk niet onthuld blijft, ga dan naar je %{collection_items_link} + om het uit deze verzameling te verwijderen. + text: 'Als je niet wilt dat je werk niet onthuld blijft, ga dan naar je + Approved Collection Items (Goedgekeurde Verzamelde Werken) pagina om het + uit deze verzameling te verwijderen: %{collection_items_url}' + faq_link_text: Verzamelingen FAQ + more_info: + html: Voor meer informatie, ga naar onze %{faq_link}. + text: 'Voor meer informatie, ga naar onze Verzamelingen FAQ: %{faq_url}' + subject: + anonymous: "[%{app_name}] Jouw werk werd anoniem gemaakt" + anonymous_unrevealed: "[%{app_name}] Je werk werd anoniem gemaakt en nog niet + onthuld" + unrevealed: "[%{app_name}] Jouw werk werd gemarkeerd als nog niet onthuld" + unrevealed_info: Nog niet onthulde werken worden niet weergegeven in taglijsten + of op de pagina met jouw werken. Iedereen die een link naar het werk volgt, + krijgt een waarschuwing dat het momenteel nog niet onthuld is en dat het niet + mogelijk is om de inhoud te bereiken. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Toegestane collectie-items) + pagina + archivist_notice: Omdat de beheerders van de collectie in hun officiële capaciteit + als Open Doors (Open Deuren) archiefbeheerders handelen, is het hen toegestaan + jouw werk aan deze collectie toe te voegen, ook al heb je collectie uitnodigingen + uitstaan. Archiefbeheerders zullen enkel werken aan een collectie toevoegen + als het op een geïmporteerd archief gehost was. + removal_instructions: + html: Als je jouw werk uit deze collectie wil verwijderen, bezoek dan jouw + %{approved_items_link}. + text: 'Als je jouw werk uit deze collectie wil verwijderen, bezoek dan jouw + Approved Collection Items (Toegestane collectie-items) pagina: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Een Open Doors (Open Deuren) archiefbeheerder + heeft je werk toegevoegd aan een collectie" + work_added: + html: De beheerders van de collectie %{collection_link} hebben jouw werk %{work_link} + toegevoegd aan hun collectie! + text: De beheerders van de collectie "%{collection_title}" (%{collection_url}) + hebben jouw werk "%{work_title}" (%{work_url}) toegevoegd aan hun collectie! + challenge_assignment_notification: + any: Vrije keuze + assignment: + html: Het volgende verzoek wordt aan jou toegewezen in de %{link} uitdaging + op AO3! + description: 'Beschrijving:' + due: 'Deze taak moet klaar zijn op:' + html: + footer: Je krijgt deze e-mail omdat je deelneemt aan de %{title} uitdaging. + Voor meer informatie over deze uitdaging en de contactinfo van de moderators, + ga naar %{footer_link}. + footer_link: de profielpagina van de uitdaging + look_up: Je kan deze taak opzoeken vanaf %{link}. + look_up_link: jouw Assignments (Taken) pagina + optional_tags: 'Optionele tags:' + prompts: 'Prompts:' + prompt_url: 'Prompt URL:' + recipient: 'Ontvanger:' + recipient_missing: 'Geen: vraag hulp aan een moderator!' + subject: "[%{app_name}][%{collection_title}] Jouw taak!" + text: + assignment: Het volgende verzoek wordt aan jou toegewezen in de "%{collection_title}" + uitdaging (%{collection_url}) op AO3! + footer: Je krijgt deze e-mail omdat je deelneemt aan de %{title} uitdaging + (%{url}). Voor meer informatie over deze uitdaging en de contactinfo van + de moderators, ga naar %{profile_url}. + look_up: Je kan deze taak opzoeken vanaf je Assignments (Taken) pagina via + %{link}. + change_email: + changed: + html: "%{login}, het e-mailadres van je account werd gewijzigd naar %{email}" + text: "%{login}, het e-mailadres van je account werd gewijzigd naar %{email}" + subject: "[%{app_name}] E-mailadres gewijzigd" + claim_notification: + access: + contact_support: neem contact op met AO3 Support + html: Afhankelijk van het archief werden je werken misschien geïmporteerd + met de toegang beperkt tot gebruikers met een account (zodat ze niet op + Google verschijnen). Als dit het geval is, hebben alleen ingelogde gebruikers + toegang tot je werken, tenzij je ervoor kiest ze volledig zichtbaar te maken. + Voor hulp bij het vrijgeven, verlaten of verwijderen van je werken, %{contact_support_link}. + text: Afhankelijk van het archief werden je werken misschien geïmporteerd + met de toegang beperkt tot gebruikers met een account (zodat ze niet op + Google verschijnen). Als dit het geval is, hebben alleen ingelogde gebruikers + toegang tot je werken, tenzij je ervoor kiest ze volledig zichtbaar te maken. + Voor hulp bij het vrijgeven, verlaten of verwijderen van je werken, neem + contact op met Support via %{support_url}. + email_tips: Wanneer je contact met ons opneemt, voeg dan e-mailadressen van + @transformativeworks.org toe aan je lijst met veilige afzenders en controleer + of ons antwoord in je ongewenste e-mail zit. + introduction: + ao3_name: Archive of Our Own – AO3 (Ons Eigen Archief) + html: Je ontvangt deze e-mail omdat je werken had in een fanwerkarchief dat + nu geïmporteerd is door %{open_doors_name_link} naar %{app_link}. Omdat + dit e-mailadres bij een account hoort dat geregistreerd stond bij het geïmporteerde + archief, zijn de bijbehorende fanwerken (zie hieronder) automatisch toegevoegd + aan je AO3-account. + open_doors_name: Open Doors (Open Deuren) + text: 'Je ontvangt deze e-mail omdat je werken had in een archief dat geïmporteerd + is door Open Doors (Open Deuren) (%{open_doors_url}) naar Archive of Our + Own – AO3 (Ons Eigen Archief): %{app_url}. Omdat dit e-mailadres bij een + account hoort dat geregistreerd stond bij het geïmporteerde archief, zijn + de bijbehorende fanwerken (zie hieronder) automatisch toegevoegd aan je + AO3-account.' + mistake: + contact_open_doors: Neem contact op met Open Deuren + html: Als dit een fout is en deze werken niet van jou zijn, verwijder ze dan + niet! %{contact_open_doors_link} en we lossen het op. + text: Als dit een fout is en deze werken niet van jou zijn, verwijder ze dan + niet! Neem contact op met Open Deuren (%{open_doors_url}) en we lossen het + op. + more_info: + ao3_news: AO3 Nieuws + contact_support: neem dan contact op met AO3 Support + faq_page: veelgestelde vragen + html: Je kan aankondigen over recent verhuisde archieven lezen op %{ao3_news_link} + en extra informatie is te vinden bij de %{faq_page_link} en %{tutorial_page_link} + van Open Deuren. Als je vragen hebt die niet in de veelgestelde vragen, + tutorials of deze e-mail beantwoord worden, %{contact_support_link}. + text: Je kan aankondigen over recent verhuisde archieven lezen op AO3 Nieuws + (%{news_url}) en extra informatie is te vinden bij de veelgestelde vragen + (%{open_doors_faq_url}) en tutorials (%{open_doors_tutorial_url}) van Open + Deuren. Als je vragen hebt die niet in de veelgestelde vragen, tutorials + of deze e-mail beantwoord worden, neem dan contact op met Support via %{support_url}. + tutorial_page: tutorials + other_works: + contact_open_doors: neem dan contact op met Open Deuren + html: Als je andere werken op het geïmporteerde archief had onder een e-mailadres + waar je niet meer bij kan, %{contact_open_doors_link} met details die jouw + identiteit kunnen bewijzen. + text: Als je andere werken op het geïmporteerde archief had onder een e-mailadres + waar je niet meer bij kan, neem dan contact op met Open Deuren met details + die jouw identiteit kunnen bewijzen. + questions: + contact_support: neem contact op met AO3 Support + html: Voor andere vragen, %{contact_support_link}. + text: Voor andere vragen, neem contact op met AO3 Support via %{support_url}. + redirects: + html: Om lijsten met aanbevelingen en bladwijzers te bewaren kunnen de webadressen + van het geïmporteerde archief tijdelijk omgeleid worden naar de geïmporteerde + kopie van deze werken (zie de aankondiging voor jouw archief om dit te checken). + Als je zelf al een kopie van deze werken hebt geüpload en je hebt de functie + om te importeren vanaf een URL %{negation} gebruikt, zullen er twee kopieën + van hetzelfde werk op AO3 staan. + subject: "[%{app_name}] Werken geüpload" + update_redirect: + contact_open_doors: neem contact op met Open Deuren + html: Als je wil dat Open Deuren de omleiding updatet zodat hij naar jouw + bestaande werk leidt, verwijder dan de geïmporteerde kopie en %{contact_open_doors_link} + met je AO3-accountnaam, je accountnaam op het geïmporteerde archief en de + titel en URL van het fanwerk waar je naar wil laten omleiden. (Als je meerdere + werken hebt waarvan je de omleiding wil laten wijzigen, kan je deze allemaal + in dezelfde e-mail noemen.) + text: Als je wil dat Open Deuren de omleiding updatet zodat hij naar jouw + bestaande werk leidt, verwijder dan de geïmporteerde kopie en neem contact + op met Open Deuren via %{open_doors_url} met je AO3-accountnaam, je accountnaam + op het geïmporteerde archief en de titel en URL van het fanwerk waar je + naar wil laten omleiden. (Als je meerdere werken hebt waarvan je de omleiding + wil laten wijzigen, kan je deze allemaal in dezelfde e-mail noemen.) + works_by: 'Deze werken werden geschreven door de persoon met het e-mailadres: + %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Alle taken zijn verstuurd. + subject: Taken verstuurd + html: + received_message: 'Je hebt een bericht ontvangen over je collectie %{collection_link}:' + text: + received_message: 'Je hebt een bericht ontvangen over je collectie "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Als medeproducent van een werk, kan je worden toegevoegd aan nieuwe + hoofdstukken ongeacht je instellingen. Je zal ook worden toegevoegd aan series + waaraan het werk wordt toegevoegd. + html: + creation: "%{creation_link} door %{pseud_links}" + edit_chapter: het hoofdstuk bewerken + edit_series: de serie bewerken + remove_chapter: Als je per ongeluk werd toegevoegd of niet als producent wil + bekend staan, dan kan je %{edit_chapter_link} om jezelf te verwijderen als + producent. + remove_series: Als je per ongeluk werd toegevoegd of niet als producent wil + bekend staan, dan kan je %{edit_series_link} om jezelf te verwijderen als + producent. + intro_chapter: 'De gebruiker %{adding_user} heeft je pseudoniem %{pseud} vastgelegd + als een medeproducent van het volgende hoofdstuk:' + intro_series: 'De gebruiker %{adding_user} heeft je pseudoniem %{pseud} vastgelegd + als een medeproducent van de volgende serie:' + subject: "[%{app_name}] Medeproducent Notificatie" + text: + creation: "%{title} (%{url}) door %{pseuds}" + remove_chapter: 'Als je per ongeluk werd toegevoegd of niet als producent + bekend wil staan, dan kan je het hoofdstuk aanpassen om jezelf te verwijderen + als producent: %{url}' + remove_series: 'Als je per ongeluk werd toegevoegd of niet als producent wil + bekend staan, dan kan je de serie bewerken om jezelf te verwijderen als + producent: %{url}' + creatorship_notification_archivist: + explanation: Omdat ze handelen in hun officiële capaciteit als Open Deuren archiefbeheerder, + zijn ze gemachtigd om je zonder verzoek toe te voegen, zelfs als je medeproductie + hebt uitgeschakeld. + html: + creation: "%{creation_link} door %{pseud_links}" + edit_chapter: het hoofdstuk bewerken + edit_series: de serie bewerken + edit_work: het werk bewerken + remove_chapter: Als je per ongeluk werd toegevoegd of als je niet als producent + bekend wilt staan, dan kan je %{edit_chapter_link} om jezelf te verwijderen + als producent. + remove_series: Als je per ongeluk werd toegevoegd of als je niet als producent + bekend wilt staan, dan kan je %{edit_series_link} om jezelf te verwijderen + als producent. + remove_work: Als je per ongeluk werd toegevoegd of als je niet als producent + bekend wilt staan, dan kan je %{edit_work_link} om jezelf te verwijderen + als producent. + intro_chapter: 'De gebruiker %{archivist} heeft jouw pseudoniem %{pseud} als + medeproducent toegevoegd aan het volgende hoofdstuk:' + intro_series: 'De gebruiker %{archivist} heeft jouw pseudoniem %{pseud} als + medeproducent toegevoegd aan de volgende serie:' + intro_work: 'De gebruiker %{archivist} heeft jouw pseudoniem %{pseud} als medeproducent + toegevoegd aan het volgende werk:' + subject: "[%{app_name}] Archiefbeheerder medeproducent notificatie" + text: + creation: "%{title} (%{url}) door %{pseuds}" + remove_chapter: 'Als je per ongeluk werd toegevoegd of als je niet als producent + bekend wilt staan, dan kan je het hoofdstuk bewerken om jezelf te verwijderen + als producent: %{url}' + remove_series: 'Als je per ongeluk werd toegevoegd of als je niet als producent + bekend wilt staan, dan kan je de serie bewerken om jezelf te verwijderen + als producent: %{url}' + remove_work: 'Als je per ongeluk werd toegevoegd of als je niet als producent + bekend wilt staan, dan kan je het werk bewerken om jezelf te verwijderen + als producent: %{url}' + creatorship_request: + html: + creation: "%{creation_link} door %{pseud_links}" + instructions: Je kan dit verzoek aanvaarden of weigeren op je %{page_name} + pagina. + page_name: Co-Creator Requests (Medeproducent aanvragen) + intro_chapter: 'De gebruiker %{inviting_user} heeft jouw pseudoniem %{pseud} + uitgenodigd om als medeproducent vermeld te worden op het volgende hoofdstuk:' + intro_series: 'De gebruiker %{inviting_user} heeft jouw pseudoniem %{pseud} + uitgenodigd om als medeproducent vermeld te worden op de volgende serie:' + intro_work: 'De gebruiker %{inviting_user} heeft jouw pseudoniem %{pseud} uitgenodigd + om als medeproducent vermeld te worden op het volgende werk:' + subject: "[%{app_name}] Medeproducent aanvraag" + text: + creation: "%{title} (%{url}) door %{pseuds}" + instructions: 'Je kan dit verzoek aanvaarden of weigeren op je Co-Creator + Requests (Medeproducent aanvragen) pagina: %{url}' + delete_work_notification: + attachment: Een kopie van je werk is voor jou bijgevoegd. + deleted_other: + html: Je werk %{title} is op verzoek van %{pseud} verwijderd. + text: Je werk "%{title}" is op verzoek van %{pseud} verwijderd. + deleted_yourself: + html: Je werk %{title} is op jouw verzoek verwijderd. + text: Je werk "%{title}" is op jouw verzoek verwijderd. + questions: + html: Als je vragen hebt, %{support}. + text: Als je vragen hebt, %{support} (%{url}). + subject: "[%{app_name}] Je werk is verwijderd" + support: neem dan contact op met Support + invite_increase_notification: + html: + body: + one: We willen je laten weten dat je een nieuwe uitnodiging hebt, waarmee + een AO3-account kan aangemaakt worden. Je kan een vriend uitnodigen via + %{invitation_page_link}. + other: We willen je laten weten dat je %{count} nieuwe uitnodigingen hebt, + waarmee AO3-accounts kunnen aangemaakt worden. Je kan een vriend uitnodigen + via %{invitation_page_link}. + invitation_page_link_text: je Invitations (Uitnodigingen) pagina + subject: "[%{app_name}] Nieuwe Uitnodigingen" + text: + body: + one: We willen je laten weten dat je een nieuwe uitnodiging hebt, waarmee + een AO3-account kan aangemaakt worden. Je kan een vriend uitnodigen via + %{invitation_page_url}. + other: We willen je laten weten dat je %{count} nieuwe uitnodigingen hebt, + waarmee AO3-accounts kunnen aangemaakt worden. Je kan een vriend uitnodigen + via %{invitation_page_url}. + invite_request_declined: + main: + one: Jammer genoeg kunnen we je verzoek voor een nieuwe uitnodiging op dit + moment niet goedkeuren. + other: Jammer genoeg kunnen we je verzoek voor %{count} nieuwe uitnodigingen + op dit moment niet goedkeuren. + reason: 'Je verzoek was:' + subject: "[%{app_name}] Verzoek uitnodigingscode geweigerd" + recipient_notification: + html: + collection: Iemand heeft je een werk cadeau gedaan in de %{collection_link} + collectie op AO3! + no_collection: Iemand heeft je een werk cadeau gedaan op AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Een werk voor jou in %{collection_title}" + no_collection: "[%{app_name}] Een werk voor jou" + text: + collection: Iemand heeft je een werk cadeau gedaan in de "%{collection_title}" + collectie (%{collection_url}) op AO3! + signup_notification: + activate: + html: "%{activate_account_link}." + text: 'Volg deze link om je account te activeren: %{activate_account_url}' + activate_your_account: volg deze link om je account te activeren + admin_posts: AO3 Nieuws + bye: We hopen dat je veel plezier gaat beleven aan AO3. + contact_support: contacteer het Support team + faq: FAQ + features: + html: Als je account is geactiveerd, kun je je eigen werken plaatsen, je via + e-mail abonneren op je favoriete producenten en werken zodat je weet wanneer + deze updaten, aanpassen hoe de website eruit ziet en functioneert, bijhouden + welke werken je hebt bezocht op AO3 via je geschiedenis, en nog veel meer. + text: Als je account is geactiveerd, kun je je eigen werken plaatsen, je via + e-mail abonneren op je favoriete producenten en werken zodat je weet wanneer + deze updaten, aanpassen hoe de website eruit ziet en functioneert, bijhouden + welke werken je hebt bezocht op AO3 via je geschiedenis, en nog veel meer. + information: + html: Er is veel informatie en advies over hoe je AO3 kunt gebruiken in onze + %{faq_link}. Het laatste nieuws over site-ontwikkeling vind je in ons %{admin_posts_link}. + Als je meer hulp nodig hebt, een probleem tegenkomt of vragen of opmerkingen + hebt, %{contact_support_link} en we helpen je graag verder. + text: 'Er is veel informatie en advies over hoe je AO3 kunt gebruiken in onze + FAQ via %{faq_url}. Het laatste nieuws over site-ontwikkeling vind je in + ons AO3 Nieuws via %{admin_posts_url}. Als je meer hulp nodig hebt, een + probleem tegenkomt of vragen of opmerkingen hebt, contacteer dan ons Support + team dat je altijd graag verder helpt: %{contact_support_url}.' + welcome: Welkom bij AO3, %{login}! diff --git a/config/locales/phrase-exports/pl.yml b/config/locales/phrase-exports/pl.yml new file mode 100755 index 0000000..8f893ba --- /dev/null +++ b/config/locales/phrase-exports/pl.yml @@ -0,0 +1,554 @@ +--- +pl: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Ostrzeżenia:' + many: 'Ostrzeżenia:' + one: 'Ostrzeżenie:' + category: + name_with_colon: + few: 'Kategorie:' + many: 'Kategorie:' + one: 'Kategoria:' + character: + name_with_colon: + few: 'Postacie:' + many: 'Postacie:' + one: 'Postać:' + fandom: + name_with_colon: + few: 'Fandomy:' + many: 'Fandomy:' + one: 'Fandom:' + freeform: + name_with_colon: + few: 'Tagi dodatkowe:' + many: 'Tagi dodatkowe:' + one: 'Tag dodatkowy:' + rating: + name_with_colon: 'Kategoria wiekowa:' + relationship: + name_with_colon: + few: 'Związki:' + many: 'Związki:' + one: 'Związek:' + work: + chapter_total_display: Rozdziały + summary: Streszczenie + models: + archive_warning: + few: Ostrzeżenia + many: Ostrzeżenia + one: Ostrzeżenie + category: + few: Kategorie + many: Kategorie + one: Kategoria + chapter: + few: Rozdziały + many: Rozdziały + one: Rozdział + character: + few: Postacie + many: Postacie + one: Postać + fandom: + few: Fandomy + many: Fandomy + one: Fandom + freeform: + few: Tagi dodatkowe + many: Tagi dodatkowe + one: Tag dodatkowy + rating: + few: Kategorie wiekowe + many: Kategorie wiekowe + one: Kategoria wiekowa + relationship: + few: Związki + many: Związki + one: Związek + series: + few: Serie + many: Serie + one: Seria + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} gości" + many: "%{count} gości" + one: 1 gościa + other: "%{count} gości" + left_kudos: + html: + few: Kudos dla %{commentable_link} od %{givers_list}. + many: Kudos dla %{commentable_link} od %{givers_list}. + one: Kudos dla %{commentable_link} od %{givers_list}. + text: + few: Kudos dla %{commentable_title} (%{commentable_url}) od %{givers_list}. + many: Kudos dla %{commentable_title} (%{commentable_url}) od %{givers_list}. + one: Kudos dla %{commentable_title} (%{commentable_url}) od %{givers_list}. + single_guest: + giver: 1 gościa + html: Kudos dla %{commentable_link} od %{giver}. + text: Kudos dla %{commentable_title} (%{commentable_url}) od 1 gościa. + subject: "[%{app_name}] Masz kudos!" + mailer: + general: + closing: + formal: Z wyrazami szacunku, + informal: Pozdrawiamy, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Rozdział %{position} pracy %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} słowa" + many: "%{count} słów" + one: "%{count} słowo" + footer: + general: + about: + html: AO3 jest prowadzonym i wspieranym przez fanów archiwum, które działa + dzięki %{donate_link}. + text: 'AO3 jest prowadzonym i wspieranym przez fanów archiwum, które działa + dzięki Waszym darowiznom: %{donate_url}.' + html: + donate_link_text: Waszym darowiznom + support_link_text: kontakt ze Wsparciem + unwanted_email: + html: Jeśli ta wiadomość została wysłana do Ciebie przez pomyłkę, prosimy + o %{support_link}. + text: Jeśli ta wiadomość została wysłana do Ciebie przez pomyłkę, prosimy + o kontakt ze Wsparciem poprzez %{support_url}. + sent_at: Wysłano w %{sent_at}. + greeting: + formal_html: Szanowna/y %{name}, + informal: + addressed_html: Cześć, %{name}! + unaddressed: Cześć! + introductory: Pozdrowienia z Archive of Our Own – AO3 (Naszego Własnego Archiwum)! + metadata_label_indicator: ":" + signature: + abuse_team: Zespół Zasad i Nadużyć AO3 + app_short_name: AO3 + open_doors: Zespół Open Doors (Drzwi Otwartych) + parent_org: Organization for Transformative Works – OTW (Organizacja na rzecz + Twórczości Przeobrażonej) + support: Zespół Wsparcia AO3 + users: + mailer: + reset_password_instructions: + expiration: Jeżeli w ciągu tygodnia nie wykorzystasz tego linku do zresetowania + hasła, straci on swoją ważność i konieczne będzie wygenerowanie nowego. + intro: 'Ktoś zażądał zmiany hasła do Twojego konta. Możesz ustawić nowe zabezpieczenie + dla swojego konta, przechodząc w poniższe łącze i wprowadzając nowe hasło:' + link_title: Zmień moje hasło. + subject: "[%{app_name}] Zmień swoje hasło" + unrequested: Jeśli nie prosiłaś/eś o zmianę hasła, możesz zignorować tę wiadomość, + a Twoje dotychczasowe hasło nadal będzie funkcjonować. + user_mailer: + admin_deleted_work_notification: + bye: Dołączamy kopię Twojej pracy, abyś mogła/mógł się do niej odnieść. + contact_abuse: skontaktuj się z naszą Komisją ds. Zasad i Nadużyć + deleted: + html: Twoja praca %{title} została usunięta z Archiwum przez administratora + strony. + text: Twoja praca "%{title}" została usunięta z Archiwum przez administratora + strony. + html: + tos_violation: Jeśli podejrzewasz, że Twoja twórczość mogła złamać Regulamin + Serwisu AO3, prosimy, %{contact_abuse_link}. + import_project: + html: Jeśli Twoja praca była częścią projektu importu zarządzanego przez naszą + grupę Open Doors (Drzwi Otwartych), prosimy o %{opendoors_link} w razie + dalszych pytań. + text: Jeśli Twoja praca była częścią projektu importu zarządzanego przez naszą + grupę Drzwi Otwartych, prosimy o skontaktowanie się z Drzwiami Otwartymi + (%{opendoors_link}) w razie dalszych pytań. + opendoors: skontaktowanie się z Drzwiami Otwartymi + subject: "[%{app_name}] Twoja praca została usunięta przez administratora" + text: + tos_violation: Jeśli podejrzewasz, że Twoja twórczość mogła złamać Regulamin + Serwisu AO3, prosimy, skontaktuj się z naszą Komisją ds. Zasad i Nadużyć + (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Gdy twoja praca jest ukryta, nadal masz do niej dostęp poprzez link + podany wyżej, ale nie jest ona wymieniona na liście Twoich prac, ani nie jest + dostępna dla innych użytkowników AO3. + check_email: Prosimy, sprawdź swojego maila, w tym folder spam, gdyż zespół + Zasad i Nadużyć mógł już się z Tobą skontaktować, aby wyjaśnić, dlaczego Twoja + praca została ukryta. + contact_abuse: kontakt z Zasadami i Nadużyciami + html: + help: Jeśli nie masz pewności, dlaczego Twoja praca została ukryta i nie dotarła + do Ciebie dalsza korespondencja w tej sprawie, prosimy o bezpośredni %{contact_abuse_link}. + hidden: Twoja praca %{title} została ukryta przez zespół Zasad i Nadużyć i + nie jest już publicznie dostępna. + tos_violation: Jeśli Twoja praca została ukryta z powodu naruszenia %{tos_link} + AO3, musisz podjąć kroki, aby skorygować naruszenie. Nieskorygowana niezgodność + z Regulaminem Serwisu może doprowadzić do usunięcia Twojej pracy z AO3. + subject: "[%{app_name}] Twoja praca została ukryta przez zespół Zasad i Nadużyć." + text: + help: 'Jeśli nie masz pewności, dlaczego Twoja praca została ukryta i nie + dotarła do Ciebie dalsza korespondencja w tej sprawie, prosimy o bezpośredni + kontakt z Zasadami i Nadużyciami: %{contact_abuse_url}.' + hidden: Twoja praca "%{title}" (%{work_url}) została ukryta przez zespół Zasad + i Nadużyć i nie jest już publicznie dostępna. + tos_violation: Jeśli Twoja praca została ukryta z powodu naruszenia Regulaminu + Serwisu AO3 (%{tos_url}), musisz podjąć kroki, aby skorygować naruszenie. + Nieskorygowana niezgodność z Regulaminem Serwisu może doprowadzić do usunięcia + Twojej pracy z AO3. + tos: Regulaminu Serwisu + anonymous_or_unrevealed_notification: + anonymous_info: Prace anonimowe pojawiają się w wynikach wyszukiwania tagów, + ale nie na stronie z Twoimi pracami. Twoja nazwa użytkownika przy pracy zostanie + zastąpiona przez "Anonymous" (Anonimowe). + anonymous_unrevealed_info: Opiekunowie kolekcji mogą później ujawnić Twoją pracę, + nadal pozostawiając ją anonimową. Twoi subskrybenci nie zostaną powiadomieni + o tej zmianie. Po ujawnieniu, Twoja praca pojawi się w wynikach wyszukiwania + tagów, ale nie na stronie Twoich prac. Na pracy, Twoja nazwa użytkownika zostanie + zamieniona na "Anonymous" (Anonimowe). + changed_status: + anonymous: + html: Opiekunowie kolekcji %{collection_link} zmienili status Twojej pracy + %{work_link} na pracę anonimową. + text: Opiekunowie kolekcji "%{collection_title}" (%{collection_url}) zmienili + status Twojej pracy "%{work_title}" (%{work_url}) na anonimową. + anonymous_unrevealed: + html: Opiekunowie kolekcji %{collection_link} zmienili status Twojej pracy + %{work_link} na anonimową i nieujawnioną. + text: Opiekunowie kolekcji "%{collection_title}" (%{collection_url}) zmienili + status Twojej pracy "%{work_title}" (%{work_url}) na anonimową i nieujawnioną. + unrevealed: + html: Opiekunowie kolekcji %{collection_link} zmienili status Twojej pracy + %{work_link} na pracę nieujawnioną. + text: Opiekunowie kolekcji "%{collection_title}" (%{collection_url}) zmienili + status Twojej pracy "%{work_title}" (%{work_url}) na nieujawnioną. + collection_items_link_text: strony Approved Collection Items (Zatwierdzonych + Elementów Kolekcji) + do_not_want: + anonymous: + html: Jeżeli nie chcesz, aby Twoja praca była anonimowa, prosimy o odwiedzenie + Twojej %{collection_items_link} w celu usunięcia pracy z kolekcji. + text: 'Jeżeli nie chcesz, żeby Twoja praca była anonimowa, prosimy przejdź + do Twojej strony Approved Collection Items (Zatwierdzonych Elementów Kolekcji), + by usunąć ją z tej kolekcji: %{collection_items_url}' + anonymous_unrevealed: + html: Jeżeli nie chcesz, żeby Twoja praca była anonimowa i nieujawniona, + prosimy przejdź do Twojej %{collection_items_link}, by usunąć ją z tej + kolekcji. + text: 'Jeżeli nie chcesz, żeby Twoja praca była anonimowa i nieujawniona, + prosimy przejdź do Twojej strony Approved Collection Items Zatwierdzonych + Elementów Kolekcji), by usunąć ją z tej kolekcji: %{collection_items_url}' + unrevealed: + html: Jeżeli nie chcesz, aby Twoja praca była nieujawniona, prosimy o odwiedzenie + Twojej %{collection_items_link} w celu usunięcia pracy z kolekcji. + text: 'Jeżeli nie chcesz, żeby Twoja praca była nieujawniona, prosimy przejdź + do Twojej strony Approved Collection Items (Zatwierdzonych Elementów Kolekcji), + by usunąć ją z tej kolekcji: %{collection_items_url}' + faq_link_text: FAQ Kolekcji + more_info: + html: Aby uzyskać więcej informacji, odwiedź nasze %{faq_link}. + text: 'Aby uzyskać więcej informacji, odwiedź nasze FAQ Kolekcji: %{faq_url}' + subject: + anonymous: "[%{app_name}] Twoja praca stała się anonimową" + anonymous_unrevealed: "[%{app_name}] Twoja praca stała się anonimową i nieujawnioną" + unrevealed: "[%{app_name}] Twoja praca stała się nieujawnioną" + unrevealed_info: Nieujawnione prace nie pojawiają się w wynikach wyszukiwania + tagów ani na stronie Twoich prac. Każdy, kto wejdzie w link do pracy, otrzyma + wiadomość, że praca jest aktualnie nieujawniona, i nie będzie w stanie uzyskać + dostępu do jej treści. + archivist_added_to_collection_notification: + approved_collection_items_page: stronę Approved Collection Items (Zaakceptowanych + Elementów Kolekcji) + archivist_notice: Ponieważ zarządzający kolekcją działają w zakresie swoich + oficjalnych uprawnień jako archiwiści Open Doors (Drzwi Otwartych), mogą oni + dodać Twoją pracę do swojej kolekcji, nawet jeśli Twoje ustawienia nie zezwalają + na zaproszenia do kolekcji. Archiwiści dodadzą Twoją pracę do kolekcji wyłącznie + jeśli była ona umieszczona na importowanym archiwum. + removal_instructions: + html: Jeśli chcesz usunąć swoją pracę z tej kolekcji, prosimy odwiedź swoją + %{approved_items_link}. + text: 'Jeśli chcesz usunąć swoją pracę z tej kolekcji, prosimy odwiedź swoją + stronę Approved Collection Items (Zaakceptowanych Elementów Kolekcji): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Archiwista Open Doors (Drzwi Otwartych) + dołączył Twoją pracę do kolekcji" + work_added: + html: Osoby zarządzające kolekcją %{collection_link} dołączyły Twoją pracę + %{work_link} do swojej kolekcji! + text: Osoby zarządzające kolekcją "%{collection_title}" (%{collection_url}) + dołączyły Twoją pracę "%{work_title}" (%{work_url}) do swojej kolekcji! + challenge_assignment_notification: + any: Pełna dowolność + assignment: + html: Przypisane zostało Ci następujące zadanie w wyzwaniu %{link} na Naszym + Własnym Archiwum! + description: 'Opis:' + due: 'To zadanie należy wykonać do:' + html: + footer: Otrzymałaś/eś ten e-mail ponieważ zapisałaś/eś się do wyzwania %{title}. + Aby dowiedzieć się więcej na temat tego wyzwania i by móc skontaktować się + z moderatorami, proszę przejdź do %{footer_link}. + footer_link: strony profilowej wyzwania + look_up: Możesz sprawdzić swoje zadanie na %{link}. + look_up_link: Twojej stronie Assignments (Zadań) + optional_tags: 'Opcjonalne Tagi:' + prompts: 'Prompty:' + prompt_url: 'URL promptu:' + recipient: 'Odbiorca:' + recipient_missing: 'Brak: skontaktuj się z moderatorem aby uzyskać pomoc!' + subject: "[%{app_name}][%{collection_title}] Twoje Zadanie!" + text: + assignment: Przypisane zostało Ci następujące zadanie w "%{collection_title}" + wyzwaniu (%{collection_url}) na Naszym Własnym Archiwum! + footer: Otrzymałaś/eś ten e-mail ponieważ zapisałaś/eś się do wyzwania %{title} + (%{url}). Aby dowiedzieć się więcej na temat tego wyzwania i by móc skontaktować + się z moderatorami, proszę przejdź do %{profile_url}. + look_up: Możesz sprawdzić to zadanie na Twojej stronie Assignments (Zadań) + na %{link}. + change_email: + changed: + html: "%{login}, adres email powiązany z Twoim kontem został zmieniony na + %{email}" + text: "%{login}, adres email powiązany z Twoim kontem został zmieniony na + %{email}" + subject: "[%{app_name}] Email został zmieniony" + collection_notification: + assignments_sent: + complete: Wszystkie zadania zostały wysłane. + subject: Wysłane zadania + html: + received_message: 'Masz nową wiadomość dotyczącą Twojej kolekcji %{collection_link}:' + text: + received_message: 'Masz nową wiadomość dotyczącą Twojej kolekcji "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Gdy jesteś współtwórcą pracy, możesz zostać dodana/y do nowych + rozdziałów bez względu na Twoje ustawienia współtworzenia. Będziesz również + dodana/y do wszelkich serii, do których należy praca. + html: + creation: "%{creation_link} autorstwa %{pseud_links}" + edit_chapter: edytować rozdział + edit_series: edytować serię + remove_chapter: Jeśli dodano cię przez pomyłkę lub nie chcesz widnieć jako + współtwórca, możesz %{edit_chapter_link}, by usunąć siebie jako twórcę. + remove_series: Jeśli dodano cię przez pomyłkę lub nie chcesz widnieć jako + współtwórca, możesz %{edit_series_link}, by usunąć siebie jako twórcę. + intro_chapter: 'Użytkownik %{adding_user} dodał Twój pseudonim %{pseud} jako + współtwórcę następującego rozdziału:' + intro_series: 'Użytkownik %{adding_user} dodał Twój pseudonim %{pseud} jako + współtwórcę następującej serii:' + subject: "[%{app_name}] Powiadomienie o Współautorstwie" + text: + creation: "%{title} (%{url}) autorstwa %{pseuds}" + remove_chapter: 'Jeśli dodano Cię przez pomyłkę lub nie chcesz widnieć jako + współtwórca, możesz edytować rozdział, by usunąć siebie jako twórcę: %{url}' + remove_series: 'Jeśli dodano Cię przez pomyłkę lub nie chcesz widnieć jako + współtwórca, możesz edytować serię, by usunąć siebie jako twórcę: %{url}' + creatorship_notification_archivist: + explanation: Ponieważ działa w zakresie swoich oficjalnych uprawnień archiwisty + Open Doors (Drzwi Otwartych), może dodać Cię bez wysłania do Ciebie prośby + o zgodę na to, nawet jeśli masz wyłączoną opcję współtworzenia. + html: + creation: "%{creation_link} autorstwa %{pseud_links}" + edit_chapter: edytować rozdział + edit_series: edytować serię + edit_work: edytować pracę + remove_chapter: Jeśli dodano Cię przez przypadek lub nie chcesz by wymieniano + Cię jako twórcę, możesz %{edit_chapter_link} aby usunąć siebie jako twórcę. + remove_series: Jeśli dodano Cię przez przypadek lub nie chcesz by wymieniano + Cię jako twórcę, możesz %{edit_series_link} aby usunąć siebie jako twórcę. + remove_work: Jeśli dodano Cię przez przypadek lub nie chcesz by wymieniano + Cię jako twórcę, możesz %{edit_work_link} aby usunąć siebie jako twórcę. + intro_chapter: 'Użytkownik %{archivist} dodał/a twój pseudonim %{pseud} jako + współtwórcę następującego rozdziału:' + intro_series: 'Użytkownik %{archivist} dodał Twój pseudonim %{pseud} jako współtwórcę + następującej serii:' + intro_work: 'Użytkownik %{archivist} dodał Twój pseudonim %{pseud} jako współtwórcę + poniższej pracy:' + subject: "[%{app_name}] Powiadomienie od archiwisty o współtworzeniu" + text: + creation: "%{title} (%{url}) autorstwa %{pseuds}" + remove_chapter: 'Jeśli dodano Cię przez przypadek lub nie chcesz by wymieniano + Cię jako twórcę, możesz edytować ten rozdział, aby usunąć siebie jako twórcę: + %{url}' + remove_series: 'Jeśli dodano Cię przez przypadek lub nie chcesz by wymieniano + Cię jako twórcę, możesz edytować tę serię, aby usunąć siebie jako twórcę: + %{url}' + remove_work: 'Jeśli dodano Cię przez przypadek lub nie chcesz by wymieniano + Cię jako twórcę, możesz edytować tę pracę, aby usunąć siebie jako twórcę: + %{url}' + creatorship_request: + html: + creation: "%{creation_link} autorstwa %{pseud_links}" + instructions: Możesz zaakceptować lub odrzucić tę propozycję na Twojej stronie + %{page_name}. + page_name: Co-Creator Requests (Propozycji Współtworzenia) + intro_chapter: 'Użytkownik %{inviting_user} zaprasza Twój pseudonim %{pseud} + do dołączenia do listy współtwórców poniższego rozdziału:' + intro_series: 'Użytkownik %{inviting_user} zaprasza Twój pseudonim %{pseud} + do dołączenia do listy współtwórców poniższej serii:' + intro_work: 'Użytkownik %{inviting_user} zaprasza Twój pseudonim %{pseud} do + dołączenia do listy współtwórców poniższej pracy:' + subject: "[%{app_name}] Propozycja współtworzenia" + text: + creation: "%{title} (%{url}) autorstwa %{pseuds}" + instructions: 'Możesz zaakceptować lub odrzucić tę propozycję na Twojej stronie + Co-Creator Requests (Propozycji Współtworzenia): %{url}' + delete_work_notification: + attachment: Dołączamy do wglądu kopię Twojej pracy. + deleted_other: + html: Wasza wspólna praca %{title} została usunięta na wniosek %{pseud}. + text: Wasza wspólna praca "%{title}" została usunięta na wniosek %{pseud}. + deleted_yourself: + html: Twoja praca %{title} została usunięta na Twój wniosek. + text: Twoja praca "%{title}" została usunięta na Twój wniosek. + questions: + html: Jeśli masz jakiekolwiek pytania, prosimy %{support}. + text: Jeśli masz jakiekolwiek pytania, prosimy %{support} (%{url}). + subject: "[%{app_name}] Twoja praca została usunięta" + support: skontaktuj się ze Wsparciem + invitation_to_claim: + access: + text: W zależności od archiwum, Twoje prace mogły zostać zaimportowane z ograniczeniem + dostępności wyłącznie do zarejestrowanych użytkowników (aby utrzymać je + poza zasięgiem wyszukiwania w Google). W takim wypadku prace będą osiągalne + tylko dla zalogowanych użytkowników, o ile nie zdecydujesz się uczynić je + ogólnodostępnymi. Aby uzyskać pomoc w odblokowaniu, osieroceniu bądź usunięciu + Twoich prac, prosimy skontaktuj się ze Wsparciem AO3. + claim_or_remove: + html: Tutaj przejmij lub usuń swoje prace. + text: 'Tutaj przejmij lub usuń swoje prace: %{claim_url}' + email_tips: W razie kontaktowania się z nami, prosimy o dodanie adresów mailowych + zawierających @transformativeworks.org do listy zaufanych nadawców oraz o + sprawdzenie, czy nasza odpowiedź nie znajduje się w folderze spam. + html: + ao3_news: Aktualnościach AO3 + contact_open_doors: skontaktowanie się z Drzwiami Otwartymi + contact_support: skontaktuj się ze Wsparciem AO3 + faq_page: stronie FAQ + tutorial_page: stronie samouczka + introduction: + text: Otrzymałaś/eś tego e-maila z ponieważ Drzwi Otwarte (%{open_doors_link}) + niedawno dokonały importu archiwum do %{app_name} (%{app_short_name} - + %{app_url}), i wierzymy, że poniższe prace należą do Ciebie. Chcielibyśmy + dać Ci szansę przejęcia (lub usunięcia/osierocenia) tych prac, jeśli sobie + tego zażyczysz. A jeśli nie posiadasz jeszcze konta pod innym adresem e-mail, + chcielibyśmy zaprosić Cię na pokład! + mistake: + text: Jeśli nastąpiła pomyłka i poniższe prace nie należą do Ciebie, nie usuwaj + ich! Prosimy o skontaktowanie się z Drzwiami Otwartymi (%{open_doors_link}), + a my wszystko uporządkujemy. + more_info: + text: Ogłoszenia o ostatnich działaniach możesz przeczytać w Aktualnościach + AO3 (%{news_link}), a więcej informacji znajdziesz na stronie FAQ Drzwi + Otwartych (%{open_doors_faq_link}) oraz stronach samouczka (%{open_doors_tutorial_link}). + W przypadku pytań, na które nie znalazłaś/eś odpowiedzi w FAQ, samouczku + ani tym e-mailu, prosimy skontaktuj się ze Wsparciem poprzez stronę %{support_link}. + other_works: + text: Jeśli na zaimportowanym archiwum posiadasz inne prace, przypisane do + adresu e-mail, do którego nie masz już dostępu, prosimy o skontaktowanie + się z Drzwiami Otwartymi i podanie jakichkolwiek informacji, mogących pomóc + w potwierdzeniu Twoich roszczeń. + questions: + text: W razie dalszych wątpliwości, prosimy skontaktuj się ze Wsparciem AO3 + przez stronę %{support_link}. + redirects: Aby zachować listy z rekomendacjami oraz zakładki, adres internetowy + zaimportowanego archiwum może przez jakiś czas jeszcze przekierowywać do zaimportowanej + kopii (dla pewności, sprawdź post z ogłoszeniem dotyczącym Twojego archiwum). + Jeśli już zamieściłaś/eś kopie tych prac i NIE użyłaś/eś funkcji importowania + z URL, na archiwum znajdą się dwie kopie tej samej pracy. + subject: "[%{app_name}] Zaproszenie do przejęcia prac" + unwanted: + text: Jeśli powyższe prace należą do Ciebie, ale nie chcesz ich przejąć, możesz + je osierocić (wówczas pozostaną one dostępne na AO3, lecz Twój pseudonim + zostania z nich usunięty) lub skasować (by zostały całkowicie usunięte z + AO3). Aby usunąć lub osierocić prace nie musisz dodawać ich do żadnego konta + - możesz zrobić to bezpośrednio z powyższego linku do przejęcia. (Żeby uzyskać + wsparcie, prosimy skontaktuj się ze Wsparciem poprzez stronę %{support_link}.) + update_redirect: + text: Jeśli wolisz, żeby Drzwi Otwarte zaktualizowały link przekierowujący + tak, aby prowadził do już istniejącej pracy, prosimy o usunięcie zaimportowanej + kopii i skontaktowanie się z Drzwiami Otwartymi przez stronę %{open_doors_link}, + podając nazwę swojego konta AO3, nazwę konta na importowanym archiwum, oraz + tytuł i URL pracy, do której ma prowadzić link. (Jeśli dotyczy to kilku + prac, możesz wyliczyć je wszystkie w jednej wiadomości). + uploaded_list: 'W zamieszczonych pracach znalazły się:' + invite_increase_notification: + html: + body: + few: Masz %{count} nowe zaproszenia, które mogą być użyte do stworzenia + nowych kont na AO3. Możesz zaprosić kogoś przez %{invitation_page_link}. + many: Masz %{count} nowych zaproszeń, które mogą być użyte do stworzenia + nowych kont na AO3. Możesz zaprosić kogoś przez %{invitation_page_link}. + one: Masz %{count} nowe zaproszenie, które może być użyte do stworzenia + nowego konta na AO3. Możesz zaprosić kogoś przez %{invitation_page_link}. + invitation_page_link_text: swoją stronę Invitations (Zaproszenia) + subject: "[%{app_name}] Nowe zaproszenia" + text: + body: + few: Masz %{count} nowe zaproszenia, które mogą być użyte do stworzenia + nowych kont na AO3. Możesz zaprosić kogoś przez swoją stronę Invitations + (Zaproszenia) (%{invitation_page_url}). + many: Masz %{count} nowych zaproszeń, które mogą być użyte do stworzenia + nowych kont na AO3. Możesz zaprosić kogoś przez swoją stronę Invitations + (Zaproszenia) (%{invitation_page_url}). + one: Masz %{count} nowe zaproszenie, które może być użyte do stworzenia + nowego konta na AO3. Możesz zaprosić kogoś przez swoją stronę Invitations + (Zaproszenia) (%{invitation_page_url}) . + invite_request_declined: + main: + few: Z przykrością informujemy, że Twoja prośba o %{count} nowe zaproszenia + w chwili obecnej nie może zostać zrealizowana. + many: Z przykrością informujemy, że Twoja prośba o %{count} nowych zaproszeń + w chwili obecnej nie może zostać zrealizowana. + one: Z przykrością informujemy, że Twoja prośba o nowe zaproszenie w chwili + obecnej nie może zostać zrealizowana. + reason: 'Treść Twojej prośby:' + subject: "[%{app_name}] Prośba o dodatkowe zaproszenia została odrzucona" + recipient_notification: + html: + collection: W kolekcji %{collection_link} na AO3 opublikowano pracę, będącą + prezentem dla Ciebie! + no_collection: Na AO3 opublikowano pracę, będącą prezentem dla Ciebie! + subject: + collection: "[%{app_name}][%{collection_title}] Obdarowano Cię pracą w %{collection_title}" + no_collection: "[%{app_name}] Obdarowano Cię pracą" + text: + collection: W kolekcji "%{collection_title}" (%{collection_url}) na AO3 opublikowano + pracę, będącą prezentem dla Ciebie! + signup_notification: + activate: + html: Prosimy, %{activate_account_link}. + text: 'Prosimy o aktywację konta: %{activate_account_url}' + activate_your_account: aktywuj swoje konto + admin_posts: archiwalnych postach adminów + bye: Mamy nadzieję, że jesteś zadowolona/y z Archiwum. + contact_support: skontaktuj się z naszym zespołem Wsparcia + faq: FAQ + features: + html: Kiedy twoje konto będzie już działać, możesz publikować swoje prace, + ustawić subskrypcje, by dostawać powiadomienia mailowe, kiedy twój/a ulubiony + autor/ka coś opublikuje lub ulubione prace zostaną zaktualizowane, ustawić + preferencje, by spersonalizować wygląd strony i to jak działa ona dla ciebie, + śledzić prace czytane w Archiwum za pomocą historii oraz wiele innych. + text: Kiedy twoje konto będzie już działać, możesz publikować swoje prace, + ustawić subskrybcje, by dostać powiadomienie mailowe, kiedy twój/a ulubiony + autor/ka coś opublikuje lub ulubione prace zostaną zaktualizowane, ustawić + preferencje, by spersonalizować wygląd strony i to jak działa ona dla ciebie, + śledzić prace czytane w Archiwum za pomocą historii oraz wiele innych. + information: + html: Możesz znaleźć wiele informacji i rad na temat używania Archiwum w naszym + %{faq_link}. Najnowsze wiadomości o rozwoju strony znajdziesz w naszych + %{admin_posts_link}. Jeśli potrzebujesz pomocy, natkniesz się na bugi lub + masz inne pytania lub komentarze, prosimy %{contact_support_link}, który + jest zawsze chętny do pomocy. + text: Możesz znaleźć wiele informacji i rad na temat używania Archiwum w naszym + %{faq_url}. Najnowsze wiadomości o rozwoju strony znajdziesz w naszych %{admin_posts_url}. + Jeśli potrzebujesz pomocy, natkniesz się na bugi lub masz inne pytania lub + komentarze, prosimy %{contact_support_url}, którzy są zawsze chętni do + pomocy. + welcome: Witaj w Naszym Własnym Archiwum, %{login}! diff --git a/config/locales/phrase-exports/pt-BR.yml b/config/locales/phrase-exports/pt-BR.yml new file mode 100755 index 0000000..1fc1612 --- /dev/null +++ b/config/locales/phrase-exports/pt-BR.yml @@ -0,0 +1,1197 @@ +--- +pt-BR: + a11y: + navigation: Navegação + abuse_reports: + new: + form: + comment: + error: Por favor descreva o problema. + include: inclua todos os links pertinentes, bem como qualquer outra informação + que julgue relevante, em sua mensagem + label: Seu comentário (campo obrigatório) + tos: Termos de Serviço + email: + description: Não podemos agir com base em denúncias que não sejam associadas + a um endereço de e-mail válido. + label: Seu endereço de e-mail (campo obrigatório) + landmark: + send: Enviar à equipe de Diretrizes e Abuso do AO3 + language: + label: Selecione o idioma (campo obrigatório) + legend: + abuse: Link e descrição da denúncia + link: + description: Se você chegou a essa página através do link "Report Abuse" + (Denunciar abuso) no fim da página, esse campo terá sido preenchido automaticamente. + error: Por favor especifique o link da página a que sua denúncia se refere. + label: Link da página que você está denunciando (campo obrigatório) + name: + label: Seu nome (campo opcional) + submit: + active: Enviar + summary: + error: Por favor digite um breve resumo da sua mensagem + label: Breve resumo da violação dos Termos de Serviço (campo obrigatório) + heading: + page_title: Denunciar Abuso + include: + ao3: Termos de Serviço do AO3 + intro: 'O que incluir na descrição:' + languages: 'Podemos responder a denúncias nas seguintes línguas: %{list_html}.' + sources: links ou screenshots de quaisquer fontes relevantes + username: o nome da conta no AO3 da pessoa que você está denunciando + purview: + support: entre em contato com a equipe de Suporte + tos: Termos de Serviço + reportable: + hack: caso você ache que sua conta foi hackeada ou que alguém está tentando + hackear sua conta, ou + intro: 'Por favor utilize esse formulário para enviar uma denúncia somente + se você não tenha nos enviado essa mesma denúncia nos últimos 60 dias. Você + pode nos contactar aqui sobre os seguintes assuntos:' + activerecord: + attributes: + admin/role: + board: Conselho de Administração + communications: Comunicação + docs: Documentação para o AO3 + open_doors: Portas Abertas + policy_and_abuse: Diretrizes e Abuso + superadmin: Superadmin + support: Suporte + tag_wrangling: Organização de Tags + translation: Tradução + archive_warning: + name_with_colon: + one: 'Advertência:' + other: 'Advertências:' + category: + name_with_colon: + one: 'Categoria:' + other: 'Categorias:' + chapters/creatorships: + base: 'Nome de artista inválido:' + pseud_id: Pseudônimo + character: + name_with_colon: + one: 'Personagem:' + other: 'Personagens:' + creatorships: + base: 'Nome de artista inválido:' + pseud_id: Pseudônimo + external_work: + author: Artista + user_defined_tags_count: Tags de fandom, relacionamento e personagem + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandoms:' + freeform: + name_with_colon: + one: 'Tag adicional:' + other: 'Tags adicionais:' + meta_tagging: + meta_tag: Metatag + meta_tag_id: Metatag + sub_tag: Subtag + sub_tag_id: Subtag + rating: + name_with_colon: 'Classificação:' + relationship: + name_with_colon: + one: 'Relacionamento:' + other: 'Relacionamentos:' + series/creatorships: + base: 'Nome de artista inválido:' + pseud_id: Pseudônimo + work: + chapter_total_display: Capítulos + summary: Sumário + work/chapters: + base: 'Capítulo inválido:' + content: Conteúdo + work/creatorships: + pseud_id: Pseudônimo + errors: + models: + block: + attributes: + blocked: + official: Desculpe, você não pode bloquear uma conta oficial do site. + blocked_id: + taken: Você já bloqueou essa conta. + comment: + attributes: + user: + format: "%{message}" + creatorship: + attributes: + pseud_id: + taken: já aparece na obra como artista. + kudo: + attributes: + commentable: + author_on_own_work: Não é possível deixar kudos na sua própria obra. + blank: Em que obra você gostaria de deixar kudos? + user_is_banned: Não é possível deixar kudos de uma conta banida do AO3. + user_is_suspended: Não é possível deixar kudos enquanto sua conta está + suspensa. + commentable_type: + inclusion: Onde você queria deixar kudos? + format: "%{message}" + taken: Você já deixou kudos nessa obra :) + mute: + attributes: + muted: + blank: Desculpe, não foi possível encontrar uma conta com esse nome. + format: "%{message}" + related_work: + attributes: + parent: + blank: A obra que você escolheu como inspiração não existe. Por favor + verifique o link. + not_work: Você só pode inserir o link para uma obra já existente no + campo Inspiração. + protected: Não é possível usar o recurso Obras relacionadas para citar + as obras de uma conta protegida como %{login}. + format: "%{message}" + user: + attributes: + password_confirmation: + confirmation: não é igual à nova senha + models: + archive_warning: + one: Advertência + other: Advertências + category: + one: Categoria + other: Categorias + chapter: + one: Capítulo + other: Capítulos + character: + one: Personagem + other: Personagens + comment: Comentar + fandom: + one: Fandom + other: Fandoms + freeform: + one: Tag adicional + other: Tags adicionais + pseud: Pseudônimo + rating: + one: Classificação + other: Classificação + relationship: + one: Relacionamento + other: Relacionamentos + series: + one: Série + other: Séries + tag: + one: Tag + other: Tags + admin: + admin_options: + delete: + bookmark: Apagar favorito + confirmation: Tem certeza que quer apagar isso? + external_work: Apagar obra externa + series: Apagar série + work: Apagar obra + edit: + external_work: Editar obra externa + edit_tags: Editar tags e idioma + hide: + bookmark: Ocultar favorito + external_work: Ocultar obra externa + series: Ocultar série + work: Ocultar obra + landmark: Ações de admin + not_spam: Desmarcar como spam + spam: Marcar como spam + unhide: + bookmark: Tornar favorito visível + external_work: Tornar visível obra externa + series: Tornar a série visível + work: Tornar a obra visível + blacklist: + emails_found: + one: um e-mail localizado + other: "%{count} e-mails localizados" + mailer: + reset_password_instructions: + link_title_html: Trocar minha senha. + passwords: + edit: + label: + confirmation: Confirmar nova senha + landmark: + submit: Enviar + page_heading: Definir minha senha de admin + submit: Definir senha de admin + new: + page_heading: Esqueceu sua senha de admin? + reset_login_html: Nome de admin + submit: Redefinir senha de admin + sessions: + new: + label: + login: Nome de admin + password: Senha de admin + landmark: + reset: Redefinir senha + page_heading: Logar como admin + reset_link: Esqueceu senha de admin? + submit: Logar como admin + settings: + index: + fields: + account_creation_enabled: Criação de conta habilitada. + downloads_enabled: Permitir downloads + enable_test_caching: Habilitar caching (configuração experimental) + hide_spam: Ocultar obras com spam automaticamente + invite_from_queue_frequency: Com que frequência (em número de dias) devemos + enviar convites para gente na fila de espera + invite_from_queue_number: Número de pessoas na fila que receberão convites + imediatamente + request_invite_enabled: Usuáries podem pedir convites + suspend_filter_counts: Desabilitar (em parte) o rastreamento de filtros + devido a um alto volume de postagens + tag_wrangling_off: Desligar organização de tags para todo mundo que não + é admin + heading: Configurações do AO3 + legend: + account_and_invitations: Contas e convites + actions: Ações + disable_support_form: Desabilitar formulário de Suporte + queue_status: "%{number} receberão convites no dia %{date}." + update: Atualizar + update: + success: As configurações do AO3 foram atualizadas com sucesso. + admins: + index: + confidentiality_reminder: Você efetuou login com uma conta admin. Isso quer + dizer que você provavelmente poderá acessar informações pessoais ou confidenciais + (como endereços de e-mail, nomes de conta, endereços de IP, nomes de quem + postou obras anônimas, etc.). Por favor não use essa informação fora de suas + responsabilidades na OTW. Se você tiver alguma pergunta sobre o que pode ou + não fazer com informações que você encontrar aqui, entre em contato com presidentes + do seu comitê. + page_title: Oi, %{login}! + roles: + heading: 'Suas permissões como admin:' + none: No momento você não tem nenhuma permissão de admin associada à sua conta. + admin_posts: + admin_post_form: + comment_permissions: + label: Quem pode comentar nesse post de admin + language: + label: Escolha um idioma + tags: + label: Tags + translated_post: + label: Tradução do post + blocked: + unblock: Desbloquear + users: + confirm_block: + sure_html: Tem certeza que você quer %{block}%{username}? + create: + blocked: Você bloqueou a conta %{name}. + index: + blocked_users: Contas bloqueadas + none: Você não bloqueou nenhuma conta. + collection_items: + collection_item_form: + add: Adicionar + add_bookmark_header: Adicionar favorito a coleções + invite: Convidar + index: + navigation: + unreviewed_by_user: Aguardando aprovação + comments: + check_blocked: + reply: Desculpe, essa pessoa bloqueou sua conta. + commentable: + blocked: Desculpe, não é possível deixar comentários, pois sua conta foi bloqueada + por alguém na lista de artistas que criaram essa obra. + permissions: + admin_post: + alt_action: Você pode, no entanto, %{support_link} se tiver comentários + ou perguntas para a nossa equipe. + disable_anon: Desculpe, esse post de notícias não permite que pessoas sem + conta registrada no AO3 deixem comentários. + support_link: entre em contato com a equipe de Suporte + options: + disable_all: Não é permitido que ninguém comente + disable_anon: Somente contas registradas podem deixar comentários + enable_all: Contas registradas e visitantes podem comentar + work: + alt_action: Mas você ainda pode deixar kudos! + disable_all: Desculpe, essa obra não permite comentários. + disable_anon: Desculpe, essa obra não permite que pessoas sem conta no AO3 + deixem comentários. + hidden: Desculpe, você não pode adicionar ou editar comentários numa obra + oculta. + unrevealed: Desculpe, você não pode adicionar ou editar comentários numa + obra não revelada. + freeze: + permission_denied: Desculpe, sua conta não tem as permissões necessárias para + congelar esses comentários. + devise: + confirmations: + confirmed: Seu endereço de e-mail foi confirmado com sucesso. + send_instructions: Você receberá em alguns minutos um e-mail com instruções + para confirmar seu e-mail. + send_paranoid_instructions: Se seu endereço de e-mail existe no nosso banco + de dados, você receberá em alguns minutos um e-mail com instruções para confirmar + seu e-mail. + failure: + admin: + already_authenticated: Você já efetuou login. + inactive: Sua conta ainda não foi ativada. + locked: Sua conta está bloqueada. + not_found_in_database: A senha ou nome de conta admin que você digitou não + está de acordo com nosso banco de dados. + timeout: Sua sessão expirou. Por favor efetue login novamente para prosseguir. + unauthenticated: Você precisa efetuar login ou criar uma conta para poder + prosseguir. + unconfirmed: Você tem que confirmar seu endereço de e-mail antes de prosseguir. + user: + already_authenticated: Você já efetou login. + inactive: Você tem que ativar sua conta antes de efetuar login. Por favor + cheque sua caixa de entrada ou entre em contato com a equipe de Suporte. + last_attempt: Você tem mais uma tentativa disponível antes que sua conta seja + bloqueada. + locked: Sua conta foi bloqueada por 5 minutes devido a um excesso de tentativas + de login mal-sucedidas. + not_found_in_database: A senha ou a conta que você digitou não estão de acordo + com nosso banco de dados. Por favor tente novamente ou redefina + sua senha. Se você não consegue efetuar login mesmo assim, visite Problemas ao logar? para maiores informações. + timeout: Sua sessão expirou. Por favor efetue login novamente para continuar. + unauthenticated: Você precisa efetuar login ou criar uma conta para prosseguir. + mailer: + password_change: + subject: Senha alterada + reset_password_instructions: + subject: "[%{app_name}] Link para redefinir senha criado" + omniauth_callbacks: + failure: 'Não foi possível autenticar você de %{kind} por causa da seguinte + razão: "%{reason}".' + success: Acesso da conta %{kind} autenticado com sucesso. + passwords: + updated: Sua senha foi alterada com sucesso. Login efetuado. + updated_not_active: Sua senha foi alterada com sucesso. + registrations: + destroyed: Adeus! Sua conta foi cancelada com sucesso. Esperamos lhe ver novamente + em breve. + signed_up: A equipe AO3 lhe deseja as boas vindas! Você se registrou com sucesso. + signed_up_but_inactive: Você criou sua conta com sucesso. No então, não foi + possível efetuar login, pois você ainda não completou a ativação da sua conta + por e-mail. + updated: Sua conta foi atualizada com sucesso. + sessions: + already_signed_out: Logout efetuado com sucesso. + signed_in: Login efetuado com sucesso. + signed_out: Logout efetuado com sucesso. + unlocks: + send_instructions: Você receberá um e-mail com instruções para desbloquear sua + conta em alguns minutos. + unlocked: Sua conta foi desbloqueada com sucesso. Por favor efetue login para + continuar. + errors: + messages: + confirmation_period_expired: tem que ser confirmada durante %{period}, por favor + envie sua solicitação novamente. + not_found: não encontrado + not_locked: não estava bloqueado + not_saved: + one: Um erro impediu que esse %{resource} fosse salvo. + other: "%{count} erros impediram que esse %{resource} fosse salvo." + feedbacks: + new: + abuse: + reports: No caso de denúncias de violações de nossos Termos de Serviço como + assédio, spam ou plágio, ou se você acha que sua conta pode ter sido hackeada, + por favor, %{contact_link}. Não podemos agir em resposta a esse tipo de + denúncia ou dar mais informações sobre denúncias enviadas à equipe de Diretrizes + e Abuso. + do_not_spam_html: "Respondemos todas as solicitações que recebemos, + mas somos uma pequena equipe voluntária. Por isso, pedimos que você + não nos envie mais de uma mensagem sobre o mesmo problema ou encoraje outras + pessoas a fazê-lo, a menos que tenham novas informações para compartilhar + conosco." + form: + comment: + description: Por favor escreva sua mensagem com o máximo de detalhes possível, + incluindo mensagens de erro e/ou links + error: Por favor, digite seu comentário. + label: Sua pergunta ou problema (campo obrigatório) + email: + label: Seu e-mail (campo obrigatório) + ip: Nosso filtro de spam coleta endereços de IP, mas nós nunca os vemos. + language: + label: Selecione o idioma (campo obrigatório) + legend: + contact_info: Informações de contato + send: Envie seu feedback + name: + label: Seu nome (campo opcional) + submit: + active: Enviar + disabled: Por favor, aguarde. + summary: + error: Por favor insira um breve resumo da sua mensagem + label: Breve resumo da sua pergunta ou problema (campo obrigatório) + heading: + instructions: Por favor utilize esse formulário para enviar perguntas sobre + como utilizar o AO3, bem como para relatar problemas técnicos. + landmark: + reference: Links para referência + page_title: Suporte e Feedback + languages_html: "Podemos responder a solicitações de Suporte nos seguintes + idiomas: %{list}. Por favor leve em consideração que respostas em línguas + além do inglês podem demorar mais." + navigation: + faqs: FAQ e tutoriais + known_issues: Problemas conhecidos + release_notes: Notas de versão + reportable: + account_creation: Dificuldades com a configuração da sua conta + bugs: Bugs, erros ou problemas inesperados na utilização do site. + intro: 'Você pode entrar em contato com a equipe de Suporte sobre vários assuntos, + incluindo:' + lost_access: Senha ou e-mail perdidos, impossibilitando o acesso à sua conta + new_features: 'Pedidos para desenvolvimento futuro de recursos ' + orphaned_works: Perguntas sobre obras orfanadas + policy_questions: Perguntas gerais sobre políticas do AO3 + site_questions: Perguntas sobre como usar o site + tag_changes: Pedidos para canonizar ou modificar tags + work_problems: Obras marcadas com a língua errada ou obras duplicadas + status: + twitter: "@AO3_Status" + home: + donate: + page_title: Doe ou faça parte da nossa equipe voluntária + kudos: + create: + success: Obrigade por deixar kudos! + guest_header: + one: "%{count} visitante também deixou kudos" + other: "%{count} visitantes também deixaram kudos" + user_links: + more_link: + one: mais %{count} usuárie + other: mais %{count} usuáries + kudo_mailer: + batch_kudo_notification: + guest: + one: 1 visitante + other: "%{count} visitantes" + left_kudos: + html: + one: "%{givers_list} deixou kudos em %{commentable_link}." + other: "%{givers_list} deixaram kudos em %{commentable_link}." + text: + one: "%{givers_list} deixou kudos em %{commentable_title} (%{commentable_url})." + other: "%{givers_list} deixaram kudos em %{commentable_title} (%{commentable_url})." + single_guest: + giver: 1 visitante + html: "%{giver} deixou kudos em %{commentable_link}." + text: 1 visitante deixou kudos em %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Kudos pra você!" + layouts: + proxy_notice: + button: Desabilitar aviso + faux_heading: 'Aviso importante:' + point1: Você está utilizando um site de proxy que não faz parte do Archive of + Our Own – AO3 (Nosso Próprio Arquivo). + point2: Quem criou esse site de proxy pode ver toda a sua atividade no site, + incluindo seu endereço de IP. Se você efetuar login na sua conta do AO3 através + desse site, ele poderá ver sua senha. + mailer: + general: + closing: + formal: Atenciosamente, + informal: Atenciosamente, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Capítulo %{position} de %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} palavra" + other: "%{count} palavras" + footer: + general: + about: + html: O AO3 é um arquivo que depende do trabalho voluntário e das %{donate_link}. + text: 'O AO3 é um arquivo que depende do trabalho voluntário e das doações + de fãs: %{donate_url}.' + html: + donate_link_text: doações de fãs + support_link_text: entre em contato com a nossa equipe de Suporte + unwanted_email: + html: Se você recebeu essa mensagem por engano, por favor %{support_link}. + text: 'Se você recebeu essa mensagem por engano, por favor entre em contato + com a nossa equipe de Suporte: %{support_url}.' + sent_at: Enviado %{sent_at}. + greeting: + formal_html: Olá, %{name}, + informal: + addressed_html: Oi, %{name}! + unaddressed: Oi! + introductory: Olá! Aqui é o Archive of Our Own – AO3 (Um Arquivo Todo Nosso). + metadata_label_indicator: ":" + signature: + abuse_team: Equipe de Diretrizes e Abuso do AO3 + app_short_name: AO3 + open_doors: Equipe do Open Doors (Portas Abertas) + parent_org: Organization for Transformative Works – OTW (Organização para + Obras Transformativas) + support: Equipe de Suporte do AO3 + muted: + users: + confirm_mute: + blocked_users_link_text: sua página de Contas Bloqueadas + cancel: Cancelar + restore_site_skin_faq_link_text: Instruções para voltar para a skin padrão + do site + will: + seeing_content: ocultar completamente obras, séries, favoritos e comentários + sempre que você estiver visitando o AO3; não haverá espaço em branco ou + indicação alguma de que algo foi removido dali + will_not: + hide_content_for_others: ocultar obras, séries, favoritos e comentários + de outras pessoas + prevent_emails: impedir você de receber e-mails com notificações de novos + comentários, capítulos ou obras dessa pessoa + confirm_unmute: + resume: + see_content: ver suas obras, séries, favoritos e comentários no site + index: + blocked_users_link_text: sua página de Contas Bloqueadas + restore_site_skin_faq_link_text: instruções para usar novamente a skin padrão + do site + pseuds: + delete_preview: + heading: Apagar pseudônimo + skins: + confirm_delete: + confirm_html: Tem certeza que quer apagar a skin "%{skin_title}"? + tags: + index: + about: + popular_in_collection: Aqui estão algumas das tags mais populares utilizadas + nessa coleção. + troubleshooting: + show: + fix_associations: + title: Consertar associações da tag + fix_counts: + title: Consertar contagem de uma tag + fix_meta_tags: + title: Consertar metatags + page_description: + tag: Se essa tag está se comportando de forma indesejada, tente uma das opções + a seguir para consertá-la. + work: Se essa obra está se comportando de forma indesejada, tente uma das + opções a seguir para consertá-la. + page_title: + tag: Investigar problema com tag + work: Investigar problema com obra + reindex_tag: + description: Reindexa essa tag e todas as obras, os favoritos, as séries, + os pseudônimos e as obras externas associados a ela. Use essa opção se nenhuma + das outras funcionou. Essa opção não conserta problemas com o preenchimento + automático. + title: Reindexar tag + reindex_work: + description: Reindexar obra. Utilize essa opção se a obra não está aparecendo + nas listagens de busca ou se está aparecendo em listagens onde não deveria + constar (por exemplo, se alguém orfanou uma obra e ainda é possível achá-la + ao se buscar pelo nome antigo; ou se a obra não segue o esperado quando + se filtram crossovers, completa/incompleta, contagem de palavras etc.). + title: Reindexar obra + update_tag_filters: + title: Atualizar filtros de tags + update_work_filters: + title: Atualizar filtros de uma obra + users: + change_username: + last_renamed: 'A última vez que você trocou o nome associado à sua conta foi + na seguinte data e hora: %{renamed_at}.' + delete_preview: + cancel: Cancelar + confirm: Tem certeza? Não é possível desfazer essa ação. + co_creations: + legend: Obras que você criou com outras pessoas + orphan_info: Você não pode deletar essas obras, pois são compartilhadas com + coartistas. Pode, no entanto, %{orphan_link} as obras ou remover completamente + seu nome como coartista. + summary: 'Você é coartista em %{work_count} obra(s) com as seguintes pessoas: + %{co_creators}.' + heading: O que você quer fazer com suas obras? + options: + delete: Apagar completamente + keep_pseud: Deixar meu pseudônimo na obra, mas associá-la à orphan_account + (conta órfã) + orphan_pseud: Mudar meu pseudônimo para "orphan" e associar à orphan_account + (conta órfã) + remove: Retirar completamente meu nome como coartista + orphan: orfanar + orphaning: orfanar + sole_creations: + collections_summary: 'Você tem %{collection_count} coleção (ou coleções) associadas + aos seguintes pseudônimos: %{pseuds}.' + legend: Obras e coleções que você postou somente sob seu próprio nome + options_info: Você pode apagá-las, mas por favor considere a opção de %{orphaning_link} + ao invés disso! + works_summary: 'Você tem %{work_count} obra(s) com os pseudônimos a seguir: + %{pseuds}.' + submit: Salvar + mailer: + reset_password_instructions: + expiration: Se você não utilizar esse link para redefinir sua senha dentro + de uma semana, ele irá expirar e você terá que solicitar um novo link. + intro: Alguém solicitou a redefinição da senha da sua conta. Para fazer a + alteração, acesse o link a seguir e insira uma nova senha. + link_title: Mudar minha senha. + subject: "[%{app_name}] Mudança de senha" + unrequested: Caso você não tenha solicitado a redefinição da sua senha, ignore + esse e-mail. Sua senha atual irá continuar funcionando. + sessions: + new: + login: + request_invite: Pedir um convite para entrar + show: + login_banner: + dismiss: Desabilitar banner de forma permanente + hide: Desabilitar banner de ajuda para quem efetua login pela primeira vez + user_mailer: + admin_deleted_work_notification: + bye: Uma cópia da obra removida encontra-se em anexo. + contact_abuse: entre em contato com a nossa equipe de Diretrizes e Abuso + deleted: + html: Sua obra %{title} foi removida do AO3 por um membro da equipe de administração + do site. + text: Sua obra "%{title}" foi apagada do AO3 por um membro da equipe de administração + do site. + html: + tos_violation: Caso seja possível que sua obra tenha violado os Termos de + Serviço do AO3, por favor %{contact_abuse_link}. + import_project: + html: Se sua obra era parte de um projeto de importação ligado ao Open Doors + (Portas Abertas), por favor %{opendoors_link} com qualquer dúvida. + text: Se sua obra era parte de um projeto de importação ligado ao Open Doors + (Portas Abertas), por favor entre em contato com a equipe do Portas Abertas + (%{opendoors_link}) com qualquer dúvida. + opendoors: entre em contato com a equipe do Portas Abertas + subject: "[%{app_name}] Sua obra foi removida pela administração do AO3" + text: + tos_violation: Caso seja possível que sua obra tenha violado os Termos de + Serviço do AO3, por favor entre em contato com a nossa equipe de Diretrizes + e Abuso (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Enquanto sua obra estiver oculta, você poderá acessá-la através do link + fornecido acima, mas ela não aparecerá na sua página de obras e não estará + disponível para quem visitar o AO3. + check_email: Por favor, cheque seu e-mail, inclusive sua pasta de spam, pois + a equipe de Diretrizes e Abuso já pode ter entrado em contato para explicar + a razão dessa medida. + contact_abuse: entre em contato com a equipe de Diretrizes e Abuso + html: + help: Se não tiver certeza do motivo dessa decisão e não tiver recebido outros + comunicados em relação a este assunto, por favor %{contact_abuse_link} diretamente. + hidden: A equipe de Diretrizes e Abuso ocultou sua obra %{title} e ela não + está mais publicamente acessível. + tos_violation: Caso isso tenha ocorrido por sua obra violar os %{tos_link} + do AO3, é necessário que você corrija a infração. A não adequação da sua + obra aos Termos de Serviço pode fazer com que ela seja removida do AO3. + subject: "[%{app_name}] A equipe de Diretrizes e Abuso ocultou sua obra" + text: + help: 'Se não tiver certeza do motivo dessa decisão e não tiver recebido outros + comunicados em relação a este assunto, por favor entre em contato diretamente + com a equipe de Diretrizes e Abuso: %{contact_abuse_url}.' + hidden: A equipe de Diretrizes e Abuso ocultou sua obra "%{title}" (%{work_url}) + e ela não está mais publicamente acessível. + tos_violation: Caso isso tenha ocorrido por sua obra violar os Termos de Serviço + (%{tos_url}) do AO3, é necessário que você corrija a infração. A não adequação + da sua obra aos Termos de Serviço pode fazer com que ela seja removida do + AO3. + tos: Termos de Serviço + anonymous_or_unrevealed_notification: + anonymous_info: Obras anônimas aparecem em todo o site, exceto na sua página + pessoal. A obra será atribuída a "Anonymous". + anonymous_unrevealed_info: A administração da coleção poderá, posteriormente, + revelar a sua obra, mas mantê-la anônima. Nesse caso, pessoas que recebem + atualizações sobre suas obras não serão notificadas. Uma vez revelada, sua + obra aparecerá em todo o site, exceto na sua página pessoal. Enquanto a obra + permanecer anônima, ela será atribuída a "Anonymous". + changed_status: + anonymous: + html: A equipe de administração da coleção %{collection_link} mudou o status + da sua obra %{work_link} para anônima. + text: A equipe de administração da coleção "%{collection_title}" (%{collection_url}) + mudou o status da sua obra "%{work_title}" (%{work_url}) para anônima. + anonymous_unrevealed: + html: A administração da coleção %{collection_link} mudou o status da sua + obra %{work_link} para anônima e não revelada. + text: A equipe de administração da coleção "%{collection_title}" (%{collection_url}) + mudou o status da sua obra "%{work_title}" (%{work_url}) para anônima + e não revelada. + unrevealed: + html: A equipe de administração da coleção %{collection_link} mudou o status + da sua obra %{work_link} para não revelada. + text: A equipe de administração da coleção "%{collection_title}" (%{collection_url}) + mudou o status da sua obra "%{work_title}" (%{work_url}) para não revelada. + collection_items_link_text: página de Approved Collection Items (Itens aprovados + para coleção) + do_not_want: + anonymous: + html: Se você não deseja que sua obra continue anônima, por favor acesse + sua %{collection_items_link} para removê-la dessa coleção. + text: 'Se você não deseja que sua obra continue anônima, por favor acesse + sua página de Approved Collection Items (Itens aprovados para coleção) + para removê-la dessa coleção: %{collection_items_url}' + anonymous_unrevealed: + html: Se você não deseja que a sua obra continue anônima e não revelada, + por favor acesse sua %{collection_items_link} para removê-la dessa coleção. + text: 'Se você não deseja que a sua obra continue anônima e não revelada, + por favor acesse sua página de Approved Collection Items (Itens aprovados + para coleção) para removê-la dessa coleção: %{collection_items_url}' + unrevealed: + html: Se você não deseja que a sua obra continue com o status de não revelada, + por favor acesse sua %{collection_items_link} para removê-la dessa coleção. + text: 'Se você não deseja que a sua obra continue com o status de não revelada, + por favor acesse sua página de Approved Collection Items (Itens aprovados + para coleção) para removê-la dessa coleção: %{collection_items_url}' + faq_link_text: seção de FAQ sobre Coleções + more_info: + html: Para mais informações, acesse a nossa %{faq_link}. + text: 'Para mais informações, acesse a nossa seção de FAQ sobre Coleções: + %{faq_url}' + subject: + anonymous: "[%{app_name}] Sua obra foi marcada como anônima" + anonymous_unrevealed: "[%{app_name}] Sua obra foi marcada como anônima e não + revelada" + unrevealed: "[%{app_name}] Sua obra foi marcada como não revelada" + unrevealed_info: Obras não reveladas não aparecem no site em geral ou na sua + página pessoal. Qualquer pessoa que acessar um link para essa obra receberá + um aviso dizendo que ela se encontra não revelada no momento e que não é possível + acessar seu conteúdo. + archivist_added_to_collection_notification: + approved_collection_items_page: página Approved Collection Items (Itens Aprovados + em Coleções) + archivist_notice: Como quem mantém a coleção atua em sua capacidade oficial + como arquivista do Open Doors (Portas Abertas), essas pessoas têm permissão + para adicionar sua obra a essa coleção, mesmo que você tenha desativado os + convites para coleção. Arquivistas só adicionarão uma obra a uma coleção se + ela tiver sido hospedada em um arquivo importado. + removal_instructions: + html: Caso queira remover sua obra dessa coleção, por favor, visite sua %{approved_items_link}. + text: 'Caso queira remover sua obra dessa coleção, por favor, visite sua página + de Approved Collection Items (Itens Aprovados em Coleções): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Sua obra foi incluída em uma coleção + do Open Doors (Portas Abertas)." + work_added: + html: A curadoria da coleção %{collection_link} incluiu sua obra %{work_link} + nessa coleção! + text: A curadoria da coleção "%{collection_title}" (%{collection_url}) incluiu + sua obra "%{work_title}" (%{work_url}) nessa coleção! + challenge_assignment_notification: + any: Quaisquer + assignment: + html: Você recebeu a seguinte tarefa no desafio %{link} no AO3! + description: 'Descrição:' + due: 'Prazo:' + html: + footer: Você recebeu esse email porque se inscreveu no desafio %{title}. Para + mais informações sobre ele e sobre como entrar em contato com a moderação, + acesse %{footer_link}. + footer_link: a página do desafio + look_up: Acesse mais detalhes sobre essa tarefa na %{link}. + look_up_link: sua página de Assignments (Tarefas) + optional_tags: 'Tags opcionais:' + prompts: 'Ideias:' + prompt_url: 'URL da ideia:' + recipient: 'Para:' + recipient_missing: 'Ninguém: entre em contato com a moderação do desafio para + receber ajuda!' + subject: "[%{app_name}][%{collection_title}] Sua tarefa!" + text: + assignment: Você recebeu a seguinte tarefa no desafio "%{collection_title}" + (%{collection_url}) no AO3! + footer: Você recebeu esse email porque se inscreveu no desafio %{title} (%{url}). + Para mais informações sobre ele e sobre como entrar em contato com a moderação, + acesse %{profile_url}. + look_up: 'Acesse mais detalhes sobre essa tarefa na sua página de Assignments + (Tarefas): %{link}.' + change_email: + changed: + html: "%{login}, o e-mail associado à sua conta foi alterado para %{email}." + text: "%{login}, o e-mail associado à sua conta foi alterado para %{email}." + subject: "[%{app_name}] Mudança de endereço de e-mail efetuada" + claim_notification: + access: + contact_support: entre em contato com o Suporte do AO3 + html: Dependendo do arquivo, talvez as suas obras tenham sido importadas com + acesso apenas para pessoas com contas registradas (para mantê-las fora das + pesquisas do Google). Se for o caso, essas obras serão acessíveis apenas + a quem fez login, ao menos que você decida torná-las visíveis a visitantes. + Se precisar de ajuda para desbloquear, orfanar, ou deletar suas obras, por + favor, %{contact_support_link}. + text: Dependendo do arquivo, talvez as suas obras tenham sido importadas com + acesso apenas para pessoas com contas registradas (para mantê-las fora das + pesquisas do Google). Se for o caso, essas obras serão acessíveis apenas + a quem fez login, ao menos que você decida torná-las visíveis a visitantes. + Se precisar de ajuda para desbloquear, orfanar, ou deletar suas obras, por + favor, entre em contato com o Suporte do AO3 no link %{support_url}. + email_tips: Se você entrar em contato conosco, por favor, adicione os endereços + de e-mail de @transformativeworks.org à sua lista de contatos e verifique + as suas pastas de spam para encontrar nossas respostas. + introduction: + ao3_name: Archive of Our Own – AO3 (Um Arquivo Todo Nosso) + html: Você está recebendo este e-mail porque tinha obras em um arquivo de + obras de fãs que foi importado pelo %{open_doors_name_link} ao %{app_link}. + Como este endereço de e-mail está conectado a um registro do arquivo importado, + as obras de fãs associadas (listadas abaixo) foram adicionadas à sua conta + do AO3. + open_doors_name: Open Doors (Portas Abertas) + text: 'Você está recebendo este e-mail porque tinha obras em um arquivo de + obras de fãs que foi importado pelo Open Doors (Portas Abertas) (%{open_doors_url}) + ao %Archive of Our Own – AO3 (Um Arquivo Todo Nosso): %{app_url}. Como este + endereço de e-mail está conectado a um registro do arquivo importado, as + obras de fãs associadas (listadas abaixo) foram adicionadas à sua conta + do AO3.' + mistake: + contact_open_doors: entre em contato com o Open Doors + html: Se isto é um erro e estas obras não são suas, por favor, não as delete! + Simplesmente %{contact_open_doors_link} e nós resolveremos. + text: Se isto é um erro e estas obras não são suas, por favor, não as delete! + Simplesmente entre em contato com o Open Doors (%{open_doors_url}) e nós + resolveremos. + more_info: + ao3_news: Notícias do AO3 + contact_support: entre em contato com o Suporte do AO3 + faq_page: página de FAQ + html: Encontre anúncios sobre arquivos recentemente movidos nas %{ao3_news_link}, + e informações adicionais na %{faq_page_link} ou no %{tutorial_page_link} + do Open Doors. Em caso de dúvidas não respondidas nas páginas de FAQ, tutoriais, + ou neste e-mail, por favor, %{contact_support_link}. + text: Encontre anúncios sobre arquivos recentemente movidos nas Notícias do + AO3 (%{news_url}), e informações adicionais na página de FAQ (%{open_doors_faq_url}) + ou no tutorial (%{open_doors_tutorial_url}) do Open Doors. Em caso de dúvidas + não respondidas nas páginas de FAQ, tutoriais, ou neste e-mail, por favor, + entre em contato com o Suporte no link %{support_url}. + tutorial_page: tutorial + other_works: + contact_open_doors: entre em contato com o Open Doors + html: Se você tiver outras obras no arquivo importado sob um endereço de e-mail + diferente ao qual não possui mais acesso, por favor, %{contact_open_doors_link} + com quaisquer informações que possam ajudar na verificação da sua identidade. + text: Se você tiver outras obras no arquivo importado sob um endereço de e-mail + diferente ao qual não possui mais acesso, por favor, entre em contato com + o Open Doors com quaisquer informações que possam ajudar na verificação + da sua identidade. + questions: + contact_support: entre em contato com o Suporte do AO3 + html: Em caso de outras dúvidas, por favor, %{contact_support_link}. + text: Em caso de outras dúvidas, por favor, entre em contato com o Suporte + do AO3 no link %{support_url}. + redirects: + html: Para preservar listas de recomendações e favoritos, os endereços dos + arquivos importados podem redirecionar à cópia importada dessas obras por + um tempo limitado (verifique o anúncio de importação do seu arquivo para + ter certeza). Se você já publicou uma cópia dessas obras e você %{negation} + utilizou a função Importação por URL, haverá duas cópias da mesma obra no + AO3. + subject: "[%{app_name}] Upload de obras" + update_redirect: + contact_open_doors: entre em contato com o Open Doors + html: Se você gostaria que o Open Doors atualizasse o redirecionamento para + a sua obra pré-existente, por favor, delete a cópia importada e %{contact_open_doors_link} + com o nome da sua conta no AO3, o nome da sua conta no arquivo importado, + o título e a URL da obra de fã que você gostaria que fosse redirecionada. + (Se você tiver múltiplas obras das quais gostaria de mudar o redirecionamento, + pode listá-las em um único e-mail.) + text: Se você gostaria que o Open Doors atualizasse o redirecionamento para + a sua obra pré-existente, por favor, delete a cópia importada e entre em + contato com o Open Doors no link %{open_doors_url} com o nome da sua conta + no AO3, o nome da sua conta no arquivo importado, o título e a URL da obra + de fã que você gostaria que fosse redirecionada. (Se você tiver múltiplas + obras das quais gostaria de mudar o redirecionamento, pode listá-las em + um único e-mail.) + works_by: 'Estas obras foram escritas sob o e-mail: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Todas as tarefas foram enviadas. + subject: Tarefas enviadas + html: + received_message: 'Você recebeu uma mensagem sobre sua coleção %{collection_link}:' + text: + received_message: 'Você recebeu uma mensagem sobre sua coleção "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Agora que o seu pseudônimo foi adicionado à obra, ele também poderá + aparecer em novos capítulos dessa mesma obra, independentemente das suas preferências + no site. Seu pseudônimo também aparecerá em qualquer série à qual a obra for + adicionada. + html: + creation: "%{creation_link} por %{pseud_links}" + edit_chapter: editar o capítulo + edit_series: editar a série + remove_chapter: Caso isso tenha ocorrido por engano ou você não queira que + seu pseudônimo apareça nessa obra como coartista, é só %{edit_chapter_link} + para remover seu nome. + remove_series: Caso isso tenha ocorrido por engano ou você não queira que + seu pseudônimo apareça nessa série como coartista, é só %{edit_series_link} + para remover seu nome. + intro_chapter: 'Seu pseudônimo %{pseud} foi adicionado por %{adding_user} como + coartista do seguinte capítulo:' + intro_series: 'Seu pseudônimo %{pseud} foi adicionado por %{adding_user} como + coartista da seguinte série:' + subject: "[%{app_name}] Sua conta foi adicionada como coartista" + text: + creation: "%{title} (%{url}) por %{pseuds}" + remove_chapter: 'Caso isso tenha ocorrido por engano ou você não queira que + seu pseudônimo apareça nessa obra como coartista, é só editar o capítulo + para remover seu nome: %{url}' + remove_series: 'Caso isso tenha ocorrido por engano ou você não queira que + seu pseudônimo apareça nessa série como coartista, é só editar a série para + remover seu nome: %{url}' + creatorship_notification_archivist: + explanation: Essa conta arquivista, por ser participante oficial do projeto + Open Doors (Portas Abertas), pode adicionar seu nome a uma obra sem solicitação + prévia, mesmo que você não tenha habilitado cocriação na sua conta. + html: + creation: "%{creation_link} por %{pseud_links}" + edit_chapter: edite o capítulo + edit_series: edite a série + edit_work: edite a obra + remove_chapter: Caso isso tenha ocorrido por engano ou você não queira que + seu pseudônimo apareça nessa obra como coartista, %{edit_chapter_link} para + remover seu nome. + remove_series: Caso isso tenha ocorrido por engano ou você não queira que + seu pseudônimo apareça nessa obra como coartista, %{edit_series_link} para + remover seu nome. + remove_work: Caso isso tenha ocorrido por engano ou você não queira que seu + pseudônimo apareça nessa obra como coartista, %{edit_work_link} para remover + seu nome. + intro_chapter: 'Seu pseudônimo %{pseud} foi adicionado como coartista do capítulo + abaixo por %{archivist}:' + intro_series: 'Seu pseudônimo %{pseud} foi adicionado como coartista da série + abaixo por %{archivist}:' + intro_work: 'Seu pseudônimo %{pseud} foi adicionado como coartista da obra abaixo + por %{archivist}:' + subject: "[%{app_name}] Uma conta arquivista adicionou você como coartista" + text: + creation: "%{title} (%{url}) por %{pseuds}" + remove_chapter: 'Caso isso tenha ocorrido por engano ou você não queira que + seu pseudônimo apareça nessa obra como coartista, você pode editar o capítulo + para remover seu nome: %{url}' + remove_series: 'Caso isso tenha ocorrido por engano ou você não queira que + seu pseudônimo apareça nessa obra como coartista, você pode editar a série + para remover seu nome: %{url}' + remove_work: 'Caso isso tenha ocorrido por engano ou você não queira que seu + pseudônimo apareça nessa obra como coartista, edite a obra para remover + seu nome: %{url}' + creatorship_request: + html: + creation: "%{creation_link} por %{pseud_links}" + instructions: Para aceitar ou recusar esse convite, acesse sua página de %{page_name}. + page_name: Co-Creator Requests (Convites para ser coartista) + intro_chapter: 'A conta %{inviting_user} convidou seu pseudônimo %{pseud} para + aparecer como coartista do seguinte capítulo:' + intro_series: 'A conta %{inviting_user} convidou seu pseudônimo %{pseud} para + aparecer como coartista da seguinte série:' + intro_work: 'A conta %{inviting_user} convidou seu pseudônimo %{pseud} para + aparecer como coartista da seguinte obra:' + subject: "[%{app_name}] Você recebeu um convite para ser coartista" + text: + creation: "%{title} (%{url}) por %{pseuds}" + instructions: 'Para aceitar ou recusar esse convite, acesse sua página de + Co-Creator Requests (Convites para ser coartista): %{url}' + delete_work_notification: + attachment: Uma cópia da obra removida encontra-se em anexo. + deleted_other: + html: Sua obra %{title} foi removida do AO3, conforme solicitado por %{pseud}. + text: Sua obra %{title} foi removida do AO3, conforme solicitado por %{pseud}. + deleted_yourself: + html: Conforme sua solicitação, a obra %{title} foi removida do AO3. + text: Conforme sua solicitação, a obra %{title} foi removida do AO3. + questions: + html: Caso tenha alguma dúvida, por favor %{support}. + text: Caso tenha alguma dúvida, por favor %{support} (%{url}). + subject: "[%{app_name}] Sua obra foi removida" + support: entre em contato com a nossa equipe de Suporte + invitation: + been_invited: Você recebeu um convite para se juntar ao nosso site beta! + has_invited: "%{user_name} convidou você para participar do nosso site beta!" + html: + faq_link_text: nossa página de FAQ + subject: "[%{app_name}] Convite" + invitation_to_claim: + access: + text: 'Dependendo do arquivo, suas obras podem ter sido importadas e disponibilizadas + apenas para pessoas registradas (para manter as obras fora de pesquisas + do Google). Se for esse o caso, as obras só serão acessíveis a quem tiver + feito login no arquivo, a não ser que você opte por torná-las totalmente + visíveis. Se precisar de ajuda para desbloquear, orfanar ou apagar suas + obras, por favor entre em contato com o Suporte do AO3. ' + claim_or_remove: + html: Reivindique ou apague suas obras aqui. + text: 'Reivindique ou apague suas obras aqui: %{claim_url}' + email_tips: Se você está entrando em contato conosco, por favor, adicione à + sua lista de contatos os e-mails do domínio @transformativeworks.org e verifique + sua pasta de spam para checar se recebeu uma resposta. + html: + ao3_news: Notícias do AO3 + contact_open_doors: entre em contato com o Portas Abertas + contact_support: entre em contato com a equipe de Suporte do AO3 + faq_page: página de FAQ + tutorial_page: página de tutorial + introduction: + text: Você está recebendo este e-mail, pois um arquivo foi recentemente importado + pelo Open Doors (Portas Abertas) (%{open_doors_link}) para %{app_name} (%{app_short_name} + - %{app_url}) e acreditamos que as obras de fãs a seguir pertencem a você. + Queremos lhe dar a chance de reivindicar (ou apagar/orfanar) essas obras + se quiser. Caso ainda não tenha uma conta sob outro endereço de e-mail, + gostaríamos de lhe convidar para participar! + mistake: + text: Se esse for um erro e essas obras não forem suas, por favor não as apague! + Por favor apenas entre em contato com o Portas Abertas %{open_doors_link} + e vamos corrigir a situação. + more_info: + html: Para anúncios sobre novas mudanças de arquivo, consulte nossa página + de %{ao3_news_link}. Para encontrar mais informações, visite também a %{faq_page_link} + e a %{tutorial_page_link} do Portas Abertas. Caso tenha alguma pergunta + que não foi respondida nos links ou nesse e-mail, por favor %{contact_support_link}. + text: Para anúncios sobre novas mudanças de arquivo, consulte nossa página + de Notícias do AO3 (%{news_link}). Para encontrar mais informações, visite + também a página de FAQ (%{open_doors_faq_link}) e de tutoriais (%{open_doors_tutorial_link}) + do Portas Abertas. Caso tenha alguma pergunta que não foi respondida nos + links ou nesse e-mail, por favor entre em contato com o Suporte em %{support_link}. + other_works: + text: Se você tinha outras obras no arquivo importado sob uma conta de e-mail + que não consegue mais acessar, por favor entre em contato com o Portas Abertas + com qualquer informação que possa ajudar a confirmar sua identidade. + questions: + html: Para outras questões, por favor %{contact_support_link}. + text: Para outras questões, por favor entre em contato com o Suporte do AO3 + em %{support_link}. + redirects: Para preservar as listas de recomendações e favoritos, os links da + página da web do arquivo importado podem redirecionar para uma cópia das obras + importadas por um tempo limitado (acesse o post de anúncio do seu arquivo + para ter certeza). Se você já publicou uma cópia dessas obras e NÃO usou a + ferramenta de importação por URL, então duas cópias da mesma obra serão armazenadas + no arquivo. + subject: "[%{app_name}] Convite para a reivindicação de obras" + unwanted: + html: Se essas obras lhe pertencem, mas você não as deseja, você pode as orfanar + (para que permaneçam no AO3 com seu nome removido) ou apagar (para que sejam + inteiramente removidas do AO3). Você não precisa adicionar essas obras a + nenhuma conta para orfanar ou apagar — a ação pode ser feita diretamente + através do link de reivindicação acima. (Para receber ajuda, por favor %{contact_support_link}.) + text: |- + Se essas obras lhe pertencem, mas você não as deseja, você pode as orfanar (para que permaneçam no AO3 com seu nome removido) ou apagar (para que sejam inteiramente removidas do AO3). Você não precisa adicionar essas obras a nenhuma conta para orfanar ou apagar — a ação pode ser feita diretamente através do link de reivindicação acima. + (Se precisar de ajuda, por favor entre em contato com o Suporte em %{support_link}.) + update_redirect: + text: Se você deseja que o Portas Abertas atualize o link de redirecionamento + para sua obra já publicada no Arquivo, por favor apague a versão importada + e entre em contato com o Portas Abertas em %{open_doors_link} com o nome + que usa na sua conta do AO3, o nome que usava no arquivo importado, o título + e a URL da obra de fã que você deseja usar como link de redirecionamento. + (Se você tiver múltiplas obras com as quais deseja realizar esse procedimento, + todas podem ser mandadas em um único e-mail.) + uploaded_list: 'Foi realizado o upload das seguintes obras:' + invite_increase_notification: + html: + body: + one: Só pra avisar que você tem um novo convite, que pode ser usado para + criar uma nova conta no AO3. Para convidar alguém, visite a %{invitation_page_link}. + other: Só pra avisar que você tem %{count} novos convites, que podem ser + usados para criar novas contas no AO3. Para convidar alguém, visite a + %{invitation_page_link}. + invitation_page_link_text: sua página de Invitations (Convites) + subject: "[%{app_name}] Novos convites" + text: + body: + one: Só pra avisar que você tem um novo convite, que pode ser usado para + criar uma nova conta no AO3. Para convidar alguém, visite a sua página + de Invitations (Convites) (%{invitation_page_url}). + other: Só pra avisar que você tem %{count} novos convites, que podem ser + usados para criar novas contas no AO3. Para convidar alguém, visite a + sua página de Invitations (Convites) (%{invitation_page_url}). + invite_request_declined: + main: + one: Lamentamos informar que a sua solicitação de um novo convite não pode + ser atendida no momento. + other: Lamentamos informar que a sua solicitação de %{count} novos convites + não pode ser atendida no momento. + reason: 'A solicitação que você nos enviou foi:' + subject: "[%{app_name}] Solicitação de convite adicional negada" + recipient_notification: + html: + collection: Uma obra de presente foi publicada para você na coleção %{collection_link} + no AO3! + no_collection: Uma obra de presente foi publicada para você no AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Uma obra de presente para + você na coleção %{collection_title}" + no_collection: "[%{app_name}] Uma obra de presente para você" + text: + collection: Uma obra de presente foi publicada para você na coleção "%{collection_title}" + (%{collection_url}) no AO3! + signup_notification: + activate: + html: Por favor %{activate_account_link}. + text: 'Por favor siga este link para ativar a sua conta: %{activate_account_url}' + activate_your_account: siga este link para ativar sua conta + admin_posts: Notícias do AO3 + bye: Esperamos que você curta usar o AO3. + contact_support: entre em contato com a nossa equipe de Suporte + faq: FAQ + features: + html: Depois que sua conta for ativada, você poderá publicar suas obras de + fã, fazer assinaturas para receber notificações por e-mail quando houver + atualizações das obras e artistas que mais gosta, configurar suas preferências + para definir a aparência e funcionamento do site para você, saber quais + obras você acessou no AO3 através do seu histórico e muito mais. + text: Depois que sua conta for ativada, você poderá publicar suas obras, fazer + assinaturas para receber notificações por e-mail quando houver atualizações + das obras e artistas que mais gosta, configurar suas preferências para definir + a aparência e funcionamento do site para você, saber quais obras você acessou + no AO3 através do seu histórico e muito mais. + information: + html: Existem muitas informações e dicas sobre como usar o AO3 na nossa %{faq_link}. + Você encontrará as mais recentes notícias a respeito do desenvolvimento + do site em %{admin_posts_link}. Se você precisar de mais ajuda, encontrar + algum bug ou tiver dúvidas ou sugestões, por favor %{contact_support_link}, + que está sempre à sua disposição. + text: 'Há muitas informações e dicas sobre como usar o AO3 na nossa FAQ em + %{faq_url}. Você encontrará as mais recentes notícias a respeito do desenvolvimento + do site em Notícias do AO3 em %{admin_posts_url}. Se você precisar de mais + ajuda, encontrar algum bug ou tiver dúvidas ou sugestões, por favor, entre + em contato com a nossa equipe de Suporte, que está sempre à sua disposição: + %{contact_support_url}' + subject: "[%{app_name}] Ative sua conta" + welcome: Boas vindas ao Archive of Our Own (AO3), %{login}! + validators: + email: + blacklist: foi bloqueado a pedido da administração. Isso que dizer que esse + endereço não pode ser utilizado em comentários de visitantes. Por favor cheque + o endereço de e-mail para se certificar de que ele é de fato seu e entre em + contato com a equipe de Suporte do AO3 se tiver qualquer pergunta. + format: + allow_blank: deveria ter o formato de um endereço de e-mail. Por favor utilize + um endereço diferente ou deixe em branco. + no_blank: deveria ter o formato de um endereço de e-mail. diff --git a/config/locales/phrase-exports/pt-PT.yml b/config/locales/phrase-exports/pt-PT.yml new file mode 100755 index 0000000..297597a --- /dev/null +++ b/config/locales/phrase-exports/pt-PT.yml @@ -0,0 +1,539 @@ +--- +pt-PT: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Aviso:' + other: 'Avisos:' + category: + name_with_colon: + one: 'Categoria:' + other: 'Categorias:' + character: + name_with_colon: + one: 'Personagem:' + other: 'Personagens:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandoms:' + freeform: + name_with_colon: + one: 'Tag Adicional:' + other: 'Tags Adicionais:' + rating: + name_with_colon: 'Classificação:' + relationship: + name_with_colon: + one: 'Relação:' + other: 'Relações:' + work: + chapter_total_display: Capítulos + summary: Sumário + models: + archive_warning: + one: Aviso + other: Avisos + category: + one: Categoria + other: Categorias + chapter: + one: Capítulo + other: Capítulos + character: + one: Personagem + other: Personagens + fandom: + one: Fandom + other: Fandoms + freeform: + one: Tag Adicional + other: Tags Adicionais + rating: + one: Classificação + other: Classificações + relationship: + one: Relação + other: Relações + series: + one: Série + other: Séries + kudo_mailer: + batch_kudo_notification: + guest: + one: uma pessoa convidada + other: "%{count} pessoas convidadas" + left_kudos: + html: + one: "%{givers_list} deixou kudos em %{commentable_link}." + other: "%{givers_list} deixaram kudos em %{commentable_link}." + text: + one: "%{givers_list} deixou kudos em %{commentable_title} (%{commentable_url})." + other: "%{givers_list} deixaram kudos em %{commentable_title} (%{commentable_url})." + single_guest: + giver: Uma pessoa convidada + html: "%{giver} deixou kudos em %{commentable_link}." + text: Uma pessoa convidada deixou kudos em %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Recebeste kudos!" + mailer: + general: + closing: + formal: Atenciosamente, + informal: Os melhores cumprimentos, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Capítulo %{position} de %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} palavra" + other: "%{count} palavras" + footer: + general: + about: + html: O AO3 é um arquivo gerido e suportado por fãs que depende das %{donate_link}. + text: 'O AO3 é um arquivo gerido e suportado por fãs que depende das tuas + doações: %{donate_url}.' + html: + donate_link_text: tuas doações + support_link_text: contacta a equipa de Suporte + unwanted_email: + html: Se recebeste esta mensagem por engano, por favor %{support_link}. + text: Se recebeste esta mensagem por engano, por favor contacta a equipa + de Suporte em %{support_url}. + sent_at: Enviada %{sent_at}. + greeting: + formal_html: Olá %{name}, + informal: + addressed_html: Olá, %{name}! + unaddressed: Olá! + introductory: Olá do Archive of Our Own – AO3 (O Nosso Próprio Arquivo)! + metadata_label_indicator: ":" + signature: + abuse_team: A equipa de Políticas e Abuso do AO3 + app_short_name: AO3 + open_doors: A equipa do Open Doors (Portas Abertas) + parent_org: Organization for Transformative Works – OTW (Organização para + Obras Transformativas) + support: A equipa de Suporte do AO3 + users: + mailer: + reset_password_instructions: + expiration: Se não utilizares este link para repor a tua palavra-passe dentro + de uma semana, o link expirará e terás de pedir um novo. + intro: 'Alguém pediu uma reposição da palavra-passe da tua conta. Podes alterar + a tua palavra-passe seguindo o link abaixo e inserindo a tua nova palavra-passe:' + link_title: Mudar a minha palavra-passe. + subject: "[%{app_name}] Repõe a tua palavra-passe" + unrequested: Se não pediste uma reposição de palavra-passe, podes ignorar + este email e a tua antiga palavra-passe continuará a funcionar. + user_mailer: + admin_deleted_work_notification: + bye: Foi anexada uma cópia da obra para tua referência. + contact_abuse: contacta o nosso Comité de Políticas e Abuso + deleted: + html: A tua obra %{title} foi eliminada do Arquivo por uma pessoa administradora + do site. + text: A tua obra "%{title}" foi eliminada do Arquivo por uma pessoa administradora + do site. + html: + tos_violation: Se é possível que a tua obra tenha violado os Termos de Serviço + do Arquivo, por favor %{contact_abuse_link}. + import_project: + html: Se a tua obra fazia parte de um projeto importado gerido pela nossa + equipa do Open Doors (Portas Abertas), por favor %{opendoors_link} com as + tuas questões. + text: Se a tua obra fazia parte de um projeto importado gerido pela nossa + equipa do Open Doors (Portas Abertas), por favor contacta o Portas Abertas + (%{opendoors_link}) com quaisquer questões que tenhas. + opendoors: contacta o Portas Abertas + subject: "[%{app_name}] A tua obra foi eliminada por uma pessoa administradora" + text: + tos_violation: Se é possível que a tua obra tenha violado os Termos de Serviço + do Arquivo, por favor contacta o nosso Comité de Políticas e Abuso (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Ainda poderás aceder à obra oculta através do link indicado acima, mas + esta não aparecerá na tua página de obras e não estará disponível para outras + pessoas utilizadoras do AO3. + check_email: Por favor verifica o teu email, incluindo a tua pasta de spam, + pois a equipa de Políticas e Abuso pode já te ter contactado para explicar + porque é que a tua obra foi ocultada. + contact_abuse: contacta a equipa de Políticas e Abuso + html: + help: Se não sabes porque é que a tua obra foi ocultada e não recebeste mais + nenhuma comunicação sobre o assunto, por favor %{contact_abuse_link} diretamente. + hidden: A tua obra %{title} foi ocultada pela equipa de Políticas e Abuso + e já não está acessível publicamente. + tos_violation: Se a tua obra foi ocultada por infringir os %{tos_link} do + AO3, será necessário que faças algo para corrigir a infração. Caso não tomes + as medidas necessárias para a tua obra estar em conformidade com os Termos + de Serviço, a tua obra poderá ser eliminada do AO3. + subject: "[%{app_name}] A tua obra foi ocultada pela equipa de Políticas e Abuso" + text: + help: 'Se não sabes porque é que a tua obra foi ocultada e não recebeste mais + nenhuma comunicação sobre o assunto, por favor contacta a equipa de abuso + diretamente: %{contact_abuse_url}.' + hidden: A tua obra "%{title}" (%{work_url}) foi ocultada pela equipa de Políticas + e Abuso e já não está acessível publicamente. + tos_violation: Se a tua obra foi ocultada por infringir os Termos de Serviço + (%{tos_url}) do AO3, será necessário que faças algo para corrigir a infração. + Caso não tomes as medidas necessárias para a tua obra estar em conformidade + com os Termos de Serviço, a tua obra poderá ser eliminada do AO3. + tos: Termos de Serviço + anonymous_or_unrevealed_notification: + anonymous_info: Obras anónimas são incluídas em listas de tags, mas não na tua + página de obras. Na obra, o teu nome de utilizador será substituído por “Anonymous” + (Anónimo). + anonymous_unrevealed_info: As pessoas responsáveis pela coleção podem revelar + a tua obra mais tarde mas mantê-la anónima. As pessoas que te subscrevem não + serão notificadas sobre esta alteração. Uma vez revelada, a tua obra será + incluída nas listas de tags, mas não na tua página de obras. Na obra, o teu + nome de utilizador será substituído por “Anonymous” (Anónimo). + changed_status: + anonymous: + html: As pessoas responsáveis por manter a coleção %{collection_link} alteraram + o estado da tua obra %{work_link} para “anónima”. + text: As pessoas responsáveis por manter a coleção "%{collection_title}" + (%{collection_url}) alteraram o estado da tua obra "%{work_title}" (%{work_url}) + para “anónima”. + anonymous_unrevealed: + html: As pessoas responsáveis por manter a coleção %{collection_link} alteraram + o estado da tua obra %{work_link} para “anónima” e “não revelada”. + text: As pessoas responsáveis por manter a coleção "%{collection_title}" + (%{collection_url}) alteraram o estado da tua obra "%{work_title}" (%{work_url}) + para “anónima” e “não revelada”. + unrevealed: + html: As pessoas responsáveis por manter a coleção %{collection_link} alteraram + o estado da tua obra %{work_link} para “não revelada”. + text: As pessoas responsáveis por manter a coleção "%{collection_title}" + (%{collection_url}) alteraram o estado da tua obra "%{work_title}" (%{work_url}) + para “não revelada”. + collection_items_link_text: página de Approved Collection Items (Itens de Coleção + Aprovados) + do_not_want: + anonymous: + html: Se não queres que a tua obra seja anónima, por favor visita a tua + %{collection_items_link} para a remover desta coleção. + text: 'Se não queres que a tua obra seja anónima, por favor visita a tua + página de Approved Collection Items (Itens de Coleção Aprovados) para + a remover desta coleção: %{collection_items_url}' + anonymous_unrevealed: + html: Se não queres que a tua obra seja anónima e fique inacessível até + ser revelada, por favor visita a tua %{collection_items_link} para a remover + desta coleção. + text: 'Se não queres que a tua obra seja anónima e fique inacessível até + ser revelada, por favor visita a tua página de Approved Collection Items + (Itens de Coleção Aprovados) para a remover desta coleção: %{collection_items_url}' + unrevealed: + html: Se não queres que a tua obra fique inacessível até ser revelada, por + favor visita a tua %{collection_items_link} para a remover desta coleção. + text: 'Se não queres que a tua obra fique inacessível até ser revelada, + por favor visita a tua página de Approved Collection Items (Itens de Coleção + Aprovados) para a remover desta coleção: %{collection_items_url}' + faq_link_text: FAQs sobre Coleções + more_info: + html: Para mais informações, visita as nossas %{faq_link}. + text: 'Para mais informações, visita as nossas FAQs sobre Coleções: %{faq_url}.' + subject: + anonymous: "[%{app_name}] A tua obra foi tornada anónima" + anonymous_unrevealed: "[%{app_name}] A tua obra foi tornada anónima e não + revelada" + unrevealed: "[%{app_name}] A tua obra foi tornada numa obra não revelada" + unrevealed_info: Obras não reveladas não são incluídas nas listas de tags ou + na tua página de obras. Qualquer pessoa que siga uma ligação para a obra vai + receber um aviso a indicar que, atualmente, não está revelada e que não poderá + aceder ao seu conteúdo. + archivist_added_to_collection_notification: + approved_collection_items_page: página Approved Collection Items (Itens de Coleção + Aprovados) + archivist_notice: Como as pessoas responsáveis pela coleção estão a agir na + sua função oficial como arquivista do Open Doors (Portas Abertas), podem adicionar + a tua obra a esta coleção, mesmo que tenhas desativado a opção de convites + para coleções. As pessoas arquivistas só irão adicionar uma obra a uma coleção + se a obra estava alojada num arquivo importado. + removal_instructions: + html: Se quiseres remover a tua obra desta coleção, por favor visita a tua + %{approved_items_link}. + text: 'Se quiseres remover a tua obra desta coleção, por favor visita a tua + página Approved Collection Items (Itens de Coleção Aprovados): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Uma pessoa arquivista do Open Doors + (Portas Abertas) adicionou a tua obra a uma coleção" + work_added: + html: As pessoas responsáveis pela coleção %{collection_link} adicionaram + a tua obra %{work_link} à sua coleção! + text: As pessoas responsáveis pela coleção "%{collection_title}" (%{collection_url}) + adicionaram a tua obra "%{work_title}" (%{work_url}) à sua coleção! + challenge_assignment_notification: + any: Qualquer + assignment: + html: Foi-te atribuída a seguinte tarefa no desafio %{link} no AO3! + description: 'Descrição:' + due: 'O prazo para esta tarefa é:' + html: + footer: Estás a receber este email porque te inscreveste no desafio %{title}. + Para mais informação acerca deste desafio e os detalhes de contacto das + pessoas moderadoras, por favor visita %{footer_link}. + footer_link: a página de perfil do desafio + look_up: Podes encontrar esta tarefa %{link}. + look_up_link: na tua página Assignments (Tarefas) + optional_tags: 'Tags Opcionais:' + prompts: 'Prompts:' + prompt_url: 'URL da prompt:' + recipient: 'Destinada a:' + recipient_missing: 'Ninguém: contacta uma pessoa moderadora para obter ajuda!' + subject: "[%{app_name}][%{collection_title}] A Tua Tarefa!" + text: + assignment: Foi-te atribuída a seguinte tarefa no desafio "%{collection_title}" + (%{collection_url}) no AO3! + footer: Estás a receber este email porque te inscreveste no desafio %{title} + (%{url}). Para mais informação acerca deste desafio e os detalhes de contacto + das pessoas moderadoras, por favor visita %{profile_url}. + look_up: Podes encontrar esta tarefa na tua página Assignments (Tarefas) em + %{link}. + change_email: + changed: + html: "%{login}, o endereço de email associado à tua conta foi mudado para + %{email}" + text: "%{login}, o endereço de email associado à tua conta foi mudado para + %{email}" + subject: "[%{app_name}] Mudança de email" + collection_notification: + assignments_sent: + complete: Já foram enviadas todas as tarefas. + subject: Tarefas enviadas + html: + received_message: 'Recebeste uma mensagem acerca da tua coleção %{collection_link}:' + text: + received_message: 'Recebeste uma mensagem acerca da tua coleção "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Quando és pessoa cocriadora numa obra, podes ser adicionada a novos + capítulos, independentemente das tuas definições de cocriação. Podes ainda + ser adicionada a quaisquer séries às quais a obra for adicionada. + html: + creation: "%{creation_link} por %{pseud_links}" + edit_chapter: editar o capítulo + edit_series: editar a série + remove_chapter: Se te adicionaram por engano ou não quiseres aparecer como + pessoa criadora, podes %{edit_chapter_link} para te removeres como pessoa + criadora. + remove_series: Caso a tua adição tenha sido por erro, ou não queiras aparecer + como pessoa criadora, podes %{edit_series_link} para te retirares como pessoa + criadora. + intro_chapter: 'A pessoa utilizadora %{adding_user} listou o teu pseudónimo + %{pseud} como cocriador no seguinte capítulo:' + intro_series: 'A pessoa utilizadora %{adding_user} listou o teu pseudónimo %{pseud} + como cocriador no na seguinte série:' + subject: "[%{app_name}] Notificação de Pessoa Cocriadora" + text: + creation: "%{title} (%{url}) por %{pseuds}" + remove_chapter: 'Se te adicionaram por engano ou não quiseres aparecer como + pessoa criadora, podes editar o capítulo para te removeres como pessoa criadora: + %{url}' + remove_series: 'Caso a tua adição tenha sido por erro, ou não queiras aparecer + como pessoa criadora, podes editar a série para te retirares como pessoa + criadora: %{url}' + creatorship_notification_archivist: + explanation: Como está a agir na sua capacidade como arquivista do Open Doors + (Portas Abertas), esta pessoa está autorizada a adicionar-te sem um pedido, + mesmo se tiveres a opção de co-criação desativada. + html: + creation: "%{creation_link} por %{pseud_links}" + edit_chapter: editar o capítulo + edit_series: editar a série + edit_work: editar a obra + remove_chapter: Se te adicionaram por engano ou não quiseres aparecer como + pessoa criadora, podes %{edit_chapter_link} para te removeres como pessoa + criadora. + remove_series: Se te adicionaram por engano ou não quiseres aparecer como + pessoa criadora, podes %{edit_series_link}para te removeres como pessoa + criadora. + remove_work: Se te adicionaram por engano ou não quiseres aparecer como pessoa + criadora, podes %{edit_work_link} para te removeres como pessoa criadora. + intro_chapter: 'A pessoa utilizadora %{archivist} adicionou o teu pseudónimo + %{pseud} como pessoa co-criadora do seguinte capítulo:' + intro_series: 'A pessoa utilizadora %{archivist} adicionou o teu pseudónimo + %{pseud} como pessoa co-criadora da seguinte série:' + intro_work: 'A pessoa utilizadora %{archivist} adicionou o teu pseudónimo %{pseud} + como pessoa co-criadora da seguinte obra:' + subject: "[%{app_name}] Notificação de adição como pessoa co-criadora por arquivista" + text: + creation: "%{title} (%{url}) por %{pseuds}" + remove_chapter: 'Se te adicionaram por engano ou não quiseres aparecer como + pessoa criadora, podes editar o capítulo para para te removeres como pessoa + criadora: %{url}' + remove_series: 'Se te adicionaram por engano ou não quiseres aparecer como + pessoa criadora, podes editar a série para te removeres como pessoa criadora: + %{url}' + remove_work: 'Se te adicionaram por engano ou não quiseres aparecer como pessoa + criadora, podes editar a obra para te removeres como pessoa criadora: %{url}' + creatorship_request: + html: + creation: "%{creation_link} por %{pseud_links}" + instructions: Podes aceitar ou rejeitar este pedido na tua página de %{page_name}. + page_name: Co-Creator Requests (Pedidos de Pessoa Co-Criadora) + intro_chapter: 'A pessoa utilizadora %{inviting_user} convidou o teu pseudónimo + %{pseud} para ser listado como pessoa co-criadora do seguinte capítulo:' + intro_series: 'A pessoa utilizadora %{inviting_user} convidou o teu pseudónimo + %{pseud} para ser listado como pessoa co-criadora da seguinte série:' + intro_work: 'A pessoa utilizadora %{inviting_user} convidou o teu pseudónimo + %{pseud} para ser listado como pessoa co-criadora da seguinte obra:' + subject: "[%{app_name}] Pedido de pessoa co-criadora" + text: + creation: "%{title} (%{url}) por %{pseuds}" + instructions: 'Podes aceitar ou rejeitar este pedido na tua página de Co-Creator + Requests (Pedidos de Pessoa Co-Criadora): %{url}' + delete_work_notification: + attachment: Segue em anexo uma cópia da tua obra para tua referência. + deleted_other: + html: A tua obra %{title} foi eliminada a pedido de %{pseud}. + text: A tua obra "%{title}" foi eliminada a pedido de %{pseud}. + deleted_yourself: + html: A tua obra %{title} foi eliminada a teu pedido. + text: A tua obra "%{title}" foi eliminada a teu pedido. + questions: + html: Se tiveres alguma pergunta, por favor %{support}. + text: Se tiveres alguma questão, por favor %{support} (%{url}). + subject: "[%{app_name}] A tua obra foi eliminada" + support: contacta a equipa de Suporte + invitation_to_claim: + access: + text: Dependendo do arquivo, as tuas obras podem ter sido importadas com restrições + para que apenas pessoas utilizadoras registadas as possam ver (de modo a + não serem visíveis em pesquisas no Google). Se for este o caso, as obras + irão apenas estar acessíveis a pessoas utilizadoras que tenham sessão iniciada, + a não ser que escolhas torná-las completamente visíveis. Para obteres ajuda + para desbloquear, orfanar ou eliminar as tuas obras, por favor entra em + contacto com a equipa de Suporte. + claim_or_remove: + html: Reivindica ou elimina as tuas obras aqui. + text: 'Reivindica ou elimina as tuas obras aqui: %{claim_url}' + email_tips: Se quiseres entrar em contacto connosco, por favor inclui os emails + de @transformativeworks.org na tua lista de permissões e verifica as tuas + pastas de spam para veres a nossa resposta. + html: + ao3_news: Notícias do AO3 + contact_open_doors: contacta o Open Doors (Portas Abertas) + contact_support: contacta a equipa de Suporte do AO3 + faq_page: página de Perguntas Frequentes (FAQs) + tutorial_page: página do tutorial + introduction: + text: Estás a receber este email porque um arquivo foi recentemente importado + pelo Open Doors (Portas Abertas) (%{open_doors_link}) para o %{app_name} + (%{app_short_name} - %{app_url}), e cremos que as seguintes obras de fãs + te pertencem. Gostaríamos de te dar uma oportunidade para reivindicar (ou + eliminar/orfanar) estas obras se assim o desejares. E se não tiveres já + uma conta com um email diferente, gostaríamos de te convidar! + mistake: + text: Se recebeste este email por engano e estas não são as tuas obras, por + favor não as apagues! Entra em contacto com o Portas Abertas (%{open_doors_link}) + e iremos resolver o problema. + more_info: + text: 'Podes ler as publicações acerca das mudanças de arquivos recentes nas + Notícias do AO3 (%{news_link}), e podes aceder a informação adicional sobre + o Portas Abertas na página de Perguntas Frequentes (FAQs) (%{open_doors_faq_link}) + ou na página de tutoriais (%{open_doors_tutorial_link}). Para quaisquer + questões não respondidas nas Perguntas Frequentes, nos tutoriais ou neste + email, por favor entra em contacto com a equipa de Suporte: %{support_link}.' + other_works: + text: Se tens outras obras no arquivo importado com um endereço de email ao + qual já não tens acesso, por favor entra em contacto com o Portas Abertas + com toda a informação que possa ajudar a verificar a tua identidade. + questions: + text: Para outras questões, por favor entra em contacto com a equipa de Suporte + do AO3 em %{support_link}. + redirects: Para preservar listas de recomendações e favoritos, os endereços + dos arquivos importados podem redirecionar para a cópia importada destas obras + durante algum tempo (consulta a publicação que anuncia a importação do arquivo + para confirmares). Se já fizeste upload de uma cópia destas obras e NÃO usaste + a função de importar de um URL, irão existir duas cópias da mesma obra no + arquivo. + subject: "[%{app_name}] Convite para reivindicar obras" + unwanted: + text: 'Se estas obras são tuas mas não as queres, podes orfaná-las (para que + continuem no AO3, mas sem o teu nome) ou eliminá-las (para que sejam completamente + removidas do AO3). Não precisas de adicionar estas obras a nenhuma conta + para poderes orfaná-las ou eliminá-las -- podes fazê-lo diretamente através + do link de reivindicação acima. (Para obteres ajuda, por favor entra em + contacto com a equipa de Suporte: %{support_link}.)' + update_redirect: + text: Se queres que o Portas Abertas atualize a redireção para que vá diretamente + para a tua obra já existente, por favor elimina a cópia importada, e entra + em contacto com o Portas Abertas em %{open_doors_link} com o teu nome de + pessoa utilizadora do AO3, o nome da tua conta no arquivo importado, e o + título e URL da obra de fã para onde queres que a redireção vá. (Se tens + várias obras que gostarias que fossem redirecionadas, podes simplesmente + listá-las num único email.) + uploaded_list: 'Foi feito upload das seguintes obras:' + invite_increase_notification: + html: + body: + one: Queremos apenas informar-te de que tens %{count} novo convite, que + pode ser utilizado para criar uma nova conta no AO3. Podes convidar uma + pessoa amiga a partir da %{invitation_page_link}. + other: Queremos apenas informar-te de que tens %{count} novos convites, + que podem ser utilizados para criar novas contas no AO3. Podes convidar + pessoas amigas a partir da %{invitation_page_link}. + invitation_page_link_text: tua página de convites + subject: "[%{app_name}] Novos Convites" + text: + body: + one: Queremos apenas informar-te de que tens %{count} novo convite, que + pode ser utilizado para criar uma nova conta no AO3. Podes convidar uma + pessoa amiga a partir da tua página Invitations (Convites) (%{invitation_page_url}). + other: Queremos apenas informar-te de que tens %{count} novos convites, + que podem ser utilizados para criar novas contas no AO3. Podes convidar + pessoas amigas a partir da tua página Invitations (Convites) (%{invitation_page_url}). + invite_request_declined: + main: + one: Lamentamos informar que, de momento, não podemos satisfazer o teu pedido + de um novo convite. + other: Lamentamos informar que, de momento, não podemos satisfazer o teu pedido + de %{count} novos convites. + reason: 'O teu pedido foi:' + subject: "[%{app_name}] Pedido de Código de Convite Adicional Recusado" + recipient_notification: + html: + collection: Foi publicada uma obra presente para ti na coleção %{collection_link} + no AO3! + no_collection: Foi publicada uma obra presente para ti no AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Uma obra presente para ti + de %{collection_title}" + no_collection: "[%{app_name}] Uma obra presente para ti" + text: + collection: Foi publicada uma obra presente para ti na coleção "%{collection_title}" + (%{collection_url}) no AO3! + signup_notification: + activate: + html: Por favor, %{activate_account_link}. + text: 'Por favor, segue este link para ativar a tua conta: %{activate_account_url}' + activate_your_account: segue este link para ativar a tua conta + admin_posts: Notícias do AO3 + bye: Esperamos que gostes de utilizar o Arquivo. + contact_support: contacta o Suporte + faq: FAQs (Perguntas Frequentes) + features: + html: Assim que a tua conta estiver a funcionar, podes publicar as tuas obras + de fã, configurar subscrições de email para receberes atualizações das tuas + pessoas criadoras ou obras favoritas, definir preferências para personalizares + o aspeto e o funcionamento do site, manter registos das obras que acedeste + no Arquivo através do teu histórico e muito mais. + text: Assim que a tua conta estiver a funcionar, podes publicar obras de fã, + configurar subscrições de email para receberes atualizações das tuas pessoas + criadoras ou obras favoritas, definir preferências para personalizares o + aspeto e o funcionamento do site, manter registos das obras que acedeste + no Arquivo através do teu histórico e muito mais. + information: + html: Há muita informação e muitos conselhos sobre a utilização do Arquivo + nas nossas %{faq_link}. Encontrarás as últimas notícias sobre os desenvolvimentos + do site nas nossas %{admin_posts_link}. Se precisares de mais ajuda, encontrares + um bug ou tiveres questões ou comentários, por favor, %{contact_support_link}, + que está sempre disponível para te ajudar. + text: 'Há muita informação e muitos conselhos sobre a utilização do Arquivo + nas nossas %{faq_url}. Encontrarás as últimas notícias sobre os desenvolvimentos + do site nas notícias do AO3 no %{admin_posts_url}. Se precisares de mais + ajuda, encontrares um bug ou tiveres questões ou comentários, por favor, + contacta a nossa equipa de Suporte, que está sempre disponível para te ajudar: + %{contact_support_url}.' + welcome: Damos-te as boas vindas ao Archive of Our Own, %{login}! diff --git a/config/locales/phrase-exports/ro.yml b/config/locales/phrase-exports/ro.yml new file mode 100755 index 0000000..64b026c --- /dev/null +++ b/config/locales/phrase-exports/ro.yml @@ -0,0 +1,672 @@ +--- +ro: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Avertismente:' + one: 'Avertisment:' + other: 'Avertismente:' + category: + name_with_colon: + few: 'Categorii:' + one: 'Categorie:' + other: 'Categorii:' + character: + name_with_colon: + few: 'Personaje:' + one: 'Personaj:' + other: 'Personaje:' + fandom: + name_with_colon: + few: 'Fandomuri:' + one: 'Fandom:' + other: 'Fandomuri:' + freeform: + name_with_colon: + few: 'Tag-uri adiționale:' + one: 'Tag adițional:' + other: 'Tag-uri adiționale:' + rating: + name_with_colon: 'Rating:' + relationship: + name_with_colon: + few: 'Relații:' + one: 'Relație:' + other: 'Relații:' + work: + chapter_total_display: Capitole + summary: Rezumat + models: + archive_warning: + few: Avertismente + one: Avertisment + other: Avertismente + category: + few: Categorii + one: Categorie + other: Categorii + chapter: + few: Capitole + one: Capitole + other: Capitole + character: + few: Personaje + one: Personaj + other: Personaje + fandom: + few: Fandomuri + one: Fandom + other: Fandomuri + freeform: + few: Tag-uri adiționale + one: Tag adițional + other: Tag-uri adiționale + rating: + few: Ratinguri + one: Rating + other: Ratinguri + relationship: + few: Relații + one: Relație + other: Relații + series: + few: Serii + one: Serie + other: Serii + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} vizitatori" + one: un vizitator + other: "%{count} de vizitatori" + left_kudos: + html: + few: "%{givers_list} au lăsat kudos pentru %{commentable_link}." + one: "%{givers_list} a lăsat kudos pentru %{commentable_link}." + other: "%{givers_list} au lăsat kudos pentru %{commentable_link}." + text: + few: "%{givers_list} au lăsat kudos pentru %{commentable_title} (%{commentable_url})." + one: "%{givers_list} a lăsat kudos pentru %{commentable_title} (%{commentable_url})." + other: "%{givers_list} au lăsat kudos pentru %{commentable_title} (%{commentable_url})." + single_guest: + giver: Un vizitator + html: "%{giver} a lăsat kudos pentru %{commentable_link}." + text: Un vizitator a lăsat kudos pentru %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Ai primit kudos!" + mailer: + general: + closing: + formal: Cu drag, + informal: Cu drag, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Capitolul %{position} din %{title} + title_with_word_count: „%{creation_title}" (%{word_count}) + word_count: + few: "%{count} cuvinte" + one: "%{count} cuvânt" + other: "%{count} de cuvinte" + footer: + general: + about: + html: AO3 este o arhivă administrată și susținută de fani care se bazează + pe %{donate_link}. + text: 'AO3 este o arhivă administrată și susținută de fani care se bazează + pe donațiile tale: %{donate_url}.' + html: + donate_link_text: donațiile tale + support_link_text: să contactezi echipa de Suport Tehnic + unwanted_email: + html: Dacă ai primit acest mesaj din greșeală te rugăm %{support_link}. + text: Dacă ai primit acest mesaj din greșeală te rugăm să contactezi echipa + de Suport Tehnic la %{support_url}. + sent_at: Trimis %{sent_at}. + greeting: + formal_html: Bună %{name}, + informal: + addressed_html: Bună %{name}! + unaddressed: Salut! + introductory: Salutări de la Archive of Our Own - AO3 (Arhiva Noastră)! + metadata_label_indicator: ":" + signature: + abuse_team: Echipa de Politici și Abuz AO3 + app_short_name: AO3 + open_doors: Echipa Open Doors (Uși Deschise) + parent_org: Organization for Transformative Works (Organizația pentru Lucrări + Transformative) + support: Echipa de Suport Tehnic AO3 + users: + mailer: + reset_password_instructions: + expiration: Dacă nu folosești acest link în următoarele șapte zile pentru + a-ți reseta parola, va trebui să ceri un link nou. + intro: 'Cineva a solicitat resetarea parolei pentru contul tău. Pentru a-ți + schimba parola, urmează link-ul de mai jos și introdu o parolă nouă:' + link_title: Schimbă parola. + subject: "[%{app_name}] Resetează-ți parola" + unrequested: Dacă nu ai solicitat schimbarea parolei, ignoră acest e-mail + și continuă să-ți folosești parola actuală. + user_mailer: + admin_deleted_work_notification: + bye: Îți trimitem în atașament o copie a lucrării tale, ca reper. + contact_abuse: contactează Comitetul de Politici și Abuz + deleted: + html: Lucrarea ta %{title} a fost ștearsă din Arhivă de către un administrator + al site-ului. + text: Lucrarea ta %{title} a fost ștearsă din Arhivă de către un administrator + al site-ului. + html: + tos_violation: Dacă e posibil ca lucrarea ta să fi încălcat Termenii de Servicii + ai Arhivei, %{contact_abuse_link}. + import_project: + html: Dacă lucrarea ta făcea parte dintr-un proiect de importare gestionat + de echipa noastră Open Doors (Uși Deschise), te rugăm %{opendoors_link} + dacă ai întrebări suplimentare. + text: Dacă lucrarea ta făcea parte dintr-un proiect de importare gestionat + de echipa noastră Open Doors (Uși Deschise), te rugăm contactează Open Doors + (%{opendoors_link}) dacă ai întrebări suplimentare. + opendoors: contactează Open Doors + subject: "[%{app_name}] Lucrarea ta a fost ștearsă de către un administrator" + text: + tos_violation: Dacă e posibil ca lucrarea ta să fi încălcat Termenii de Servicii + ai Arhivei, te rugăm contactează Comitetul de Politici și Abuz (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Cât timp lucrarea ta este ascunsă, vei putea în continuare să o accesezi + prin link-ul furnizat mai sus, dar nu va fi listată pe pagina ta de lucrări + și nu va fi disponibilă pentru alți utilizatori ai AO3. + check_email: Te rugăm să îți verifici e-mailul, inclusiv folderul de spam, deoarece + este posibil ca echipa Politici și Abuz să te fi contactat deja, explicând + de ce lucrarea ta a fost ascunsă. + contact_abuse: să contactezi echipa de Politici și Abuz + html: + help: Dacă nu ești sigur/ă de ce lucrarea ta a fost ascunsă și nu ai fost + contactat/ă cu privire la această problemă, te rugăm %{contact_abuse_link} + direct. + hidden: Lucrarea ta %{title} a fost ascunsă de echipa de Politici și Abuz + și nu mai este accesibilă publicului. + tos_violation: Dacă lucrarea ta a fost ascunsă din cauza încălcării %{tos_link} + ai AO3, ți se va cere să iei măsuri pentru a corecta încălcarea. Dacă lucrarea + ta în continuare nu respecta Termenii de Servicii, acest lucru poate conduce + la ștergerea lucrării tale de pe AO3. + subject: "[%{app_name}] Lucrarea ta a fost ascunsă de echipa de Politici și + Abuz" + text: + help: Dacă nu ești sigur/ă de ce lucrarea ta a fost ascunsă și nu ai fost + contactat/ă cu privire la această problemă, te rugăm să contactezi echipa + de Politici și Abuz %{contact_abuse_url} direct. + hidden: Lucrarea ta "%{title}" (%{work_url}) a fost ascunsă de echipa de Politici + și Abuz și nu mai este accesibilă publicului. + tos_violation: Dacă lucrarea ta a fost ascunsă din cauza încălcării (%{tos_url}) + ai AO3, ți se va cere să iei măsuri pentru a corecta încălcarea. Dacă lucrarea + ta în continuare nu respecta Termenii de Servicii, acest lucru poate conduce + la ștergerea lucrării tale de pe AO3. + tos: Termenilor de Servicii + anonymous_or_unrevealed_notification: + anonymous_info: Lucrările anonime sunt incluse pe listele generate de tag-uri, + dar nu și pe pagina ta de lucrări. Pe lucrare, numele tău de utilizator va + fi înlocuit cu "Anonymous" („Anonim”). + anonymous_unrevealed_info: Administratorii colecției pot dezvălui lucrarea ta + ulterior, dar sa o lase anonima. Persoanele care sunt abonate la pagina ta + nu vor primit notificare despre aceasta schimbare. Odată dezvăluită, lucrarea + va fi inclusă pe listele generate de tag-uri, dar nu și pe pagina ta de lucrări. + Pe lucrare numele tău de utilizator va fi înlocuit cu "Anonymous" (Anonim). + changed_status: + anonymous: + html: Administratorii colecției %{collection_link} au marcat ca anonim statusul + lucrării tale %{work_link}. + text: Administratorii colecției „%{collection_title}” (%{collection_url}) + au schimbat statusul lucrării tale „%{work_title}” (%{work_url}) în anonimă. + anonymous_unrevealed: + html: Administratorii colecției %{collection_link} au marcat ca anonim și + nedezvăluit statusul lucrării tale %{work_link}. + text: Administratorii colecției „%{collection_title}” (%{collection_url}) + au schimbat statusul lucrării tale „%{work_title}” (%{work_url}) în anonimă + și nedezvăluită. + unrevealed: + html: Administratorii colecției %{collection_link} au marcat ca nedezvăluit + statusul lucrării tale %{work_link}. + text: Administratorii colecției „%{collection_title}” (%{collection_url}) + au schimbat statusul lucrării tale „%{work_title}” (%{work_url}) în nedezvăluită. + collection_items_link_text: pagina Approved Collection Items (Lucrări Aprobate + pentru Colecții) + do_not_want: + anonymous: + html: Dacă nu dorești ca lucrarea ta să fie anonimă, te rugăm vizitează + %{collection_items_link} pentru a o șterge din aceasta colecție. + text: 'Dacă nu dorești ca lucrarea ta să fie anonimă, te rugăm vizitează + pagina Approved Collection Items (Lucrări Aprobate pentru Colecții) pentru + a o șterge din aceasta colecție: %{collection_items_url}' + anonymous_unrevealed: + html: Dacă nu dorești ca lucrarea ta să fie nedezvăluită și anonimă, te + rugăm vizitează %{collection_items_link} pentru a o șterge din aceasta + colecție + text: 'Dacă nu dorești ca lucrarea ta să fie nedezvăluită și anonimă, te + rugăm vizitează pagina Approved Collection Items (Lucrări Aprobate pentru + Colecții) pentru a o șterge din aceasta colecție: %{collection_items_url}' + unrevealed: + html: Dacă nu dorești ca lucrarea ta să fie nedezvăluită, te rugăm vizitează + %{collection_items_link} pentru a o șterge din aceasta colecție. + text: 'Dacă nu dorești ca lucrarea ta să fie nedezvăluită, te rugăm vizitează + pagina Approved Collection Items (Lucrări Aprobate pentru Colecții) pentru + a o șterge din aceasta colecție: %{collection_items_url}' + faq_link_text: Întrebări Frecvente despre Colecții + more_info: + html: Pentru mai multe informații vizitează %{faq_link}. + text: 'Pentru mai multe informații vizitează Întrebări Frecvente despre Colecții: + %{faq_url}' + subject: + anonymous: "[%{app_name}] Lucrarea ta a fost marcată ca anonimă" + anonymous_unrevealed: "[%{app_name}] Lucrarea ta a fost marcată ca anonimă + și nedezvăluită" + unrevealed: "[%{app_name}] Lucrarea ta a fost marcată ca nedezvăluită" + unrevealed_info: Lucrările nedezvăluite nu sunt incluse pe listele generate + de tag-uri sau pe pagina ta de lucrări. Oricine folosește un link către lucrare + va primi o notificare că nu este dezvăluită în prezent și nu va putea accesa + conținutul acesteia. + archivist_added_to_collection_notification: + approved_collection_items_page: Pagina ta de Approved Collection Items (Lucrări + Aprobate pentru Colecții) + archivist_notice: Deoarece întreținătorii colecției acționează în calitate oficială + de arhivari ai Open Doors (Uși Deschise), au permisiunea să adauge lucrarea + ta la această colecție, chiar dacă ai dezactivat invitațiile la colecții. + Arhivarii vor adăuga o lucrare la o colecție doar dacă aceasta a fost găzduită + pe o arhivă importată. + removal_instructions: + html: Dacă dorești să elimini lucrarea ta din această colecție, te rugăm să + vizitezi %{approved_items_link}. + text: 'Dacă dorești să elimini lucrarea ta din această colecție, te rugăm + să vizitezi pagina ta de Approved Collection Items (Lucrări Aprobate pentru + Colecții): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Un arhivar Open Doors (Uși Deschise) + a adăugat lucrarea ta la o colecție" + work_added: + html: Întreținătorii colecției %{collection_link} au adăugat lucrarea ta %{work_link} + la colecția lor! + text: Întreținătorii colecției „%{collection_title}" (%{collection_url}) au + adăugat lucrarea ta „%{work_title}" (%{work_url}) la colecția lor! + challenge_assignment_notification: + any: Oricare + assignment: + html: Ai primit sarcina de mai jos în provocarea %{link} pe AO3! + description: 'Descriere:' + due: 'Aceasta sarcină trebuie îndeplinită până pe:' + html: + footer: Ai primit acest email pentru că te-ai înscris în provocarea %{title}. + Pentru mai multe detalii despre această provocare și detaliile de contact + ale moderatorilor/ moderatoarelor, te rugăm să accesezi %{footer_link}. + footer_link: pagina de profil a provocării + look_up: Poți să verifici această sarcină pe %{link}. + look_up_link: pagina ta de Assignments (Sarcini) + optional_tags: 'Tag-uri opționale:' + prompts: 'Sugestii:' + prompt_url: 'Link pentru sugestie:' + recipient: 'Destinatar:' + recipient_missing: 'Nici unul/ una: contactează un moderator/ o moderatoare + pentru ajutor!' + subject: "[%{app_name}][%{collection_title}] Sarcina ta!" + text: + assignment: Ai primit sarcina de mai jos în provocarea "%{collection_title}" + (%{collection_url}) pe AO3! + footer: Ai primit acest email pentru că te-ai înscris în provocarea %{title} + (%{url}). Pentru mai multe detalii despre această provocare și detaliile + de contact ale moderatorilor/ moderatoarelor, te rugăm să accesezi %{profile_url}. + look_up: Poți să verifici această sarcină pe pagina ta de Assignments (Sarcini), + accesând %{link}. + change_email: + changed: + html: "%{login}, adresa de e-mail asociată cu contul tău a fost schimbată + la %{email}" + text: "%{login}, adresa de e-mail asociată cu contul tău a fost schimbată + la %{email}" + subject: "[%{app_name}] Adresa de e-mail schimbată" + claim_notification: + access: + contact_support: contactează echipa de Suport Tehnic AO3 + html: În funcție de arhivă, este posibil ca lucrările tale să fi fost importate + cu acces limitat doar la utilizatorii/oarele înregistrați/e (pentru a le + ascunde de căutările Google). Dacă ăsta este cazul, lucrările vor fi accesibile + numai utilizatorilor/elor conectați/e, cu excepția cazului în care alegi + să le faci pe deplin vizibile. Pentru ajutor cu deblocarea, abandonarea + sau ștergerea lucrărilor tale, te rugăm %{contact_support_link}. + text: În funcție de arhivă, este posibil ca lucrările tale să fi fost importate + cu acces limitat doar la utilizatorii/oarele înregistrați/e (pentru a le + ascunde de căutările Google). Dacă ăsta este cazul, lucrările vor fi accesibile + numai utilizatorilor/elor conectați/e, cu excepția cazului în care alegi + să le faci pe deplin vizibile. Pentru ajutor cu deblocarea, abandonarea + sau ștergere a lucrărilor tale, te rugăm contactează echipa de Suport Tehnic + AO3 pe %{support_url}. + email_tips: Dacă ne contactezi, te rugăm să adaugi adrese de email de la @transformativeworks.org + la lista ta de contacte sigure și să verifici folderul de spam pentru răspunsul + nostru. + introduction: + ao3_name: Archive of Our Own – AO3 (Arhiva Noastră) + html: Primești acest email deoarece aveai lucrări într-o arhivă de lucrări + fanice care a fost importată de %{open_doors_name_link} pe %{app_link}. + Deoarece această adresă de email este conectată la o adresă înscrisă pe + arhiva importată, lucrările fanice asociate (enumerate mai jos) au fost + adăugate automat în contul tău AO3. + open_doors_name: Open Doors (Uși Deschise) + text: 'Primești acest email deoarece aveai lucrări într-o arhivă de lucrări + fanice care a fost importată de Open Doors (Uși Deschise) (%{open_doors_url}) + pe Archive of Our Own – AO3 (Arhiva Noastră): %{app_url}. Deoarece această + adresă de email este conectată la o adresă înscrisă pe arhiva importată, + lucrările fanice asociate (enumerate mai jos) au fost adăugate automat în + contul tău AO3.' + mistake: + contact_open_doors: contactează echipa Uși Deschise + html: Dacă e o greșeală și acestea nu sunt lucrările tale, te rugăm să nu + le ștergi! Te rugăm doar %{contact_open_doors_link} și vom rezolva problema. + text: Dacă e o greșeală și acestea nu sunt lucrările tale, te rugăm să nu + le ștergi! Te rugăm doar contactează echipa Uși Deschise (%{open_doors_url}) + și vom rezolva problema. + more_info: + ao3_news: Știri AO3 + contact_support: contactează echipa de Suport Tehnic AO3 + faq_page: pagina de Întrebări Frecvente + html: Poți citi anunțuri despre mutarea recentă a arhivei pe %{ao3_news_link} + și poți găsi informații suplimentare pe %{faq_page_link} sau %{tutorial_page_link} + ale Open Doors. Pentru orice întrebări la care nu ai găsit răspuns în Întrebările + Frecvente, tutoriale sau în acest email, te rugăm %{contact_support_link}. + text: Poți citi anunțuri despre mutarea recentă a arhivei pe AO3 News (%{news_url}) + și poți găsi informații suplimentare pe pagina de Întrebări Frecvente (%{open_doors_faq_url}) + sau pagina de tutoriale ale Open Doors. Pentru orice întrebări la care nu + ai găsit răspuns în Întrebările Frecvente, tutoriale sau in acest email, + te rugăm contactează echipa de Suport Tehnic la %{support_url}. + tutorial_page: pagina de tutorial + other_works: + contact_open_doors: contactează echipa Uși Deschise + html: Dacă ai avut alte lucrări în arhiva importată sub o adresă de e-mail + pe care nu o mai poți accesa, te rugăm %{contact_open_doors_link} cu orice + informații care te pot ajuta să îți dovedești identitatea. + text: Dacă ai avut alte lucrări în arhiva importată sub o adresă de e-mail + pe care nu o mai poți accesa, te rugăm contactează echipa Uși Deschise cu + orice informații care te pot ajuta să îți dovedești identitatea. + questions: + contact_support: contactează echipa de Suport Tehnic AO3 + html: Pentru alte întrebări, te rugăm %{contact_support_link}. + text: Pentru alte întrebări, te rugăm contactează echipa de Suport Tehnic + AO3 la %{support_url}. + redirects: + html: Pentru a păstra listele de recomandări și semnele de carte, adresele + web ale arhivei importate pot redirecționa către copia importată a acestor + lucrări pentru un timp limitat (verifică postarea de anunț pentru arhivata + pentru a fi sigur/ă). Dacă ai încărcat deja o copie a acestor lucrări și + %{negation} ai folosit funcția de import din URL, vor exista două copii + ale aceleiași lucrări pe AO3. + subject: "[%{app_name}] Lucrări încărcate" + update_redirect: + contact_open_doors: contactează echipa Uși Deschise + html: Dacă dorești ca Open Doors să actualizeze redirecționarea pentru a ajunge + la lucrarea ta existentă, te rugăm să ștergi copia importată și %{contact_open_doors_link} + } cu numele contului tău AO3, numele contului tău din arhiva importată și + titlul și adresa URL a lucrării fanice la care ai dori să conducă redirecționarea. + (Dacă ai mai multe lucrări pentru care dorești să modifici redirecționările, + le poți enumera într-un singur email.) + text: Dacă dorești ca Open Doors să actualizeze redirecționarea pentru a ajunge + la lucrarea ta existentă, te rugăm să ștergi copia importată și contactează + echipa Uși Deschise la %{open_doors_url} cu numele contului tău AO3, numele + contului tău din arhiva importată și titlul și adresa URL a lucrării fanice + la care ai dori să conducă redirecționarea. (Dacă ai mai multe lucrări pentru + care dorești să modifici redirecționările, le poți enumera într-un singur + e-mail.) + works_by: 'Aceste lucrări au fost scrise sub e-mailul: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Toate sarcinile au fost acum trimise. + subject: Sarcinile au fost trimise + html: + received_message: 'Ai primit un mesaj despre colecția ta %{collection_link}:' + text: + received_message: 'Ai primit un mesaj despre colecția ta "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Când apari drept co-creator/ co-creatoare la o lucrare, poți fi + adăugat(ă) la capitole noi, indiferent de setările tale pentru co-creator. + De asemenea, vei fi adăugat(ă) la orice serie la care se adaugă lucrarea. + html: + creation: "%{creation_link} de %{pseud_links}" + edit_chapter: edita capitolul + edit_series: edita seria + remove_chapter: Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + drept creator/ creatoare, poți %{edit_chapter_link} pentru a te scoate de + pe lista de creatori. + remove_series: Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + drept creator/ creatoare, poți %{edit_series_link} pentru a te scoate de + pe lista de creatori. + intro_chapter: 'Utilizatorul/ utilizatoarea %{adding_user} a adăugat pseudonimul + tău %{pseud} drept co-creator/ co-creatoare la următorul capitol:' + intro_series: 'Utilizatorul/ utlizatoarea %{adding_user} a adăugat pseudonimul + tău %{pseud} drept co-creator/ co-creatoare la următoarea serie:' + subject: "[%{app_name}] Notificare co-creator/ co-creatoare" + text: + creation: "%{title} (%{url}) de %{pseuds}" + remove_chapter: 'Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + drept creator/ creatoare, poți edita capitolul pentru a te scoate de pe + lista de creatori: %{url}' + remove_series: 'Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + drept creator/ creatoare, poți edita seria pentru a te scoate de pe lista + de creatori: %{url}' + creatorship_notification_archivist: + explanation: Deoarece își exercită capacitatea oficială de arhivar al Open Doors + (Uși Deschise), poate să te adauge fără a trimite o solicitare, chiar dacă + ai funcția de co-creație dezactivată. + html: + creation: "%{creation_link} de %{pseud_links}" + edit_chapter: editezi capitolul + edit_series: editezi seria + edit_work: editezi lucrarea + remove_chapter: Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + pe lista de creatori, poți să %{edit_chapter_link} pentru a te elimina din + lista de creatori. + remove_series: Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + pe lista de creatori, poți să %{edit_series_link} pentru a te elimina din + lista de creatori. + remove_work: Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + pe lista de creatori, poți să %{edit_work_link} pentru a te elimina din + lista de creatori. + intro_chapter: 'Utilizatorul %{archivist} ți-a adăugat pseudonimul %{pseud} + drept co-creator la următorul capitol:' + intro_series: 'Utilizatorul %{archivist} ți-a adăugat pseudonimul %{pseud} drept + co-creator la următoarea serie:' + intro_work: 'Utilizatorul %{archivist} ți-a adăugat pseudonimul %{pseud} drept + co-creator la următoarele lucrări:' + subject: "[%{app_name}] Notificare de co-creator de la arhivar" + text: + creation: "%{title} (%{url}) de %{pseuds}" + remove_chapter: 'Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + pe lista de creatori, poți să editezi capitolul pentru a te elimina din + lista de creatori: %{url}' + remove_series: 'Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + pe lista de creatori, poți să editezi seria pentru a te elimina din lista + de creatori: %{url}' + remove_work: 'Dacă ai fost adăugat(ă) din greșeală sau nu dorești să apari + pe lista de creatori, poți să editezi lucrarea pentru a te elimina din lista + de creatori: %{url}' + creatorship_request: + html: + creation: "%{creation_link} de %{pseud_links}" + instructions: Poți să accepți sau să respingi această cerere pe pagina ta + de %{page_name} + page_name: Co-Creator Requests (Cerere de co-creator/ co-creatoare) + intro_chapter: 'Utilizatorul/ utilizatoarea %{inviting_user} a invitat pseudonimul + tău %{pseud} să fie adaugat la lista de co-creatori/ co-creatoare pentru capitolul + următor:' + intro_series: 'Utilizatorul/ utilizatoarea %{inviting_user} a invitat pseudonimul + tău%{pseud} să fie adaugat la lista de co-creatori/ co-creatoare pentru seria + următoare:' + intro_work: 'Utilizatorul/ utilizatoarea %{inviting_user} a invitat pseudonimul + tău %{pseud} să fie adaugat la lista de co-creatori/ co-creatoare pentru lucrarea + următoare:' + subject: "[%{app_name}] Cerere de co-creator/ co-creatoare" + text: + creation: "%{title} (%{url}) de %{pseuds}" + instructions: Poți să accepți sau să respingi această cerere pe pagina de + Co-Creator Requests (Cereri de co-creator) %{url} + delete_work_notification: + attachment: Atașată este o copie a lucrării tale ca și referință. + deleted_other: + html: Lucrarea ta %{title} a fost ștearsă la cererea lui %{pseud}. + text: Lucrarea ta "%{title}" a fost ștearsă la cererea lui %{pseud}. + deleted_yourself: + html: Lucrarea ta %{title} a fost ștearsă la cererea ta. + text: Lucrarea ta "%{title}" a fost ștearsă la cererea ta. + questions: + html: Dacă ai întrebări, te rugăm %{support}. + text: Dacă ai întrebări, te rugăm %{support} (%{url}). + subject: "[%{app_name}] Lucrarea ta a fost ștearsă" + support: să contactezi echipa de Suport Tehnic + invitation_to_claim: + access: + text: În funcție de arhivă, este posibil ca lucrările tale să fi fost importate + în așa fel încât să fie accesibile numai utilizatorilor înregistrați (pentru + a le păstra în afara căutărilor Google). În cazul acesta, lucrările vor + putea fi accesate doar de către utilizatorii conectați, dacă nu alegi să + le faci vizibile pentru oricine. Pentru ajutor cu deblocarea, abandonarea + sau ștergerea lucrărilor tale, te rugăm să contactezi echipa de Suport Tehnic + AO3. + claim_or_remove: + html: Revendică sau șterge-ți lucrările aici. + text: 'Revendică sau șterge-ti lucrările aici: %{claim_url}' + email_tips: Dacă ne contactezi, te rugăm să adaugi adresele de e-mail de la + @transformativeworks.org la lista ta autorizată și să verifici folderele de + spam pentru a găsi răspunsul de la noi. + html: + ao3_news: Știri AO3 + contact_open_doors: să contactezi Uși Deschise + contact_support: să contactezi echipa de Suport Tehnic AO3 + faq_page: pagina Întrebări Frecvente + tutorial_page: pagina de tutorial + introduction: + text: Ai primit acest e-mail pentru că o arhivă a fost importată recent de + către Open Doors (Uși Deschise) (%{open_doors_link}) în %{app_name} (%{app_short_name} + - %{app_url}) și considerăm că următoarele lucrări îți aparțin. Dorim să + îți oferim opțiunea de a revendica (sau șterge/abandona) aceste lucrări, + dacă vrei. Și dacă nu ai deja un cont înregistrat pe o adresă de e-mail + diferită, dorim să te invităm la bord! + mistake: + text: Dacă am greșit și aceste lucrări nu îți aparțin, te rugăm să nu le ștergi! + Te rugăm doar să contactezi Uși Deschise (%{open_doors_link}) și ne vom + ocupa noi de ele. + more_info: + text: Poți citi anunțuri despre mutări recente ale arhivelor la Știri AO3 + (%{news_link}) și informații suplimentare pe pagina Întrebări Frecvente + (%{open_doors_faq_link}) sau pagina de tutoriale (%{open_doors_tutorial_link}) + ale Uși Deschise. Pentru orice întrebări care nu sunt incluse în Întrebările + Frecvente, tutoriale sau în acest e-mail, te rugăm să contactezi echipa + de Suport Tehnic AO3 la %{support_link}. + other_works: + text: Dacă ai în arhiva importată alte lucrări înregistrate cu adrese de e-mail + pe care nu le mai poți accesa, te rugăm să contactezi Uși Deschise și să + furnizezi orice informație care ne poate ajuta să-ți verificăm identitatea. + questions: + text: Pentru alte întrebări, te rugăm contactează echipa de Suport Tehnic + AO3 la %{support_link}. + redirects: 'Pentru a păstra listele de recomandări sau semnele de carte, adresele + web ale arhivei importate pot redirecționa către copia importată a acestor + lucrări doar pentru o perioadă limitată de timp (verifică postarea anunțului + pentru arhiva ta ca să te asiguri). Dacă ai încărcat deja o copie a acestor + lucrări și NU ai folosit funcția de importare din URL, vor exista două copii + ale aceleiași lucrări în arhivă. ' + subject: "[%{app_name}] Invitație de a revendica lucrări" + unwanted: + text: Dacă aceste lucrări îți aparțin, dar nu le vrei, le poți abandona (vor + rămâne pe AO3, dar numele tău va fi șters) sau șterge (vor fi înlăturate + complet de pe AO3). Nu trebuie să adaugi aceste lucrări la niciun cont ca + să le abandonezi sau să le ștergi--poți să faci acest lucru direct prin + accesarea link-ului de revendicare de mai sus. (Pentru ajutor, te rugăm + să contactezi echipa de Suport Tehnic AO3 la %{support_link}.) + update_redirect: + text: Dacă dorești ca Uși Deschise să actualizeze redirecționarea către lucrările + tale existente, te rugăm să ștergi copia importată și să contactezi Uși + Deschise la %{open_doors_link} cu numele contului tău de pe AO3, numele + contului tău în arhiva importată și titlul și URL-ul lucrării către care + ți-ai dori să se facă redirecționarea. (Dacă ai mai multe lucrări la care + dorești să schimbi redirecționările, le poți lista pe toate într-un singur + e-mail.) + uploaded_list: 'Lucrările încărcate includ:' + invite_increase_notification: + html: + body: + few: Vrem să te anunțăm că ai %{count} invitații noi care pot fi folosite + pentru a crea conturi noi de arhivă. Poți invita un prieten accesând %{invitation_page_link}. + one: Vrem să te anunțăm că ai %{count} invitație nouă care poate fi folosită + pentru a crea un cont nou de arhivă. Poți invita un prieten accesând %{invitation_page_link}. + other: Vrem să te anunțăm că ai %{count} de invitații noi care pot fi folosite + pentru a crea conturi noi de arhivă. Poți invita un prieten accesând %{invitation_page_link}. + invitation_page_link_text: pagina ta de Invitations (Invitații) + subject: "[%{app_name}] Invitații noi" + text: + body: + few: Vrem să te anunțăm că ai %{count} invitații noi care pot fi folosite + pentru a crea conturi noi de arhivă. Poți invita un prieten accesând pagina + Invitations (Invitații) (%{invitation_page_url}). + one: Vrem să te anunțăm că ai %{count} invitație nouă care poate fi folosită + pentru a crea un cont nou de arhivă. Poți invita un prieten accesând pagina + Invitations (Invitații) (%{invitation_page_url}). + other: Vrem să te anunțăm că ai %{count} de invitații noi care pot fi folosite + pentru a crea conturi noi de arhivă. Poți invita un prieten accesând pagina + Invitations (Invitații) (%{invitation_page_url}). + invite_request_declined: + main: + few: Te informăm cu regret că solicitarea pentru %{count} invitații noi nu + poate fi procesată pentru moment. + one: Te informăm cu regret că solicitarea pentru o nouă invitație nu poate + fi procesată pentru moment. + other: Te informăm cu regret că solicitarea pentru %{count} de invitații noi + nu poate fi procesată pentru moment. + reason: 'Solicitarea ta a fost:' + subject: "[%{app_name}] Solicitarea pentru codul de invitație suplimentar a + fost respinsă" + recipient_notification: + html: + collection: O lucrare cadou a fost postată pentru tine în colecția %{collection_link} + pe AO3! + no_collection: O lucrare cadou a fost postată pentru tine pe AO3! + subject: + collection: "[%{app_name}][%{collection_title}] O lucrare cadou pentru tine + de la %{collection_title}" + no_collection: "[%{app_name}] O lucrare cadou pentru tine" + text: + collection: O lucrare cadou a fost postată pentru tine în colecția „%{collection_title}" + (%{collection_url}) pe AO3! + signup_notification: + activate: + html: Te rugăm %{activate_account_link}. + text: 'Te rugăm să accesezi acest link pentru a-ți activa contul: %{activate_account_url}' + activate_your_account: să accesezi acest link pentru a-ți activa contul. + admin_posts: Știri AO3 + bye: Sperăm că o să-ți facă plăcere să folosești Arhiva. + contact_support: iei legătura cu echipa de Suport Tehnic + faq: Întrebări Frecvente + features: + html: După ce contul tău a fost înființat și funcționează, poți să postezi + lucrările tale de fan, să îți stabilești notificări pe e-mail pentru a fi + înștiințat/-ă când creatorii sau lucrările tale preferate au fost actualizate, + să îți definești preferințele pentru a personaliza modul în care site-ul + arată și funcționează pentru tine, să ții evidența lucrărilor pe care le-ai + accesat pe arhivă prin intermediul istoricului tău și multe altele. + text: După ce contul tău a fost înființat și funcționează, poți să postezi + lucrările tale de fan, să îți stabilești notificări pe e-mail pentru a fi + înștiințat/-ă când creatorii sau lucrările tale preferate au fost actualizate, + să îți definești preferințele pentru a personaliza modul în care site-ul + arată și funcționează pentru tine, să ții evidența lucrărilor pe care le-ai + accesat pe AO3 prin intermediul istoricului tău și multe altele. + information: + html: Găsești mai multe informații și sfaturi despre cum să folosești Arhiva + în secțiunea %{faq_link} și cele mai recente știri despre îmbunătățirile + aduse site-ului în %{admin_posts_link}. Dacă ai nevoie de mai mult ajutor, + sau ai descoperit ceva ce nu merge sau dacă ai întrebări sau comentarii, + te rugăm să %{contact_support_link}, care este oricând dornică să ajute. + text: 'Găsești mai multe informații și sfaturi despre cum să folosești Arhiva + în secțiunea %{faq_url} și cele mai recente știri despre îmbunătățirile + aduse site-ului în secțiunea de Știri AO3: %{admin_posts_url}. Dacă ai nevoie + de mai mult ajutor, sau ai descoperit ceva ce nu merge sau dacă ai întrebări + sau comentarii, te rugăm să contactezi echipa de Suport Tehnic, care este + oricând dornică să ajute: %{contact_support_url}.' + welcome: Bine ai venit pe Archive of Our Own, %{login}! diff --git a/config/locales/phrase-exports/ru.yml b/config/locales/phrase-exports/ru.yml new file mode 100755 index 0000000..d82ab54 --- /dev/null +++ b/config/locales/phrase-exports/ru.yml @@ -0,0 +1,640 @@ +--- +ru: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Предупреждения:' + many: 'Предупреждения:' + one: 'Предупреждение:' + category: + name_with_colon: + few: 'Категории:' + many: 'Категории:' + one: 'Категория:' + character: + name_with_colon: + few: 'Персонажи:' + many: 'Персонажи:' + one: 'Персонаж:' + fandom: + name_with_colon: + few: 'Фандомы:' + many: 'Фандомы:' + one: 'Фандом:' + freeform: + name_with_colon: + few: 'Дополнительные теги:' + many: 'Дополнительные теги:' + one: 'Дополнительный тег:' + rating: + name_with_colon: 'Рейтинг:' + relationship: + name_with_colon: + few: 'Отношения:' + many: 'Отношения:' + one: 'Отношения:' + work: + chapter_total_display: Главы + summary: Содержание + models: + archive_warning: + few: Предупреждения + many: Предупреждения + one: Предупреждение + category: + few: Категории + many: Категории + one: Категория + chapter: + few: Главы + many: Главы + one: Глава + character: + few: Персонажи + many: Персонажи + one: Персонаж + fandom: + few: Фандомы + many: Фандомы + one: Фандом + freeform: + few: Дополнительные теги + many: Дополнительные теги + one: Дополнительный тег + rating: + few: Рейтинги + many: Рейтинги + one: Рейтинг + relationship: + few: Отношения + many: Отношения + one: Отношения + series: + few: Циклы + many: Циклы + one: Цикл + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} гостей" + many: "%{count} гостей" + one: "%{count} гость" + left_kudos: + html: + few: "%{givers_list} дарят вам кудос за %{commentable_link}." + many: "%{givers_list} дарят вам кудос за %{commentable_link}." + one: "%{givers_list} дарит вам кудос за %{commentable_link}." + text: + few: "%{givers_list} дарят вам кудос за %{commentable_title} (%{commentable_url})." + many: "%{givers_list} дарят вам кудос за %{commentable_title} (%{commentable_url})." + one: "%{givers_list} дарит вам кудос за %{commentable_title} (%{commentable_url})." + single_guest: + giver: Один гость + html: "%{giver} дарит вам кудос за %{commentable_link}." + text: Один гость подарил вам кудос за %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Вы получили кудос!" + mailer: + general: + closing: + formal: С уважением, + informal: Счастливо, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Глава %{position} работы «%{title}» + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} слова" + many: "%{count} слов" + one: "%{count} слово" + footer: + general: + about: + html: AO3 – это архив, созданный и существующий благодаря фанатам, и он + полагается на %{donate_link}. + text: 'AO3 – это архив, созданный и существующий благодаря фанатам, и + он полагается на ваши пожертвования: %{donate_url}.' + html: + donate_link_text: ваши пожертвования + support_link_text: обратитесь в Поддержку + unwanted_email: + html: Если вы получили это сообщение по ошибке, пожалуйста, %{support_link}. + text: Если вы получили это сообщение по ошибке, пожалуйста, обратитесь + в Поддержку – %{support_url}. + sent_at: Отправлено в %{sent_at}. + greeting: + formal_html: Здравствуйте, %{name}, + informal: + addressed_html: Привет, %{name}! + unaddressed: Привет! + introductory: Привет от Archive of Our Own – AO3 (Нашего Архива)! + metadata_label_indicator: ":" + signature: + abuse_team: Команда Политики и нарушений АО3 + app_short_name: АО3 + open_doors: Команда Open Doors (Открытые двери) + parent_org: Organization for Transformative Works – OTW (Организация Трансформационных + Работ) + support: Команда Технической поддержки АО3 + users: + mailer: + reset_password_instructions: + expiration: Если вы не воспользуетесь этой ссылкой для сброса пароля в течение + недели, срок ее действия закончится, и вам придется запросить новый. + intro: 'Кто-то запросил сброс пароля для вашей учетной записи. Чтобы изменить + пароль своей учетной записи, перейдите по ссылке ниже и введите новый пароль:' + link_title: Изменить пароль. + subject: "[%{app_name}] Сброс пароля" + unrequested: Если вы не запрашивали сброс пароля, вы можете проигнорировать + это письмо. Ваш действующий пароль продолжит работать. + user_mailer: + admin_deleted_work_notification: + bye: К письму приложена копия вашей работы. + contact_abuse: свяжитесь с нашим комитетом Политик и нарушений + deleted: + html: Ваша работа %{title} была удалена администратором AO3. + text: Ваша работа "%{title}" была удалена администратором AO3. + html: + tos_violation: Если есть вероятность того, что данная работа нарушает Пользовательское + соглашение AO3, пожалуйста, %{contact_abuse_link}. + import_project: + html: Если данная работа была импортирована на AO3 как часть проекта Открытые + двери, пожалуйста, %{opendoors_link}, если возникнут дополнительные вопросы. + text: Если данная работа была импортирована на AO3 как часть проекта Открытые + двери, пожалуйста, свяжитесь с командой Открытых дверей (%{opendoors_link}), + если возникнут дополнительные вопросы. + opendoors: свяжитесь с командой Открытых дверей + subject: "[%{app_name}] Ваша работа была удалена администратором сайта" + text: + tos_violation: Если есть вероятность того, что данная работа нарушает Пользовательское + соглашение AO3, пожалуйста, свяжитесь с нашим комитетом Политик и нарушений + (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Пока ваша работа скрыта, она остается доступной вам по ссылке выше, + но она не будет отображаться в списке ваших работ, и будет недоступна другим + пользователям AO3. + check_email: Пожалуйста, проверьте вашу почту, включая папку со спамом - возможно, + комитет Политик и Нарушений уже связался с вами с объяснением, почему ваша + работа была скрыта. + contact_abuse: свяжитесь с комитетом Политик и Нарушений + html: + help: Если вы не уверены, почему ваша работа была скрыта, и с вами не связывались + по этому поводу, пожалуйста %{contact_abuse_link} напрямую. + hidden: Ваша работа %{title} была скрыта комитетом Политик и Нарушений и больше + не находится в публичном доступе. + tos_violation: Если ваша работа была скрыта, потому что нарушает %{tos_link} + AO3, вы должны будете исправить нарушение - иначе ваша работа может быть + удалена с AO3. + subject: "[%{app_name}] Комитет Политик и Нарушений скрыл вашу работу" + text: + help: 'Если вы не уверены, почему ваша работа была скрыта, и с вами не связывались + по этому поводу, пожалуйста свяжитесь с комитетом Политик и Нарушений напрямую: + %{contact_abuse_url}.' + hidden: Ваша работа "%{title}" (%{work_url}) была скрыта комитетом Политик + и Нарушений и больше не находится в публичном доступе. + tos_violation: Если ваша работа была скрыта потому что она нарушает Пользовательское + соглашение AO3 (%{tos_url}), вы должны будете исправить нарушение - иначе + ваша работа может быть удалена с AO3 + tos: Пользовательское соглашение + anonymous_or_unrevealed_notification: + anonymous_info: Анонимные работы можно найти по тегам, но они не отображаются + в списке ваших работ. В самой работе ваше имя пользователя будет заменено + на "Anonymous" (Анонимный автор). + anonymous_unrevealed_info: В будущем кураторы коллекции могут открыть вашу работу, + но оставить ее анонимной. Ваши подписчики не будут об этом уведомлены. Когда + работа будет открыта, ее можно будет найти по тегам, но она не будет отображаться + в списке ваших работ. В самой работе ваше имя пользователя будет заменено + на "Anonymous" (Анонимный автор). + changed_status: + anonymous: + html: Кураторы коллекции %{collection_link} изменили статус вашей работы + %{work_link} на анонимный. + text: Кураторы коллекции "%{collection_title}" (%{collection_url}) изменили + статус вашей работы "%{work_title}" (%{work_url}) на анонимный. + anonymous_unrevealed: + html: Кураторы коллекции %{collection_link} изменили статус вашей работы + %{work_link} на анонимный и скрытый. + text: Кураторы коллекции "%{collection_title}" (%{collection_url}) изменили + статус вашей работы "%{work_title}" (%{work_url}) на анонимный и скрытый. + unrevealed: + html: Кураторы колекции %{collection_link} изменили статус вашей работы + %{work_link} на скрытый. + text: Кураторы коллекции "%{collection_title}" (%{collection_url}) изменили + статус вашей работы "%{work_title}" (%{work_url}) на скрытый. + collection_items_link_text: страницу Approved Collection Items (Утвержденные + Работы в Коллекциях) + do_not_want: + anonymous: + html: Если вы не хотите, чтобы ваша работа была анонимной, пожалуйста, перейдите + на %{collection_items_link}, чтобы удалить ее из этой коллекции. + text: 'Если вы не хотите, чтобы ваша работа оставалась анонимной, пожалуйста, + перейдите на страницу Approved Collection Items (Утвержденные Работы в + Коллекциях), чтобы удалить ее из этой коллекции: %{collection_items_url}' + anonymous_unrevealed: + html: Если вы не хотите, чтобы ваша работа оставалась анонимной и скрытой, + пожалуйста, перейдите на %{collection_items_link}, чтобы удалить ее из + этой коллекции. + text: 'Если вы не хотите, чтобы ваша работа оставалась анонимной и скрытой, + пожалуйста, перейдите на страницу Approved Collection Items (Утвержденные + Работы в Коллекциях),чтобы удалить ее из этой коллекции: %{collection_items_url}' + unrevealed: + html: Если вы не хотите, чтобы ваша работа оставалась скрытой, пожалуйста, + перейдите на %{collection_items_link}, чтобы удалить ее из этой коллекции. + text: 'Если вы не хотите, чтобы ваша работа оставалась скрытой, пожалуйста, + перейдите на страницу Approved Collection Items (Утвержденные Работы в + Коллекциях), чтобы удалить ее из этой коллекции: %{collection_items_url}' + faq_link_text: FAQ Коллекций + more_info: + html: Более подробную информацию можно найти в %{faq_link}. + text: 'Более подробную информацию можно найти в нашем FAQ Коллекций: %{faq_url}' + subject: + anonymous: "[%{app_name}] Ваша работа теперь анонимна" + anonymous_unrevealed: "[%{app_name}] Ваша работа теперь скрыта и анонимна" + unrevealed: "[%{app_name}] Ваша работа теперь скрыта" + unrevealed_info: Скрытые работы нельзя найти по тегам, и они не отображаются + в списке ваших работ. При нажатии на ссылку работы пользователь будет уведомлен, + что работа скрыта, и не сможет увидеть ее содержания. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Одобренные предметы + коллекции) + archivist_notice: Поскольку хранители коллекции выступают в официальном качестве + архивариусов Open Doors (Открытых дверей), им разрешено добавлять ваши работы + в эту коллекцию, даже если у вас отключены приглашения в коллекции. Архивариусы + добавят произведение в коллекцию только в том случае, если оно было размещено + в импортируемом архиве. + removal_instructions: + html: Если вы желаете удалить свою работу из этой коллекции, посетите страницу + %{approved_items_link}. + text: Если вы желаете удалить свою работу из этой коллекции, посетите страницу + Approved Collection Items (Одобренные предметы коллекции) %{approved_items_url}. + subject: "[%{app_name}][%{collection_title}] Архивариус комитета Open Doors + (Открытые двери) добавил вашу работу в коллекцию." + work_added: + html: Хранители коллекции %{collection_link} добавили вашу работу %{work_link} + в свою коллекцию. + text: Хранители коллекции "%{collection_title}" (%{collection_url}) добавили + вашу работу "%{work_title}" (%{work_url} в свою коллекцию! + challenge_assignment_notification: + any: Любой + assignment: + html: Вам было поручено выполнение следующей заявки челленджа %{link} на AO3! + description: 'Описание:' + due: 'Задание необходимо выполнить до:' + html: + footer: Вы получили это письмо, потому что записались на участие в челлендже + %{title}. Чтобы узнать больше об этом челлендже и получить контактные данные + модераторов, пожалуйста, посетите %{footer_link}. + footer_link: профиль челленджа + look_up: Вы можете уточнить детали этого задания на %{link}. + look_up_link: своей странице Assignments (Задания) + optional_tags: 'Дополнительные теги:' + prompts: 'Заявки:' + prompt_url: 'URL заявки:' + recipient: 'Получатель:' + recipient_missing: 'Отсутствует: свяжитесь с модератором!' + subject: "[%{app_name}][%{collection_title}] Ваше задание!" + text: + assignment: Вам было поручено выполнение следующей заявки челленджа "%{collection_title}" + (%{collection_url}) на AO3! + footer: Вы получили это письмо, потому что записались на участие в челлендже + %{title} (%{url}).Чтобы узнать больше об этом челлендже и получить контактные + данные модераторов, пожалуйста, посетите %{profile_url}. + look_up: Вы можете найти это задание на своей странице Assignments (Задания) + по адресу %{link}. + change_email: + changed: + html: "%{login}, адрес электронной почты, привязанный к вашему аккаунту, был + изменен на %{email}" + text: "%{login}, адрес электронной почты, привязанный к вашему аккаунту, был + изменен на %{email}" + subject: "[%{app_name}] Изменение адреса электронной почты" + claim_notification: + access: + contact_support: свяжитесь с поддержкой АО3 + html: В зависимости от архива ваши работы могли быть импортированы только + для зарегистрированных пользователей (чтобы они индексировались Google). + В этом случае работы будут доступны только зарегистрированным пользователям, + если вы не решите сделать их полностью видимыми. Для помощи в разблокировке, + отказе или удалении ваших работ, пожалуйста, %{contact_support_link}. + text: В зависимости от архива ваши работы могли быть импортированы только + для зарегистрированных пользователей (чтобы они не попадали в поиск Google). + В этом случае работы будут доступны только зарегистрированным пользователям, + если вы не решите сделать их полностью видимыми. Для помощи в разблокировке, + отказе или удалении ваших работ, пожалуйста, свяжитесь с Поддержкой АО3 + по ссылке %{support_url}. + email_tips: Если вы связываетесь с нами, пожалуйста добавьте адреса с @transformativeworks.org + в белый список и проверяйте вашу папку Спам. + introduction: + ao3_name: Archive of Our Own – AO3 (Наш архив) + html: Вы получили это письмо, потому что ваши работы были в архиве, который + был перенесен %{open_doors_name_link} в %{app_link}. Поскольку этот адрес + электронной почты связан с тем, который использовался в переносимом архиве, + соответствующие фан-работы (перечисленные ниже) были автоматически добавлены + в вашу учетную запись на AO3. + open_doors_name: Open Doors (Открытые двери) + text: 'Вы получили это письмо, потому что у вас были произведения в архиве + фан-работ, которые были перенесены Open Doors (Открытыми дверями) (%{open_doors_url}) + в Archive of Our Own – AO3 (Наш архив): %{app_url}. Поскольку этот адрес + электронной почты связан с тем, который зарегистрирован в переносимом архиве, + соответствующие фан-работы (перечисленные ниже) были автоматически добавлены + в вашу учетную запись AO3.' + mistake: + contact_open_doors: свяжитесь с Открытыми дверями + html: Если произошла ошибка и это не ваши работы, пожалуйста, не удаляйте + их. Пожалуйста, %{contact_open_doors_link} и мы во всем разберемся. + text: Если произошла ошибка и это не ваши работы, пожалуйста, не удаляйте + их. Пожалуйста, свяжитесь с Открытыми дверями (%{open_doors_url}) и мы во + всем разберемся. + more_info: + ao3_news: новости АО3 + contact_support: связаться с поддержкой АО3 + faq_page: FAQ + html: Вы можете прочитать новости о недавних перемещениях архива по адресу + %{ao3_news_link} и найти дополнительную информацию на странице Открытых + дверей %{faq_page_link} или %{tutorial_page_link}. По другим вопросам, которые + не упомянуты в FAQ или этом письме, пожалуйста, %{contact_support_link}. + text: Вы можете прочитать объявления о недавних перемещениях архива в новостях + АО3 (%{news_url}) и найти дополнительную информацию на странице FAQ Открытых + дверей (%{open_doors_faq_url}) или на странице руководств (%{open_doors_tutorial_url}). + По вопросам, на которые нет ответов в FAQ, руководства или этом письме, + пожалуйста, свяжитесь с Поддержкой АО3 по ссылке %{support_url}. + tutorial_page: руководство + other_works: + contact_open_doors: свяжитесь с Открытыми дверями + html: Если у вас есть другие работы в переносимом архиве с электронным адресом, + к которому у вас больше нет доступа, %{contact_open_doors_link} с любой + информацией, которая поможет подтвердить вашу личность. + text: Если у вас есть другие работы в переносимом архиве с электронным адресом, + к которому у вас больше нет доступа, свяжитесь с Открытыми дверями с любой + информацией, которая поможет подтвердить вашу личность. + questions: + contact_support: свяжитесь с Поддержкой АО3 + html: По другим вопросам, пожалуйста, %{contact_support_link}. + text: по другим вопросам, пожалуйста, свяжитесь с Поддержкой АО3 по ссылке + %{support_url}. + redirects: + html: Для сохранения списков рекомендаций и закладок, ссылки импортированного + архива будут переадресовывать на импортированную копию этих произведений + в течение ограниченного времени (чтобы убедиться, проверьте сообщение с + объявлением для вашего архива). Если вы уже загрузили копию этих работ и + %{negation} использовали функцию импорта из URL, на AO3 будет две копии + одной и той же работы. + subject: "[%{app_name}] Работы загружены" + update_redirect: + contact_open_doors: свяжитесь с Открытыми дверями + html: Если вы хотите, чтобы Открытые двери обновили ссылки для переадресации, + указав вашу существующую работу, удалите импортированную копию и %{contact_open_doors_link} + с именем вашей учетной записи AO3, именем вашей учетной записи в импортированном + архиве, а также названием и URL-адресом фан-работы, на которые вы хотите + сделать переадресацию. (Если у вас есть несколько работ, для которых вы + хотите изменить переадресацию, вы можете перечислить их в одном электронном + письме.) + text: Если вы хотите, чтобы Открытые двери обновили ссылки для переадресации, + указав на вашу существующую работу, удалите импортированную копию и свяжитесь + с Открытыми дверями по ссылке %{open_doors_url} с именем вашей учетной записи + AO3, именем вашей учетной записи в импортированном архиве, а также названием + и URL-адресом фан-работы, на которые вы хотите создать переадресацию. (Если + у вас есть несколько работ, для которых вы хотите изменить ссылки, вы можете + перечислить их в одном электронном письме.) + works_by: 'Эти работы были написаны с указанием почтового адреса: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Все задания были отправлены. + subject: Задания отправлены + html: + received_message: 'Вы получили сообщение о вашей коллекции %{collection_link}:' + text: + received_message: 'Вы получили сообщение о вашей коллекции "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Если вы указаны как соавтор для работы, вас могут добавить в соавторы + следующих глав вне зависимости от ваших настроек. Вы также будете указаны + как соавтор к любому циклу, которому принадлежит эта работа. + html: + creation: "%{creation_link} за авторством %{pseud_links}" + edit_chapter: редактировать главу + edit_series: Редактировать серию + remove_chapter: Если вы были добавлены по ошибке или вы не хотите быть соавтором, + вы можете %{edit_chapter_link} отредактировать соавторство. + remove_series: Если вы были добавлены по ошибке или вы не хотите быть соавтором, + вы можете %{edit_series_link} отредактировать соавторство. + intro_chapter: 'Пользователь %{adding_user} предложил указать ваш псевдоним + %{pseud} в качестве соавтора следующей работы:' + intro_series: 'Пользователь %{adding_user} предложил указать ваш псевдоним %{pseud} + в качестве соавтора следующей серии:' + subject: "[%{app_name}] Уведомление о соавторстве" + text: + creation: "%{title} (%{url}) за авторством %{pseuds}" + remove_chapter: 'Если вы были добавлены по ошибке или вы не хотите быть автором, + вы можете отредактировать главу, чтобы убрать авторство: %{url}' + remove_series: 'Если вы были добавлены по ошибке или вы не хотите быть автором, + вы можете отредактировать серию, чтобы убрать авторство: %{url}' + creatorship_notification_archivist: + explanation: Действуя в рамках своих официальных полномочий, архивариус Открытых + дверей может добавить вас без предварительного запроса, даже если у вас отключены + приглашения к соавторству. + html: + creation: "%{creation_link} за авторством %{pseud_links}" + edit_chapter: отредактировать главу + edit_series: отредактировать цикл + edit_work: отредактировать работу + remove_chapter: Если вас добавили по ошибке или если вы не хотите быть указаны + автором, вы можете %{edit_chapter_link}, чтобы убрать себя из списка авторов. + remove_series: Если вас добавили по ошибке или если вы не хотите быть указаны + автором, вы можете %{edit_series_link}, чтобы убрать себя из списка авторов. + remove_work: Если вас добавили по ошибке или если вы не хотите быть указаны + автором, вы можете %{edit_work_link}, чтобы убрать себя из списка авторов. + intro_chapter: 'Пользователь %{archivist} добавил ваш псевдоним %{pseud} соавтором + к следующей главе:' + intro_series: 'Пользователь %{archivist} добавил ваш псевдоним %{pseud} соавтором + к следующему циклу работ:' + intro_work: 'Пользователь %{archivist} добавил ваш псевдоним %{pseud} соавтором + к следующей работе:' + subject: "[%{app_name}] Уведомление о добавлении в соавторы архивариусом" + text: + creation: "%{title} (%{url}) за авторством %{pseuds}" + remove_chapter: 'Если вас добавили по ошибке или если вы не хотите быть указаны + автором, вы можете отредактировать главу, чтобы убрать себя из списка авторов: + %{url}' + remove_series: 'Если вас добавили по ошибке или если вы не хотите быть указаны + автором, вы можете отредактировать цикл, чтобы убрать себя из списка авторов: + %{url}' + remove_work: 'Если вас добавили по ошибке или вы не не хотите быть указаны + соавтором, вы можете отредактировать работу, чтобы убрать себя из списка + авторов: %{url}' + creatorship_request: + html: + creation: "%{creation_link} за авторством %{pseud_links}" + instructions: Вы можете принять или отклонить этот запрос на странице %{page_name} + page_name: Co-Creator Requests (Запросы на соавторство) + intro_chapter: 'Пользователь %{inviting_user} предлагает включить ваш псевдоним + %{pseud} в список соавторов следующей работы:' + intro_series: 'Пользователь %{inviting_user} предлагает включить ваш псевдоним + %{pseud} в список соавторов следующего цикла работ:' + intro_work: 'Пользователь %{inviting_user} предлагает включить ваш псевдоним + %{pseud} в список соавторов следующей работы:' + subject: "[%{app_name}] Запрос на соавторство" + text: + creation: "%{title} (%{url}) за авторством %{pseuds}" + instructions: 'Вы можете принять или отклонить этот запрос на странице Co-Creator + Requests (Запросы на соавторство): %{url}' + delete_work_notification: + attachment: В приложении - копия вашей работы для ознакомления. + deleted_other: + html: Ваша работа %{title} была удалена по запросу %{pseud}. + text: Ваша работа "%{title}" была удалена по запросу %{pseud}. + deleted_yourself: + html: Ваша работа %{title} была удалена по вашему запросу. + text: Ваша работа "%{title}" была удалена по вашему запросу. + questions: + html: Если у вас есть вопросы, пожалуйста %{support}. + text: Если у вас есть вопросы, пожалуйста %{support} (%{url}). + subject: "[%{app_name}] Ваша работа была удалена" + support: свяжитесь с Поддержкой + invitation_to_claim: + access: + text: В зависимости от архива, ваши работы могли быть импортированы так, что + теперь они доступны только зарегистрированным пользователям (так их нельзя + найти с помощью Google). В этом случае работы будут доступны только вошедшим + в аккаунт пользователям, если вы не решите сделать их полностью видимыми. + Для помощи в разблокировке, отказе от работ или их удалении, пожалуйста, + свяжитесь с Поддержкой AO3. + claim_or_remove: + html: Заявите об авторстве или удалите свои работы здесь. + text: 'Заявите об авторстве или удалите свои работы здесь: %{claim_url}' + email_tips: Если вы связываетесь с нами, пожалуйста, добавьте в белый список + / контакты адреса на @transformativeworks.org и проверяйте папки со спамом + на предмет нашего ответа. + html: + ao3_news: Новостях AO3 + contact_open_doors: свяжитесь с Открытыми Дверями + contact_support: свяжитесь с Поддержкой AO3 + faq_page: странице FAQ + tutorial_page: руководствах + introduction: + text: Вы получили это письмо, потому что Open Doors (Открытые Двери) (%{open_doors_link}) + недавно импортировали архив на %{app_name} (%{app_short_name} - %{app_url}), + и мы предполагаем, что некоторые работы принадлежат вам. Мы хотели бы предоставить + вам шанс заявить о вашем авторстве (или удалить/отказаться от) этих работ, + если вы захотите. И если у вас еще нет аккаунта, привязанного к другому + адресу электронной почты, мы хотели бы пригласить вас зарегистрироваться! + mistake: + text: Если это ошибка и это не ваши работы, пожалуйста, не удаляйте их! Просто + свяжитесь с Открытыми Дверями (%{open_doors_link}), и мы разберемся с этим. + more_info: + text: 'Вы можете прочитать анонс недавнего импорта архива в Новостях AO3 (%{news_link}) + и найти дополнительную информацию на странице FAQ Открытых Дверей (%{open_doors_faq_link}) + или в руководствах (%{open_doors_tutorial_link}). Если у вас есть вопросы, + ответов на которые нет в FAQ, руководствах или этом письме, пожалуйста, + свяжитесь с Поддержкой по ссылке: %{support_link}.' + other_works: + text: Если у вас были другие работы на импортированном архиве, связанные с + адресом электронной почты, к которому вы больше не имеете доступа, пожалуйста + свяжитесь с Открытыми Дверьми и предоставьте любую информацию, которая поможет + подтвердить вашу личность. + questions: + text: По другим вопросам, пожалуйста, свяжитесь с Поддержкой AO3 на %{support_link}. + redirects: Чтобы сохранить списки рекомендаций и закладки, веб-адреса импортированного + архива могут перенаправлять на импортированную копию этих произведений в течение + ограниченного времени (проверьте, пожалуйста, анонс импорта для вашего архива). + Если вы уже загрузили копию этих работ и НЕ использовали функцию импорта из + URL, в Архиве будет две копии одной и той же работы. + subject: "[%{app_name}] Приглашение к заявлению прав на работу" + unwanted: + text: 'Если эти работы принадлежат вам, но вы не хотите заявлять на них права, + вы можете отказаться от них (тогда они остануться на AO3, но ваше имя будет + с них удален) или удалить их (тогда они будут полностью удалены с AO3). + Вам не нужно добавлять эти работы в какую-либо учетную запись, чтобы отказаться + от них или удалить их — вы можете сделать это прямо по ссылке выше. (Для + помощи, пожалуйста, свяжитесь с Поддержкой по ссылке: %{support_link}.)' + update_redirect: + text: Если вы хотите, чтобы Открытые Двери обновили перенаправление так, чтобы + оно указывало на уже существовавшую работу, удалите импортированную копию + и свяжитесь с Открытыми Дверями через %{open_doors_link}, указав имя своей + учетной записи AO3, имя своей учетной записи в импортированном архиве, а + также название и ссылку на фан-работу, на которую вы бы хотели сделать перенаправление. + (Если у вас есть несколько работ, для которых вы хотите изменить перенаправления, + вы можете перечислить их в одном письме.) + uploaded_list: 'Загруженные работы включают в себя:' + invite_increase_notification: + html: + body: + few: Мы просто хотели сказать, что у вас %{count} новых приглашения, которые + можно использовать для создания новых аккаунтов в архиве. Пригласить друзей + можно на %{invitation_page_link}. + many: Мы просто хотели сказать, что у вас %{count} новых приглашений, которые + можно использовать для создания новых аккаунтов в архиве. Пригласить друзей + можно на %{invitation_page_link}. + one: Мы просто хотели сказать, что у вас %{count} новое приглашение, которое + можно использовать для создания новых аккаунтов в архиве. Пригласить друзей + можно на %{invitation_page_link}. + invitation_page_link_text: странице "Invitations" (Приглашения) + subject: "[%{app_name}] Новые приглашения" + text: + body: + few: Мы просто хотели сказать, что у вас %{count} новых приглашения, которые + можно использовать для создания новых аккаунтов в архиве. Пригласить друзей + можно на (%{invitation_page_url}). + many: Мы просто хотели сказать, что у вас %{count} новых приглашений, которые + можно использовать для создания новых аккаунтов в архиве. Пригласить друзей + можно на (%{invitation_page_url}). + one: Мы просто хотели сказать, что у вас %{count} новое приглашение, которое + можно использовать для создания новых аккаунтов в архиве. Пригласить друзей + можно на (%{invitation_page_url}). + invite_request_declined: + main: + few: К сожалению, мы вынуждены сообщить вам, что ваш запрос на %{count} новых + приглашения не может быть выполнен в настоящее время. + many: К сожалению, мы вынуждены сообщить вам, что ваш запрос на %{count} новых + приглашений не может быть выполнен в настоящее время. + one: К сожалению, мы вынуждены сообщить вам, что ваш запрос на %{count} новое + приглашение не может быть выполнен в настоящее время. + reason: 'Ваш запрос был следующим:' + subject: "[%{app_name}] Отказ в получении дополнительного кода приглашения" + recipient_notification: + html: + collection: Подарочная работа для вас была опубликована в коллекции %{collection_link} + на AO3! + no_collection: Для вас была опубликована подарочная работа на AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Подарочная работа для вас + от %{collection_title}" + no_collection: "[%{app_name}] Подарок для вас" + text: + collection: Подарочная работа для вас была опубликована в коллекции "%{collection_title}" + (%{collection_url}) на AO3! + signup_notification: + activate: + html: Пожалуйста, %{activate_account_link}. + text: 'Пожалуйста, пройдите по ссылке для активации своего аккаунта: %{activate_account_url}' + activate_your_account: пройдите по ссылке для активации аккаунта + admin_posts: Новости АО3 + bye: Надеемся, что вам понравится использовать Наш Архив. + contact_support: свяжитесь с Технической поддержкой + faq: FAQ + features: + html: Как только ваш аккаунт будет активирован, вы сможете публиковать свои + фан-работы, получать уведомления об обновлениях любимых авторов и работ + по электронной почте, настраивать внешний вид и работу сайта, отслеживать + работы, к которым вы обращались на AO3 через свою историю, и многое другое. + text: Как только ваш аккаунт будет активирован, вы сможете публиковать свои + фан-работы, получать уведомления об обновлениях любимых авторов и работ + по электронной почте, отслеживать работы, к которым вы обращались на AO3 + через свою историю, и многое другое. + information: + html: Информацию и советы по использованию Архива можно найти в нашем %{faq_link}. + Ознакомиться с последними новостями по развитию сайта можно в %{admin_posts_link}. + Чтобы обратиться за помощью, сообщить о баге на сайте, задать вопрос или + внести свое предложение, пожалуйста, %{contact_support_link}, они всегда + рады помочь. + text: 'Информацию и советы по использованию Архива можно найти в нашем FAQ + по ссылке %{faq_url}. Вы найдете последние новости по развитию сайта в Новостях + АО3 по ссылке %{admin_posts_url}. Чтобы обратиться за помощью, сообщить + о баге на сайте, задать вопрос или внести свое предложение, пожалуйста, + свяжитесь с нашей командой Поддержки, они всегда рады помочь: %{contact_support_url}.' + welcome: Добро пожаловать на Наш Архив, %{login}! diff --git a/config/locales/phrase-exports/scr.yml b/config/locales/phrase-exports/scr.yml new file mode 100755 index 0000000..d6dac5f --- /dev/null +++ b/config/locales/phrase-exports/scr.yml @@ -0,0 +1,518 @@ +--- +scr: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Upozorenja:' + one: 'Upozorenje:' + other: 'Upozorenja:' + category: + name_with_colon: + few: 'Категорије:' + one: 'Kategorija:' + other: 'Kategorije:' + character: + name_with_colon: + few: 'Likovi:' + one: 'Lik:' + other: 'Likovi:' + fandom: + name_with_colon: + few: 'Fandomi:' + one: 'Fandom:' + other: 'Fandomi:' + freeform: + name_with_colon: + few: 'Dodatni tagovi:' + one: 'Dodatan tag:' + other: 'Dodatni tagovi:' + rating: + name_with_colon: 'Ocena primerenosti sadržaja:' + relationship: + name_with_colon: + few: 'Odnosi između likova:' + one: 'Odnos između likova:' + other: 'Odnosi između likova:' + work: + chapter_total_display: Poglavlja + summary: Sažetak + models: + archive_warning: + few: Upozorenja + one: Upozorenje + other: Upozorenja + category: + few: Kategorije + one: Kategorija + other: Kategorije + chapter: + few: Glave + one: Glava + other: Glave + character: + few: Likovi + one: Lik + other: Ликови + fandom: + few: Fandomi + one: Fandom + other: Fandomi + freeform: + few: Dodatni tagovi + one: Dodatan tag + other: Dodatni tagovi + rating: + few: Ocene primerenosti zadržaja + one: Ocena primerenosti zadržaja + other: Ocene primerenosti zadržaja + relationship: + few: Odnosi između likova + one: Odnos između likova + other: Odnosi između likova + series: + few: Serijali + one: Serijal + other: Serijali + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} госта" + one: "%{count} гост" + other: "%{count} гостију" + left_kudos: + html: + few: "%{givers_list} су похвалили %{commentable_link}." + one: "%{givers_list} је похвалио/ла %{commentable_link}." + other: "%{givers_list} су похвалили %{commentable_link}." + text: + few: "%{givers_list} су похвалили %{commentable_title} (%{commentable_url})." + one: "%{givers_list} је похвалио/ла %{commentable_title} (%{commentable_url})." + other: "%{givers_list} су похвалили %{commentable_title} (%{commentable_url})." + single_guest: + giver: Гост/гошћа + html: "%{giver} је оставио/ла похвалу на %{commentable_link}." + text: Гост/гошћа је оставио/ла похвалу на %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Добили сте похвале!" + mailer: + general: + closing: + formal: Srdačan pozdrav, + informal: Sve najbolje, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: "%{title}: Поглавље %{position}" + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} reči" + one: "%{count} reč" + other: "%{count} reči" + footer: + general: + about: + html: AO3 je arhiva koju vode i podržavaju fanovi, a oslanja se na %{donate_link}. + text: 'AO3 je arhiva koju vode i podržavaju fanovi, a oslanja se na Vaše + donacije: %{donate_url}.' + html: + donate_link_text: Vaše donacije + support_link_text: kontaktirajte Korisničku podršku + unwanted_email: + html: Ako ste greškom primili ovu poruku, molimo Vas %{support_link}. + text: Ako ste greškom primili ovu poruku, molimo Vas kontaktirajte Korisničku + podršku na %{support_url}. + sent_at: Poslato u %{sent_at}. + greeting: + formal_html: Poštovani/a %{name}, + informal: + addressed_html: Zdravo, %{name}! + unaddressed: Zdravo! + introductory: Pozdrav od Archive of Our Own – AO3-a (Naše sopstvene arhive)! + metadata_label_indicator: ":" + signature: + abuse_team: Tim Politike i zloupotrebe AO3-a + app_short_name: AO3 + open_doors: Tim Open Doors (Otvorenih vrata) + parent_org: Organization for Transformative Works – OTW (Organizacija za transformativne + radove) + support: Tim Korisničke podrške AO3-a + users: + mailer: + reset_password_instructions: + expiration: Ако не искористите овај линк да ресетујете своју лозинку у року + од недељу дана, истећи ће и мораћете затражити нови. + intro: 'неко је затражио ресетовање лозинке за Bаш налог. Можете променити + лозинку Bашег налога тако што ћете пратити линк испод и унети Вашу нову + лозинку:' + link_title: Промени моју лозинку. + subject: "[%{app_name}] Ресетујте своју лозинку" + unrequested: Уколико нисте затражили ово ресетовање лозинке, можете занемарити + овај имејл и Ваша претходна лозинка ће наставити да ради. + user_mailer: + admin_deleted_work_notification: + bye: У прилогу је копија Вашег дела за Вашу референцу. + contact_abuse: контактирајте наш Одбор за злоупотребу + deleted: + html: Ваше дело %{title} је избрисано са АО3-a од стране администратора сајта. + text: Ваше дело "%{title}" је избрисано са AO3-a од стране администратора + сајта. + html: + tos_violation: Ако постоји могућност да је Ваше дело прекршило Услове коришћења + AO3-a, молимо Вас, %{contact_abuse_link}. + import_project: + html: Ако је Ваше дело било део увезеног пројекта којим се бави наш тим Open + Doors (Отворених врата), молимо Вас, %{opendoors_link} ако имате додатна + питања. + text: Ако је Ваше дело било део увезеног пројекта којим се бави наш тим Open + Doors (Отворених врата), молимо Вас, контактирајте Отворена врата (%{opendoors_link}) + ако имате додатна питања. + opendoors: контактирајте Отворена врата + subject: "[%{app_name}] Ваше дело је избрисано од стране администратора" + text: + tos_violation: Ако постоји могућност да је Ваше дело прекршило Услове коришћења + АО3-а, молимо Вас, контактирајте наш Одбор за злоупотребу (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Иако је Ваше дело сакривено, и даље ћете моћи да му приступите кроз + линк изнад, али неће бити наведено на Вашој страници дела, и неће бити доступно + другим корисницима АО3-а. + check_email: Молимо проверите Ваш имејл, укључујући фолдер за спам, јер Вас + је тим Политике и злоупотребе можда већ контактирао и објаснио зашто је Ваше + дело сакривено. + contact_abuse: контактирајте Политику и злоупотребу + html: + help: Ако нисте сигурни зашто је Ваше дело сакривено, и нисте примили више + информација о овоме, молимо директно %{contact_abuse_link}. + hidden: Ваше дело %{title} је сакривено од стране тима Политике и злоупотребе + и више није јавно доступно. + tos_violation: Ако је Ваше дело сакривено јер је прекршило АО3-ове %{tos_link}, + мораћете да исправите прекршај. Ако Ваше дело не доведете у сагласност са + Условима коришћења, то може довести до брисања Вашег дела са АО3-а. + subject: "[%{app_name}] Ваше дело је сакривено од стране тима Политике и злоупотребе" + text: + help: 'Ако нисте сигурни зашто је Ваше дело сакривено, и нисте примили више + информација о овоме, молимо директно контактирајте Политику и злоупотребу: + %{contact_abuse_url}.' + hidden: Ваше дело "%{title}" (%{work_url}) је сакривено од стране тима Политике + и злоупотребе и више није јавно доступно. + tos_violation: Ако је Ваше дело сакривено јер је прекршило АО3-ове Услове + коришћења (%{tos_url}), мораћете да исправите прекршај. Ако Ваше дело не + доведете у сагласност са Условима коришћења, то може довести до брисања + Вашег дела са АО3-а. + tos: Услове коришћења + anonymous_or_unrevealed_notification: + anonymous_info: Анонимна дела су укључена у излистане тагове, али нису на Вашој + страници радова. На самом делу, Ваше корисничко име ће бити замењено са "Anonymous" + (Анонимно). + anonymous_unrevealed_info: Одржаваоци збирке могу касније открити Ваше дело, + али га оставити анонимним. Људи који Вас буду пратили неће бити обавештени + када ова промена ступи на снагу. Након што је откривено, Ваше дело ће бити + укључено у излистане тагове, али неће бити на страници Ваших радова. На самом + делу, Ваше корисничко име ће бити замењено са "Anonymous" (Анонимно). + changed_status: + anonymous: + html: Одржаваоци %{collection_link} збирке су променили статус Вашег дела + %{work_link} на анонимно. + text: Одржаваоци "%{collection_title}" (%{collection_url}) збирке су променили + статус Вашег дела "%{work_title}" (%{work_url}) на анонимно. + anonymous_unrevealed: + html: Одржаваоци %{collection_link} збирке су променили статус Вашег дела + %{work_link} на анонимно и неоткривено. + text: Одржаваоци "%{collection_title}" (%{collection_url}) збирке су променили + статус Вашег дела "%{work_title}" (%{work_url}) на анонимно и неоткривено. + unrevealed: + html: Одржаваоци %{collection_link} збирке су променили статус Вашег дела + %{work_link} на неоткривено. + text: Одржаваоци "%{collection_title}" (%{collection_url}) збирке су променили + статус Вашег дела "%{work_title}" (%{work_url}) на неоткривено. + collection_items_link_text: страницу Approved Collection Items (Одобрени предмети + из збирке) + do_not_want: + anonymous: + html: Ако не желите да Ваше дело буде анонимно, молимо Вас да посетите Вашу + %{collection_items_link} како бисте га уклонили из ове збирке. + text: 'Ако не желите да Ваше дело буде анонимно, молимо Вас да посетите + Вашу страницу Approved Collection Items (Одобрени предмети из збирке) + како бисте га уклонили из ове збирке: %{collection_items_url}' + anonymous_unrevealed: + html: Ако не желите да Ваше дело буде анонимно и неоткривено, молимо Вас + да посетите Вашу %{collection_items_link} како бисте га уклонили из ове + збирке. + text: 'Ако не желите да Ваше дело буде анонимно и неоткривено, молимо Вас + да посетите Вашу страницу Approved Collection Items (Одобрени предмети + из збирке) како бисте га уклонили из ове збирке: %{collection_items_url}' + unrevealed: + html: Ако не желите да Ваше дело буде неоткривено, молимо Вас да посетите + Вашу %{collection_items_link} како бисте га уклонили из ове збирке. + text: 'Ако не желите да Ваше дело буде неоткривено, молимо Вас да посетите + Вашу страницу Approved Collection Items (Одобрени предмети из збирке) + како бисте га уклонили из ове збирке: %{collection_items_url}' + faq_link_text: Често постављена питања о збиркама + more_info: + html: За више информација, посетите наша %{faq_link}. + text: 'За више информација, посетите наша Често постављена питања о збиркама: + %{faq_url}' + subject: + anonymous: "[%{app_name}] Ваше дело је начињено анонимним" + anonymous_unrevealed: "[%{app_name}] Ваше дело је начињено анонимним и неоткривеним" + unrevealed: "[%{app_name}] Ваше дело је начињено неоткривеним" + unrevealed_info: Неоткривена дела нису укључена у излистане тагове и нису на + страници Ваших радова. Свако ко буде пратио линк до Вашег дела ће добити обавештење + да је дело тренутно неоткривено, и да није могуће да се приступи његовом садржају. + challenge_assignment_notification: + any: Bilo koji + assignment: + html: Dodeljen Vam je sledeći zahtev u okviru izazova %{link} na AO3-u! + description: 'Opis:' + due: 'Rok za ovaj zadatak je:' + html: + footer: Primili ste ovaj mejl jer ste se prijavili za izazov %{title}. Za + više informacija o izazovu i kontakt informacije moderatora, molimo Vas + da posetite %{footer_link}. + footer_link: profilnu stranicu izazova + look_up: Ovaj zadatak možete potražiti na %{link}. + look_up_link: Vašoj stranici Assignments (Zadaci) + optional_tags: 'Proizvoljni tagovi:' + prompts: 'Ideje (prompts):' + prompt_url: 'Link ideje:' + recipient: 'Primalac:' + recipient_missing: 'Nepoznato: kontaktirajte moderatora za pomoć!' + subject: "[%{app_name}][%{collection_title}] Vaš zadatak!" + text: + assignment: Dodeljen Vam je sledeći zahtev u okviru izazova "%{collection_title}" + (%{collection_url}) na AO3-u! + footer: Primili ste ovaj mejl jer ste se prijavili za izazov %{title} (%{url}). + Za više informacija o izazovu i kontakt informacije moderatora, molimo Vas + da posetite %{profile_url}. + look_up: Ovaj zadatak možete potražiti na Vašoj stranici Assignments (Zadaci) + na %{link}. + change_email: + changed: + html: "%{login}, имејл који је повезан са Вашим налогом је промењен у %{email}" + text: "%{login}, имејл који је повезан са Вашим налогом је промењен у %{email}" + subject: "[%{app_name}] Имејл је промењен" + claim_notification: + access: + contact_support: kontaktirajte Korisničku podršku AO3-a + html: Zavisno od arhive, Vaša dela su možda unesena kao ograničena samo za + registrovane korisnike (kako bi bila sakrivena od Gugl pretraga). Ako je + ovo slučaj, dela će biti dostupna samo ulogovanim korisnicima osim ako Vi + ne odlučite da ih učinite potpuno vidljivim. Za pomoć oko otključavanja, + odricanja od ili brisanja dela, molimo %{contact_support_link}. + text: Zavisno od arhive, Vaša dela su možda unesena kao ograničena samo za + registrovane korisnike (kako bi bila sakrivena od Gugl pretraga). Ako je + ovo slučaj, dela će biti dostupna samo ulogovanim korisnicima osim ako Vi + ne odlučite da ih učinite potpuno vidljivim. Za pomoć oko otključavanja, + odricanja od ili brisanja dela, molimo kontaktirajte Korisničku podršku + AO3-a na %{support_url}. + email_tips: Ako nas kontaktirate, molimo dodajte imejl adrese od @transformativeworks.org + na Vašu listu bezbednih kontakata i proverite Vaše spam foldere za naš odgovor. + introduction: + ao3_name: Archive of Our Own – AO3 (Našu sopstvenu arhivu) + html: Primili ste ovaj imejl jer ste imali dela u arhivi fan-dela koju su + %{open_doors_name_link} unela na %{app_link}. Pošto je ova imejl adresa + povezana sa jednom koja je registrovana na unesenoj arhivi, povezana fan-dela + (navedena ispod) su automatski dodata na Vaš AO3 nalog. + open_doors_name: Open Doors (Otvorena vrata) + text: 'Primili ste ovaj imejl jer ste imali dela u arhivi fan-dela koju su + Open Doors (Otvorena vrata) (%{open_doors_url}) unela na Archive of Our + Own – AO3 (Našu sopstvenu arhivu): %{app_url}. Pošto je ova imejl adresa + povezana sa jednom koja je registrovana na unesenoj arhivi, povezana fan-dela + (navedena ispod) su automatski dodata na Vaš AO3 nalog.' + mistake: + contact_open_doors: kontaktirate Otvorena vrata + html: Ako je ovo greška i ovo nisu Vaša dela, molimo Vas da ih ne obrišete! + Molimo Vas da samo %{contact_open_doors_link} i mi ćemo rešiti problem. + text: Ako je ovo greška i ovo nisu Vaša dela, molimo Vas da ih ne obrišete! + Molimo Vas da samo kontaktirate Otvorena vrata (%{open_doors_url}) i mi + ćemo rešiti problem. + more_info: + ao3_news: AO3 vestima + contact_support: kontaktirajte Korisničku podršku AO3-a + faq_page: stranici Često postavljenih pitanja + html: Možete pročitati objave o skorašnjim prenosima arhiva na %{ao3_news_link}, + i pronaći još informacija na %{faq_page_link} ili %{tutorial_page_link} + Otvorenih vrata. Za pitanja na koja nije odgovoreno u Često postavljenim + pitanjima, tutorijalima ili ovom imejlu, molimo %{contact_support_link}. + text: Možete pročitati objave o skorašnjim prenosima arhiva na AO3 vestima + (%{news_url}), i pronaći još informacija na stranici Često postavljenih + pitanja (%{open_doors_faq_url}) ili stranici tutorijala (%{open_doors_tutorial_url}) + Otvorenih vrata. Za pitanja na koja nije odgovoreno u Često postavljenim + pitanjima, tutorijalima ili ovom imejlu, molimo kontaktirajte Korisničku + podršku AO3-a na %{support_url}. + tutorial_page: stranici tutorijala + other_works: + contact_open_doors: kontaktirajte Otvorena vrata + html: Ako ste imali druga dela na unesenoj arhivi pod imejl adresom kojoj + više ne možete da pristupite, molimo Vas, %{contact_open_doors_link} sa + bilo kojim informacijama koje mogu da pomognu u potvrđivanju Vašeg identiteta. + text: Ako ste imali druga dela na unesenoj arhivi pod imejl adresom kojoj + više ne možete da pristupite, molimo Vas, kontaktirajte Otvorena vrata sa + bilo kojim informacijama koje mogu da pomognu u potvrđivanju Vašeg identiteta. + questions: + contact_support: kontaktirajte Korisničku podršku AO3-a + html: Za druga pitanja, molimo %{contact_support_link}. + text: Za druga pitanja, molimo kontaktirajte Korisničku podršku AO3-a na %{support_url}. + redirects: + html: Kako bi očuvali liste preporuka i obeleživače, veb adrese unesene arhive + će možda voditi do unesenih kopija ovih dela na ograničeno vreme (proverite + objavu za Vašu arhivu kako biste bili sigurni). Ako ste Vi već objavili + kopiju ovih dela i %{negation} koristili opciju unosa putem URL-a, na AO3-u + će postojati dve kopije istog dela. + subject: "[%{app_name}] Dodata dela" + update_redirect: + contact_open_doors: kontaktirate Otvorena vrata + html: Ako želite da Otvorena vrata ažuriraju preusmerenje kako bi vodilo do + Vašeg već postojećeg dela, molimo da obrišete unesenu kopiju i %{contact_open_doors_link} + sa imenom Vašeg AO3 naloga, imenom Vašeg naloga na unesenoj arhivi, i naslovom + i URL-om fan-dela prema kom biste želeli da vodi veb adresa. (Ako imate + više dela za koja biste želeli da promenite preusmerenje, možete da ih navedete + u jednom imejlu.) + text: Ako želite da Otvorena vrata ažuriraju preusmerenje kako bi vodilo do + Vašeg već postojećeg dela, molimo da obrišete unesenu kopiju i kontaktirate + Otvorena vrata na %{open_doors_url} sa imenom Vašeg AO3 naloga, imenom Vašeg + naloga na unesenoj arhivi, i naslovom i URL-om fan-dela prema kom biste + želeli da vodi veb adresa. (Ako imate više dela za koja biste želeli da + promenite preusmerenje, možete da ih navedete u jednom imejlu.) + works_by: 'Ova dela su bila napisana sa imejla: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Сви задаци су послати. + subject: Задаци послати + html: + received_message: 'Примили сте поруку о својој збирци %{collection_link}:' + text: + received_message: 'Примили сте поруку о својој збирци "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Када сте коаутор неког дела, можете бити додани новим главама без + обзира на Ваша подешавања о коауторству. Бићете додани и на сваки серијал + у који је тај рад додан. + html: + creation: "%{creation_link} од %{pseud_links}" + edit_chapter: уредити поглавље + edit_series: уредити серијал + remove_chapter: Ако сте додани грешком или не желите да будете наведени као + аутор, можете %{edit_chapter_link} да бисте уклонили себе са листе аутора. + remove_series: Ако сте додани грешком или не желите да будете наведени као + аутор, можете %{edit_series_link} да бисте уклонили себе са листе аутора. + intro_chapter: 'Корисник %{adding_user} је навео Ваш псеудоним %{pseud} као + коаутора следећег поглавља:' + intro_series: 'Корисник %{adding_user} је навео Ваш псеудоним %{pseud} као коаутора + следећег серијала:' + subject: "[%{app_name}] Обавештење о коауторству" + text: + creation: "%{title} (%{url}) од %{pseuds}" + remove_chapter: 'Ако сте додани грешком или не желите да будете наведени као + аутор, можете уредити поглавље дa бисте уклонили себе као аутора: %{url}' + remove_series: 'Ако сте додани грешком или не желите да будете наведени као + аутор, можете уредити серијал дa бисте уклонили себе као аутора: %{url}' + creatorship_notification_archivist: + explanation: Pošto postupaju po svojoj zvaničnoj nadležnosti kao arhivar Otvorenih + vrata, dozvoljeno im je da Vas dodaju bez zahteva, čak i ako Vam je opcija + koautorstva onemogućena. + html: + creation: "%{creation_link} оd %{pseud_links}" + edit_chapter: uredite poglavlje + edit_series: uredite serijal + edit_work: uredite delo + remove_chapter: Ako ste dodati greškom ili ne želite da budete navedeni kao + autor, možete da %{edit_chapter_link} da biste uklonili sebe kao autora. + remove_series: Ako ste dodati greškom ili ne želite da budete navedeni kao + autor, možete da %{edit_series_link} da biste uklonili sebe kao autora. + remove_work: Ako ste dodati greškom ili ne želite da budete navedeni kao autor, + možete da %{edit_work_link} da biste uklonili sebe kao autora. + intro_chapter: 'Korisnik %{archivist} je dodao Vaš pseudonim %{pseud} kao koautora + na sledeće poglavlje:' + intro_series: 'Korisnik %{archivist} je dodao Vaš pseudonim %{pseud} kao koautora + na sledeći serijal:' + intro_work: 'Korisnik %{archivist} je dodao Vaš pseudonim %{pseud} kao koautora + na sledeće delo:' + subject: "[%{app_name}] Arhivarsko obaveštenje o koautorstvu" + text: + creation: "%{title} (%{url}) od %{pseuds}" + remove_chapter: 'Ako ste dodati greškom ili ne želite da budete navedeni kao + autor, možete da uredite poglavlje da biste uklonili sebe kao autora: %{url}' + remove_series: 'Ako ste dodati greškom ili ne želite da budete navedeni kao + autor, možete da uredite serijal da biste uklonili sebe kao autora: %{url}' + remove_work: 'Ako ste dodati greškom ili ne želite da budete navedeni kao + autor, možete da uredite delo da biste uklonili sebe kao autora: %{url}' + creatorship_request: + html: + creation: "%{creation_link} од стране %{pseud_links}" + instructions: Можете да прихватите или одбијете овај захтев на Вашој страници + %{page_name}. + page_name: Co-Creator Requests (Захтеви за коаутора) + intro_chapter: 'Корисник %{inviting_user} је позвао Ваш псеудоним %{pseud} да + буде на листи коаутора следећег поглавља:' + intro_series: 'Корисник %{inviting_user} је позвао Ваш псеудоним %{pseud} да + буде на листи коаутора следећег серијала:' + intro_work: 'Корисник %{inviting_user} је позвао Ваш псеудоним %{pseud} да буде + на листи коаутора на следећем делу:' + subject: "[%{app_name}] Захтев за коаутора" + text: + creation: "%{title} (%{url}) од стране %{pseuds}" + instructions: 'Можете да прихватите или одбијете овај захтев на Вашој страници + Co-Creator Requests (Захтеви за коаутора): %{url}' + delete_work_notification: + attachment: У прилогу је копија Вашег дела ако желите да га прегледате. + deleted_other: + html: Ваше дело %{title} је избрисано на захтев %{pseud}. + text: Ваше дело "%{title}" је избрисано на захтев %{pseud}. + deleted_yourself: + html: Ваше дело %{title} је избрисано на Ваш захтев. + text: Ваше дело %{title} је избрисано на Ваш захтев. + questions: + html: Ако имате питања, молимо Вас %{support}. + text: Ако имате питања, молимо Вас %{support} (%{url}). + subject: "[%{app_name}] Ваше дело је избрисано" + support: контактирајте Корисничку подршку + invite_increase_notification: + html: + body: + few: Samo smo hteli da Vas obavestimo da imate %{count} nove pozivnice, + koje se mogu koristiti za kreiranje novih naloga na AO3-u. Možete pozvati + prijatelja na %{invitation_page_link}. + one: Samo smo hteli da Vas obavestimo da imate %{count} novu pozivnicu, + koja se može koristiti za kreiranje novih naloga na AO3-u. Možete pozvati + prijatelja na %{invitation_page_link}. + other: Samo smo hteli da Vas obavestimo da imate %{count} novih pozivnica, + koje se mogu koristiti za kreiranje novih naloga na AO3-u. Možete pozvati + prijatelja na %{invitation_page_link}. + invitation_page_link_text: Vašoj stranici Invitations (Pozivnice) + subject: "[%{app_name}] Nove pozivnice" + text: + body: + few: Samo smo hteli da Vas obavestimo da imate %{count} novе pozivnicе, + koje se mogu koristiti za kreiranje novih naloga na AO3-u. Možete pozvati + prijatelja na Vašoj stranici Invitations (Pozivnice) (%{invitation_page_url}). + one: Samo smo hteli da Vas obavestimo da imate %{count} novu pozivnicu, + koja se može koristiti za kreiranje novih naloga na AO3-u. Možete pozvati + prijatelja na Vašoj stranici Invitations (Pozivnice) (%{invitation_page_url}). + other: Samo smo hteli da Vas obavestimo da imate %{count} novih pozivnica, + koje se mogu koristiti za kreiranje novih naloga na AO3-u. Možete pozvati + prijatelja na Vašoj stranici Invitations (Pozivnice) (%{invitation_page_url}). + invite_request_declined: + main: + few: Са жаљењем Вас обавештавамо да се Ваш захтев за %{count} нове позивнице + не може тренутно испунити. + one: Са жаљењем Вас обавештавамо да се Ваш захтев за %{count} нову позивницу + не може тренутно испунити. + other: Са жаљењем Вас обавештавамо да се Ваш захтев за %{count} нових позивница + не може тренутно испунити. + reason: 'Ваш захтев је био:' + subject: "[%{app_name}] Захтев за додатни позивни код је одбијен" + recipient_notification: + html: + collection: Поклон дело за Вас је објављено у %{collection_link} збирци на + АО3-у! + no_collection: Поклон дело за Вас је објављено на АО3-у! + subject: + collection: "[%{app_name}][%{collection_title}] Поклон дело за Вас из %{collection_title}" + no_collection: "[%{app_name}] Поклон дело за Вас" + text: + collection: Поклон дело за Вас је објављено у "%{collection_title}" збирци + (%{collection_url}) на АО3-у! diff --git a/config/locales/phrase-exports/sk.yml b/config/locales/phrase-exports/sk.yml new file mode 100755 index 0000000..581f68b --- /dev/null +++ b/config/locales/phrase-exports/sk.yml @@ -0,0 +1,2 @@ +--- +sk: {} diff --git a/config/locales/phrase-exports/sl.yml b/config/locales/phrase-exports/sl.yml new file mode 100755 index 0000000..74d4e45 --- /dev/null +++ b/config/locales/phrase-exports/sl.yml @@ -0,0 +1,647 @@ +--- +sl: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Opozorila:' + one: 'Opozorilo:' + other: 'Opozorila:' + two: 'Opozorili:' + category: + name_with_colon: + few: 'Kategorije:' + one: 'Kategorija:' + other: 'Kategorije:' + two: 'Kategoriji:' + character: + name_with_colon: + few: 'Liki:' + one: 'Lik:' + other: 'Liki:' + two: 'Lika:' + fandom: + name_with_colon: + few: 'Fandomi:' + one: 'Fandom:' + other: 'Fandomi:' + two: 'Fandoma:' + freeform: + name_with_colon: + few: 'Dodatne oznake:' + one: 'Dodatna oznaka:' + other: 'Dodatne oznake:' + two: 'Dodatni oznaki:' + rating: + name_with_colon: 'Ocena primernosti:' + relationship: + name_with_colon: + few: 'Razmerja:' + one: 'Razmerje:' + other: 'Razmerja:' + two: 'Razmerji:' + work: + chapter_total_display: Poglavja + summary: Povzetek + models: + archive_warning: + few: Opozorila + one: Opozorilo + other: Opozorila + two: Opozorili + category: + few: Kategorije + one: Kategorija + other: Kategorije + two: Kategoriji + chapter: + few: Poglavja + one: Poglavje + other: Poglavja + two: Poglavji + character: + few: Liki + one: Lik + other: Liki + two: Lika + fandom: + few: Fandomi + one: Fandom + other: Fandomi + two: Fandoma + freeform: + few: Dodatne oznake + one: Dodatna oznaka + other: Dodatne oznake + two: Dodatni oznaki + rating: + few: Ocene primernosti + one: Ocena primernosti + other: Ocene primernosti + two: Oceni primernosti + relationship: + few: Razmerja + one: Razmerje + other: Razmerja + two: Razmerji + series: + few: Serije + one: Serija + other: Serije + two: Seriji + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} gosti/je" + one: "%{count} gost/ja" + other: "%{count} gostov/ij" + two: "%{count} gosta/ji" + left_kudos: + html: + few: "%{givers_list} so pohvalili/e %{commentable_link}." + one: "%{givers_list} je pohvalil/a %{commentable_link}." + other: "%{givers_list} je pohvalilo %{commentable_link}." + two: "%{givers_list} sta pohvalila/i %{commentable_link}." + text: + few: "%{givers_list} so pohvalili/e %{commentable_title} (%{commentable_url})." + one: "%{givers_list} je pohvalil/a %{commentable_title} (%{commentable_url})." + other: "%{givers_list} je pohvalilo %{commentable_title} (%{commentable_url})." + two: "%{givers_list} sta pohvalila/i %{commentable_title} (%{commentable_url})." + single_guest: + giver: Gost/ja + html: "%{giver} je pohvalil/a %{commentable_link}." + text: Gost/ja je pohvalil/a %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Dobili ste pohvalo!" + mailer: + general: + closing: + formal: S spoštovanjem, + informal: Z lepimi pozdravi, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Poglavje %{position}, delo %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} besede" + one: "%{count} beseda" + other: "%{count} besed" + two: "%{count} besedi" + footer: + general: + about: + html: Naš lastni arhiv upravljajo in vzdržujejo fani, zato se zanaša na + %{donate_link}. + text: 'Naš lastni arhiv upravljajo in vzdržujejo fani, zato se zanaša + na vaše donacije: %{donate_url}.' + html: + donate_link_text: vaše donacije + support_link_text: kontaktirajte Pomoč uporabnikom + unwanted_email: + html: Če ste to sporočilo prejeli po pomoti, prosimo %{support_link}. + text: Če ste to sporočilo prejeli po pomoti, prosimo kontaktirajte Pomoč + uporabnikom preko %{support_url}. + sent_at: Poslano dne %{sent_at}. + greeting: + formal_html: Spoštovani %{name}, + informal: + addressed_html: Zdravo, %{name}! + unaddressed: Zdravo! + introductory: Lep pozdrav od Archive Of Our Own - AO3! + metadata_label_indicator: ":" + signature: + abuse_team: Ekipa za pravila in zlorabo AO3 + app_short_name: AO3 + open_doors: Ekipa Open Doors (Odprta vrata) + parent_org: Organization for Transformative Works - OTW (Organizacija za tranformativna + dela) + support: AO3 ekipa za pomoč uporabnikom + users: + mailer: + reset_password_instructions: + expiration: Če povezave za spremembo gesla ne uporabite v roku enega tedna, + bo ta potekla in morali boste zahtevati novo. + intro: 'Nekdo je zahteval ponastavitev vašega gesla. Svoje geslo lahko spremenite + tako, da sledite slednji povezavi in vnesete novo geslo:' + link_title: Spremeni moje geslo. + subject: "[%{app_name}] Ponastavite svoje geslo" + unrequested: Če ponastavitve gesla niste zahtevali, lahko prezrete to elektronsko + sporočilo in vaše trenutno geslo bo ostalo veljavno. + user_mailer: + admin_deleted_work_notification: + bye: V priponki lahko najdete kopijo svojega dela. + contact_abuse: stopite v stik z Odborom za pravila in zlorabo. + deleted: + html: Administrator je vaše delo %{title} odstranil iz AO3. + text: Administrator je vaše delo %{title} odstranil iz AO3. + html: + tos_violation: Če je vaše delo morda kršilo Pogoje uporabe AO3, prosimo %{contact_abuse_link}. + import_project: + html: Če je bilo vaše delo del uvoženega projekta pod nadzorom naše ekipe + Open Doors (Odprta vrata), prosimo %{opendoors_link} z vsemi nadaljnjimi + vprašanji. + text: Če je bilo vaše delo del uvoženega projekta pod nadzorom naše ekipe + Open Doors (Odprta vrata), prosimo kontaktirajte Odprta vrata (%{opendoors_link}) + z vsemi nadaljnjimi vprašanji. + opendoors: kontaktirajte Odprta vrata + subject: "[%{app_name}] Administrator je odstranil vaše delo" + text: + tos_violation: Če je vaše delo morda kršilo Pogoje uporabe AO3, prosimo stopite + v stik z Odborom za pravila in zlorabo (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Medtem ko je vaše delo skrito, do njega še vedno lahko dostopate preko + zgornje povezave; ne bo pa navedeno na vaši strani z deli in ne bo dostopno + drugim uporabnikom AO3-ja. + check_email: Prosimo preverite vašo elektronsko pošto, vključno s predalom za + vsiljeno pošto, saj je ekipa za pravila in zlorabo morda že stopila v stik + z vami in razložila, zakaj je bilo vaše delo skrito. + contact_abuse: stopite v stik z Ekipo za pravila in zlorabo + html: + help: Če ne veste, zakaj je bilo vaše delo skrito in niste dobili nobenega + nadaljnjega sporočila o tej zadevi, prosimo %{contact_abuse_link}. + hidden: Ekipa za pravila in zlorabo je skrila vaše delo %{title}, ki zdaj + ni več javno dostopno. + tos_violation: Če je bilo vaše delo skrito, ker je kršilo %{tos_link} AO3, + boste morali to kršitev odpraviti. Če tega ne storite, bo vaše delo morda + odstranjeno iz AO3. + subject: "[%{app_name}] Ekipa za pravila in zlorabo je skrila vaše delo" + text: + help: 'Če ne veste, zakaj je bilo vaše delo skrito in niste dobili nobenega + nadaljnjega sporočila o tej zadevi, prosimo kontaktirajte Ekipo za pravila + in zlorabo: %{contact_abuse_url}.' + hidden: Ekipa za pravila in zlorabo je skrila vaše delo "%{title}" (%{work_url}), + ki zdaj ni več javno dostopno. + tos_violation: Če je bilo vaše delo skrito, ker je kršilo Pogoje uporabe (%{tos_url}) + AO3, boste morali to kršitev odpraviti. Če tega ne storite, bo vaše delo + morda odstranjeno iz AO3. + tos: Pogoje uporabe + anonymous_or_unrevealed_notification: + anonymous_info: Anonimna dela so vključena na sezname oznak, ne pa na vaši strani + z deli. Na delu bo vaše uporabniško ime nadomeščeno z "Anonymous" (Anonimno). + anonymous_unrevealed_info: Vzdrževalci zbirke bodo morda kasneje razkrili vaše + delo in ga hkrati pustili anonimnega. Kdor je naročen na vaše vsebine o tej + spremembi ne bo obveščen. Ko je delo enkrat razkrito, bo prikazano na seznamih + oznak, vendar ga ne bo na vaši strani z deli. Na delu bo vaše uporabniško + ime nadomeščeno z "Anonymous" (Anonimno). + changed_status: + anonymous: + html: Vzdrževalci zbirke %{collection_link} so spremenili status vašega + dela %{work_link} v anonimnega. + text: Vzdrževalci zbirke "%{collection_title}" (%{collection_url}) so status + vašega dela "%{work_title}" (%{work_url}) spremenili v anonimnega. + anonymous_unrevealed: + html: Vzdrževalci zbirke %{collection_link} so spremenili status vašega + dela %{work_link} v anonimnega in nerazkritega. + text: Vzdrževalci zbirke "%{collection_title}" (%{collection_url}) so status + vašega dela "%{work_title}" (%{work_url}) spremenili v anonimnega in nerazkritega. + unrevealed: + html: Vzdrževalci zbirke %{collection_link} so spremenili status vašega + dela %{work_link} v nerazkritega. + text: Vzdrževalci zbirke "%{collection_title}" (%{collection_url}) so status + vašega dela "%{work_title}" (%{work_url}) spremenili v nerazkritega. + collection_items_link_text: stran Approved Collection Items (Odobreni elementi + v zbirki) + do_not_want: + anonymous: + html: Če ne želite, da je vaše delo anonimno, prosimo obiščite vašo %{collection_items_link}, + da ga odstranite iz te zbirke. + text: 'Če ne želite, da je vaše delo anonimno, obiščite stran Approved Collection + Items (Odobreni elementi v zbirki), da ga odstranite iz te zbirke: %{collection_items_url}' + anonymous_unrevealed: + html: Če ne želite, da je vaše delo anonimno in nerazkrito, obiščite vašo + %{collection_items_link}, da ga odstranite iz te zbirke. + text: 'Če ne želite, da je vaše delo anonimno in nerazkrito, obiščite stran + Approved Collection Items page (Odobreni elementi v zbirki), da ga odstranite + iz te zbirke: %{collection_items_url}' + unrevealed: + html: Če ne želite, da je vaše delo nerazkrito, obiščite vašo %{collection_items_link}, + da ga odstranite iz te zbirke. + text: 'Če ne želite, da je vaše delo narazkrito, obiščite stran Approved + Collection Items (Odobreni elementi v zbirki), da ga odstranite iz te + zbirke: %{collection_items_url}' + faq_link_text: Pogosta vprašanja o zbirkah + more_info: + html: Za več informacij obiščite naša %{faq_link}. + text: 'Za več informacij obiščite naša pogosta vprašanja o zbirkah: %{faq_url}' + subject: + anonymous: "[%{app_name}] Vaše delo je postalo anonimno" + anonymous_unrevealed: "[%{app_name}] Vaše delo je postalo anonimno in nerazkrito" + unrevealed: "[%{app_name}] Vaše delo je postalo nerazkrito" + unrevealed_info: Nerazkrita dela niso vključena v sezname oznak ali navedena + na strani vaših del. Kdorkoli sledi povezavi do dela, bo prejel obvestilo, + da je delo trenutno nerazkrito in da dostop do vsebine ni mogoč. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (odobrena dela v zbirkah) + archivist_notice: Ker vzdrževalci_ke zbirke arhivirajo v imenu Open Doors (Odprtih + vrat), lahko vaše delo dodajo tej zbirki, tudi če ste onemogočili povabila + v zbirke. Dela se na ta način zbirkam dodajajo samo, če jih je prej gostil + arhiv, ki smo ga uvozili na AO3. + removal_instructions: + html: Če želite delo iz te zbirke odstraniti, prosimo, obiščite svojo stran + %{approved_items_link}. + text: 'Če želite delo iz te zbirke odstraniti, prosimo, obiščite svojo stran + Approved Collection Items (odobrena dela v zbirkah): %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Arhivist_ka Open Doors (Odprtih + vrat) je vaše delo dodal_a zbirki" + work_added: + html: Vzdrževalci_ke zbirke %{collection_link} so vaše delo %{work_link} dodali_e + svoji zbirki! + text: Vzdrževalci zbirke "%{collection_title}" (%{collection_url}) so vaše + delo "%{work_title}" (%{work_url}) dodali svoji zbirki! + challenge_assignment_notification: + any: Po želji + assignment: + html: Dodeljena vam je bila naslednja zahteva v izzivu %{link} na AO3! + description: 'Opis:' + due: 'Rok za oddajo naloge:' + html: + footer: To sporočilo ste prejeli, ker ste se prijavili na izziv %{title}. + Za več informacij o tem izzivu in za kontaktne podatke moderatork_jev, prosimo, + obiščite %{footer_link}. + footer_link: profilno stran izziva + look_up: Nalogo si lahko ogledate na %{link}. + look_up_link: svoji strani Assignments (Naloge) + optional_tags: 'Neobvezne oznake:' + prompts: 'Iztočnice (prompti):' + prompt_url: 'URL iztočnice (prompta):' + recipient: 'Prejemnik_ca:' + recipient_missing: 'Nihče: kontaktirajte moderatorja_ko za pomoč!' + subject: "[%{app_name}][%{collection_title}] Vaša naloga!" + text: + assignment: Dodeljena vam je bila naslednja naloga v izzivu "%{collection_title}" + (%{collection_url}) na AO3! + footer: To sporočilo ste prejeli, ker ste se prijavili na izziv %{title} (%{url}). + Za več informacij o tem izzivu in za kontaktne podatke moderatorjev, prosimo, + obiščite %{profile_url}. + look_up: Nalogo si lahko ogledate na svoji strani Assignments (Naloge) na + %{link}. + change_email: + changed: + html: "%{login}, elektronski naslov povezan z vašim računom je bil spremenjen + v %{email}" + text: "%{login}, elektronski naslov povezan z vašim računom je bil spremenjen + v %{email}" + subject: "[%{app_name}] Sprememba elektronskega naslova" + claim_notification: + access: + contact_support: podporo AO3 + html: Od posameznega arhiva je odvisno, ali bodo dela kot privzeto na voljo + zgolj prijavljenim uporabnikom (v izogib pojavljanja med zadetki iskanja + v Googlu). V tem primeru bodo dela na voljo le prijavljenim članom, razen + če se odločite, da jih naredite vidne vsem uporabnikom. Za pomoč pri spreminjanju + vidnosti, opuščanju ali brisanju del se obrnite na %{contact_support_link}. + text: Od posameznega arhiva je odvisno, ali bodo dela kot privzeto na voljo + zgolj prijavljenim uporabnikom (v izogib pojavljanja med zadetki iskanja + v Googlu). V tem primeru bodo dela na voljo le prijavljenim članom, razen + če se odločite, da jih naredite vidne vsem uporabnikom. Za pomoč pri spreminjanju + vidnosti, opuščanju ali brisanju del se obrnite na podporo AO3 na %{support_url}. + email_tips: Če se nam odločite pisati, prosimo, dodajte @transformativeworks.org + med zaupanja vredne stike in za našim odgovorom pobrskajte po mapi z vsiljeno + pošto. + introduction: + ao3_name: Archive of Our Own – AO3 (Naš lastni arhiv) + html: To e-poštno sporočilo ste prejeli, ker so vaša dela gostovala na arhivu + fanovskih del, ki so ga na %{app_link} uvozila %{open_doors_name_link}. + Ker je ta e-poštni naslov povezan z e-poštnim naslovom, registriranim na + uvoženem arhivu, smo fanovska dela, ki ste jih z njim naložili (našteta + spodaj), avtomatično dodali vašemu računu AO3. + open_doors_name: Open Doors (Odprta vrata) + text: To e-poštno sporočilo ste prejeli, ker so vaša dela gostovala na arhivu + fanovskih del, ki so ga na Archive of Our Own – AO3 (Naš lastni arhiv) (%{app_url}) + uvozila Open Doors (Odprta vrata) (%{open_doors_url}). Ker je ta e-poštni + naslov povezan z e-poštnim naslovom, registriranim na uvoženem arhivu, smo + fanovska dela, ki ste jih z njim naložili (našteta spodaj), avtomatično + dodali vašemu računu AO3. + mistake: + contact_open_doors: stopite v stik z Odprtimi vrati + html: Če je prišlo do pomote in dela niso vaša, jih nikar ne brišite. Prosimo, + da %{contact_open_doors_link}, ki vam bodo priskočila na pomoč. + text: Če je prišlo do pomote in dela niso vaša, jih nikar ne brišite. Prosimo, + da stopite v stik z Odprtimi vrati (%{open_doors_url}), ki vam bodo priskočila + na pomoč. + more_info: + ao3_news: novicah AO3 + contact_support: podporo AO3 + faq_page: pogostimi vprašanji + html: O aktualnih uvozih arhivov si lahko preberete v %{ao3_news_link}, dodatne + informacije pa poiščete med %{faq_page_link} o Odprtih vratih ali na %{tutorial_page_link}. + Vsa vprašanja, na katera ne najdete odgovora v pogostih vprašanjih, vodičih + ali tem e-poštnem sporočilu, lahko naslovite na %{contact_support_link}. + text: O aktualnih uvozih arhivov si lahko preberete v novicah AO3 (%{news_url}), + dodatne informacije pa poiščete med pogostimi vprašanji o Odprtih vratih + (%{open_doors_faq_url}) ali na strani z vodičem (%{open_doors_tutorial_url}). + Vsa vprašanja, na katera ne najdete odgovora v pogostih vprašanjih, vodičih + ali tem e-poštnem sporočilu, lahko naslovite na podporo uporabnikom na %{support_url}. + tutorial_page: strani z vodičem + other_works: + contact_open_doors: stopite v stik z Odprtimi vrati + html: Če ste imeli na uvoženem arhivu pod e-poštnim naslovom, do katerega + ste izgubili dostop, objavljena druga dela, prosimo, %{contact_open_doors_link} + z vsakršno informacijo, ki nam bo pomagala overiti vašo identiteto. + text: Če ste imeli na uvoženem arhivu pod e-poštnim naslovom, do katerega + ste izgubili dostop, objavljena druga dela, prosimo, stopite v stik z Odprtimi + vrati z vsakršno informacijo, ki nam bo pomagala overiti vašo identiteto. + questions: + contact_support: podporo AO3 + html: Ostala vprašanja lahko naslovite na %{contact_support_link}. + text: Ostala vprašanja lahko naslovite na podporo uporabnikom AO3 na %{support_url}. + redirects: + html: Da se ohranijo seznami priporočil in zaznamki, bodo spletni naslovi + uvoženega arhiva nekaj časa morda preusmerjeni na uvožene kopije teh del + (če se želite prepričati o tem, si preberite oznanilo o uvozu za vaš arhiv). + Če ste kopije zgoraj navedenih del na AO3 že naložili sami in jih %{negation} + uvozili prek hiperpovezave, bosta na AO3 obstajali po dve kopiji vsakega + posameznega dela. + subject: Dela uvožena na [%{app_name}] + update_redirect: + contact_open_doors: Stopite v stik z Odprtimi vrati + html: Če želite, da Odprta vrata namesto na novo kopijo preusmerjajo na to, + ki ste jo že naložili, prosimo, izbrišite neželeno novo in %{contact_open_doors_link} + z vašima uporabniškima računoma na AO3 ter na uvoženem arhivu in z naslovom + dela ter hiperpovezavo, na katero naj po novem vodi preusmeritev. (Če želite + preusmeritve spremeniti za več del, jih lahko naštejete v enem samem e-poštnem + sporočilu.) + text: Če želite, da Odprta vrata namesto na novo kopijo preusmerjajo na to, + ki ste jo že naložili, prosimo, izbrišite neželeno novo in prek %{open_doors_url} + stopite v stik z Odpritimi vrati z vašima uporabniškima računoma na AO3 + ter na uvoženem arhivu in z naslovom dela ter hiperpovezavo, na katero naj + po novem vodi preusmeritev. (Če želite preusmeritve spremeniti za več del, + jih lahko naštejete v enem samem e-poštnem sporočilu.) + works_by: Sledeča dela so bila povezana z e-poštnim naslovom %{email} + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Vse naloge so bile poslane. + subject: Naloge so bile poslane + html: + received_message: 'Prejeli ste obvestilo glede svoje zbirke %{collection_link}:' + text: + received_message: 'Prejeli ste obvestilo glede svoje zbirke "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Kot soustvarjalec_ka dela ste lahko dodani v nova poglavja ne glede + na vaše nastavitve o soustvarjalstvu. Dodani boste tudi v vse serije, v katere + je delo dodano. + html: + creation: "%{creation_link} od %{pseud_links}" + edit_chapter: uredite poglavje + edit_series: uredite serijo + remove_chapter: Če ste bili dodani po pomoti ali ne želite biti navedeni kot + ustvarjalec_ka, lahko %{edit_chapter_link} in se odstranite. + remove_series: Če ste bili dodani po pomoti ali ne želite biti navedeni kot + ustvarjalec_ka, %{edit_series_link} in se odstranite. + intro_chapter: 'Uporabnik_ca %{adding_user} je dodal_a vaš pseudonim %{pseud} + kot soustvarjalca_ko sledečega poglavja:' + intro_series: 'Uporabnik_ca %{adding_user} je vaš psevdonim %{pseud} navedel_a + kot soustvarjalca_ko naslednje serije:' + subject: "[%{app_name}] Obvestilo o soustvarjalstvu" + text: + creation: "%{title} (%{url}) od %{pseuds}" + remove_chapter: 'Če ste bili dodani po pomoti ali ne želite biti navedeni + kot ustvarjalec_ka, lahko uredite poglavje in odstranite navedbo: %{url}' + remove_series: Če ste bili dodani po pomoti ali ne želite biti navedeni kot + ustvarjalec_ka, lahko uredite serijo in odstranite navedbo %{url} + creatorship_notification_archivist: + explanation: Ker deluje v imenu Open Doors (Odprtih vrat), vas arhivist_ka lahko + doda brez povabila, tudi če imate soustvarjanje onemogočeno. + html: + creation: "%{creation_link} od %{pseud_links}" + edit_chapter: poglavje uredite + edit_series: serijo uredite + edit_work: delo uredite + remove_chapter: Če ste bili dodani po pomoti ali ne želite biti navedeni kot + ustvarjalec_ka, lahko %{edit_chapter_link} in se odstranite. + remove_series: Če ste bili dodani po pomoti ali ne želite biti navedeni kot + ustvarjalec_ka, lahko %{edit_series_link} in se odstranite. + remove_work: Če ste bili dodani po pomoti ali ne želite biti navedeni kot + ustvarjalec_ka, lahko %{edit_work_link} in se odstranite. + intro_chapter: 'Uporabnik_ca %{archivist} je dodal_a vaš psevdonim %{pseud} + kot soustvarjalca_ko sledečega poglavja:' + intro_series: 'Uporabnik_ca %{archivist} je dodal_a vaš psevdonim %{pseud} kot + soustvarjalca_ko sledeče serije:' + intro_work: 'Uporabnik_ca %{archivist} je dodal_a vaš psevdonim %{pseud} kot + soustvarjalko_ca sledečega dela:' + subject: Obvestilo arhivista_ke [%{app_name}] o soustvarjalstvu + text: + creation: "%{title} (%{url}) od %{pseuds}" + remove_chapter: 'Če ste bili dodani po pomoti ali ne želite biti navedeni + kot ustvarjalec, lahko uredite poglavje in se odstranite: %{url}' + remove_series: 'Če ste bili dodani po pomoti ali ne želite biti navedeni kot + ustvarjalec, lahko uredite serijo in se odstranite: %{url}' + remove_work: 'Če ste bili dodani po pomoti ali ne želite biti navedeni kot + ustvarjalec, lahko uredite delo in se odstranite: %{url}' + creatorship_request: + html: + creation: "%{creation_link}, avtorstvo: %{pseud_links}" + instructions: Prošnjo lahko sprejmete ali zavrnete na vaši strani %{page_name}. + page_name: Co-Creator Requests (Prošnje za status soustvarjalca) + intro_chapter: 'Uporabnik_ca %{inviting_user} je povabil_a vaš psevdonim %{pseud} + za navedbo kot soustvarjalca_ko sledečega poglavja:' + intro_series: 'Uporabnik_ca %{inviting_user} je povabil_a vaš psevdonim %{pseud} + za navedbo kot soustvarjalca_ko sledeče serije:' + intro_work: 'Uporabnik_ca %{inviting_user} je povabil_a vaš psevdonim %{pseud} + za navedbo kot soustvarjalca_ko sledečega dela:' + subject: "[%{app_name}] Prošnja za status soustvarjalca" + text: + creation: "%{title} (%{url}), avtorstvo: %{pseuds}" + instructions: 'Prošnjo lahko sprejmete ali zavrnete na vaši strani Co-Creator + Requests (Prošnje za status soustvarjalca): %{url}' + delete_work_notification: + attachment: V priponki lahko najdete kopijo svojega dela. + deleted_other: + html: Vaše delo %{title} je bilo izbrisano na zahtevo %{pseud}. + text: Vaše delo "%{title}" je bilo izbrisano na zahtevo %{pseud}. + deleted_yourself: + html: Vaše delo %{title} je bilo izbrisano na vašo zahtevo. + text: Vaše delo "%{title}" je bilo izbrisano na vašo zahtevo. + questions: + html: Če imate vprašanja, prosimo, %{support}. + text: Če imate vprašanja, prosimo, %{support} (%{url}). + subject: "[%{app_name}] Vaše delo je bilo izbrisano" + support: kontaktirajte pomoč uporabnikom + invitation_to_claim: + access: + text: Glede na arhiv so bila vaša dela morda uvožena tako, da so dostopna + samo registriranim uporabnikom (da niso dostopna na google iskanju). V tem + primeru so ta dela dostopna samo prijavljenim uporabnikom, razen če se odločite, + da bodo popolnoma vidna. Če potrebujete pomoč pri odklepanju, opuščanju + ali izbrisanju vašim del, prosimo, kontaktirajte AO3 podporo uporabnikom. + claim_or_remove: + html: Kliknite tu, da si prilastite ali odstranite svoja dela. + text: 'Kliknite tu, da si prilastite ali odstranite svoja dela: %{claim_url}' + email_tips: 'Če nas kontaktirate, prosimo dodajte e-mail naslove @transformativeworks.org + na seznam dovoljenih naslovov in preverite, če je bil naš odgovor preusmerjen + v vašo mapo z vsiljeno pošto. ' + html: + ao3_news: AO3 novice + contact_open_doors: kontaktirajte Odprta vrata + contact_support: kontaktirajte podporo uporabnikom AO3 + faq_page: Pogosta vprašanja + tutorial_page: vodič + introduction: + text: Ta e-mail ste prejeli, ker so pred kratkim pri Odprtih vratih (%{open_doors_link}) + uvozili arhiv v %{app_name} (%{app_short_name} - %{app_url}). Naslednja + fan-dela naj bi pripadala vam. Radi bi vam dali priložnost, da si ta dela, + če tako želite, prilastite (ali da jih izbrišete oz. da jih opustite). Če + še nimate uporabniškega računa pod drugim e-mailom, bi vas radi povabili, + da se nam pridružite! + mistake: + text: Če je prišlo do napake in ta dela niso vaša, vas naprošamo, da jih ne + izbrišite! Prosimo, kontaktirajte Odprta vrata (%{open_doors_link}) in razrešili + bomo težavo. + more_info: + text: Obvestila o nedavnih premikih arhivov lahko preberete na AO3 novicah + (%{news_link}), dodatne informacije pa lahko najdete na strani Odprtih vratih + s pogostimi vprašanji (%{open_doors_faq_link}) ali v vodiču (%{open_doors_tutorial_link}). + Za vprašanja, na katere ni odgovora na strani z pogostimi vprašanji, v vodiču + ali v tem e-mailu, prosimo, kontaktirajte podporo uporabnikom na %{support_link}. + other_works: + text: Če ste imeli na uvoženem arhivu druga dela pod e-poštnim naslovom, do + katerega nimate več dostopa, prosimo, kontaktirajte Odprta vrata z kakršnimi + koli informacijami, ki bi nam lahko pomagale potrditi vašo identiteto. + questions: + text: Za druga vprašanja, prosimo, kontaktirajte AO3 podporo uporabnikom na + %{support_link}. + redirects: Zato, da ohranjamo sezname priporočil in zaznamke, lahko spletni + naslovi uvoženega arhiva za določen čas preusmerijo na uvoženo kopijo teh + del (da se prepričate o tem, preverite objavo z obvestilom za vaš arhiv). + Če ste že naložili kopijo teh del in NISTE uporabili funkcije uvoza iz URL-ja, + bosta v arhivu dve kopiji istega dela. + subject: "[%{app_name}] Povabilo k zahtevku za lastništvo dela" + unwanted: + text: Če so ta dela vaša, ampak jih ne želite lastiti, jih lahko opustite + oz. osirotite (tako bodo ostala na AO3, ampak brez vašega imena). Če želite + opustiti ali popolnoma izbrisati ta dela, za to ne potrebujete dodati nobenega + uporabniškega računa, temveč lahko to storite direktno na zgornji povezavi + (za pomoč, prosimo, kontaktirajte podporo uporabnikom na %{support_link}). + update_redirect: + text: Če želite, da Odprta vrata posodobijo preusmeritev, da kaže na vaše + obstoječe delo, izbrišite uvoženo kopijo in kontaktirajte Odprta vrata na + %{open_doors_link} z imenom vašega AO3 računa, z imenom računa na uvoženem + arhivu in z naslovom ter URL-jem fan-dela, kamor želite, da vodi preusmeritev. + (Če imate več del, za katera bi radi spremenili preusmeritve, jih lahko + navedete v enem e-mailu.) + uploaded_list: 'Objavljena dela vključujejo:' + invite_increase_notification: + html: + body: + few: Sporočamo vam, da imate %{count} nova vabila za ustvarjanje novega + uporabniškega računa na AO3. Podarite jih lahko preko %{invitation_page_link}. + one: Sporočamo vam, da imate %{count} novo vabilo za ustvarjanje novega + uporabniškega računa na AO3. Podarite ga lahko preko %{invitation_page_link}. + other: Sporočamo vam, da imate %{count} novih vabil za ustvarjanje novega + uporabniškega računa na AO3. Podarite jih lahko preko %{invitation_page_link}. + two: Sporočamo vam, da imate %{count} novi vabili za ustvarjanje novega + uporabniškega računa na AO3. Podarite ju lahko preko %{invitation_page_link}. + invitation_page_link_text: vaše strani Invitations (Vabila) + subject: "[%{app_name}] Nova vabila" + text: + body: + few: Sporočamo vam, da imate %{count} nova vabila za ustvarjanje novega + uporabniškega računa na AO3. Podarite jih lahko preko %{invitation_page_url}. + one: Sporočamo vam, da imate %{count} novo vabilo za ustvarjanje novega + uporabniškega računa na AO3. Prijatelje lahko povabite preko vaše strani + Invitations (Vabila) (%{invitation_page_url}). + other: Sporočamo vam, da imate %{count} novih vabil za ustvarjanje novega + uporabniškega računa na AO3. Podarite jih lahko preko %{invitation_page_url}. + two: Sporočamo vam, da imate %{count} novi vabili za ustvarjanje novega + uporabniškega računa na AO3. Prijatelje lahko povabite preko vaše strani + Invitations (Vabila) (%{invitation_page_url}). + invite_request_declined: + main: + few: Žal vam sporočamo, da vam trenutno ne moremo posredovati %{count} kod + za povabila. + one: Žal vam sporočamo, da vam trenutno ne moremo posredovati %{count} nove + kode za povabilo. + other: Žal vam sporočamo, da vam trenutno ne moremo posredovati %{count} kod + za povabila. + two: Žal vam sporočamo, da vam trenutno ne moremo posredovati %{count} kod + za povabila. + reason: 'Vaša prošnja:' + subject: "[%{app_name}] Prošnja za dodatne kode za povabila zavrnjena" + recipient_notification: + html: + collection: Na AO3 je bilo v zbirki %{collection_link} objavljeno delo, ki + vam je bilo podarjeno! + no_collection: Na AO3 je bilo objavljeno delo, ki vam je bilo podarjeno! + subject: + collection: "[%{app_name}][%{collection_title}] Podarjeno delo za vas iz %{collection_title}" + no_collection: "[%{app_name}] Podarjeno delo za vas" + text: + collection: Na AO3 je bilo v zbirki "%{collection_title}" (%{collection_url}) + objavljeno delo, ki vam je bilo podarjeno! + signup_notification: + activate: + html: Prosimo, %{activate_account_link}. + text: 'Prosimo, kliknite na naslednji link, da aktivirate svoj račun: %{activate_account_url}.' + activate_your_account: kliknite na naslednjo povezavo, da aktivirate vaš račun + admin_posts: AO3 Novice + bye: Upamo, da boste uživali v uporabi AO3. + contact_support: kontaktirajte pomoč uporabnikom + faq: pogostih vprašanjih + features: + html: Ko aktivirate svoj račun, lahko objavljate svoja fan-dela, nastavite + e-poštne naročnine, da boste obveščeni o najnovejših posodobitvah vaših + najljubših ustvarjalcev in del, nastavite preference, da si prilagodite + delovanje in izgled strani, vodite evidenco del, do katerih ste dostopali + na AO3 preko vaše zgodovine, in še veliko več. + text: Ko aktivirate svoj račun, lahko objavljate svoja fan-dela, nastavite + e-poštne naročnine, da boste obveščeni o najnovejših posodobitvah vaših + najljubših ustvarjalcev in del, nastavite preference, da si prilagodite + delovanje in izgled strani, vodite evidenco del, do katerih ste dostopali + na AO3 preko vaše zgodovine, in še veliko več. + information: + html: Veliko informacij in nasvetov o tem kako uporabljati AO3 najdete v naših + %{faq_link}. Najnovejše novice o razvoju strani najdete v %{admin_posts_link}. + Če potrebujete pomoč, naletite na napako, ali imate vprašanja ali komentarje, + prosimo, %{contact_support_link}, katere člani so vedno na voljo, da vam + pomagajo. + text: Veliko informacij in nasvetov o tem kako uporabljati AO3 najdete na + strani s pogostimi vprašanji v %{faq_url}. Najnovejše informacije o razvoju + strani AO3 Novic najdete v %{admin_posts_url}. Če potrebujete pomoč, naletite + na napako, ali imate vprašanja ali komentarje, prosimo, %{contact_support_url}, + katere člani so vedno na voljo, da vam pomagajo. + welcome: Pozdravljeni v Archive of Our Own, %{login}! diff --git a/config/locales/phrase-exports/sv.yml b/config/locales/phrase-exports/sv.yml new file mode 100755 index 0000000..0c3432b --- /dev/null +++ b/config/locales/phrase-exports/sv.yml @@ -0,0 +1,617 @@ +--- +sv: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Varning:' + other: 'Varningar:' + category: + name_with_colon: + one: 'Kategori:' + other: 'Kategorier:' + character: + name_with_colon: + one: 'Karaktär:' + other: 'Karaktärer:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandoms:' + freeform: + name_with_colon: + one: 'Ytterligare tagg:' + other: 'Ytterligare taggar:' + rating: + name_with_colon: 'Åldersgräns:' + relationship: + name_with_colon: + one: 'Relation:' + other: 'Relationer:' + work: + chapter_total_display: Kapitel + summary: Sammanfattning + models: + archive_warning: + one: Varning + other: Varningar + category: + one: Kategori + other: Kategorier + chapter: + one: Kapitel + other: Kapitel + character: + one: Karaktär + other: Karaktärer + fandom: + one: Fandom + other: Fandoms + freeform: + one: Ytterligare tagg + other: Ytterligare taggar + rating: + one: Åldersgräns + other: Åldersgränser + relationship: + one: Relation + other: Relationer + series: + one: Serie + other: Serier + kudo_mailer: + batch_kudo_notification: + guest: + one: en gäst + other: "%{count} gäster" + left_kudos: + html: + one: "%{givers_list} berömde %{commentable_link}." + other: "%{givers_list} berömde %{commentable_link}." + text: + one: "%{givers_list} berömde %{commentable_title} (%{commentable_url})." + other: "%{givers_list} berömde %{commentable_title} (%{commentable_url})." + single_guest: + giver: En gäst + html: "%{giver} berömde %{commentable_link}." + text: En gäst berömde %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Du har fått beröm!" + mailer: + general: + closing: + formal: Med vänliga hälsningar, + informal: Vänliga hälsningar, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Kapitel %{position} av %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} ord" + other: "%{count} ord" + footer: + general: + about: + html: AO3 är ett arkiv som drivs och stöds av fans och som är beroende + av %{donate_link}. + text: 'AO3 är ett arkiv som drivs och stöds av fans och som är beroende + av era gåvor: %{donate_url}.' + html: + donate_link_text: era gåvor + support_link_text: kontakta Support + unwanted_email: + html: Om du felaktigt har fått detta meddelande, vänligen %{support_link}. + text: Om du felaktigt har fått detta meddelande, vänligen kontakta Support + på %{support_url}. + sent_at: Skickat %{sent_at}. + greeting: + formal_html: Bästa %{name}, + informal: + addressed_html: Hej, %{name}! + unaddressed: Hej! + introductory: Hej från Archive of Our Own – AO3 (Vårt eget arkiv)! + metadata_label_indicator: ":" + signature: + abuse_team: AO3:s team för Policy och missbruk + app_short_name: AO3 + open_doors: Open Doors (Öppna dörrar)-teamet + parent_org: Organization for Transformative Works – OTW (Organisationen för + transformativa verk) + support: AO3:s Support-team + users: + mailer: + reset_password_instructions: + expiration: Om du inte använder den här länken för att återställa ditt lösenord + inom en vecka kommer den att gå ut och du behöver begära en ny länk. + intro: 'Någon har begärt en återställning av ditt kontos lösenord. Du kan + ändra ditt lösenord genom att följa länken nedan och skriva in ditt nya + lösenord:' + link_title: Ändra mitt lösenord. + subject: "[%{app_name}] Återställ ditt lösenord" + unrequested: Om det inte var du som begärde återställning av ditt lösenord + så kan du bortse från det här mailet. Ditt tidigare lösenord kommer att + fortsätta fungera. + user_mailer: + admin_deleted_work_notification: + bye: Som hänvisning har vi bifogat en kopia av ditt verk. + contact_abuse: kontakta vår kommitté för Policy och missbruk + deleted: + html: Ditt verk %{title} har blivit raderat från AO3 av en av webbplatsens + administratörer. + text: Ditt verk "%{title}" har blivit raderat från AO3 av en av webbplatsens + administratörer. + html: + tos_violation: Om det är möjligt att ditt verk bröt mot AO3:s användarvillkor, + var vänlig %{contact_abuse_link}. + import_project: + html: Om ditt verk var en del av ett importprojekt som hanteras av vårt Öppna + dörrar-team, var vänlig %{opendoors_link} om du har frågor. + text: Om ditt verk var en del av ett importprojekt som hanteras av vårt Öppna + dörrar-team, var vänlig kontakta Öppna dörrar (%{opendoors_link}) om du + har frågor. + opendoors: kontakta Öppna dörrar + subject: "[%{app_name}] Ditt verk har blivit raderat av en administratör" + text: + tos_violation: Om det är möjligt att ditt verk bröt mot AO3:s användarvillkor, + var vänlig kontakta vår kommitté för Policy och missbruk (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Fastän ditt verk är dolt kan du fortfarande nå det genom länken ovan, + men det kommer inte att finnas med på listan över dina verk och det är inte + tillgängligt för andra som använder AO3. + check_email: Var vänlig kolla din e-post, inklusive din mapp för skräppost, + eftersom teamet för Policy och missbruk redan kan ha kontaktat dig för att + förklara varför ditt verk är dolt. + contact_abuse: kontakta Policy och missbruk + html: + help: Om du är osäker på varför ditt verk blivit dolt och vi inte har kommunicerat + med dig på annat sätt angående detta, var vänlig %{contact_abuse_link} direkt. + hidden: Ditt verk %{title} har blivit dolt av teamet för Policy och missbruk + och är inte längre tillgängligt för allmänheten. + tos_violation: Om ditt verk har dolts på grund av ett brott mot AO3:s %{tos_link}, + så kommer du att behöva åtgärda problemet. Om du inte korrigerar ditt verk + så att det stämmer överens med användarvillkoren så kan verket komma att + raderas från AO3. + subject: "[%{app_name}] Ditt verk har blivit dolt av teamet för Policy och missbruk" + text: + help: 'Om du är osäker på varför ditt verk har blivit dolt och vi inte har + kommunicerat med dig på annat sätt angående detta, var vänlig kontakta Policy + och missbruk direkt: %{contact_abuse_url}.' + hidden: Ditt verk "%{title}" (%{work_url}) har blivit dolt av teamet för Policy + och missbruk och är inte längre tillgängligt för allmänheten. + tos_violation: Om ditt verk har dolts på grund av ett brott mot AO3:s användarvillkor + (%{tos_url}), så kommer du att behöva åtgärda problemet. Om du inte korrigerar + ditt verk så att det stämmer överens med användarvillkoren så kan verket + komma att raderas från AO3. + tos: användarvillkor + anonymous_or_unrevealed_notification: + anonymous_info: Anonyma verk ingår i tagglistor, men inte på din sida med verk. + På verket kommer ditt användarnamn ersättas med “Anonymous” (Anonym). + anonymous_unrevealed_info: De ansvariga för samlingen kan senare välja att avslöja + ditt verk, men låta det förbli anonymt. Användare som följer dig kommer inte + bli meddelade om denna förändring. När ditt verk har blivit avslöjat kommer + verket finnas med i taggsidor, men inte på din sida med verk. På verket kommer + ditt användarnamn att ersättas med "Anonymous" (Anonymt). + changed_status: + anonymous: + html: De som är ansvariga för samlingen %{collection_link} har ändrat status + på ditt verk %{work_link} till anonym. + text: De ansvariga för samlingen "%{collection_title}" (%{collection_url}) + har ändrat status på ditt verk "%{work_title}" (%{work_url}) till anonym. + anonymous_unrevealed: + html: De som är ansvariga för samlingen %{collection_link} har ändrat status + på ditt verk %{work_link} till anonymt och dolt. + text: De ansvariga för samlingen "%{collection_title}" (%{collection_url}) + har ändrat status på ditt verk "%{work_title}" (%{work_url}) till anonymt + och dolt. + unrevealed: + html: De som är ansvariga för samlingen %{collection_link} har ändrat status + på ditt verk %{work_link} till dolt. + text: De ansvariga för samlingen "%{collection_title}" (%{collection_url}) + har ändrat status på ditt verk "%{work_title}" (%{work_url}) till dolt. + collection_items_link_text: sidan för Approved Collection Items (Godkända samlingsobjekt) + do_not_want: + anonymous: + html: Om du inte vill att ditt verk ska vara anonymt, var god besök %{collection_items_link} + för att ta bort det från den här samlingen. + text: 'Om du inte vill att ditt verk ska vara anonymt, var god besök sidan + Approved Collection Items (Godkända samlingsobjekt) för att ta bort det + från samlingen: %{collection_items_url}' + anonymous_unrevealed: + html: Om du inte vill att ditt verk ska vara anonymt och dolt, var god besök + %{collection_items_link} för att ta bort det från den här samlingen. + text: 'Om du inte vill att ditt verk ska vara anonymt eller dolt, var god + besök sidan Approved Collection Items (Godkända samlingsobjekt) för att + ta bort den från samlingen: %{collection_items_url}' + unrevealed: + html: Om du inte vill att ditt verk ska vara dolt, var god besök %{collection_items_link} + för att ta bort det från den här samlingen. + text: 'Om du inte vill att ditt verk ska döljas, var god besök sidan Approved + Collection Items (Godkända samlingsobjekt) för att ta bort den från samlingen: + %{collection_items_url}' + faq_link_text: Vanliga frågor om samlingar + more_info: + html: För mer information, var god läs våra %{faq_link}. + text: 'För mer information var god läs våra Vanliga frågor om samlingar: %{faq_url}' + subject: + anonymous: "[%{app_name}] Ditt verk har anonymiserats" + anonymous_unrevealed: "[%{app_name}] Ditt verk har anonymiserats och dolts" + unrevealed: "[%{app_name}] Ditt verk har dolts" + unrevealed_info: Dolda verk finns inte med på tagglistor eller sidor med verk. + Alla som följer en länk till verket kommer få ett meddelande om att verket + har dolts och att de inte kan komma åt verkets innehåll. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Godkända samlingsobjekt) + archivist_notice: Eftersom de ansvariga/moderatorerna agerar i sin officiella + kapacitet som Open Doors (Öppna dörrar) arkivarier, så är det tillåtet för + dem att lägga till ditt verk till denna samling, även om du som skapare avaktiverat + inbjudningar till samlingar. Arkivarier kommer bara att lägga till verk i + samlingar om verket fanns på ett importerat arkiv. + removal_instructions: + html: Om du skulle vilja ta bort ditt verk från denna samling, var god se + din sida för %{approved_items_link}. + text: Om du skulle vilja ta bort ditt verk från denna samling, gå till din + sida för Approved Collection Items (Godkända samlingsobjekt) :%{approved_items_url}. + subject: "[%{app_name}][%{collection_title}] En Open Doors (Öppna dörrar) arkivarie + har lagt till ditt verk i en samling" + work_added: + html: De ansvariga för samlingen %{collection_link} har lagt till ditt verk + %{work_link} till sin samling! + text: De ansvariga för samlingen "%{collection_title}" (%{collection_url}) + har lagt till ditt verk "%{work_title}" (%{work_url}) till sin samling! + challenge_assignment_notification: + any: Vilka som helst + assignment: + html: Du har blivit tilldelad följande förfrågan i %{link}-utmaningen på AO3! + description: 'Beskrivning:' + due: 'Det här uppdraget ska lämnas in:' + html: + footer: Du får det här mailet för att du har anmält dig till %{title}-utmaningen. + För mer information om den här utmaningen och kontaktuppgifter till moderatorerna, + vänligen besök %{footer_link}. + footer_link: uppdragets profilsida + look_up: Du kan nå ditt uppdrag via %{link}. + look_up_link: din sida för Assignments (Uppdrag) + optional_tags: 'Valfria taggar:' + prompts: 'Prompts:' + prompt_url: 'Prompt-URL:' + recipient: 'Mottagare:' + recipient_missing: 'Ingen: kontakta en moderator för att få hjälp!' + subject: "[%{app_name}][%{collection_title}] Ditt uppdrag!" + text: + assignment: Du har blivit tilldelad följande förfrågan i "%{collection_title}"-utmaningen + (%{collection_url}) på AO3! + footer: Du får det här mailet för att du har anmält dig till %{title}-utmaningen + (%{url}). För mer information om den här utmaningen och kontaktuppgifter + till moderatorerna, vänligen besök %{profile_url}. + look_up: Du kan nå ditt uppdrag via din sida för Assignments (Uppdrag) på + %{link}. + change_email: + changed: + html: "%{login}, e-postadressen som är knuten till ditt konto har ändrats + till %{email}" + text: "%{login}, e-postadressen som är knuten till ditt konto har ändrats + till %{email}" + subject: "[%{app_name}] E-postadressen har ändrats" + claim_notification: + access: + contact_support: kontakta AO3 support + html: Beroende på arkivet kan det vara så att dina verk har importerats och + begränsats till endast registrerade användare (för att gömma dem från Googles + sökresultat). Om det är så, kommer verken bara finnas tillgängliga för inloggade + användare, såvida du inte väljer att göra dem synliga för alla. För hjälp + med att låsa upp, anonymisera eller radera dina verk, vänligen %{contact_support_link}. + text: Beroende på arkivet kan det vara så att dina verk har importerats och + begränsats till endast registrerade användare (för att gömma dem från Googles + sökresultat). Om det är så kommer verken bara finnas tillgängliga för inloggade + användare, såvida du inte väljer att göra dem synliga för alla. För hjälp + med att låsa upp, anonymisera eller radera dina verk, vänligen kontakta + AO3 Support på %{support_url}. + email_tips: Om du kontaktar oss, var snäll och lägg till mailadresser från @transformativeworks.org + på din lista med säkra kontakter och håll koll på din skräppost för att säkerställa + att du ser vårt svar. + introduction: + ao3_name: Archive of Our Own – AO3 (Vårt eget arkiv) + html: Du får det här mailet eftersom du hade verk på ett arkiv för verk av + fans som har importerats av %{open_doors_name_link} till %{app_link}. Eftersom + den här e-postadressen är kopplad till en användare på det importerade arkivet + så kommer de tillhörande verken (listade nedan) automatiskt läggas till + på ditt konto på AO3. + open_doors_name: Open Doors (Öppna dörrar) + text: 'Du får det här mailet eftersom du hade verk på ett arkiv för verk av + fans som har importerats av Open Doors (Öppna dörrar) (%{open_doors_url}) + till Archive of Our Own – AO3 (Vårt eget arkiv): %{app_url}. Eftersom den + här epostadressen är kopplat till en användare på det importerade arkivet + så kommer de tillhörande verken (listade nedan) automatiskt läggas till + på ditt konto på AO3.' + mistake: + contact_open_doors: kontakta Öppna dörrar + html: Om detta är ett misstag och verken inte är dina, vänligen radera dem + inte! Var snäll och %{contact_open_doors_link} så löser vi det. + text: Om detta är ett misstag och verken inte är dina, vänligen radera dem + inte! Var snäll och kontakta Öppna dörrar (%{open_doors_url}) så löser vi + det. + more_info: + ao3_news: Nyheter på AO3 + contact_support: kontakta AO3 support + faq_page: Vanliga frågor + html: Du kan läsa tillkännagivanden om nya arkivöverföringar på %{ao3_news_link} + och du hittar ytterligare information på Öppna dörrars %{faq_page_link} + eller %{tutorial_page_link}. För frågor som inte finns med i Vanliga frågor, + guider eller detta mail, vänligen %{contact_support_link}. + text: Du kan läsa tillkännagivanden om nya arkivöverföringar på AO3 Nyheter + (%{news_url}), och du hittar ytterligare information på Öppna dörrars sida + för Vanliga frågor (%{open_doors_faq_url}) eller sidan för guider (%{open_doors_tutorial_url}). + För frågor som inte finns med i Vanliga frågor, guider eller detta mail, + vänligen kontakta Support på %{support_url}. + tutorial_page: guider + other_works: + contact_open_doors: kontakta Öppna dörrar + html: Om du hade verk på det importerade arkivet under en mailadress som du + inte längre har tillgång till, vänligen %{contact_open_doors_link} med någon + form av information som kan hjälpa oss verifiera din identitet. + text: Om du hade verk på det importerade arkivet under en mailadress som du + inte längre har tillgång till, vänligen kontakta Öppna dörrar med någon + form av information som kan hjälpa oss verifiera din identitet. + questions: + contact_support: kontakta AO3 support + html: För andra frågor, vänligen %{contact_support_link}. + text: För andra frågor, vänligen kontakta AO3:s Support på %{support_url}. + redirects: + html: För att bevara rekommendationslistor och bokmärken kan det importerade + arkivets webbaddresser dirigera om till den importerade kopian av dessa + verk under en begränsad tid (se inlägget med tillkännagivandet för ditt + arkiv för att vara säker). Om du redan laddat upp en kopia av dessa verk + och %{negation} använt funktionen "importera från URL", så kommer det att + finnas två kopior av samma verk på AO3. + subject: "[%{app_name}] Uppladdade verk" + update_redirect: + contact_open_doors: kontakta Öppna dörrar + html: Om du vill att Öppna dörrar uppdaterar omdirigeringen till ditt redan + existerande verk, vänligen radera kopian och %{contact_open_doors_link} + med ditt användarnamn på AO3, ditt användarnamn på det importerade arkivet, + samt titel och länk till verket du vill att omdirigeringen ska leda till. + (Om du har flera verk du skulle vilja ändra omdirigeringen på, så kan du + skriva alla i samma mail.) + text: Om du vill att Öppna dörrar uppdaterar omdirigeringen till ditt redan + existerande verk, vänligen radera kopian och kontakta Öppna dörrar på %{open_doors_url} + med ditt användarnamn på AO3, ditt användarnamn på det importerade arkivet, + samt titel och länk till verket du vill att omdirigeringen ska leda till. + (Om du har flera verk du skulle vilja ändra omdirigeringen på, kan du skriva + alla i samma mail.) + works_by: 'Dessa verk skapades under e-postadressen: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Alla uppdrag har nu skickats ut. + subject: Uppdragen utskickade + html: + received_message: 'Du har fått ett meddelande om din samling %{collection_link}:' + text: + received_message: 'Du har fått ett meddelande om din samling "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: När du är medskapare till ett verk kan du bli tillagd på nya kapitel + oavsett vilka medskaparinställningar du har. Du kommer även att bli tillagd + som medskapare av eventuella serier som verket läggs till i. + html: + creation: "%{creation_link} av %{pseud_links}" + edit_chapter: redigera kapitlet + edit_series: redigera serien + remove_chapter: Om du blivit felaktigt tillagd eller om du inte vill vara + listad som skapare till verket kan du %{edit_chapter_link} för att ta bort + dig själv. + remove_series: Om du har blivit felaktigt tillagd eller inte vill vara listad + som skapare av verket, kan du %{edit_series_link} för att ta bort dig själv + som skapare. + intro_chapter: 'Användaren %{adding_user} har lagt till din pseudonym %{pseud} + som medskapare till följande kapitel:' + intro_series: 'Användaren %{adding_user} har angett din pseudonym %{pseud} som + medskapare av denna serie:' + subject: "[%{app_name}] Avisering: Du är tillagd som medskapare" + text: + creation: "%{title} (%{url}) av %{pseuds}" + remove_chapter: 'Om du blivit felaktigt tillagd eller om du inte vill vara + listad som skapare till verket kan du redigera kapitlet för att ta bort + dig själv: %{url}' + remove_series: 'Om du blivit felaktigt tillagd eller om du inte vill vara + listad som skapare till verket kan du redigera serien för att ta bort dig + själv: %{url}' + creatorship_notification_archivist: + explanation: Eftersom hen agerar i sin roll som officiell arkivarie för Open + Doors (Öppna dörrar) så får hen lägga till dig utan att be om lov, även om + du har stängt av medskapande. + html: + creation: "%{creation_link} av %{pseud_links}" + edit_chapter: redigera kapitlet + edit_series: redigera serien + edit_work: redigera verket + remove_chapter: Om du blivit tillagd av misstag eller inte vill vara listad + som skapare kan du %{edit_chapter_link} för att ta bort dig själv som skapare. + remove_series: Om du blivit tillagd av misstag eller inte vill vara listad + som skapare kan du %{edit_series_link} för att ta bort dig själv som skapare. + remove_work: Om du blivit tillagd av misstag eller inte vill vara listad som + skapare kan du %{edit_work_link} för att ta bort dig själv som skapare. + intro_chapter: 'Användaren %{archivist} har lagt till din pseudonym %{pseud} + som medskapare till följande kapitel:' + intro_series: 'Användaren %{archivist} har lagt till din pseudonym %{pseud} + som medskapare till följande serie:' + intro_work: 'Användaren %{archivist} har lagt till din pseudonym %{pseud} som + medskapare till följande verk:' + subject: "[%{app_name}] En arkivarie har lagt till dig som medskapare" + text: + creation: "%{title} (%{url}) av %{pseuds}" + remove_chapter: 'Om du blivit tillagd av misstag eller inte vill vara listad + som skapare kan du redigera kapitlet för att ta bort dig själv som skapare: + %{url}' + remove_series: 'Om du blivit tillagd av misstag eller inte vill vara listad + som skapare kan du redigera serien för att ta bort dig själv som skapare: + %{url}' + remove_work: 'Om du blivit tillagd av misstag eller inte vill vara listad + som skapare kan du redigera verket för att ta bort dig själv som skapare: + %{url}' + creatorship_request: + html: + creation: "%{creation_link} av %{pseud_links}" + instructions: Du kan acceptera eller avslå förfrågan på din sida för %{page_name}. + page_name: Co-Creator Requests (Medskaparförfrågan) + intro_chapter: 'Användaren %{inviting_user} har bjudit in din pseudonym %{pseud} + att listas som medskapare på följande kapitel:' + intro_series: 'Användaren %{inviting_user} har bjudit in din pseudonym %{pseud} + att listas som medskapare på följande serier:' + intro_work: 'Användaren %{inviting_user} har bjudit in din pseudonym %{pseud} + att listas som medskapare på följande verk:' + subject: "[%{app_name}] Medskaparförfrågan" + text: + creation: "%{title} (%{url}) av %{pseuds}" + instructions: 'Du kan acceptera eller avslå förfrågan på din sida för Co-Creator + Requests (Medskaparförfrågan): %{url}' + delete_work_notification: + attachment: Bifogat finns en kopia av ditt verk för din kännedom. + deleted_other: + html: Ditt verk "%{title}" togs bort på begäran av %{pseud}. + text: Ditt verk "%{title}" togs bort på begäran av %{pseud}. + deleted_yourself: + html: Ditt verk %{title} togs bort på din begäran. + text: Ditt verk "%{title}" togs bort på din begäran. + questions: + html: Om du har frågor, vänligen %{support}. + text: Om du har frågor, vänligen %{support} (%{url}). + subject: "[%{app_name}] Ditt verk har tagits bort" + support: kontakta Support + invitation_to_claim: + access: + text: Beroende på arkivtyp kan dina verk ha blivit tillgängliga endast för + registrerade användare (för att exkludera dem från googlesökningar) vid + importen. Om så är fallet kommer verken endast vara tillgängliga för inloggade + användare om du inte väljer att göra dem synliga för alla. För hjälp med + att låsa upp, anonymisera eller radera dina verk, vänligen kontakta AO3 + support. + claim_or_remove: + html: Gör anspråk på eller ta bort dina verk här. + text: 'Gör anspråk på eller ta bort dina verk här: %{claim_url}' + email_tips: Om du kontaktar oss, vänligen vitlista mailadresser från @transformativeworks.org + och kontrollera om vårt svar finns i din skräppost. + html: + ao3_news: AO3 nyheter + contact_open_doors: kontakta Öppna dörrar + contact_support: kontakta AO3 support + faq_page: Vanliga frågor och svar + tutorial_page: handledningssidan + introduction: + text: Du har fått det här mailet för att ett arkiv nyligen har blivit importerat + av Öppna dörrar (%{open_doors_link}) till %{app_name} (%{app_short_name} + - %{app_url}), och vi tror att följande verk tillhör dig. Vi vill ge dig + möjlighet att göra anspråk på (eller radera/anonymisera) dessa verk. Och + om du inte redan har ett konto med en annan mailadress vill vi välkomna + dig ombord! + mistake: + text: Om det har skett ett misstag och det här inte är dina verk, snälla radera + dem inte! Vänligen kontakta (%{open_doors_link}) så löser vi det. + more_info: + text: Du kan läsa tillkännagivanden rörande arkivflyttar på AO3 nyheter (%{news_link}), + och hitta ytterligare information på Öppna dörrars sida med vanliga frågor + och svar %{open_doors_faq_link} eller på handledningssidan %{open_doors_tutorial_link}. + Om du har frågor som inte besvarats i detta mail eller länkarna ovan, vänligen + kontakta Support via %{support_link}. + other_works: + text: Om du hade andra verk i det importerade arkivet under en mailadress + du inte längre har tillgång till, vänligen kontakta Öppna dörrar med information + som kan hjälpa till att verifiera din identitet. + questions: + text: För andra frågor, vänligen kontakta AO3 support via %{support_link}. + redirects: För att bevara rekommendationslistor och bokmärken kan det importerade + arkivets webbadresser under en begränsad tid omdirigeras till en importerad + kopia av dessa verk (se inlägget med tillkännagivelser om ditt arkiv för att + vara på den säkra sidan). Om du redan har laddat upp en kopia av dessa verk + och INTE använde funktionen för import av URL kommer det att finnas två kopior + av samma verk i arkivet. + subject: "[%{app_name}] Inbjudan att göra anspråk på verk" + unwanted: + text: Om dessa verk tillhör dig, men du inte vill ha kvar dem kan du anonymisera + dem (så att de finns kvar på AO3 men utan ditt namn) eller radera dem (så + att de tas bort helt från AO3). Du behöver inte lägga till dessa verk till + något konto för att kunna anonymisera eller radera dem -- du kan göra det + direkt från anspråkslänken ovan. (För hjälp, vänligen kontakta oss på Support + via %{support_link}.) + update_redirect: + text: Om du vill att Öppna dörrar ska uppdatera länken så att den riktas mot + ett av dina verk som redan finns, vänligen radera den importerade kopian + och kontakta Öppna dörrar %{open_doors_link} med namnet på ditt AO3-konto, + ditt namn på det importerade arkivet, samt titel och URL på verket du vill + omdirigera länken till. (Om du har många verk du vill rikta om kan du skriva + dessa i samma mail.) + uploaded_list: 'De uppladdade verken inkluderar:' + invite_increase_notification: + html: + body: + one: Vi vill bara berätta för dig att du har %{count} ny inbjudan som kan + användas för att skapa ett nytt konto på AO3. Du kan bjuda in en vän via + %{invitation_page_link}. + other: Vi vill bara berätta för dig att du har %{count} nya inbjudningar + som kan användas för att skapa nya konton på AO3. Du kan bjuda in en vän + via %{invitation_page_link}. + invitation_page_link_text: Invitations (din sida för inbjudningar) + subject: "[%{app_name}] Nya inbjudningar" + text: + body: + one: Vi vill bara berätta för dig att du har %{count} ny inbjudan som kan + användas för att skapa ett nytt konto på AO3. Du kan bjuda in en vän via + Invitations (din sida för inbjudningar)(%{invitation_page_url}). + other: Vi vill bara berätta för dig att du har %{count} nya inbjudningar + som kan användas för att skapa nya konton på AO3. Du kan bjuda in en vän + via Invitations (din sida för inbjudningar)(%{invitation_page_url}). + invite_request_declined: + main: + one: Vi måste tyvärr informera dig om att din förfrågan om en ny inbjudningskod + inte kan uppfyllas just nu. + other: Vi måste tyvärr informera dig om att din förfrågan om %{count} nya + inbjudningskoder inte kan uppfyllas just nu. + reason: 'Din förfrågan var:' + subject: "[%{app_name}] Ansökan om ytterligare inbjudningskod nekad" + recipient_notification: + html: + collection: Ett verk som är tillägnat dig har publicerats i samlingen %{collection_link} + på AO3! + no_collection: Ett verk som är tillägnat dig har blivit publicerat på AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Ett verk är tillägnat dig + i %{collection_title}" + no_collection: "[%{app_name}] Ett verk tillägnat dig" + text: + collection: Ett verk som är tillägnat dig har publicerats i samlingen "%{collection_title}" + (%{collection_url}) på AO3! + signup_notification: + activate: + html: Var vänlig %{activate_account_link}. + text: 'Var vänlig följ denna länk för att aktivera ditt konto: %{activate_account_url}' + activate_your_account: Följ på denna länk för att aktivera ditt konto + admin_posts: AO3 Nyheter + bye: Vi hoppas att du trivs med att använda Arkivet. + contact_support: kontakta Support + faq: Vanliga frågor + features: + html: När ditt konto väl är färdigställt kan du lägga upp dina verk, ordna + mail-prenumerationer så att du vet när dina favoritskapare eller favoritverk + uppdateras, göra egna inställningar för hur sajten ska se ut och fungera + för dig, hålla koll på vilka verk du har gått in på eller läst på Arkivet + via din historik, och mycket mer. + text: När ditt konto väl är färdigställt kan du lägga upp dina verk, ordna + mail-prenumerationer så att du vet när dina favoritskapare eller favoritverk + uppdateras, göra egna inställningar för hur sajten ska se ut och fungera + för dig, hålla koll på vilka verk du har gått in på eller läst på Arkivet + via din historik, och mycket mer. + information: + html: Det finns massor av information och råd om hur du använder Arkivet i + våra %{faq_link}. Du hittar de senaste nyheterna om sajtens utveckling i + våra %{admin_posts_link}. Om du behöver mer hjälp, stöter på en bugg, eller + har frågor eller kommentarer, %{contact_support_link}, som alltid är glada + att hjälpa till. + text: 'Det finns massor av information och råd om hur du använder Arkivet + i våra Vanliga frågor här: %{faq_url}. Du hittar de senaste nyheterna om + sajtens utveckling på AO3 Nyheter här: %{admin_posts_url}. Om du behöver + mer hjälp, stöter på en bugg, eller har frågor eller kommentarer, var vänlig + kontakta vårt Support-team, som alltid är glada att hjälpa till: %{contact_support_url}.' + welcome: Välkommen till AO3, %{login}! diff --git a/config/locales/phrase-exports/th.yml b/config/locales/phrase-exports/th.yml new file mode 100755 index 0000000..40bbbff --- /dev/null +++ b/config/locales/phrase-exports/th.yml @@ -0,0 +1,459 @@ +--- +th: + activerecord: + attributes: + archive_warning: + name_with_colon: + other: 'คำเตือน:' + category: + name_with_colon: + other: 'ประเภท:' + character: + name_with_colon: + other: 'ตัวละคร:' + fandom: + name_with_colon: + other: 'แฟนดอม:' + freeform: + name_with_colon: + other: 'แท็กเพิ่มเติม:' + rating: + name_with_colon: 'เรตติ้ง:' + relationship: + name_with_colon: + other: 'ความสัมพันธ์:' + work: + chapter_total_display: บท + summary: คำโปรย + models: + archive_warning: + other: คำเตือน + category: + other: ประเภท + chapter: + other: บท + character: + other: ตัวละคร + fandom: + other: แฟนดอม + freeform: + other: แท็กเพิ่มเติม + rating: + other: เรตติ้ง + relationship: + other: ความสัมพันธ์ + series: + other: ซีรีย์ + kudo_mailer: + batch_kudo_notification: + guest: + other: "%{count} ผู้เข้าชม" + left_kudos: + html: + other: "%{givers_list} ได้มอบคำชมเชยบน %{commentable_link}." + text: + other: "%{givers_list} ได้มอบคำชมเชยบน %{commentable_title} (%{commentable_url})." + single_guest: + giver: ผู้เข้าชมคนหนึ่ง + html: "%{giver} ได้มอบคำชมเชยบน %{commentable_link}." + text: ผู้เข้าชมคนหนึ่งได้มอบคำชมเชยบน %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] คุณได้รับคำชมเชย!" + mailer: + general: + closing: + formal: ด้วยความเคารพ + informal: ด้วยความนับถือ + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: ตอนที่ %{position} ของเรื่อง %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + other: "%{count} คำ" + footer: + general: + about: + html: AO3 คือคลังข้อมูลที่ดำเนินการโดยแฟนๆ และสนับสนุนแฟนๆ ซึ่งขึ้นอยู่กับ + %{donate_link} + text: 'AO3 คือคลังข้อมูลที่ดำเนินการโดยแฟนๆ และสนับสนุนแฟนๆ ซึ่งขึ้นอยู่กับการบริจาคของคุณ: + %{donate_url}' + html: + donate_link_text: การบริจาคของคุณ + support_link_text: ติดต่อฝ่ายช่วยเหลือ + unwanted_email: + html: หากคุณได้รับข้อความนี้โดยความผิดพลาด กรุณาติดต่อ %{support_link} + text: หากคุณได้รับข้อความนี้โดยความผิดพลาด กรุณาติดต่อฝ่ายช่วยเหลือที่ + %{support_url} + sent_at: ส่งเมื่อ %{sent_at} + greeting: + formal_html: เรียน %{name}, + informal: + addressed_html: สวัสดี %{name}! + unaddressed: สวัสดี! + introductory: ขอทักทายจาก Archive of Our Own – AO3 (คลังเก็บข้อมูลของเราเอง)! + metadata_label_indicator: ":" + signature: + abuse_team: ทีมนโยบายป้องกันการละเมิด + app_short_name: AO3 + open_doors: ทีม The Open Doors (โอเพนดอร์ส) + parent_org: Organization for Transformative Works – OTW (องค์กรเพื่อผลงานทรานสฟอร์เมทีฟ) + support: ทีมช่วยเหลือ AO3 + users: + mailer: + reset_password_instructions: + expiration: หากคุณไม่กดเข้าลิงก์นี้เพื่อทำการเปลี่ยนรหัสผ่านภายในหนี่งสัปดาห์ + ลิงก์นี้จะหมดอายุการใช้งานและคุณจะต้องส่งคำขอเปลี่ยนแปลงรหัสผ่านใหม่อีกครั้ง + intro: 'มีผู้ใช้งานส่งคำร้องขอเปลี่ยนรหัสผ่านสำหรับบัญชีของคุณ คุณสามารถเปลี่ยนแปลงรหัสผ่านของคุณโดยการกดลิงก์ข้างใต้นี้และใส่รหัสผ่านใหม่:' + link_title: เปลี่ยนรหัสผ่านของฉัน + subject: "[%{app_name}] เปลี่ยนรหัสผ่านของคุณ" + unrequested: หากคุณไม่ได้ส่งคำร้องขอเปลี่ยนแปลงรหัสผ่านนี้ คุณสามารถปล่อยผ่านอีเมลฉบับนี้และรหัสผ่านเดิมของคุณจะสามารถใช้งานได้ตามปกติ + user_mailer: + admin_deleted_work_notification: + bye: สิ่งที่แนบมานี้คือสำเนาผลงานของคุณเพื่อการอ้างอิง + contact_abuse: โปรดติดต่อฝ่ายนโยบายป้องกันการละเมิด + deleted: + html: "%{title} ผลงานของคุณถูกลบจาก AO3 โดยแอดมินของเว็บไซต์" + text: ผลงานของคุณ "%{title}" ถูกลบจาก AO3 โดยแอดมินเว็บไซต์ + html: + tos_violation: หากผลงานของคุณมีความเป็นไปได้ที่จะละเมิดกฎข้อตกลงของ AO3 %{contact_abuse_link} + import_project: + html: หากผลงานของคุณคือส่วนหนึ่งของโปรเจ็กต์สำคัญที่ดูแลโดย Open Doors (โอเพนดอร์ส) + ของเรา โปรดเข้าไปที่ %{opendoors_link} สำหรับข้อสงสัยเพิ่มเติม + text: หากผลงานของคุณคือส่วนหนึ่งของโปรเจ็กต์สำคัญที่ดูแลโดย Open Doors (โอเพนดอร์ส) + ของเรา โปรดติดต่อโอเพนดอร์ส (%{opendoors_link})สำหรับข้อสงสัยเพิ่มเติม + opendoors: ติดต่อโอเพนดอร์ส + subject: "[%{app_name}] ผลงานของคุณถูกลบโดยแอดมิน" + text: + tos_violation: หากผลงานของคุณมีความเป็นไปได้ที่จะละเมิดกฎข้อตกลงของ AO3 โปรดติดต่อฝ่ายนโยบายป้องกันการละเมิด + (%{contact_abuse_url}) + admin_hidden_work_notification: + access: ขณะที่ผลงานของคุณถูกซ่อน คุณยังสามารถเข้าถึงมันได้ผ่านลิงค์ด้านบน แต่มันจะไม่อยู่ในหน้าเพจผลงานของคุณ + และผู้ใช้ AO3 คนอื่นจะไม่สามารถเข้าถึงมันได้ + check_email: โปรดตรวจสอบอีเมลของคุณรวมทั้งโฟลเดอร์สแปม ทีมนโยบายและการละเมิดอาจติดต่อคุณเพื่ออธิบายว่าเหตุใดผลงานคุณจึงถูกซ่อนไปแล้ว + contact_abuse: ติดต่อนโยบายและการละเมิด + html: + help: หากไม่มั่นใจว่าเหตุใดผลงานคุณจึงถูกซ่อนและยังไม่ได้รับการติดต่อในเรื่องนี้ + โปรดเข้าไปที่ %{contact_abuse_link} โดยตรง + hidden: ผลงานของคุณเรื่อง %{title} ถูกซ่อนไว้โดยทีมนโยบายและการละเมิดและคนทั่วไปไม่สามารถเข้าถึงมันได้ + tos_violation: หากผลงานคุณถูกซ่อนเนื่องจากการละเมิด %{tos_link} ของ AO3 คุณต้องแก้ไขการละเมิดนั้น + หากไม่ทำให้ผลงานเป็นไปตามเงื่อนไขการให้บริการ อาจทำให้ผลงานคุณถูกลบจาก AO3 + ได้ + subject: "[%{app_name}] ผลงานของคุณถูกซ่อนไว้โดยทีมนโยบายและการละเมิด" + text: + help: 'หากไม่มั่นใจว่าเหตุใดผลงานคุณจึงถูกซ่อนและยังไม่ได้รับการติดต่อในเรื่องนี้ + โปรดติดต่อนโยบายและการละเมิดโดยตรง: %{contact_abuse_url}' + hidden: ผลงานของคุณเรื่อง "%{title}" (%{work_url}) ถูกซ่อนไว้โดยทีมนโยบายและการละเมิดและคนทั่วไปไม่สามารถเข้าถึงมันได้ + tos_violation: หากผลงานคุณถูกซ่อนเนื่องจากการละเมิดเงื่อนไขการให้บริการของ + AO3 (%{tos_url}) คุณต้องแก้ไขการละเมิดนั้น หากไม่ทำให้ผลงานเป็นไปตามเงื่อนไขการให้บริการ + อาจทำให้ผลงานคุณถูกลบจาก AO3 ได้ + tos: เงื่อนไขการให้บริการ + anonymous_or_unrevealed_notification: + anonymous_info: ผลงานนิรนามจะรวมอยู่ในรายชื่อแท็กแต่ไม่ปรากฎบนหน้าเพจผลงานของคุณ + ชื่อผู้ใช้ของคุณบนผลงานจะถูกแทนที่ด้วย "Anonymous" (นิรนาม) + anonymous_unrevealed_info: ผู้ดูแลคอลเล็กชันอาจเปิดเผยผลงานของคุณในภายหลังแต่คงสถานะนิรนามไว้ + คนอื่นที่ติดตามคุณจะไม่ได้รับการแจ้งเตือนเรื่องการเปลี่ยนแปลงนี้ เมื่อผลงานถูกเปิดเผยแล้ว + ผลงานของคุณจะรวมอยู่ในรายชื่อแท็กแต่ไม่อยู่ในหน้าเพจผลงานของคุณ ชื่อผู้ใช้ของคุณบนผลงานจะถูกแทนที่ด้วย + "Anonymous" (นิรนาม) + changed_status: + anonymous: + html: ผู้ดูแลคอลเล็กชัน %{collection_link} ได้เปลี่ยนสถานะผลงาน %{work_link} + ของคุณเป็นแบบนิรนาม + text: ผู้ดูแลคอลเล็กชัน "%{collection_title}" (%{collection_url}) ได้เปลี่ยนสถานะผลงาน + "%{work_title}" (%{work_url}) ของคุณเป็นแบบนิรนาม + anonymous_unrevealed: + html: ผู้ดูแลคอลเล็กชัน %{collection_link} ได้เปลี่ยนสถานะ %{work_link} + ผลงานของคุณเป็นแบบนิรนามและไม่เปิดเผย + text: ผู้ดูแลคอลเล็กชัน "%{collection_title}" (%{collection_url}) ได้เปลี่ยนสถานะผลงาน + "%{work_title}" (%{work_url}) ของคุณเป็นแบบนิรนามและไม่เปิดเผย + unrevealed: + html: ผู้ดูแลคอลเล็กชัน %{collection_link} ได้เปลี่ยนสถานะผลงาน %{work_link} + ของคุณเป็นแบบไม่เปิดเผย + text: ผู้ดูแลคอลเล็กชัน "%{collection_title}" (%{collection_url}) ได้เปลี่ยนสถานะผลงาน + "%{work_title}" (%{work_url}) ของคุณเป็นแบบไม่เปิดเผย + collection_items_link_text: หน้าเพจ Approved Collection Items (ไอเท็มคอลเล็กชันที่ได้รับการอนุญาต) + do_not_want: + anonymous: + html: หากไม่ต้องการให้ผลงานของคุณเป็นแบบนิรนาม ไปที่ %{collection_items_link} + เพื่อลบมันออกจากคอลเล็กชันนี้ + text: 'หากไม่ต้องการให้ผลงานของคุณเป็นแบบนิรนาม ไปที่หน้าเพจ Approved Collection + Items (ไอเท็มคอลเล็กชันที่ได้รับการอนุญาต) เพื่อลบมันออกจากคอลเล็กชันนี้: + %{collection_items_url}' + anonymous_unrevealed: + html: หากไม่ต้องการให้ผลงานของคุณเป็นแบบนิรนามและไม่ถูกเปิดเผย ไปที่ %{collection_items_link} + เพื่อลบมันออกจากคอลเล็กชันนี้ + text: 'หากไม่ต้องการให้ผลงานของคุณเป็นแบบนิรนามและไม่ถูกเปิดเผย ไปที่หน้าเพจ + Approved Collection Items (ไอเท็มคอลเล็กชันที่ได้รับการอนุญาต) เพื่อลบมันออกจากคอลเล็กชันนี้: + %{collection_items_url}' + unrevealed: + html: หากไม่ต้องการให้ผลงานของคุณเป็นแบบไม่เปิดเผย ไปที่ %{collection_items_link} + เพื่อลบมันออกจากคอลเล็กชันนี้ + text: 'หากไม่ต้องการให้ผลงานของคุณเป็นแบบไม่เปิดเผย ไปที่หน้าเพจ Approved + Collection Items (ไอเท็มคอลเล็กชันที่ได้รับการอนุญาต) เพื่อลบมันออกจากคอลเล็กชันนี้: + %{collection_items_url}' + faq_link_text: คำถามที่พบบ่อยเกี่ยวกับคอลเล็กชัน + more_info: + html: อ่านข้อมูลเพิ่มเติมได้ที่ %{faq_link} + text: 'ดูเพิ่มเติมได้ที่คำถามที่พบบ่อยเกี่ยวกับคอลเล็กชัน: %{faq_url}' + subject: + anonymous: "[%{app_name}] ผลงานของคุณถูกตั้งค่าเป็นนิรนามแล้ว" + anonymous_unrevealed: "[%{app_name}] ผลงานของคุณถูกตั้งค่าเป็นแบบนิรนามและไม่เปิดเผย" + unrevealed: "[%{app_name}] ผลงานของคุณถูกตั้งค่าเป็นไม่เปิดเผย" + unrevealed_info: ผลงานที่ไม่ถูกเปิดเผยจะไม่ปรากฎในรายชื่อแท็กและบนหน้าเพจผลงานของคุณ + ผู้ที่มาตามลิงก์ผลงานจะได้รับการแจ้งเตือนว่าตอนนี้ผลงานไม่ถูกเปิดเผย และพวกเขาไม่สามารถเข้าถึงเนื้อหาได้ + archivist_added_to_collection_notification: + approved_collection_items_page: เพจ Approved Collection Items (คอลเลกชันที่ได้รับการอนุมัติ) + archivist_notice: เนื่องจากผู้ดูแลคอลเลกชันนับเป็นผู้จัดเก็บและดูแลข้อมูลของ + Open Doors (โอเพนดอร์ส) ดังนั้นพวกเขาจึงสามารถเพิ่มผลงานของคุณเข้าไปในคอลเลกชันนี้ได้ + แม้ว่าคุณจะได้ทำการปิดฟังก์ชันรับคำเชิญเข้าร่วมของคอลเลกชันก็ตาม ผู้จัดเก็บและดูแลข้อมูลจะเพิ่มผลงานของคุณเข้าไปในคอลเลกชัน + ก็ต่อเมื่อผลงานถูกโฮสต์ในคลังข้อมูลที่ถูกนำเข้ามา + removal_instructions: + html: หากคุณต้องการที่จะลบผลงานของคุณออกจากคอลเลกชันนี้ ให้ไปที่ %{approved_items_link}. + text: 'หากคุณต้องการลบผลงานของคุณออกจากคอลเลกชันนี้ โปรดไปที่หน้า Approved + Collection Items (คอลเลกชันที่อนุมัติ) ของคุณ: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] ผู้เก็บและดูแลข้อมูลของ Open Doors + (โอเพนดอร์ส) ได้เพิ่มผลงานของคุณเข้าไปในคอลเลกชัน" + work_added: + html: ผู้ดูแลของคอลเลกชัน %{collection_link} ได้เพิ่มผลงานของคุณ %{work_link} + เข้าไปในคอลเลกชัน! + text: ผู้ดูแลคอลเลกชันของ "%{collection_title}" (%{collection_url}) ได้เพิ่มงานของคุณ + "%{work_title}" (%{work_url}) เข้าไปในคอลเลกชันของพวกเขา! + challenge_assignment_notification: + any: อะไรก็ได้ + assignment: + html: คุณได้รับมอบหมายให้ทำตามคำขอจากชาเลนจ์ %{link} ที่ AO3! + description: 'คำนิยาม:' + due: 'กำหนดส่งงาน:' + html: + footer: คุณได้รับอีเมล์นี้เนื่องจากคุณได้ลงทะเบียนสำหรับชาเลนจ์ %{title} สำหรับข้อมูลเพิ่มเติมเกี่ยวกับชาเลนจ์นี้และช่องทางติดต่อมอเดอเรเตอร์ + กรุณาไปที่ %{footer_link} + footer_link: เพจประวัติของชาเลนจ์ + look_up: คุณสามารถค้นหางานนี้ได้จาก %{link} + look_up_link: เพจ Assignments (งานที่ได้รับมอบหมาย) ของคุณ + optional_tags: 'แท็กเพิ่มเติม:' + prompts: 'โจทย์เรื่อง:' + prompt_url: 'URL โจทย์เรื่อง:' + recipient: 'ผู้รับ:' + recipient_missing: 'ไม่มี: ขอความช่วยเหลือจากมอเดอเรเตอร์!' + subject: "[%{app_name}][%{collection_title}] งานของคุณ!" + text: + assignment: คุณได้รับมอบหมายให้ทำตามคำขอจาก %{collection_title} ชาเลนจ์ (%{collection_url}) + ที่ AO3! + footer: คุณได้รับอีเมล์นี้เนื่องจากคุณได้ลงทะเบียนสำหรับชาเลนจ์ %{title} (%{url}) + สำหรับข้อมูลเพิ่มเติมเกี่ยวกับชาเลนจ์นี้และช่องทางติดต่อมอเดอเรเตอร์ กรุณาไปที่ + %{profile_url} + look_up: คุณสามารถค้นหางานนี้ได้จากเพจ Assignments (งานที่ได้รับมอบหมาย) ของคุณที่ + %{link} + change_email: + changed: + html: "%{login}, อีเมล์ที่เกี่ยวข้องกับบัญชีของคุณถูกเปลี่ยนเป็น %{email}" + text: "%{login}, อีเมล์ที่เกี่ยวข้องกับบัญชีของคุณถูกเปลี่ยนเป็น %{email}" + subject: "[%{app_name}] อีเมล์ถูกเปลี่ยนแล้ว" + claim_notification: + access: + contact_support: ติดต่อฝ่ายบริการช่วยเหลือ + html: ผลงานของคุณอาจถูกนำเข้ามาให้เฉพาะผู้ใช้ที่ลงทะเบียนแล้วอ่านได้เท่านั้น + ขึ้นอยู่กับการตั้งค่าบนไฟล์ต้นฉบับ (เพื่อป้องกันไม่ให้ถูกค้นหาจาก Google + ได้) ในกรณีนี้ ผู้ใช้งานที่เข้าสู่ระบบเท่านั้นที่จะสามารถเข้าถึงผลงานได้ + เว้นแต่คุณจะเลือกให้มองเห็นผลงานได้ทั้งหมด หากต้องการความช่วยเหลือในการปลดล็อก + ทอดทิ้งผลงาน หรือลบผลงานของคุณ โปรด %{contact_support_link} + text: ผลงานของคุณอาจถูกนำเข้ามาให้เฉพาะผู้ใช้ที่ลงทะเบียนแล้วอ่านได้เท่านั้น + ขึ้นอยู่กับการตั้งค่าบนไฟล์ต้นฉบับ (เพื่อป้องกันไม่ให้ถูกค้นหาจาก Google + ได้) ในกรณีนี้ ผู้ใช้ที่เข้าสู่ระบบเท่านั้นที่จะสามารถเข้าถึงผลงานได้ เว้นแต่คุณจะเลือกให้มองเห็นผลงานได้ทั้งหมด + หากต้องการความช่วยเหลือในการปลดล็อก ทอดทิ้งผลงาน หรือลบผลงานของคุณ โปรดติดต่อฝ่ายบริการช่วยเหลือที่ + %{support_url} + email_tips: หากคุณกำลังติดต่อเรา โปรดเพิ่มที่อยู่อีเมลจาก @transformativeworks.org + ลงในรายชื่อผู้ติดต่อที่ปลอดภัย และตรวจสอบโฟลเดอร์สแปมของคุณเพื่อค้นหาอีเมลตอบกลับของเรา + introduction: + ao3_name: Archive of Our Own – AO3 (คลังเก็บข้อมูลของเราเอง) + html: คุณได้รับอีเมลนี้เนื่องจากคุณมีผลงานที่อยู่ในคลังแฟนเวิร์กที่ถูกนำเข้ามา + %{app_link} โดย %{open_doors_name_link} เพราะอีเมลนี้เชื่อมโยงกับอีเมลที่ลงทะเบียนไว้ในคลังผลงานที่ถูกนำเข้ามา + แฟนเวิร์กที่เกี่ยวข้อง (ตามรายชื่อด้านล่างนี้) จึงถูกเพิ่มเข้าไปยังบัญชี + AO3 ของคุณโดยอัตโนมัติ + open_doors_name: Open Doors (โอเพนดอร์ส) + text: 'คุณได้รับอีเมลนี้เนื่องจากคุณมีผลงานที่อยู่ในคลังแฟนเวิร์กที่ถูกนำเข้ามาใน + Archive of Our Own – AO3 (คลังเก็บข้อมูลของเราเอง): %{app_url} โดย Open + Doors (โอเพนดอร์ส) (%{open_doors_url}) เนื่องจากอีเมลนี้เชื่อมโยงกับอีเมลที่ลงทะเบียนไว้ในคลังผลงานที่ถูกนำเข้ามา + แฟนเวิร์กที่เกี่ยวข้อง (ตามรายชื่อด้านล่างนี้) จึงถูกเพิ่มเข้าไปยังบัญชี + AO3 ของคุณโดยอัตโนมัติ' + mistake: + contact_open_doors: ติดต่อโอเพนดอร์ส + html: หากมีข้อผิดพลาดและผลงานเหล่านี้ไม่ใช่ของคุณ กรุณาอย่าลบมัน! โปรด %{contact_open_doors_link} + แล้วเราจะดำเนินการแก้ไขต่อไป + text: หากมีข้อผิดพลาดและผลงานเหล่านี้ไม่ใช่ของคุณ กรุณาอย่าลบมัน! โปรดติดต่อ + Open Doors (%{open_doors_url}) แล้วเราจะดำเนินการแก้ไขต่อไป + more_info: + ao3_news: ข่าวสาร AO3 + contact_support: ติดต่อฝ่ายบริการช่วยเหลือ + faq_page: หน้าคำถามที่พบบ่อย + html: คุณสามารถอ่านประกาศเกี่ยวกับการย้ายเอกสารสำคัญล่าสุดได้ที่ %{ao3_news_link} + และค้นหาข้อมูลเพิ่มเติมได้ทาง %{faq_page_link} หรือ %{tutorial_page_link} + ของ Open Doors สำหรับคำถามใดๆ ที่ไม่พบคำตอบในหน้าคำถามที่พบบ่อย วิธีการใช้งาน + หรือในอีเมลนี้ โปรด %{contact_support_link} + text: คุณสามารถอ่านประกาศเกี่ยวกับการย้ายเอกสารล่าสุดได้ที่ AO3 News (%{news_url}) + และค้นหาข้อมูลเพิ่มเติมได้ที่หน้าคำถามที่พบบ่อยของ Open Doors (%{open_doors_faq_url}) + หรือหน้าวิธีการใช้งาน (%{open_doors_tutorial_url}) สำหรับคำถามใดๆ ที่ไม่พบคำตอบในหน้าคำถามที่พบบ่อย + วิธีการใช้งาน หรือในอีเมลนี้ โปรดติดต่อฝ่ายบริการช่วยเหลือที่ %{support_url} + tutorial_page: หน้าวิธีการใช้งาน + other_works: + contact_open_doors: ติดต่อโอเพนดอร์ส + html: หากคุณมีผลงานอื่นในไฟล์ที่ถูกนำเข้าภายใต้ที่อยู่อีเมลที่คุณไม่สามารถเข้าถึงได้อีกต่อไป + โปรด %{contact_open_doors_link} พร้อมข้อมูลใดๆ ที่สามารถช่วยยืนยันตัวตนของคุณได้ + text: หากคุณมีผลงานอื่นในไฟล์ที่ถูกนำเข้าภายใต้ที่อยู่อีเมลที่คุณไม่สามารถเข้าถึงได้อีกต่อไป + โปรดติดต่อ Open Doors พร้อมข้อมูลใดๆ ที่สามารถช่วยยืนยันตัวตนของคุณได้ + questions: + contact_support: ติดต่อฝ่ายบริการช่วยเหลือ + html: หากมีข้อสงสัยอื่นๆ โปรด %{contact_support_link} + text: หากมีข้อสงสัยอื่นๆ โปรดติดต่อฝ่ายบริการช่วยเหลือ AO3 ที่ %{support_url} + redirects: + html: เพื่อสงวนรายการแนะนำและบุ๊คมาร์คให้อยู่บนเว็บไซต์ต่อไป ที่อยู่เว็บของไฟล์ที่ถูกนำเข้าอาจเปลี่ยนเส้นทางไปยังสำเนาที่ถูกนำเข้าของผลงานเหล่านี้ในระยะเวลาที่จำกัด + (ตรวจสอบโพสต์ประกาศเกี่ยวกับไฟล์ของคุณอีกครั้ง) หากคุณได้อัปโหลดสำเนาของงานเหล่านี้แล้ว + และคุณ%{negation}ได้ ใช้ฟีเจอร์การนำเข้าจาก URL จะมีสำเนาของผลงานเดียวกันนี้สองชุดใน + AO3 + subject: "[%{app_name}] ผลงานถูกอัปโหลดแล้ว" + update_redirect: + contact_open_doors: ติดต่อโอเพนดอร์ส + html: หากคุณต้องการให้ Open Doors อัปเดตการเปลี่ยนเส้นทางให้ชี้ไปยังผลงานที่มีอยู่แล้วของคุณ + โปรดลบสำเนาที่ถูกนำเข้า และ %{contact_open_doors_link} พร้อมชื่อบัญชี AO3 + ของคุณ ชื่อบัญชีของคุณในไฟล์ที่ถูกนำเข้า และชื่อกับ URL ของแฟนเวิร์คที่คุณต้องการเปลี่ยนเส้นทางไปหา + (หากคุณมีผลงานหลายชิ้นที่คุณต้องการเปลี่ยนเส้นทาง คุณสามารถแสดงรายการเหล่านี้ไว้ในอีเมลฉบับเดียวได้) + text: หากคุณต้องการให้ Open Doors อัปเดตการเปลี่ยนเส้นทางให้ชี้ไปยังงานที่มีอยู่แล้วของคุณ + โปรดลบสำเนาที่นำเข้า และติดต่อ Open Doors ที่ %{open_doors_url} พร้อมชื่อบัญชี + AO3 ของคุณ ชื่อบัญชีของคุณในไฟล์เก็บถาวรที่นำเข้า และ ชื่อกับ URL ของแฟนเวิร์คที่คุณต้องการให้เปลี่ยนเส้นทางไป + (หากคุณมีผลงานหลายชิ้นที่คุณต้องการเปลี่ยนเส้นทาง คุณสามารถแสดงรายการเหล่านี้ไว้ในอีเมลฉบับเดียว) + works_by: 'ผลงานเหล่านี้เขียนขึ้นภายใต้อีเมล: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: ผลงานที่ได้รับมอบหมายทั้งหมดถูกส่งออกไปแล้ว + subject: ผลงานที่ได้รับมอบหมายถูกส่งออกไปแล้ว + html: + received_message: 'คุณได้รับข้อความเกี่ยวกับคอลเลกชันของคุณ %{collection_link}:' + text: + received_message: 'คุณได้รับข้อความเกี่ยวกับคอลเลกชันของคุณ "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: เมื่อคุณได้รับมอบหมายให้เป็นผู้ร่วมสร้างผลงาน คุณจะถูกเพิ่มเข้าบทถัดๆ + ไปของผลงานนั้นได้ ไม่ว่าคุณจะตั้งค่าผู้ร่วมสร้างผลงานไว้แบบไหนก็ตาม และถ้าผลงานนั้นถูกเพิ่มเข้าไปในซีรีย์ใดๆ + คุณก็จะถูกเพิ่มไปยังซีรีย์นั้นเช่นกัน + html: + creation: "%{creation_link} โดย %{pseud_links}" + edit_chapter: แก้ไขบท + edit_series: แก้ไขซีรีย์ + remove_chapter: หากมีความผิดพลาดเกิดขึ้นและคุณไม่ต้องการถูกมอบหมายให้เป็นผู้สร้างผลงานแล้ว + คุณสามารถ %{edit_chapter_link} เพื่อถอนตัวออกจากการเป็นผู้สร้างผลงานได้ + remove_series: หากมีความผิดพลาดเกิดขึ้นและคุณไม่ต้องการถูกมอบหมายให้เป็นผู้สร้างผลงานแล้ว + คุณสามารถ %{edit_series_link} เพื่อถอนตัวออกจากการเป็นผู้สร้างผลงานได้ + intro_chapter: 'ผู้ใช้ %{adding_user} ได้มอบหมายให้นามแฝง %{pseud} ของคุณเป็นผู้ร่วมสร้างผลงานของบทต่อไปนี้:' + intro_series: 'ผู้ใช้ %{adding_user} ได้มอบหมายให้นามแฝง %{pseud} ของคุณให้เป็นผู้ร่วมสร้างผลงานของซีรีย์ต่อไปนี้:' + subject: "[%{app_name}] ข้อความแจ้งเตือนผู้ร่วมสร้างผลงาน" + text: + creation: "%{title} (%{url}) โดย %{pseuds}" + remove_chapter: 'หากมีความผิดพลาดเกิดขึ้นและคุณไม่ต้องการถูกมอบหมายให้เป็นผู้สร้างผลงานแล้ว + คุณสามารถแก้ไขบทเพื่อถอนตัวออกจากการเป็นผู้สร้างผลงานได้: %{url}' + remove_series: 'หากมีความผิดพลาดเกิดขึ้นและคุณไม่ต้องการถูกมอบหมายให้เป็นผู้สร้างผลงานแล้ว + คุณสามารถแก้ไขซีรีย์เพื่อถอนตัวออกจากการเป็นผู้สร้างผลงานได้: %{url}' + creatorship_notification_archivist: + explanation: เพราะพวกเขาอยู่ในฐานะผู้จัดเก็บเอกสารของ Open Doors (โอเพ่นดอร์) + พวกเขาจึงได้รับอนุญาตให้เพิ่มคุณเป็นผู้ร่วมสร้างผลงานได้โดยไม่จำเป็นต้องส่งคำขอ + แม้ว่าคุณจะปิดตัวเลือกสำหรับการสร้างผลงานร่วมไว้ก็ตาม + html: + creation: "%{creation_link} โดย %{pseud_links}" + edit_chapter: แก้ไขตอน + edit_series: แก้ไขซีรีส์ + edit_work: แก้ไขผลงาน + remove_chapter: หากคุณถูกเพิ่มเข้ามาอย่างไม่ได้ตั้งใจหรือไม่ต้องการลงรายชื่อ + คุณสามารถ %{edit_chapter_link} เพื่อลบชื่อคุณออกจากการเป็นผู้สร้างผลงาน + remove_series: หากคุณถูกเพิ่มเข้ามาอย่างไม่ได้ตั้งใจหรือไม่ต้องการลงรายชื่อ + คุณสามารถ %{edit_series_link} เพื่อลบชื่อคุณออกจากการเป็นผู้สร้างผลงาน + remove_work: หากคุณถูกเพิ่มเข้ามาอย่างไม่ได้ตั้งใจหรือไม่ต้องการลงรายชื่อ + คุณสามารถ %{edit_work_link} เพื่อลบชื่อคุณออกจากการเป็นผู้สร้างผลงาน + intro_chapter: 'ผู้ใช้งาน %{archivist} ได้เพิ่มนามแฝง %{pseud} ของคุณเป็นผู้ร่วมสร้างผลงานตอนต่อไปนี้:' + intro_series: 'ผู้ใช้งาน %{archivist} ได้เพิ่มนามแฝง %{pseud} ของคุณเป็นผู้ร่วมสร้างผลงานซีรีส์ต่อไปนี้:' + intro_work: 'ผู้ใช้งาน %{archivist} ได้เพิ่มนามแฝง %{pseud} ของคุณเป็นผู้ร่วมสร้างผลงานดังต่อไปนี้:' + subject: "[%{app_name}] การแจ้งเตือนจากผู้รวบรวมผลงานของผู้ร่วมสร้างผลงาน" + text: + creation: "%{title} (%{url}) โดย %{pseuds}" + remove_chapter: 'หากคุณถูกเพิ่มเข้ามาอย่างไม่ได้ตั้งใจหรือไม่ต้องการลงรายชื่อ + คุณสามารถแก้ไขตอนเพื่อลบชื่อคุณออกจากการเป็นผู้สร้างได้: %{url}' + remove_series: 'หากคุณถูกเพิ่มเข้ามาอย่างไม่ได้ตั้งใจหรือไม่ต้องการลงรายชื่อ + คุณสามารถแก้ไขซีรีส์เพื่อลบชื่อคุณออกจากการเป็นผู้สร้างได้: %{url}' + remove_work: 'หากคุณถูกเพิ่มเข้ามาอย่างไม่ได้ตั้งใจหรือไม่ต้องการลงรายชื่อ + คุณสามารถแก้ไขผลงานเพื่อลบชื่อคุณออกจากการเป็นผู้สร้างได้: %{url}' + creatorship_request: + html: + creation: "%{creation_link} โดย %{pseud_links}" + instructions: คุณสามารถยอมรับหรือปฏิเสธคำขอนี้ได้บนเพจ %{page_name} ของคุณ + page_name: Co-Creator Requests (คำขอเป็นผู้ร่วมสร้างผลงาน) + intro_chapter: 'ผู้ใช้งาน %{inviting_user} ได้ส่งคำเชิญให้นามแฝง %{pseud} ของคุณเป็นผู้ร่วมสร้างผลงานตอนต่อไปนี้:' + intro_series: 'ผู้ใช้งาน %{inviting_user} ได้ส่งคำเชิญให้นามแฝง %{pseud} ของคุณเป็นผู้ร่วมสร้างซีรีส์ต่อไปนี้:' + intro_work: 'ผู้ใช้งาน %{inviting_user} ได้ส่งคำเชิญให้นามแฝง %{pseud} ของคุณเป็นผู้ร่วมสร้างผลงานดังต่อไปนี้:' + subject: "[%{app_name}] คำขอเป็นผู้ร่วมสร้างผลงาน" + text: + creation: "%{title} (%{url}) โดย %{pseuds}" + instructions: 'คุณสามารถยอมรับหรือปฏิเสธคำขอนี้ได้บนเพจ Co-Creator Requests + (คำขอเป็นผู้ร่วมสร้างผลงาน) ของคุณ: %{url}' + delete_work_notification: + attachment: สิ่งที่แนบมาด้วยคือสำเนาผลงานของคุณสำหรับอ้างอิง + deleted_other: + html: ผลงาน %{title} ของคุณถูกลบตามคำขอของ %{pseud} + text: ผลงาน "%{title}" ของคุณถูกลบตามคำขอของ %{pseud} + deleted_yourself: + html: ผลงาน %{title} ของคุณถูกลบตามที่คุณขอแล้ว + text: ผลงาน "%{title}" ของคุณถูกลบตามที่คุณขอแล้ว + questions: + html: หากมีข้อสงสัยใดๆ กรุณา %{support} + text: หากมีข้อสงสัยใดๆ กรุณาติดต่อ %{support} (%{url}) + subject: "[%{app_name}] ผลงานของคุณถูกลบแล้ว" + support: ติดต่อฝ่ายบริการช่วยเหลือ + invite_increase_notification: + html: + body: + other: เราขอแจ้งให้ทราบว่าคุณมี %{count} คำเชิญใหม่ซึ่งสามารถใช้สร้างบัญชีใหม่ใน + AO3 ได้ คุณสามารถเชิญเพื่อนหนึ่งคนได้ที่ %{invitation_page_link} + invitation_page_link_text: หน้าเพจ Invitations (คำเชิญ) ของคุณ + subject: "[%{app_name}] คำเชิญใหม่" + text: + body: + other: เราขอแจ้งให้ทราบว่าคุณมี %{count} คำเชิญใหม่ซึ่งสามารถใช้สร้างบัญชีใหม่ใน + AO3 ได้ คุณสามารถเชิญเพื่อนหนึ่งคนได้ที่เพจ Invitations (คำเชิญ) (%{invitation_page_url}) + invite_request_declined: + main: + other: ขออภัยที่ไม่สามารถตอบรับคำขอของคุณสำหรับ %{count} คำเชิญใหม่ได้ในขณะนี้ + reason: 'คำขอของคุณ:' + subject: "[%{app_name}] คำขอคำเชิญเพิ่มเติมของคุณถูกปฏิเสธ" + recipient_notification: + html: + collection: ผลงานของขวัญได้ถูกโพสต์ให้คุณแล้วในคอลเล็กชัน %{collection_link} + ที่ AO3! + no_collection: ผลงานของขวัญได้ถูกโพสต์ให้คุณแล้วใน AO3! + subject: + collection: "[%{app_name}][%{collection_title}] ผลงานของขวัญสำหรับคุณจาก %{collection_title}" + no_collection: "[%{app_name}] ผลงานของขวัญสำหรับคุณ" + text: + collection: ผลงานของขวัญได้ถูกโพสต์ให้คุณแล้วในคอลเล็กชัน "%{collection_title}" + (%{collection_url}) ที่ AO3! + signup_notification: + activate: + text: 'กรุณาคลิกลิงค์นี้เพื่อเปิดใช้บัญชีของคุณ: %{activate_account_url}' + admin_posts: ข่าว AO3 + bye: ขอให้คุณมีความสุขกับการใช้ AO3 นะ + contact_support: ติดต่อฝ่ายช่วยเหลือ + faq: FAQ + features: + html: เมื่อเปิดใช้งานบัญชีได้แล้ว คุณสามารถโพสต์แฟนเวิร์คของคุณ, ตั้งค่าการติดตามผ่านอีเมลที่จะแจ้งเตือนคุณเมื่อผู้แต่งหรือผลงานมีอัปเดต, + ตั้งค่าการใช้งานหน้าตาเว็บไซต์และวิธีทำงานของมัน, ติดตามผลงานที่คุณเคยเข้าถึงใน + AO3 ผ่านประวัติส่วนตัวและอีกมากมายได้เลย + text: เมื่อเปิดใช้งานบัญชีได้แล้ว คุณสามารถโพสต์แฟนเวิร์คของคุณ, ตั้งค่าการติดตามผ่านอีเมลที่จะแจ้งเตือนคุณเมื่อผู้แต่งหรือผลงานมีอัปเดต, + ตั้งค่าการใช้งานหน้าตาเว็บไซต์และวิธีทำงานของมัน, ติดตามผลงานที่คุณเคยเข้าถึงใน + AO3 ผ่านประวัติส่วนตัวและอีกมากมายได้เลย + information: + html: มีข้อมูลและคำแนะนำในการใช้ AO3 มากมายใน %{faq_link} ของเรา อ่านข่าวล่าสุดเกี่ยวกับการพัฒนาเว็บไซต์ได้ทาง + %{admin_posts_link} ถ้าคุณต้องการความช่วยเหลือเพิ่มเติมเช่น บังเอิญเจอบั๊กหรือมีคำถามหรือมีความเห็น + กรุณา %{contact_support_link} ซึ่งยินดีช่วยเหลือตลอดเวลา + text: 'มีข้อมูลและคำแนะนำในการใช้ AO3 มากมายใน %{faq_url} อ่านข่าวล่าสุดเกี่ยวกับการพัฒนาเว็บไซต์ได้ในข่าว + AO3 ทาง %{admin_posts_url} ถ้าคุณต้องการความช่วยเหลือเพิ่มเติมเช่น บังเอิญเจอบั๊กหรือมีคำถามหรือมีความเห็น + กรุณาติดต่อทีมช่วยเหลือของเราซึ่งยินดีช่วยเหลือตลอดเวลา: %{contact_support_url}' + welcome: ยินดีต้อนรับสู่ AO3 %{login} ! diff --git a/config/locales/phrase-exports/tr.yml b/config/locales/phrase-exports/tr.yml new file mode 100755 index 0000000..2d916c9 --- /dev/null +++ b/config/locales/phrase-exports/tr.yml @@ -0,0 +1,520 @@ +--- +tr: + activerecord: + attributes: + archive_warning: + name_with_colon: + one: 'Uyarı:' + other: 'Uyarılar:' + category: + name_with_colon: + one: 'Kategori:' + other: 'Kategoriler:' + character: + name_with_colon: + one: 'Karakter:' + other: 'Karakterler:' + fandom: + name_with_colon: + one: 'Fandom:' + other: 'Fandomlar:' + freeform: + name_with_colon: + one: 'İlave Etiket:' + other: 'İlave Etiketler:' + rating: + name_with_colon: 'Kitle:' + relationship: + name_with_colon: + one: 'İlişki:' + other: 'İlişkiler:' + work: + chapter_total_display: Bölümler + summary: Özet + models: + archive_warning: + one: Uyarı + other: Uyarılar + category: + one: Kategori + other: Kategoriler + chapter: + one: Bölüm + other: Bölümler + character: + one: Karakter + other: Karakterler + fandom: + one: Fandom + other: Fandomlar + freeform: + one: İlave Etiket + other: İlave Etiketler + rating: + one: Kitle + other: Kitle + relationship: + one: İlişki + other: İlişkiler + series: + one: Dizi + other: Diziler + kudo_mailer: + batch_kudo_notification: + guest: + one: bir ziyaretçi + other: "%{count} ziyaretçi" + left_kudos: + html: + one: "%{givers_list}, %{commentable_link} eserinize kalp bıraktı." + other: "%{givers_list}, %{commentable_link} eserinize kalp bıraktı." + text: + one: "%{givers_list}, %{commentable_title} (%{commentable_url}) eserinize + kalp bıraktı." + other: "%{givers_list}, %{commentable_title} (%{commentable_url}) eserinize + kalp bıraktı." + single_guest: + giver: Bir ziyaretçi + html: "%{giver}, %{commentable_link} eserinize kalp bıraktı." + text: Bir ziyaretçi %{commentable_title} (%{commentable_url}) eserinize kalp + bıraktı. + subject: "[%{app_name}] Kalp aldınız!" + mailer: + general: + closing: + formal: En içten dileklerimizle, + informal: İyi dileklerimizle, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: "%{title} 'ın %{position} . bölümü" + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + one: "%{count} kelime" + other: "%{count} kelime" + footer: + general: + about: + html: AO3 hayranlar tarafından yönetilen ve desteklenen bir arşivdir, + varlığını sürdürmesini sağlayan şey %{donate_link}. + text: 'AO3 hayranlar tarafından yönetilen, hayranlar tarafından desteklenen + ve sizin bağışlarınızla varlığını sürdüren bir arşivdir: %{donate_url}.' + html: + donate_link_text: sizin bağışlarınızdır + support_link_text: Teknik Destek ile iletişime geçin + unwanted_email: + html: Eğer bu mesajı bir hata sonucu aldıysanız lütfen %{support_link}. + text: Eğer bu mesajı bir hata sonucu aldıysanız lütfen %{support_url} + adresinden Teknik Destek ile iletişime geçin. + sent_at: "%{sent_at} tarihinde gönderilmiştir." + greeting: + formal_html: Sayın %{name}, + informal: + addressed_html: Merhaba %{name}! + unaddressed: Merhaba! + introductory: Archive of Our Own – AO3 (Kendimize Ait Bir Arşiv)ten selamlar! + metadata_label_indicator: ":" + signature: + abuse_team: AO3 Poliçe ve Kötüye Kullanım ekibi + app_short_name: AO3 + open_doors: Open Doors (Açık Kapılar) ekibi + parent_org: Organization for Transformative Works – OTW (Transformatif Eserler + Derneği) + support: AO3 Teknik Destek ekibi + users: + mailer: + reset_password_instructions: + expiration: Şifrenizi sıfırlamak için yukarıdaki linki bir hafta içinde kullanmadığınız + takdirde linkin süresi dolacak ve yeni bir talepte bulunmanız gerekecektir. + intro: 'Hesabınız için şifre sıfırlama talebinde bulunuldu. Aşağıdaki bağlantıyı + takip edip yeni şifrenizi girerek hesabınızın şifresini değiştirebilirsiniz:' + link_title: Şifremi değiştir. + subject: "[%{app_name}] Şifrenizi sıfırlayın" + unrequested: Eğer şifre sıfırlama talebinde bulunmadıysanız bu e-postayı görmezden + gelerek önceki şifrenizi kullanmaya devam edebilirsiniz. + user_mailer: + admin_deleted_work_notification: + bye: Referans için eserinizin bir kopyası ektedir. + contact_abuse: Poliçe ve Kötüye Kullanım Komitesi ile iletişime geçin + deleted: + html: Eseriniz, %{title}, bir site yöneticisi tarafından AO3’ten silinmiştir. + text: Eseriniz "%{title}" bir site yöneticisi tarafından AO3’ten silinmiştir. + html: + tos_violation: Eğer eserinizin AO3’ün Kullanım Şartlarını ihlal etmiş olma + ihtimali var ise lütfen %{contact_abuse_link}. + import_project: + html: Eğer eseriniz, Open Doors (Açık Kapılar) ekibimiz tarafından yönetilen + bir içe aktarma projesinin parçası ise lütfen sorularınız için %{opendoors_link}. + text: Eğer eseriniz Open Doors (Açık Kapılar) ekibimiz tarafından yönetilen + bir içe aktarma projesinin parçası ise lütfen sorularınız için Açık Kapılar + (%{opendoors_link}) ile iletişime geçin. + opendoors: Açık Kapılar ile iletişime geçin + subject: "[%{app_name}] Eseriniz bir yönetici tarafından silinmiştir" + text: + tos_violation: Eğer eserinizin AO3’ün Kullanım Şartlarını ihlal etmiş olma + ihtimali var ise lütfen Poliçe ve Kötüye Kullanım Komitesi (%{contact_abuse_url}) + ile iletişime geçin. + admin_hidden_work_notification: + access: Eseriniz gizliyken de yukarıda verilen link üzerinden ona erişim sağlamanız + mümkün olacak, fakat eser çalışma sayfanızda listelenmeyecek ve AO3'ün diğer + kullanıcıları esere erişemiyor olacak. + check_email: Poliçe ve Kötüye Kullanım Komitesi eserinizin neden gizlendiğini + açıklamak için sizinle daha önce iletişime geçmiş olabilir. Bu nedenle lütfen, + spam klasörünüz de dahil olmak üzere, e-postalarınızı kontrol edin. + contact_abuse: Poliçe ve Kötüye Kullanım Komitesi’yle iletişime geçin + html: + help: Eserinizin neden gizlendiğinden emin değilseniz ve bu konuyla ilgili + herhangi başka bilgi almadıysanız, lütfen doğrudan %{contact_abuse_link}. + hidden: "%{title} adlı eseriniz Poliçe ve Kötüye Kullanım Komitesi tarafından + gizlenmiştir ve artık herkese açık değildir." + tos_violation: Eseriniz, AO3’ün %{tos_link} ihlali nedeniyle gizlendiyse, + ihlali düzeltmek için sizin aksiyon almanız gerekecektir. Eserinizin Kullanım + Şartları’na uygun hale getirilmemesi, eserinizin AO3'ten silinmesine neden + olabilir. + subject: "[%{app_name}] eseriniz Poliçe ve Kötüye Kullanım Komitesi tarafından + gizlenmiştir" + text: + help: 'Eserinizin neden gizlendiğinden emin değilseniz ve bu konuyla ilgili + başka bilgi almadıysanız, lütfen doğrudan Poliçe ve Kötüye Kullanım Komitesi’yle + iletişime geçin: %{contact_abuse_url}.' + hidden: '"%{title}" (%{work_url}) adlı eseriniz Poliçe ve Kötüye Kullanım + Komitesi tarafından gizlenmiştir ve artık herkese açık değildir.' + tos_violation: Eseriniz, AO3 Kullanım Şartları’nın (%{tos_url}) ihlali nedeniyle + gizlendiyse, ihlali düzeltmek için sizin aksiyon almanız gerekecektir. Eserinizin + Kullanım Şartları’na uygun hale getirilmemesi, eserinizin AO3'ten silinmesine + neden olabilir. + tos: Kullanım Şartları + anonymous_or_unrevealed_notification: + anonymous_info: Anonim eserler etiket listelerine dahil edilir, ancak sizin + eserler sayfanızda gösterilmez. Eserde bulunan kullanıcı adınız ise "Anonymous" + (Anonim) olarak değiştirilir. + anonymous_unrevealed_info: İlerleyen dönemlerde koleksiyon sorumluları eserinizin + durumunu gizli olmaktan çıkarıp eseri genele açabilir, ancak eserin anonim + durumunu koruyabilir. Size abone olan kişiler böylesi bir değişiklikten haberdar + edilmez. Eser genel erişime açıldığında, eseriniz etiket listelerine dahil + edilir, ancak sizin eserler sayfanızda gösterilmez. Eserde kullanıcı adınız + "Anonymous" (Anonim) ile değiştirilir. + changed_status: + anonymous: + html: "%{collection_link} koleksiyonunu sorumluları, %{work_link} eserinizin + durumunu anonim olarak değiştirdi." + text: '"%{collection_title}" (%{collection_url}) koleksiyonunun sorumluları + "%{work_title}" (%{work_url}) eserinizin durumunu anonim olarak değiştirdi.' + anonymous_unrevealed: + html: "%{collection_link}’ın koleksiyon sorumluları, %{work_link} eserinizin + durumunu anonim ve gizli olarak değiştirdi." + text: '"%{collection_title}" (%{collection_url}) koleksiyonunun sorumluları"%{work_title}" + (%{work_url}) eserinizin durumunu anonim ve gizli olarak değiştirdi.' + unrevealed: + html: "%{collection_link}’ın koleksiyon sorumluları, %{work_link} eserinizin + durumunu gizli olarak değiştirdi." + text: '"%{collection_title}" (%{collection_url}) koleksiyonunun sorumluları + "%{work_title}" (%{work_url}) eserinizin durumunu gizli olarak değiştirdi.' + collection_items_link_text: Approved Collection Items (Onaylı Koleksiyon Öğeleri) + sayfası + do_not_want: + anonymous: + html: Eserinizin anonim olmasını istemiyorsanız, eserinizi bu koleksiyondan + çıkarmak için %{collection_items_link} sayfasını ziyaret ediniz. + text: 'Eserinizin anonim olmasını istemiyorsanız, eserinizi bu koleksiyondan + çıkarmak için Approved Collection Items (Onaylı Koleksiyon Öğeleri) sayfanızı + ziyaret edebilirsiniz: %{collection_items_url}' + anonymous_unrevealed: + html: Eserinizin anonim ve gizli olmasını istemiyorsanız, eserinizi bu koleksiyondan + çıkarmak için lütfen %{collection_items_link} sayfasını ziyaret ediniz. + text: 'Eserinizin anonim ve gizli olmasını istemiyorsanız, eserinizi bu + koleksiyondan çıkarmak için Approved Collection Items (Onaylı Koleksiyon + Öğeleri) sayfanızı ziyaret edebilirsiniz: %{collection_items_url}' + unrevealed: + html: Eserinizin gizli olmasını istemiyorsanız, eserinizi bu koleksiyondan + çıkarmak için lütfen %{collection_items_link} sayfasını ziyaret ediniz. + text: 'Eserinizin gizli olmasını istemiyorsanız, eserinizi bu koleksiyondan + çıkarmak için Approved Collection Items (Onaylı Koleksiyon Öğeleri) sayfanızı + ziyaret edebilirsiniz: %{collection_items_url}' + faq_link_text: Koleksiyonlar SSS + more_info: + html: Daha fazla bilgi için, %{faq_link} sayfasına göz atabilirsiniz. + text: 'Daha fazla bilgi için, Koleksiyonlar SSS sayfasına göz atabilirsiniz: + %{faq_url}' + subject: + anonymous: "[%{app_name}] Eseriniz anonim hale getirildi" + anonymous_unrevealed: "[%{app_name}] Eseriniz anonim ve gizli hale getirildi" + unrevealed: "[%{app_name}] Eseriniz gizli hale getirildi" + unrevealed_info: Gizli eserler etiket listelerinde veya eser sayfanızda yer + almaz. Eser bağlantısını takip eden herkes, eserin şu anda gizli olduğuna + dair bir bildirimle karşılaşır ve içeriğine erişim sağlayamazlar. + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (Onaylanan Koleksiyon + Ögeleri) sayfası + archivist_notice: Siz koleksiyon davetlerini devre dışı bırakmış olsanız bile, + koleksiyon yöneticilerinin Open Doors (Açık Kapılar) arşivciliği kapsamındaki + yetkileri dahilinde eserinizi bu koleksiyona ekleme izni bulunmaktadır. Arşivciler + bir eseri yalnızca eser içe aktarılan bir arşivde barındırılıyorsa bir koleksiyona + eklemektedir. + removal_instructions: + html: Eserinizi bu koleksiyondan çıkarmak isterseniz, lütfen %{approved_items_link} + linkini ziyaret edin. + text: 'Eserinizi bu koleksiyondan çıkarmak isterseniz, lütfen Approved Collection + Items (Onaylanan Koleksiyon Ögeleri) sayfanızı ziyaret edin: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Bir Open Doors (Açık Kapılar) arşivcisi + eserinizi bir koleksiyona ekledi" + work_added: + html: "%{collection_link} koleksiyonunun yöneticileri %{work_link} eserinizi + koleksiyona ekledi!" + text: '"%{collection_title}" (%{collection_url}) koleksiyonunun yöneticileri + "%{work_title}" (%{work_url}) eserinizi koleksiyonlarına ekledi!' + challenge_assignment_notification: + any: Herhangi bir + assignment: + html: AO3'teki %{link} oyununda size aşağıdaki istek atandı! + description: 'Tanım:' + due: 'Bu görevin teslim tarihi:' + html: + footer: Bu e-postayı, %{title} oyununa kaydolduğunuz için aldınız. Bu oyun + hakkında daha fazla bilgi ve moderatörlerin iletişim bilgileri için lütfen + %{footer_link} adresini ziyaret edin. + footer_link: oyun profil sayfası + look_up: Bu görevi %{link} adresinden arayabilirsiniz. + look_up_link: Assignments (Görevler) sayfanız + optional_tags: 'İsteğe Bağlı Etiketler:' + prompts: 'Fikirler:' + prompt_url: 'Fikir URL''si:' + recipient: 'Alıcı:' + recipient_missing: 'Hiç kimse: yardım için bir moderatörle iletişime geçin!' + subject: "[%{app_name}][%{collection_title}] Göreviniz!" + text: + assignment: AO3'teki "%{collection_title}" oyununda (%{collection_url}) size + aşağıdaki istek atandı! + footer: Bu e-postayı, %{title} oyununa (%{url}) kaydolduğunuz için aldınız. + Bu oyun hakkında daha fazla bilgi ve moderatörlerin iletişim bilgileri için + lütfen %{profile_url} adresini ziyaret edin. + look_up: Bu görevi, %{link} adresindeki Assignments (Görevler) sayfanızdan + arayabilirsiniz. + change_email: + changed: + html: "%{login}, hesabınızla ilişkili e-posta adresiniz %{email} olarak değiştirilmiştir." + text: "%{login}, hesabınızla ilişkili e-posta adresiniz %{email} olarak değiştirilmiştir." + subject: "[%{app_name}] E-posta adresiniz değiştirildi" + claim_notification: + access: + contact_support: AO3 Teknik Destek Komitesi ile iletişime geçin + html: Arşive bağlı olarak eserleriniz yalnızca kayıtlı kullanıcılara açık + olacak şekilde aktarılmış olabilir (Bu Google aramalarında gözükmesini engellemek + için yapılır). Eğer durum böyleyse, siz tamamen görünür yapmadığınız takdirde + eserlerinize yalnızca giriş yapmış kullanıcılar erişebilecek. Kilidi kaldırmak, + terk etmek veya eserlerinizi silmek konusunda yardım için, lütfen %{contact_support_link}. + text: Arşive bağlı olarak eserleriniz yalnızca kayıtlı kullanıcılara açık + olacak şekilde aktarılmış olabilir (Bu Google aramalarında gözükmesini engellemek + için yapılır). Eğer durum böyleyse, siz tamamen görünür yapmadığınız takdirde + eserlerinize yalnızca giriş yapmış kullanıcılar erişebilecek. Kilidi kaldırmak, + terk etmek veya eserlerinizi silmek konusunda yardım için, lütfen %{support_url}'den + AO3 Teknik Destek Komitesi ile iletişime geçin. + email_tips: Bizimle iletişime geçiyorsanız lütfen @transformativeworks.org'daki + e-posta adreslerini güvenli kişiler listenize ekleyin ve yanıtımız için spam + klasörlerinizi kontrol edin. + introduction: + ao3_name: Archive of Our Own – AO3 (Kendimize Ait Bir Arşiv) + html: Bu e-postayı alıyorsunuz çünkü bir hayran eseri arşivinde %{open_doors_name_link} + tarafından %{app_link}'e aktarılan eserleriniz bulunmakta. Bu e-posta adresi + aktarılan arşivde kayıtlı olan bir adrese bağlı olduğundan, ilgili hayran + eserleri (aşağıda listelenmiştir) otomatik olarak AO3 hesabınıza eklenmiştir. + open_doors_name: Open Doors (Açık Kapılar) + text: 'Bu e-postayı alıyorsunuz çünkü bir hayran eseri arşivinde Open Doors + (Açık Kapılar) (%{open_doors_url}) tarafından Archive of Our Own – AO3 (Kendimize + Ait Bir Arşiv): %{app_url}''e aktarılan eserleriniz bulunmakta. Bu e-posta + adresi aktarılan arşivde kayıtlı olan bir adrese bağlı olduğundan, ilgili + hayran eserleri (aşağıda listelenmiştir) otomatik olarak AO3 hesabınıza + eklenmiştir.' + mistake: + contact_open_doors: Açık Kapılar ile iletişime geçin + html: Eğer bu bir hataysa ve bunlar sizin eserleriniz değilse, lütfen onları + silmeyin! Lütfen %{contact_open_doors_link} ve biz düzeltelim. + text: Eğer bu bir hataysa ve bunlar sizin eserleriniz değilse, lütfen onları + silmeyin! Lütfen Açık Kapılar ile iletişime geçin (%{open_doors_url}) ve + biz düzeltelim. + more_info: + ao3_news: AO3 Duyuruları + contact_support: AO3 Teknik Destek Komitesi ile iletişime geçin. + faq_page: SSS Sayfası + html: Yakın zamandaki arşiv hareketleri hakkındaki duyuruları %{ao3_news_link} + adresinden okuyabilir ve daha fazla bilgiyi Açık Kapılar'ın %{faq_page_link} + veya %{tutorial_page_link} adresinde bulabilirsiniz. SSS'lerde, eğitimlerde + ya da bu e-postada yanıtlanmayan sorularınız için, lütfen %{contact_support_link} + text: Yakın zamandaki arşiv hareketleri hakkındaki duyuruları AO3 Duyurularından + (%{news_url}) okuyabilir ve daha fazla bilgiyi Açık Kapılar'ın SSS sayfası + (%{open_doors_faq_url}) veya eğitimler sayfasından (%{open_doors_tutorial_url}) + bulabilirsiniz. SSS'lerde, eğitimlerde ya da bu e-postada yanıtlanmayan + sorularınız için, %{support_url}'den Teknik Destek Komitesi ile iletişime + geçin. + tutorial_page: eğitim sayfası + other_works: + contact_open_doors: Açık Kapılar ile iletişime geçin + html: Eğer aktarılan arşivde artık erişemediğiniz bir e-posta altında eserleriniz + varsa, lütfen kimliğinizi onaylamaya yardımcı bilgiler ile %{contact_open_doors_link}. + text: Eğer aktarılan arşivde artık erişemediğiniz bir e-posta altında eserleriniz + varsa, lütfen kimliğinizi onaylamaya yardımcı bilgilerle Açık Kapılar ile + iletişime geçin. + questions: + contact_support: AO3 Teknik Destek Komitesi ile iletişime geçin + html: Diğer sorularınız için lütfen %{contact_support_link}. + text: Diğer sorularınız için lütfen %{support_url}'den AO3 Teknik Destek Komitesi + ile iletişime geçin. + redirects: + html: Öneri listeleri ve yer işaretlerini korumak için, aktarılan arşivin + web adresi kısa bir süreliğine bu eserlerin aktarılan bir kopyasına yönlendirebilir + (emin olmak için arşivinizdeki duyuru gönderilerini kontrol ediniz). Eğer + çoktan bu eserin bir kopyasını yüklediyseniz ve URL'den aktar özelliğini + %{negation}, AO3'te aynı eserin iki kopyası olacaktır. + subject: "[%{app_name}] Yüklenen eserler" + update_redirect: + contact_open_doors: Açık Kapılar ile iletişime geçin + html: Açık Kapılar'ın yönlendirmeyi önceden var olan eserinize işaret edecek + şekilde güncellemesini istiyorsanız, lütfen aktarılan kopyayı silin ve AO3 + hesap adınız, aktarılan arşivdeki hesap adınız ve yönlendirmek istediğiniz + hayran eserinin adını ve URL'si ile %{contact_open_doors_link}. (Yönlendirmelerini + değiştirmek istediğiniz birden fazla eser varsa, bunları tek e-postada belirtebilirsiniz.) + text: Açık Kapılar'ın yönlendirmeyi önceden var olan eserinize işaret edecek + şekilde güncellemesini istiyorsanız, lütfen aktarılan kopyayı silin ve AO3 + hesap adınız, aktarılan arşivdeki hesap adınız ve yönlendirmek istediğiniz + hayran eserinin adını ve URL'si ile %{open_doors_url} linkinden Açık Kapılar + ile iletişime geçin. (Yönlendirmelerini değiştirmek istediğiniz birden fazla + eser varsa, bunları tek e-postada belirtebilirsiniz.) + works_by: 'Eserler bu e-posta altında yazılmıştır: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Bütün atamalar gönderildi. + subject: Atamalar gönderildi + html: + received_message: "%{collection_link} koleksiyonunuz hakkında bir mesaj aldınız:" + text: + received_message: '"%{collection_title}" koleksiyonunuz (%{collection_url}) + hakkında bir mesaj aldınız:' + creatorship_notification: + explanation: Bir eserin ortak yazarı olduğunuzda, ortak yazarlık ayarlarınızdan + bağımsız olarak yeni bölümlere ekleyebilirsiniz. Ayrıca çalışmanın eklendiği + herhangi bir diziye de ekleneceksiniz. + html: + creation: "%{pseud_links} tarafından %{creation_link}" + edit_chapter: bölümü düzenleyerek + edit_series: diziyi düzenleyerek + remove_chapter: Yanlışlıkla eklendiyseniz veya yazar olarak listelenmek istemiyorsanız, + %{edit_chapter_link} kendinizi yazarlıktan kaldırabilirsiniz. + remove_series: Yanlışlıkla eklendiyseniz veya yazar olarak listelenmek istemiyorsanız, + %{edit_series_link} kendinizi yazarlıktan kaldırabilirsiniz. + intro_chapter: "%{adding_user} kullanıcısı %{pseud} takma adınızı aşağıdaki + bölümde ortak yazar olarak listeledi:" + intro_series: "%{adding_user} kullanıcısı %{pseud} takma adınızı aşağıdaki dizide + ortak yazar olarak listeledi:" + subject: "[%{app_name}] Ortak yazar bildirimi" + text: + creation: "%{pseuds} tarafından %{title} (%{url})" + remove_chapter: 'Yanlışlıkla eklendiyseniz veya yazar olarak listelenmek istemiyorsanız, + kendinizi yazar olarak kaldırmak için bölümü düzenleyebilirsiniz: %{url}' + remove_series: 'Yanlışlıkla eklendiyseniz veya yazar olarak listelenmek istemiyorsanız, + kendinizi yazar olarak kaldırmak için diziyi düzenleyebilirsiniz: %{url}' + creatorship_notification_archivist: + explanation: Open Doors (Açık Kapılar) arşivcileri, onlara verilen yetki dahilinde + ortaklığı devre dışı bırakmış olsanız bile sizi talep olmadan ortak yaratıcı + olarak ekleme hakkına sahiptirler. + html: + creation: "%{pseud_links} tarafından %{creation_link}" + edit_chapter: bölümü düzenleyebilirsiniz + edit_series: seriyi düzenleyebilirsiniz + edit_work: eseri düzenleyebilirsiniz + remove_chapter: Eğer yanlışlıkla eklendiyseniz veya yaratıcı olarak listelenmek + istemiyorsanız kendinizi yaratıcılıktan çıkarmak için %{edit_chapter_link}. + remove_series: Eğer yanlışlıkla eklendiyseniz veya yaratıcı olarak listelenmek + istemiyorsanız kendinizi yaratıcılıktan çıkarmak için %{edit_series_link}. + remove_work: Eğer yanlışlıkla eklendiyseniz veya yaratıcı olarak listelenmek + istemiyorsanız kendinizi yaratıcılıktan çıkarmak için %{edit_work_link}. + intro_chapter: "%{archivist} kullanıcısı %{pseud} takma adınızı ortak yaratıcı + olarak aşağıdaki bölüme ekledi:" + intro_series: "%{archivist} kullanıcısı %{pseud} takma adınızı ortak yaratıcı + olarak aşağıdaki seriye ekledi:" + intro_work: "%{archivist} kullanıcısı %{pseud} takma adınızı ortak yaratıcı + olarak aşağıdaki esere ekledi:" + subject: "[%{app_name}] Ortak yaratıcı arşivci bildirimi" + text: + creation: "%{pseuds} tarafından %{title} (%{url})" + remove_chapter: 'Eğer yanlışlıkla eklendiyseniz veya yaratıcı olarak listelenmek + istemiyorsanız kendinizi yaratıcılıktan çıkarmak için bölümü düzenleyebilirsiniz: + %{url}' + remove_series: 'Eğer yanlışlıkla eklendiyseniz veya yaratıcı olarak listelenmek + istemiyorsanız kendinizi yaratıcılıktan çıkarmak için seriyi düzenleyebilirsiniz: + %{url}' + remove_work: 'Eğer yanlışlıkla eklendiyseniz veya yaratıcı olarak listelenmek + istemiyorsanız kendinizi yaratıcılıktan çıkarmak için eseri düzenleyebilirsiniz: + %{url}' + creatorship_request: + html: + creation: "%{pseud_links} tarafından %{creation_link}" + instructions: Bu isteği %{page_name} sayfanızdan kabul edebilir veya reddedebilirsiniz. + page_name: Co-Creator Requests (Eş-Yazar İstekleri) + intro_chapter: 'Kullanıcı %{inviting_user}, %{pseud} takma adınızı eş-yazar + olarak aşağıdaki bölüme ekleme isteğinde bulundu:' + intro_series: 'Kullanıcı %{inviting_user}, %{pseud} takma adınızı eş-yazar olarak + aşağıdaki seriye ekleme isteğinde bulundu:' + intro_work: 'Kullanıcı %{inviting_user}, %{pseud} takma adınızı eş-yazar olarak + aşağıdaki esere ekleme isteğinde bulundu:' + subject: "[%{app_name}] Eş-yazar isteği" + text: + creation: "%{pseuds} tarafından %{title} (%{url})" + instructions: 'Bu isteği Co-Creator Requests (Eş-Yazar İstekleri) sayfanızdan + kabul edebilir veya reddedebilirsiniz: %{url}' + delete_work_notification: + attachment: Ekte referansınız için eserinizin bir kopyası bulunmaktadır. + deleted_other: + html: "%{title} eseriniz %{pseud} kullanıcısının isteği üzerine silindi." + text: '"%{title}" eseriniz %{pseud} kullanıcısının isteği üzerine silinmiştir.' + deleted_yourself: + html: "%{title} eseriniz isteğiniz üzerine silindi." + text: '"%{title}" eseriniz isteğiniz üzerine silinmiştir.' + questions: + html: Sorularınız varsa, lütfen %{support}. + text: Sorularınız varsa, lütfen %{support} (%{url}). + subject: "[%{app_name}] Eseriniz silinmiştir" + support: Teknik Destek Komitesi ile iletişime geçin + invite_increase_notification: + html: + body: + one: AO3'te yeni bir hesap oluşturmak için kullanabileceğiniz %{count} yeni + davetiyeniz olduğunu size bildirmek istedik. Dilerseniz %{invitation_page_link} + üzerinden bir arkadaşınızı davet edebilirsiniz. + other: AO3'te yeni hesaplar oluşturmak için kullanabileceğiniz %{count} + yeni davetiyeniz olduğunu size bildirmek istedik. Dilerseniz %{invitation_page_link} + üzerinden bir arkadaşınızı davet edebilirsiniz. + invitation_page_link_text: Invitations (Davetiyeler) sayfanız + subject: "[%{app_name}] Yeni Davetiyeler" + text: + body: + one: AO3'te yeni bir hesap oluşturmak için kullanabileceğiniz %{count} yeni + davetiyeniz olduğunu size bildirmek istedik. Dilerseniz Invitations (Davetiyeler) + sayfası (%{invitation_page_url}) üzerinden bir arkadaşınızı davet edebilirsiniz. + other: AO3'te yeni hesaplar oluşturmak için kullanabileceğiniz %{count} + yeni davetiyeniz olduğunu size bildirmek istedik. Dilerseniz Invitations + (Davetiyeler) sayfası (%{invitation_page_url}) üzerinden bir arkadaşınızı + davet edebilirsiniz. + invite_request_declined: + main: + one: Yeni bir davete ilişkin talebinizi şu anda yerine getiremeyeceğimizi + üzülerek bildiriyoruz. + other: "%{count} yeni davet talebinizi şu anda yerine getiremeyeceğimizi üzülerek + bildiriyoruz." + reason: 'Talebiniz şöyleydi:' + subject: "[%{app_name}] İlave Davet Kodu İsteğiniz Reddedildi" + recipient_notification: + html: + collection: AO3'te %{collection_link} koleksiyonunda sizin için hediye bir + hediye eser yayınlandı! + no_collection: AO3'te sizin için bir hediye eser yayınlandı! + subject: + collection: "[%{app_name}][%{collection_title}] %{collection_title} tarafından + size hediye edilmiş bir eser" + no_collection: "[%{app_name}] Size hediye edilmiş bir eser" + text: + collection: AO3'te "%{collection_title}" koleksiyonunda (%{collection_url}) + sizin için hediye bir eser yayınlandı! diff --git a/config/locales/phrase-exports/uk.yml b/config/locales/phrase-exports/uk.yml new file mode 100755 index 0000000..d97f23d --- /dev/null +++ b/config/locales/phrase-exports/uk.yml @@ -0,0 +1,667 @@ +--- +uk: + activerecord: + attributes: + archive_warning: + name_with_colon: + few: 'Попередження:' + many: 'Попередження:' + one: 'Попередження:' + category: + name_with_colon: + few: 'Категорії:' + many: 'Категорії:' + one: 'Категорія:' + character: + name_with_colon: + few: 'Персонажі:' + many: 'Персонажі:' + one: 'Персонаж:' + fandom: + name_with_colon: + few: 'Фандоми:' + many: 'Фандоми:' + one: 'Фандом:' + freeform: + name_with_colon: + few: 'Додаткові теги:' + many: 'Додаткові теги:' + one: 'Додатковий тег:' + rating: + name_with_colon: 'Рейтинг:' + relationship: + name_with_colon: + few: 'Стосунки:' + many: 'Стосунки:' + one: 'Стосунки:' + work: + chapter_total_display: Розділи + summary: Опис + models: + archive_warning: + few: Попередження + many: Попередження + one: Попередження + category: + few: Категорії + many: Категорії + one: Категорія + chapter: + few: Розділи + many: Розділи + one: Розділ + character: + few: Персонаж + many: Персонажі + one: Персонаж + fandom: + few: Фандоми + many: Фандоми + one: Фандом + freeform: + few: Додаткові теги + many: Додаткові теги + one: Додатковий тег + rating: + few: Рейтинги + many: Рейтинги + one: Рейтинг + relationship: + few: Стосунки + many: Стосунки + one: Стосунки + series: + few: Серії + many: Серії + one: Серія + kudo_mailer: + batch_kudo_notification: + guest: + few: "%{count} гостей" + many: "%{count} гостей" + one: "%{count} гостя" + left_kudos: + html: + few: Вподобайка для %{commentable_link} від %{givers_list}. + many: Вподобайка для %{commentable_link} від %{givers_list}. + one: Вподобайка для %{commentable_link} від %{givers_list}. + text: + few: Вподобайка для %{commentable_title} (%{commentable_url}) від %{givers_list}. + many: Вподобайка для %{commentable_title} (%{commentable_url}) від %{givers_list}. + one: Вподобайка для %{commentable_title} (%{commentable_url}) від %{givers_list}. + single_guest: + giver: 1-го гостя + html: Вподобайка для %{commentable_link} від %{giver}. + text: Вподобайка для %{commentable_title} (%{commentable_url}) від 1-го гостя. + subject: "[%{app_name}] Ви отримали вподобайку!" + mailer: + general: + closing: + formal: Щиро, + informal: Вcього найкращого, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Розділ %{position} роботи %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + few: "%{count} слова" + many: "%{count} слів" + one: "%{count} слово" + footer: + about: + html: АО3 – це керований та забезпечуваний фанатами архів, який залежить від %{your_donations_link}. + text: 'АО3 – це керований та забезпечуваний фанатами архів, який залежить від Ваших пожертв: %{your_donations_url}.' + your_donations: Ваших пожертв + sent_at: Відправлено %{sent_at}. + why_policy_abuse: + contact_policy_abuse: 'зв''яжіться з Політикою та Зловживаннями' + html: Якщо Ви не розумієте, чому Ви отримали це повідомлення, будь ласка, %{contact_policy_abuse_link}. + text: 'Якщо Ви не розумієте, чому Ви отримали це повідомлення, будь ласка, зв''яжіться з Політикою та Зловживаннями: %{contact_policy_abuse_url}.' + why_support: + contact_support: 'зв''яжіться з Підтримкою' + html: Якщо Ви не розумієте, чому Ви отримали це повідомлення, будь ласка, %{contact_support_link}. + text: 'Якщо Ви не розумієте, чому Ви отримали це повідомлення, будь ласка, зв''яжіться з Підтримкою: %{contact_support_url}.' + greeting: + formal: + addressed_html: Вітаємо, %{name}, + unaddressed: Вітаємо, + informal: + addressed_html: Привіт, %{name}! + unaddressed: Привіт! + introductory: Вітання з Archive of Our Own – AO3 (Нашого Власного Архіву)! + metadata_label_indicator: ":" + signature: + abuse_team: Команда Політики та зловживань AO3 + app_short_name: AO3 + open_doors: Команда Open Doors (Відкритих Дверей) + parent_org: Organization for Transformative Works – OTW (Організація Перетворчих Робіт) + support: Команда Підтримки АО3 + users: + mailer: + reset_password_instructions: + expiration: Якщо Ви не використаєте це посилання протягом одного тижня, воно + стане недійсним, і Вам потрібно буде надіслати новий запит на зміну пароля. + intro: 'Хтось надіслав запит на зміну пароля для Вашого облікового запису. + Ви можете змінити пароль Вашого облікового запису, якщо натиснете на посилання + нижче і введете новий пароль:' + link_title: Змінити пароль + subject: "[%{app_name}] Запит на зміну пароля" + unrequested: Якщо Ви не подавали запит на зміну пароля, Ви можете проігнорувати + цей лист. Ваш минулий пароль продовжить бути дійсним. + user_mailer: + admin_deleted_work_notification: + bye: Для ознайомлення прикріплена копія Вашої роботи. + contact_abuse: зв'яжіться з нашим комітетом Політики і зловживань + deleted: + html: Вашу роботу %{title} було видалено з АО3 адміністратором сайту. + text: Вашу роботу “%{title}” було видалено з АО3 адміністратором сайту. + html: + tos_violation: Якщо можливо, що Ваша робота порушила Умови використання АО3, + будь ласка, %{contact_abuse_link}. + import_project: + html: Якщо Ваша робота була частиною проекту імпортування, організованого + Open Doors (Відкритими Дверима), будь ласка, %{opendoors_link} для роз’яснення + будь-яких подальших питань. + text: Якщо Ваша робота була частиною проекту імпортування, організованого + Open Doors (Відкритими Дверима), будь ласка, зверніться до Відкритих Дверей + (%{opendoors_link}) для роз’яснення будь-яких подальших питань. + opendoors: зверніться до Відкритих Дверей + subject: "[%{app_name}] Вашу роботу було видалено адміністратором" + text: + tos_violation: Якщо можливо, що Ваша робота порушила Умови використання АО3, + будь ласка, зв'яжіться з нашим комітетом Політики та зловживань (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Хоча Вашу роботу приховано, Ви все одно маєте доступ до неї за посиланням, + наданим вище, але вона не відображатиметься на сторінці Ваших робіт, а інші + користувачі АО3 не матимуть до неї доступу. + check_email: Будь ласка, перевірте Вашу електронну пошту, включно зі спамом, + оскільки команда Політики та зловживань вже могла зв'язатися з Вами, щоб пояснити + чому Вашу роботу було приховано. + contact_abuse: Політикою та зловживаннями + html: + help: Якщо Ви не впевнені чому Вашу роботу було приховано, і Ви не отримали + жодних листів стосовно цього питання, будь ласка, зв'яжіться напряму з %{contact_abuse_link}. + hidden: Вашу роботу %{title} було приховано командою Політики та зловживань, + і до неї більше немає публічного доступу. + tos_violation: Якщо Вашу роботу було приховано через порушення %{tos_link} + AO3, Вам потрібно буде виправити ці порушення. Якщо Ви не зміните роботу + відповідно до вимог Умов використання, це може призвести до її видалення + з АО3. + subject: "[%{app_name}] Вашу роботу було приховано командою Політики та зловживань" + text: + help: 'Якщо Ви не впевнені чому Вашу роботу було приховано, і Ви не отримали + жодних листів стосовно цього питання, будь ласка, зв''яжіться напряму з + Політикою та зловживаннями: %{contact_abuse_url}.' + hidden: Вашу роботу "%{title}" (%{work_url}) було приховано командою Політики + та зловживань, і до неї більше немає публічного доступу. + tos_violation: Якщо Вашу роботу було приховано через порушення Умов використання + AO3 (%{tos_url}), Вам потрібно буде виправити ці порушення. Якщо Ви не зміните + роботу відповідно до вимог Умов використання, це може призвести до її видалення + з АО3. + tos: Умов використання + anonymous_or_unrevealed_notification: + anonymous_info: 'Анонімні роботи відображаються на сторінках тегів, але не на + Вашій сторінці робіт. На самій роботі Ваше ім''я користувача буде змінено + на "Anonymous" (Анонім). + + ' + anonymous_unrevealed_info: Утримувачі колекції можуть в майбутньому відкрити + Вашу роботу, але залишити її анонімною. Користувачі, які на Вас підписались, + не отримають повідомлення про цю зміну. Після того, як її відкриють, Ваша + робота з’явиться на сторінках тегів, але не на Вашій сторінці робіт. На самій + роботі Ваше ім'я користувача буде змінено на "Anonymous" (Анонім). + changed_status: + anonymous: + html: Утримувачі колекції %{collection_link} змінили статус Вашої роботи + %{work_link} на анонімний. + text: Утримувачі колекції "%{collection_title}" (%{collection_url}) змінили + статус Вашої роботи "%{work_title}" (%{work_url}) на анонімний. + anonymous_unrevealed: + html: Утримувачі колекції %{collection_link} змінили статус Вашої роботи + %{work_link} на анонімний та закритий. + text: Утримувачі колекції "%{collection_title}" (%{collection_url}) змінили + статус Вашої роботи "%{work_title}" (%{work_url}) на анонімний та закритий. + unrevealed: + html: Утримувачі колекції %{collection_link} змінили статус Вашої роботи + %{work_link} на закритий. + text: Утримувачі колекції "%{collection_title}" (%{collection_url}) змінили + статус Вашої роботи "%{work_title}" (%{work_url}) на закритий. + collection_items_link_text: Approved Collection Items (Підтверджених робіт в + колекціях) + do_not_want: + anonymous: + html: Якщо Ви не бажаєте, щоб Ваша робота була анонімною, перейдіть, будь + ласка, на Вашу сторінку %{collection_items_link}, щоб видалити її з цієї + колекції. + text: 'Якщо Ви не бажаєте, щоб Ваша робота була анонімною, перейдіть, будь + ласка, на Вашу сторінку Approved Collection Items (Підтверджених робіт + в колекціях), щоб видалити її з цієї колекції: %{collection_items_url}' + anonymous_unrevealed: + html: Якщо Ви не бажаєте, щоб Ваша робота була анонімною і закритою, перейдіть, + будь ласка, на Вашу сторінку %{collection_items_link}, щоб видалити її + з цієї колекції. + text: 'Якщо Ви не бажаєте, щоб Ваша робота була анонімною і закритою, перейдіть, + будь ласка, на Вашу сторінку Approved Collection Items (Підтверджених + робіт в колекціях), щоб видалити її з цієї колекції: %{collection_items_url}' + unrevealed: + html: Якщо Ви не бажаєте, щоб Ваша робота була закритою, перейдіть, будь + ласка, на Вашу сторінку %{collection_items_link}, щоб видалити її з цієї + колекції. + text: 'Якщо Ви не бажаєте, щоб Ваша робота була закритою, перейдіть на Вашу + сторінку Approved Collection Items (Підтверджених робіт в колекціях), + щоб видалити її з цієї колекції: %{collection_items_url}' + faq_link_text: FAQ Колекцій + more_info: + html: Для додаткової інформації відвідайте наше %{faq_link}. + text: 'Для додаткової інформації відвідайте наше FAQ Колекцій: %{faq_url}' + subject: + anonymous: "[%{app_name}] Вашу роботу зробили анонімною" + anonymous_unrevealed: "[%{app_name}] Вашу роботу зробили анонімною і закритою" + unrevealed: "[%{app_name}] Вашу роботу зробили закритою" + unrevealed_info: Закриті роботи не відображаються ані на сторінках тегів, ані + на Вашій сторінці робіт. Кожен, хто перейде за посиланням на Вашу роботу, + отримає повідомлення, що вона є закритою, і вони не зможуть переглянути її + вміст. + archivist_added_to_collection_notification: + approved_collection_items_page: сторінки Approved Collection Items (Деталі затвердженої + колекції) + archivist_notice: Оскільки розпорядники колекції виступають у ролі архіваріусів + Open Doors (Відкритих Дверей), їм дозволено додати Вашу роботу до цієї колекції, + навіть якщо у Вас вимкнено опцію запрошення до колекції. Архіваріуси додадуть + роботу до колекції, лише якщо вона розміщена в імпортованому архіві. + removal_instructions: + html: Якщо Ви хочете прибрати свою роботу з цієї колекції, будь ласка, перейдіть + до Вашої %{approved_items_link}. + text: 'Якщо Ви хочете прибрати свою роботу з цієї колекції, будь ласка, перейдіть + до Вашої сторінки Approved Collection Items (Деталі затвердженої колекції): + %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Архіваріус Open Doors (Відкритих + Дверей) додав Вашу роботу до колекції" + work_added: + html: Розпорядники колекції %{collection_link} додали Вашу роботу %{work_link} + до їхньої колекції! + text: Розпорядники колекції "%{collection_title}" (%{collection_url}) додали + Вашу роботу "%{work_title}" (%{work_url}) до їхньої колекції! + challenge_assignment_notification: + any: Будь-які + assignment: + html: Вам було призначено наступну заявку в челенджі %{link} на AO3! + description: 'Опис:' + due: 'Кінцевий термін цього завдання:' + html: + footer: Ви отримали цей електронний лист, тому що Ви записались до челенджу + %{title}. Щоб отримати більше інформації про цей челендж і контактну інформацію + модераторів, перегляньте %{footer_link}. + footer_link: сторінку профілю челенджу + look_up: Ви можете переглянути це завдання на %{link}. + look_up_link: сторінці з Вашими Assignments (Завданнями) + optional_tags: 'Теги на вибір:' + prompts: 'Заявки:' + prompt_url: 'Посилання на заявку:' + recipient: 'Отримувач:' + recipient_missing: 'Немає: зв''яжіться з модератором, щоб отримати допомогу!' + subject: "[%{app_name}][%{collection_title}] Ваше завдання!" + text: + assignment: Вам було призначено наступну заявку в челенджі "%{collection_title}" + (%{collection_url}) на AO3! + footer: Ви отримали цей електронний лист, тому що Ви записались до челенджу + %{title} (%{url}). Щоб отримати більше інформації про цей челендж і контактну + інформацію модераторів, перегляньте %{profile_url}. + look_up: Ви можете переглянути це завдання на сторінці з Вашими Assignments + (Завданнями) за посиланням %{link}. + change_email: + changed: + html: "%{login}, електронну адресу, що пов'язана з Вашим обліковим записом, + було змінено на %{email}" + text: "%{login}, електронну адресу, що пов'язана з Вашим обліковим записом, + було змінено на %{email}" + subject: "[%{app_name}] Електронну адресу змінено" + claim_notification: + access: + contact_support: зверніться до Служби Підтримки АО3. + html: Залежно від архіву, Ваші роботи могли бути імпортовані з доступом лише + для зареєстрованих користувачів (аби їх не було видно в пошуку Google). + У такому випадку, тільки залогінені користувачі матимуть можливість переглядати + Ваші роботи, якщо Ви самі не вирішите відкрити до них доступ повністю. Щоб + отримати допомогу з налаштуванням доступу до робіт, видаленням або відмовою + від них, будь ласка, %{contact_support_link}. + text: 'Залежно від архіву, Ваші роботи могли бути імпортовані з доступом лише + для зареєстрованих користувачів (аби їх не було видно в пошуку Google). + В такому випадку, тільки залогінені користувачі матимуть можливість переглядати + Ваші роботи, якщо Ви самі не вирішили відкрити до них доступ повністю. Щоб + отримати допомогу з відкриттям робіт, видаленням або відмовою від них, будь + ласка, зверніться до Служби Підтримки за посиланням: %{support_url}.' + email_tips: Якщо Ви вирішили написати нам, будь ласка, додайте @transformativeworks.org + до Вашого списку надійних контактів і перевіряйте папку зі спамом на наявність + нашої відповіді. + introduction: + ao3_name: Archive of Our Own – AO3 (Нашого Власного Архіву) + html: Ви отримали цей електронний лист, тому що Ваші роботи перебували в архіві + фанробіт, який %{open_doors_name_link} імпортували до %{app_link}. Оскільки + ця електронна адреса збігається з адресою, зареєстрованою в імпортованому + архіві, пов'язані фанроботи (перелічені нижче) було автоматично додано до + Вашого облікового запису на АО3. + open_doors_name: Open Doors (Відкриті Двері) + text: 'Ви отримали цей електронний лист, тому що Ваші роботи перебували в + архіві фанробіт, який Open Doors (Відкриті Двері) (%{open_doors_url}) імпортували + до Archive of Our Own – AO3 (Нашого Власного Архіву): %{app_url}. Оскільки + ця електронна адреса збігається з адресою, зареєстрованою в імпортованому + архіві, пов''язані фанроботи (перелічені нижче) було автоматично додано + до Вашого облікового запису на АО3.' + mistake: + contact_open_doors: зв'яжіться з Відкритими Дверима + html: Якщо виникла помилка, і ці роботи Вам не належать, будь ласка, не видаляйте + їх! Просто %{contact_open_doors_link}, і ми вирішимо цю проблему. + text: Якщо виникла помилка, і ці роботи Вам не належать, будь ласка, не видаляйте + їх! Просто зв'яжіться з Відкритими Дверима (%{open_doors_url}), і ми вирішимо + цю проблему. + more_info: + ao3_news: Новин АО3 + contact_support: зверніться до Служби Підтримки АО3. + faq_page: сторінці FAQ + html: Ви можете прочитати оголошення про нещодавні переміщення архіву на сторінці + %{ao3_news_link}, а також ознайомитися з додатковою інформацією на %{faq_page_link} + Відкритих Дверей або на %{tutorial_page_link}. Якщо Ви не знайдете відповіді + на своє питання у наших посібниках, FAQ або у цьому листі, будь ласка, %{contact_support_link}. + text: 'Ви можете прочитати оголошення про нещодавні переміщення архіву на + сторінці Новин АО3 (%{news_url}), а також ознайомитися з додатковою інформацією + на сторінці FAQ Відкритих Дверей (%{open_doors_faq_url}) або на сторінці + з посібниками (%{open_doors_tutorial_url}). Якщо Ви не знайдете відповіді + на своє запитання у наших посібниках, FAQ або в цьому листі, будь ласка, + зверніться до Служби Підтримки за посиланням: %{support_url}.' + tutorial_page: сторінці з посібниками + other_works: + contact_open_doors: зв'яжіться з Відкритими Дверима + html: Якщо у Вас є інші роботи в імпортованому архіві, але у Вас немає доступу + до електронної адреси, під якою вони були написані, будь ласка, %{contact_open_doors_link} + та надайте будь-яку інформацію, яка могла б допомогти верифікувати Вас. + text: Якщо у Вас є інші роботи в імпортованому архіві, але у Вас немає доступу + до електронної адреси, під якою вони були написані, будь ласка, зв'яжіться + з Відкритими Дверима та надайте будь-яку інформацію, яка могла б допомогти + верифікувати Вас. + questions: + contact_support: зверніться до Служби Підтримки АО3. + html: Для інших запитів, будь ласка, %{contact_support_link}. + text: 'Для інших запитів, будь ласка, звертайтеся до Служби Підтримки АО3 + за посиланням: %{support_url}.' + redirects: + html: Для збереження списків і закладок, протягом обмеженого часу веб-адреса + імпортованого архіву може перенаправляти користувачів до імпортованої копії + цих робіт (перегляньте оголошення про Ваш архів, аби знати точну інформацію). + Якщо Ви вже завантажили копію цих робіт і %{negation} використали функцію + імпорту з URL-адреси, на AO3 буде дві копії однієї роботи. + subject: "[%{app_name}] Роботи завантажені" + update_redirect: + contact_open_doors: зверніться до Відкритих Дверей + html: Якщо Ви хочете, щоб Відкриті Двері оновили перенаправлення на Вашу вже + наявну роботу, будь ласка, видаліть імпортовану копію та %{contact_open_doors_link}, + вказавши ім'я Вашого облікового запису на АО3, ім'я Вашого облікового запису + в імпортованому архіві, а також назву та URL- адресу фанроботи, на яку Ви + б хотіли зробити перенаправлення. + text: 'Якщо Ви хочете, щоб Відкриті Двері оновили перенаправлення на Вашу + вже наявну роботу, будь ласка, видаліть імпортовану копію та зверніться + до Відкритих Дверей за посиланням: %{open_doors_url}, вказавши ім''я Вашого + облікового запису на АО3, ім''я Вашого облікового запису в імпортованому + архіві, а також назву та URL- адресу фанроботи, на яку Ви б хотіли зробити + перенаправлення.' + works_by: 'Ці роботи були написані під електронною адресою: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Усі завдання було щойно розіслано. + subject: Завдання надіслано + html: + received_message: 'Ви отримали повідомлення про Вашу колекцію %{collection_link}:' + text: + received_message: 'Ви отримали повідомлення про Вашу колекцію "%{collection_title}" + (%{collection_url}):' + creatorship_notification: + explanation: Коли Ви - співтворець роботи, Вас можна додати до нових розділів + незалежно від Ваших налаштувань. Також Ви будете доданими до будь-якої серії, + до якої додадуть роботу. + html: + creation: "%{creation_link} авторства %{pseud_links}" + edit_chapter: відредагувати розділ + edit_series: відредагувати серію + remove_chapter: Якщо Вас помилково зробили співтворцем, або Ви не хочете бути + вказаними в якості творця, Ви можете %{edit_chapter_link}, щоб видалити + себе як творця. + remove_series: Якщо Вас помилково зробили співтворцем, або Ви не хочете бути + вказаними в якості творця, Ви можете %{edit_series_link}, щоб видалити себе + як творця. + intro_chapter: 'Користувач %{adding_user} додав Вас, %{pseud}, у якості співтворця + наступного розділу:' + intro_series: 'Користувач %{adding_user} додав Вас, %{pseud}, в якості співтворця + до наступної серії:' + subject: "[%{app_name}] Повідомлення про співавторство" + text: + creation: "%{title} (%{url}) авторства %{pseuds}" + remove_chapter: 'Якщо Вас помилково зробили співтворцем, або Ви не хочете + бути вказаними в якості творця, Ви можете відредагувати розділ, щоб видалити + себе як творця: %{url}' + remove_series: 'Якщо Вас помилково зробили співтворцем, або Ви не хочете бути + вказаними в якості творця, Ви можете відредагувати серію, щоб видалити себе + як творця: %{url}' + creatorship_notification_archivist: + explanation: Оскільки даний користувач виступає у ролі архіваріуса Open Doors + (Відкритих Дверей), цей користувач має можливість додати Вас без запиту, навіть + якщо Ви вимкнули можливість співавторства. + html: + creation: "%{creation_link} авторства %{pseud_links}" + edit_chapter: відредагувати розділ + edit_series: відредагувати серію + edit_work: відредагувати роботу + remove_chapter: Якщо Вас помилково зробили співтворцем, або Ви не хочете бути + вказаними в якості творця, Ви можете %{edit_chapter_link}, щоб видалити + себе як творця. + remove_series: Якщо Вас помилково зробили співтворцем, або Ви не хочете бути + вказаними в якості творця, Ви можете %{edit_series_link}, щоб видалити себе + як творця. + remove_work: Якщо Вас помилково зробили співтворцем, або Ви не хочете бути + вказаними в якості творця, Ви можете %{edit_work_link}, щоб видалити себе + як творця. + intro_chapter: 'Користувач %{archivist} додав Ваc, %{pseud}, у якості співтворця + в наступному розділі:' + intro_series: 'Користувач %{archivist} додав Ваc, %{pseud}, у якості співтворця + в наступній серії:' + intro_work: 'Користувач %{archivist} додав Ваc, %{pseud}, у якості співтворця + в наступній роботі:' + subject: "[%{app_name}] Повідомлення від архіваріуса про співавторство" + text: + creation: "%{title} (%{url}) авторства %{pseuds}" + remove_chapter: 'Якщо Вас помилково зробили співтворцем, або Ви не хочете + бути вказаними в якості творця, Ви можете відредагувати розділ, щоб видалити + себе як творця: %{url}' + remove_series: 'Якщо Вас помилково зробили співтворцем, або Ви не хочете бути + вказаними в якості творця, Ви можете відредагувати серію, щоб видалити себе + як творця: %{url}' + remove_work: 'Якщо Вас помилково зробили співтворцем, або Ви не хочете бути + вказаними в якості творця, Ви можете відредагувати роботу, щоб видалити + себе як творця: %{url}' + creatorship_request: + html: + creation: "%{creation_link} авторства %{pseud_links}" + instructions: Ви можете прийняти або відхилити цей запит на Вашій сторінці + %{page_name}. + page_name: Co-Creator Requests (Запитів на співавторство) + intro_chapter: 'Користувач %{inviting_user} запросив Вас, %{pseud}, стати співтворцем + наступного розділу:' + intro_series: 'Користувач %{inviting_user} запросив Вас, %{pseud}, стати співтворцем + наступної серії:' + intro_work: 'Користувач %{inviting_user} запросив Вас, %{pseud}, стати співтворцем + наступної роботи:' + subject: "[%{app_name}] Запит на додання співтворця" + text: + creation: "%{title} (%{url}) авторства %{pseuds}" + instructions: 'Ви можете прийняти або відхилити цей запит на Вашій сторінці + Co-Creator Requests (Запитів на співавторство): %{url}.' + delete_work_notification: + attachment: Для ознайомлення прикріплена копія Вашої роботи. + deleted_other: + html: Вашу роботу %{title} було видалено на прохання користувача %{pseud}. + text: Вашу роботу "%{title}" було видалено на прохання користувача %{pseud}. + deleted_yourself: + html: Вашу роботу %{title} було видалено на Ваше прохання. + text: Вашу роботу "%{title}" було видалено на Ваше прохання. + questions: + html: Якщо у Вас виникнуть запитання, будь ласка, %{support}. + text: Якщо у Вас виникнуть запитання, будь ласка, %{support} (%{url}). + subject: "[%{app_name}] Вашу роботу було видалено" + support: зв'яжіться з Підтримкою + invitation_to_claim: + access: + text: Залежно від архіву, під час імпорту ваші роботи могли бути обмеженими + для перегляду лише зареєстрованими користувачами (щоб вони не з’являлись + під часу пошуку в Google). Якщо це відбулось, ваші роботи зможуть переглядати + лише залогінені користувачі, поки ви не зробите їх видимими для всіх. Для + допомоги з відкриттям, відмовою від або видаленням ваших робіт, просимо + вас сконтактуватись зі службою Підтримки. + claim_or_remove: + html: Підтвердіть власність або відмовтесь від ваших робіт тут. + text: 'Підтвердіть власність або відмовтесь від ваших робіт тут: %{claim_url}' + email_tips: Якщо ви з нам сконтактувались, внесіть будь ласка електронні адреси + з домени @transformativeworks.org до білого списку і перевірте, чи наша відповідь + не потрапила у вашу папку Спам. + html: + ao3_news: Новин AO3 + contact_open_doors: сконтактуйтесь з Відкритими Дверима + contact_support: сконтактуватись зі службою Підтримки АО3 + faq_page: сторінці FAQ + tutorial_page: сторінці посібника + introduction: + text: Ви отримали це повідомлення оскільки нещодавно архів був заімпортованим + Комітетом Open Doors (Відкритих Дверей) (%{open_doors_link}) в %{app_name} + (%{app_short_name} - %{app_url}) і нам здається, що наведені нижче роботи + належать вам. Ми б хотіли дати вам можливість підтвердити власність (або + видалити/відмовитись від) цих робіт, якщо ви хочете. Крім того, якщо у вас + немає акаунту пов’язаного з іншою адресою електронної пошти, ми б хотіли + вас до себе запросити! + mistake: + text: Якщо ви отримали це повідомлення помилково або це не ваші роботи, ми + б просили їх не видаляти! Будь ласка, сконтактуйтесь з Відкритими Дверима + (%{open_doors_link}), і ми з цим розберемось. + more_info: + text: Ви можете ознайомитись з нещодавніми перенесеннями архіву на сторінці + Новин АО3 (%{news_link}), а також знайти додаткову інформацію на сторінці + FAQ (%{open_doors_faq_link}) або сторінці посібника (%{open_doors_tutorial_link}) + Відкритих Дверей. Якщо у вас виникли питання, відповідей на які немає в + FAQ, посібнику чи цьому листі, просимо вас сконтактуватись зі службою Підтримки, + перейшовши за посиланням %{support_link}. + other_works: + text: Якщо ви мали інші роботи на заімпортованому архіві, розміщенні під іншою + адресою електронної пошти, до якої ви більше не маєте доступу, будь ласка, + сконтактуйтесь з Відкритими Дверима, надаючи усю можливу інформацію, яка + допоможе підтвердити вашу особистість. + questions: + text: Просимо вас сконтактуватись зі службою Підтримки AO3, перейшовши за + посиланням %{support_link}, якщо ви маєте інші питання. + redirects: Задля збереження списків рекомендацій і закладок, веб-адреси імпортованих + архівів протягом деякого часу будуть перенаправляти на імпортовану копію цих + робіт (перевірте оголошення на вашому архіві, щоб у цьому впевнитись). Якщо + ви вже опублікували копію цієї роботи і НЕ використовували для цього функцію + “імпортувати з URL-адреси”, в архіві будуть знаходитись дві копії однієї і + тієї ж роботи. + subject: "[%{app_name}] Запрошення до підтвердження власності роботи" + unwanted: + text: Якщо ці роботи дійсно належать вам, але вони вам не потрібні, ви можете + відмовитись від них (в цьому випадку вони залишаться на АО3, але ваше ім’я + буде усунутим) або видалити їх (в цьому випадку вони повністю будуть усунутими + з АО3). Вам не потрібно додавати ці роботи до якогось акаунту, щоб відмовитись + від них або їх усунути - ви можете це зробити безпосередньо, перейшовши + за посиланням на підтвердження власності, що знаходиться вище. (Якщо вам + потрібна допомога, просимо вас сконтактуватись зі службою Підтримки, перейшовши + за посиланням %{support_link}). + update_redirect: + text: Якщо ви б хотіли, щоб Відкриті Двері перенесли перенаправлення на вашу + уже існуючу роботу, усуньте, будь ласка, імпортовану копію і сконтактуйтесь + з Відкритими Дверима за посиланням %{open_doors_link}, подаючи ім’я вашого + акаунту на АО3, ім’я вашого акаунту на заімпортованому архіві та назву і + посилання на роботу, на яку ви хочете перенести перенаправлення. (Якщо ви + хочете змінити перенаправлення для кількох робіт, ви можете вислати їх усі + в одному листі). + uploaded_list: 'Список завантажених робіт складається з:' + invite_increase_notification: + html: + body: + few: Ми всього лише хотіли повідомити, що Ви отримали %{count} новi запрошення. + Їх можна використати для створення нових облікових записів на AO3. Ви + можете запросити друга через %{invitation_page_link}. + many: Ми всього лише хотіли повідомити, що Ви отримали %{count} нових запрошень. + Їх можна використати для створення нових облікових записів на AO3. Ви + можете запросити друга через %{invitation_page_link}. + one: Ми всього лише хотіли повідомити, що Ви отримали %{count} нове запрошення. + Його можна використати для створення нового облікового запису на AO3. + Ви можете запросити друга через %{invitation_page_link}. + invitation_page_link_text: сторінку Ваших Invitations (Запрошень) + subject: "[%{app_name}] Нові запрошення" + text: + body: + few: Ми всього лише хотіли повідомити, що Ви отримали %{count} новi запрошення. + Їх можна використати для створення нових облікових записів на AO3. Ви + можете запросити друга через сторінку Ваших Invitations (Запрошень) (%{invitation_page_url}). + many: Ми всього лише хотіли повідомити, що Ви отримали %{count} нових запрошень. + Їх можна використати для створення нових облікових записів на AO3. Ви + можете запросити друга через через сторінку Ваших Invitations (Запрошень) + (%{invitation_page_url}). + one: Ми всього лише хотіли повідомити, що Ви отримали %{count} нове запрошення. + Його можна використати для створення нового облікового запису на AO3. + Ви можете запросити друга через сторінку Ваших Invitations (Запрошень) + (%{invitation_page_url}). + invite_request_declined: + main: + few: 'На жаль, ми змушені повідомити Вам, що наразі Ваш запит на %{count} + нові запрошення не може бути виконаним. ' + many: 'На жаль, ми змушені повідомити Вам, що наразі Ваш запит на %{count} + нових запрошень не може бути виконаним. ' + one: 'На жаль, ми змушені повідомити Вам, що наразі Ваш запит на %{count} + нове запрошення не може бути виконаним. ' + reason: 'Ваш запит:' + subject: "[%{app_name}] Вам відмовлено у додаткових запрошеннях" + recipient_notification: + html: + collection: Для Вас на АО3 було опубліковано роботу-подарунок у колекції %{collection_link}! + no_collection: Для Вас на АО3 було опубліковано роботу-подарунок! + subject: + collection: "[%{app_name}][%{collection_title}] Подарунок для Вас від %{collection_title}" + no_collection: "[%{app_name}] Подарунок для Вас" + text: + collection: Для Вас на АО3 було опубліковано роботу-подарунок у колекції %{collection_title} + (%{collection_url})! + signup_notification: + activate: + html: " Будь ласка, %{activate_account_link}." + text: 'Будь ласка, перейдіть за цим посиланням, щоб активувати Ваш обліковий + запис: %{activate_account_url}' + activate_your_account: перейдіть за цим посиланням, щоб активувати Ваш обліковий + запис + admin_posts: Новин АО3 + bye: Сподіваємось, що Вам сподобається AO3! + contact_support: зв’яжіться з Підтримкою + faq: FAQ + features: + html: Як тільки Ваш профіль буде активовано, Ви зможете публікувати власні + фанроботи, налаштувати емейл-підписки, щоб дізнатися, коли Ваш улюблений + автор обновить свою роботу; налаштувати інтерфейс сайту згідно Вашим вподобанням; + слідкувати, які роботи Ви переглянули в історії Архіву, та багато інших + речей. + text: Як тільки Ваш профіль буде активовано, Ви зможете публікувати власні + фанроботи, налаштувати емейл-підписки, щоб дізнатися коли Ваш улюблений + автор обновить свою роботу; налаштувати інтерфейс сайту згідно Вашим вподобанням; + слідкувати, які роботи Ви переглянули в історії Архіву, та багато інших + речей. + information: + html: Інформацію про те, як користуватись Архівом, можна знайти у розділі %{faq_link}. + Найновіші оновлення сайту та новини знаходяться на сторінці %{admin_posts_link}. + Якщо Вам потрібна допомога, Ви знайшли баг, маєте питання чи застереження, + будь ласка %{contact_support_link}, котрі завжди з радістю Вам допоможуть. + text: 'Інформацію про те, як користуватись Архівом, можна знайти у розділі + FAQ за посиланням %{faq_url}. Найновіші оновлення сайту та новини знаходяться + на сторінці Новин АО3 за посиланням %{admin_posts_url}. Якщо Вам потрібна + допомога, Ви знайшли баг, маєте питання чи застереження, зв’яжіться з командою + Підтримки, перейшовши з цим посиланням: %{contact_support_url}, котрі завжди + з радістю Вам допоможуть.' + welcome: Ласкаво просимо до АО3, %{login}! diff --git a/config/locales/phrase-exports/vi.yml b/config/locales/phrase-exports/vi.yml new file mode 100755 index 0000000..d05a820 --- /dev/null +++ b/config/locales/phrase-exports/vi.yml @@ -0,0 +1,613 @@ +--- +vi: + activerecord: + attributes: + archive_warning: + name_with_colon: + other: 'Cảnh Báo:' + category: + name_with_colon: + other: 'Hạng Mục:' + character: + name_with_colon: + other: 'Nhân Vật:' + fandom: + name_with_colon: + other: 'Fandom:' + freeform: + name_with_colon: + other: 'Từ Khoá Bổ Sung:' + rating: + name_with_colon: 'Giới Hạn Độ Tuổi:' + relationship: + name_with_colon: + other: 'Mối Quan Hệ:' + work: + chapter_total_display: Chương + summary: Tóm Tắt + models: + archive_warning: + other: Cảnh Báo + category: + other: Hạng Mục + chapter: + other: Chương + character: + other: Nhân Vật + fandom: + other: Fandom + freeform: + other: Từ Khoá Bổ Sung + rating: + other: Giới Hạn Độ Tuổi + relationship: + other: Mối Quan Hệ + series: + other: Bộ + kudo_mailer: + batch_kudo_notification: + guest: + other: "%{count} người đọc khách" + left_kudos: + html: + other: "%{givers_list} đã tán dương tác phẩm %{commentable_link}." + text: + other: "%{givers_list} đã tán dương tác phẩm %{commentable_title} (%{commentable_url})." + single_guest: + giver: Một người đọc khách + html: "%{giver} đã tán dương tác phẩm %{commentable_link}." + text: Một người đọc khách đã tán dương tác phẩm %{commentable_title} (%{commentable_url}). + subject: "[%{app_name}] Tán dương gửi đến bạn!" + mailer: + general: + closing: + formal: Trân trọng, + informal: Trân trọng, + creation: + link_with_word_count: "%{creation_link} (%{word_count})" + title_with_chapter_number: Chương %{position} của tác phẩm %{title} + title_with_word_count: '"%{creation_title}" (%{word_count})' + word_count: + other: "%{count} từ" + footer: + general: + about: + html: AO3 là một kho tàng lưu trữ được điều hành và vận hành bởi fan, + và duy trì nhờ %{donate_link}. + text: 'AO3 là một kho tàng lưu trữ được điều hành và vận hành bởi fan, + và duy trì nhờ quyên góp của bạn: %{donate_url}.' + html: + donate_link_text: quyên góp của bạn + support_link_text: liên hệ Ban Hỗ Trợ Kỹ Thuật + unwanted_email: + html: Nếu thông báo này có sai sót hoặc nhầm lẫm, xin hãy %{support_link}. + text: Nếu thông báo này có sai sót hoặc nhầm lẫn, xin hãy liên hệ ban + Hỗ Trợ Kỹ Thuật tại %{support_url}. + sent_at: Gửi vào lúc %{sent_at}. + greeting: + formal_html: Thân gửi %{name}, + informal: + addressed_html: Xin chào, %{name}! + unaddressed: Xin chào! + introductory: Hello from the Archive of Our Own – AO3 (Xin gửi lời chào từ + Kho Tàng Lưu Trữ của Chúng Ta)! + metadata_label_indicator: ":" + signature: + abuse_team: Đội ngũ Chính Sách & Xử Lý Lạm Quyền của AO3 + app_short_name: AO3 + open_doors: Đội ngũ Open Doors (Cửa Mở) + parent_org: Organization for Transformative Works – OTW (Tổ Chức cho các Tác + Phẩm Được Biến Đổi) + support: Đội ngũ Hỗ Trợ Kỹ Thuật của AO3 + users: + mailer: + reset_password_instructions: + expiration: Trong thời hạn 1 tuần, nếu bạn không dùng đường link này để đặt + lại mật khẩu, đường link sẽ mất hiệu lực; bạn sẽ phải yêu cầu đường link + mới. + intro: Ai đó đã yêu cầu đặt lại mật khẩu cho tài khoản của bạn. Bạn có thể + thay đổi mật khẩu bằng cách nhấn vào đường link bên dưới và điền mật khẩu + mới. + link_title: Thay đổi mật khẩu của tôi. + subject: "[%{app_name}] Đặt lại mật khẩu" + unrequested: Nếu bạn không yêu cầu đặt lại mật khẩu, bạn có thể bỏ qua email + này; mật khẩu cũ của bạn vẫn sẽ tiếp tục có hiệu lực. + user_mailer: + admin_deleted_work_notification: + bye: Bản sao tác phẩm của bạn được đính kèm trong thư này. + contact_abuse: liên hệ đội ngũ Xử Lý Lạm Quyền của chúng tôi. + deleted: + html: Quản trị viên đã xóa tác phẩm %{title} của bạn khỏi AO3. + text: Quản lý trang web đã xóa tác phẩm %{title} của bạn quản lý trang web + khỏi AO3. + html: + tos_violation: Nếu tác phẩm của bạn vi phạm Điều Khoản Dịch Vụ của AO3, vui + lòng %{contact_abuse_link}. + import_project: + html: Nếu tác phẩm của bạn nằm trong dự án đăng lại thuộc quyền quản lý của + đội ngũ Open Doors (Cửa Mở), hãy %{opendoors_link} để biết thêm thông tin + chi tiết. + text: Nếu tác phẩm của bạn nằm trong dự án đăng lại thuộc quyền quản lý của + đội ngũ Open Doors (Cửa Mở), hãy liên hệ Open Doors (%{opendoors_link}) + để biết thêm thông tin chi tiết. + opendoors: liên hệ Open Doors + subject: "[%{app_name}] Quản trị viên đã xóa tác phẩm của bạn" + text: + tos_violation: Nếu tác phẩm của bạn vi phạm Điều Khoản Dịch Vụ AO3, hãy liên + hệ đội ngũ Xử Lý Lạm Quyền của chúng tôi (%{contact_abuse_url}). + admin_hidden_work_notification: + access: Bạn vẫn có thể truy cập tác phẩm bị ẩn của mình qua đường dẫn trên; + tuy nhiên, tác phẩm này sẽ không xuất hiện tại trang tác phẩm của bạn, đồng + thời sẽ bị ẩn với những người dùng AO3 khác. + check_email: Ban Xử Lý Lạm Quyền AO3 có thể đã liên lạc với bạn về quyết định + và lý do ẩn tác phẩm; xin vui lòng kiểm tra hộp thư của bạn, kể cả hộp thư + rác. + contact_abuse: liên hệ Ban Xử Lý Lạm Quyền + html: + help: Nếu bạn không rõ vì sao tác phẩm của mình bị ẩn và chưa được thông báo + gì thêm về việc này, vui lòng trực tiếp %{contact_abuse_link}. + hidden: Ban Xử Lý Lạm Quyền đã ẩn tác phẩm %{title} của bạn; tác phẩm này + không còn ở chế độ mở truy cập công khai. + tos_violation: Nếu tác phẩm của bạn bị ẩn do vi phạm %{tos_link} của AO3, + bạn sẽ được yêu cầu có hành động điều chỉnh để khắc phục. Không xử lý vi + phạm về Điều Khoản Dịch Vụ có thể dẫn tới việc tác phẩm của bạn bị xóa khỏi + AO3. + subject: "[%{app_name}] Ban Xử Lý Lạm Quyền đã ẩn tác phẩm của bạn" + text: + help: 'Nếu bạn không rõ vì sao tác phẩm của mình bị ẩn và chưa được thông + báo gì thêm về việc này, vui lòng trực tiếp liên hệ Ban Xử Lý Lạm Quyền: + %{contact_abuse_url}.' + hidden: Ban Xử Lý Lạm Quyền đã ẩn tác phẩm "%{title}" (%{work_url}) của bạn; + tác phẩm này không còn ở chế độ mở truy cập công khai. + tos_violation: Nếu tác phẩm của bạn bị ẩn do vi phạm Điều Khoản Dịch Vụ (%{tos_url}) + của AO3, bạn sẽ được yêu cầu có hành động điều chỉnh để khắc phục. Không + xử lý vi phạm về Điều Khoản Dịch Vụ có thể dẫn tới việc tác phẩm của bạn + bị xóa khỏi AO3. + tos: Điều Khoản Dịch Vụ + anonymous_or_unrevealed_notification: + anonymous_info: Tác phẩm ẩn danh vẫn sẽ được liệt kê trong danh mục từ khóa, + nhưng sẽ không xuất hiện trên trang tác phẩm của bạn. Tên người dùng hiển + thị cùng tác phẩm sẽ trở thành "Anonymous" ("Ẩn danh"). + anonymous_unrevealed_info: Trong tương lai, tác phẩm của bạn có thể sẽ được + người quản lý bộ sưu tập công khai, song vẫn giữ trạng thái ẩn danh. Những + người đăng ký theo dõi bạn sẽ không được thông báo về thay đổi này. Sau khi + công khai, tác phẩm của bạn sẽ được liệt kê trong danh mục từ khóa, nhưng + sẽ không xuất hiện trên trang tác phẩm của bạn. Tên người dùng hiển thị cùng + tác phẩm sẽ trở thành "Anonymous" ("Ẩn danh"). + changed_status: + anonymous: + html: Người quản lý bộ sưu tập %{collection_link} đã chuyển trạng thái tác + phẩm %{work_link} của bạn thành ẩn danh. + text: Người quản lý của bộ sưu tập "%{collection_title}" (%{collection_url}) + đã chuyển trạng thái tác phẩm "%{work_title}" (%{work_url}) của bạn sang + trạng thái ẩn danh. + anonymous_unrevealed: + html: Người quản lý bộ sưu tập %{collection_link} đã chuyển trạng thái tác + phẩm %{work_link} của bạn thành ẩn danh và chưa công khai. + text: Người quản lý của bộ sưu tập "%{collection_title}" (%{collection_url}) + đã chuyển trạng thái tác phẩm "%{work_title}" (%{work_url}) của bạn sang + trạng thái ẩn danh và chưa công khai. + unrevealed: + html: Người quản lý bộ sưu tập %{collection_link} đã chuyển trạng thái tác + phẩm %{work_link} của bạn thành chưa công khai. + text: Người quản lý của bộ sưu tập "%{collection_title}" (%{collection_url}) + đã chuyển trạng thái tác phẩm "%{work_title}" (%{work_url}) của bạn sang + trạng thái chưa công khai. + collection_items_link_text: Trang Approved Collection Items (Tác Phẩm Được Duyệt + cho Bộ Sưu Tập) + do_not_want: + anonymous: + html: Nếu bạn không muốn ẩn danh tác phẩm này, vui lòng vào %{collection_items_link} + của bạn để rút tác phẩm khỏi bộ sưu tập. + text: 'Nếu bạn không muốn tác phẩm của bạn ẩn danh, vui lòng vào trang Approved + Collection Items (Tác Phẩm Được Duyệt cho Bộ Sưu Tập) của bạn để rút tác + phẩm khỏi bộ sưu tập: %{collection_items_url}' + anonymous_unrevealed: + html: Nếu bạn muốn công khai và không ẩn danh tác phẩm, vui lòng vào %{collection_items_link} + của bạn để rút tác phẩm khỏi bộ sưu tập. + text: 'Nếu bạn muốn công khai và không ẩn danh tác phẩm, vui lòng vào trang + Approved Collection Items (Tác Phẩm Được Duyệt cho Bộ Sưu Tập) của bạn + để rút tác phẩm khỏi bộ sưu tập: %{collection_items_url}' + unrevealed: + html: Nếu bạn muốn công khai tác phẩm, vui lòng vào %{collection_items_link} + của bạn để rút tác phẩm khỏi bộ sưu tập. + text: 'Nếu bạn muốn công khai tác phẩm, vui lòng vào trang Approved Collection + Items (Tác Phẩm Được Duyệt cho Bộ Sưu Tập) của bạn để rút tác phẩm khỏi + bộ sưu tập: %{collection_items_url}' + faq_link_text: Câu hỏi thường gặp về Bộ Sưu Tập + more_info: + html: Để biết thêm thông tin, vui lòng tham khảo %{faq_link}. + text: 'Để biết thêm thông tin, vui lòng tham khảo Câu hỏi thường gặp về Bộ + Sưu Tập: %{faq_url}' + subject: + anonymous: "[%{app_name}] Tác phẩm của bạn đã chuyển sang trạng thái ẩn danh" + anonymous_unrevealed: "[%{app_name}] Tác phẩm của bạn đã chuyển sang trạng + thái ẩn danh và chưa công khai" + unrevealed: "[%{app_name}] Tác phẩm của bạn đã chuyển sang trạng thái chưa + công khai" + unrevealed_info: Tác phẩm chưa công khai sẽ không được liệt kê trong danh mục + từ khóa hay trang tác phẩm của bạn. Bất kỳ ai truy cập qua đường link tác + phẩm sẽ nhận được thông báo rằng tác phẩm hiện chưa được công khai, và nội + dung hiện chưa thể truy cập. + archivist_added_to_collection_notification: + approved_collection_items_page: Trang Approved Collection Items (Bộ Sưu Tập + đã Phê Duyệt) + archivist_notice: Bởi vì quản lý bộ sưu tập còn có vai trò là người lưu trữ + của Open Doors (Cửa Mở), họ được phép thêm tác phẩm của bạn vào bộ sưu tập + này, kể cả khi bạn đã tắt lời mời tham gia bộ sưu tập. Người lưu trữ chỉ thêm + một tác phẩm vào bộ sưu tập khi tác phẩm đó có mặt trên một kho tàng được + sáp nhập. + removal_instructions: + html: Nếu bạn muốn xóa tác phẩm của mình khỏi bộ sưu tập này, vui lòng truy + cập %{approved_items_link} của bạn. + text: 'Nếu bạn muốn xóa tác phẩm của mình khỏi bộ sưu tập này, vui lòng truy + cập trang Approved Collection Items (Bộ sưu tập đã phê duyệt) của bạn: %{approved_items_url}.' + subject: "[%{app_name}][%{collection_title}] Một người lưu trữ của Open Doors + (Cửa Mở) đã thêm tác phẩm của bạn vào một bộ sưu tập" + work_added: + html: Quản lý bộ sưu tập %{collection_link} đã thêm tác phẩm %{work_link} + của bạn vào bộ sưu tập của họ! + text: Quản lý bộ sưu tập "%{collection_title}" (%{collection_url}) đã thêm + tác phẩm "%{work_title}" (%{work_url}) của bạn vào bộ sưu tập của họ! + challenge_assignment_notification: + any: Bất kỳ + assignment: + html: Đây là nhiệm vụ của bạn trong thử thách %{link} tại AO3! + description: 'Mô tả:' + due: 'Thời hạn hoàn thành nhiệm vụ:' + html: + footer: Bạn nhận được email này vì bạn đã đăng ký tham gia thử thách %{title}. + Để biết thêm chi tiết về thử thách này và thông tin liên hệ của điều phối + viên, vui lòng truy cập %{footer_link}. + footer_link: trang chính của thử thách + look_up: Bạn có thể tìm hiểu thêm về nhiệm vụ này ở %{link}. + look_up_link: trang Assignments (Nhiệm Vụ) của bạn + optional_tags: 'Từ khóa tùy chọn:' + prompts: 'Chủ đề gợi ý:' + prompt_url: 'Địa chỉ URL của chủ đề gợi ý:' + recipient: 'Người nhận:' + recipient_missing: 'Không có người nhận: hãy liên hệ điều phối viên để được + giúp đỡ!' + subject: "[%{app_name}][%{collection_title}] Nhiệm Vụ của Bạn!" + text: + assignment: Đây là nhiệm vụ của bạn trong thử thách "%{collection_title}" + (%{collection_url}) tại AO3! + footer: Bạn nhận được email này vì bạn đã đăng ký tham gia thử thách %{title} + (%{url}). Để biết thêm chi tiết về thử thách này và thông tin liên hệ của + điều phối viên, vui lòng truy cập %{profile_url}. + look_up: Bạn có thể tìm hiểu thêm về nhiệm vụ này tại ở Assignments (Nhiệm + Vụ) của bạn tại %{link}. + change_email: + changed: + html: "%{login}, email dùng để đăng ký tài khoản của bạn đã được đổi thành + %{email}" + text: "%{login}, email dùng để đăng ký tài khoản của bạn đã được đổi thành + %{email}" + subject: "[%{app_name}] Thay đổi email" + claim_notification: + access: + contact_support: liên lạc Ban Hỗ Trợ của AO3 + html: Tùy thuộc vào kho tàng gốc, sau khi được nhập vào, các tác phẩm của + bạn có thể chỉ hiển thị với người dùng đã đăng ký (để tránh những tác phẩm + ấy hiển thị khi dùng chức năng tìm kiếm của Google). Trong trường hợp đó, + chỉ những người dùng đã đăng nhập mới có thể nhìn thấy tác phẩm, trừ khi + bạn cho phép hiển thị với mọi người. Để mở khóa, bỏ quyền sở hữu hoặc xóa + tác phẩm, hãy %{contact_support_link}. + text: Tùy thuộc vào kho tàng gốc, sau khi được nhập vào, các tác phẩm của + bạn có thể chỉ hiển thị với người dùng đã đăng ký (để tránh những tác phẩm + ấy hiển thị khi dùng chức năng tìm kiếm của Google). Trong trường hợp đó, + chỉ những người dùng đã đăng nhập mới có thể nhìn thấy tác phẩm, trừ khi + bạn cho phép hiển thị với mọi người. Để mở khóa, bỏ quyền sở hữu hoặc xóa + tác phẩm, hãy liên lạc với Ban Hỗ Trợ AO3 ở %{support_url}. + email_tips: Để đảm bảo liên lạc giữa hai bên, hãy thêm @transformativeworks.org + vào danh sách email an toàn của bạn và kiểm tra hòm thư spam nếu không tìm + thấy phản hồi của chúng tôi. + introduction: + ao3_name: Archive of Our Own – AO3 (Kho Tàng Lưu Trữ của Chúng Ta) + html: Bạn nhận được thư này vì bạn có tác phẩm đăng tải ở trang kho tàng lưu + trữ tác phẩm fan được %{open_doors_name_link} nhập vào %{app_link}. Vì địa + chỉ e-mail này liên kết trực tiếp với địa chỉ e-mail đăng ký trong dữ liệu + trang kho tàng được nhập, các tác phẩm tương ứng (được liệt kê sau đây) + đã được tự động thêm vào tài khoản AO3 của bạn. + open_doors_name: Open Doors (Dự án Cửa Mở) + text: 'Bạn nhận được email này vì những tác phẩm của bạn trong kho tàng lưu + trữ tác phẩm của fan đã được nhập bởi Open Doors (Cửa Mở) (%{open_doors_url} + đến Archive of Our Own – AO3 (Kho tàng lưu trữ của chúng ta): %{app_url}.. + Vì địa chỉ email này được liên kết với email đăng ký ở kho tàng đó, nên + những tác phẩm liên quan (được liệt kê bên dưới) được tự động thêm vào tài + khoản AO3 của bạn.' + mistake: + contact_open_doors: liên lạc với Open Doors + html: Nếu các tác phẩm kể trên không phải của bạn, xin vui lòng đừng xóa tác + phẩm, mà hãy %{contact_open_doors_link} để chúng tôi tìm phương án giải + quyết. + text: Nếu đây không phải những tác phẩm của bạn, xin đừng xóa chúng đi! Hãy + liên lạc với Open Doors (%{open_doors_url}) và chúng tôi sẽ tìm phương án + giải quyết. + more_info: + ao3_news: Tin tức AO3 + contact_support: liên lạc với đội ngũ Hỗ Trợ của AO3 + faq_page: trang Hỏi Đáp + html: Bạn có thể tìm đọc thông báo về các đợt nhập lưu trữ dữ liệu gần đây + tại trang %{ao3_news_link} và tìm hiểm thêm thông tin tại %{faq_page_link} + hoặc %{tutorial_page_link} của dự án Open Doors. Với những vấn đề chưa được + giải đáp trong trang Hỏi Đáp và trang Hướng Dẫn, vui lòng %{contact_support_link}. + text: Bạn có thể đọc thông báo về việc nhập dữ liệu từ kho tàng khác tại Tin + Tức AO3 (%{news_url}), và đọc thêm thông tin tại Trang Hỏi Đáp của Cửa Mở + (%{open_doors_faq_url}) hoặc Trang Hướng dẫn (%{open_doors_tutorial_url}). + Với những câu hỏi chưa được giải đáp trong Trang Hướng Đáp, Trang Hướng + dẫn và email này, hãy liên lạc Ban Hỗ Trợ tại %{support_url}. + tutorial_page: trang Hướng Dẫn + other_works: + contact_open_doors: liên lạc với Cửa Mở + html: Nếu bạn còn những tác phẩm khác đã được nhập vào nhưng lại liên kết + với email bạn không còn đăng nhập được, hãy %{contact_open_doors_link} đính + kèm thông tin chứng minh bạn là người sáng tác. + text: Nếu bạn còn những tác phẩm khác đã được nhập vào nhưng lại liên kết + với email bạn không còn đăng nhập được, hãy liên lạc với Cửa Mở đính kèm + thông tin chứng minh bạn là người sáng tác. + questions: + contact_support: liên lạc Ban Hỗ Trợ của AO3 + html: Với những câu hỏi khác, hãy %{contact_support_link}. + text: Nếu bạn có câu hỏi nào khác, hãy liên lạc Ban Hỗ Trợ của AO3 tại %{support_url}. + redirects: + html: Để giữ danh sách đề cử và dấu trang, đường link những kho tàng được + nhập liệu có thể sẽ được chuyển hướng đến bản sao chép được nhập liệu của + những tác phẩm ấy trong một khoảng thời gian giới hạn (kiểm tra thông báo + về kho tàng để biết về thời gian). Nếu bạn đã đăng tải những tác phẩm này + và %{negation} dùng tính năng nhập liệu từ URL, tác phẩm đấy sẽ có 2 bản + trên AO3. + subject: "[%{app_name}] Tác phẩm đã đăng tải" + update_redirect: + contact_open_doors: liên lạc với Cửa Mở + html: Nếu bạn muốn Cửa Mở cập nhật đường link chuyển hướng sang tác phẩm đã + có sẵn của bạn, hãy xóa tác phẩm được nhập liệu, và %{contact_open_doors_link} + cùng tên tài khoản AO3, tên tài khoản trên kho tàng được nhập liệu của bạn, + tên và URL của tác phẩm mà bạn muốn được chuyển hướng đến. Nếu bạn có nhiều + tác phẩm cùng muốn chuyển hướng, bạn có thể liệt kê trong cùng một mail. + text: Nếu bạn muốn Cửa Mở cập nhật đường link chuyển hướng sang tác phẩm đã + có sẵn của bạn, hãy xóa tác phẩm được nhập liệu, và liên lạc với Cửa Mở + tại %{open_doors_url} cùng tên tài khoản AO3, tên tài khoản trên kho tàng + được nhập liệu của bạn, tên và URL của tác phẩm mà bạn muốn được chuyển + hướng đến. Nếu bạn có nhiều tác phẩm cùng muốn chuyển hướng, bạn có thể + liệt kê trong cùng một mail. + works_by: 'Những tác phẩm dưới đây được liên kết với email: %{email}' + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: Tất cả nhiệm vụ đã được gửi. + subject: Các nhiệm vụ đã được gửi + html: + received_message: 'Bạn có một tin nhắn về bộ sưu tập %{collection_link} của + bạn:' + text: + received_message: 'Bạn có một tin nhắn về bộ sưu tập "%{collection_title}" + (%{collection_url}) của bạn:' + creatorship_notification: + explanation: Nếu bạn là đồng tác giả của một tác phẩm nào đó, bút danh của bạn + sẽ được đưa vào danh sách tác giả của các chương mới, bất kể thiết lập cá + nhân của bạn về đồng sáng tác. Bạn cũng sẽ được liệt kê vào danh sách tác + giả trong mọi bộ tác phẩm có chứa tác phẩm này. + html: + creation: "%{creation_link} bởi %{pseud_links}" + edit_chapter: chỉnh sửa chương truyện + edit_series: chỉnh sửa bộ tác phẩm + remove_chapter: Nếu bị thêm nhầm hoặc không muốn được liệt kê là đồng tác + giả, bạn có thể %{edit_chapter_link} để loại bỏ mình khỏi danh sách tác + giả. + remove_series: Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là đồng tác + giả, bạn có thể %{edit_series_link} để loại bỏ mình khỏi danh sách tác giả. + intro_chapter: 'Người dùng %{adding_user} đã liệt kê bút danh %{pseud} của bạn + làm đồng tác giả của chương truyện sau:' + intro_series: 'Người dùng %{adding_user} đã thêm bút danh %{pseud} của bạn làm + đồng tác giả của bộ tác phẩm:' + subject: "[%{app_name}] Thông báo đồng sáng tác" + text: + creation: "%{title} (%{url}) bởi %{pseuds}" + remove_chapter: 'Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là đồng + tác giả, bạn có thể chỉnh sửa chương truyện để loại bỏ mình khỏi danh sách + tác giả: %{url}' + remove_series: 'Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là đồng + tác giả, bạn có thể chỉnh sửa bộ tác phẩm để loại bỏ mình khỏi danh sách + tác giả: %{url}' + creatorship_notification_archivist: + explanation: Người dùng này hiện đang là chuyên viên lưu trữ của Open Doors + (Cửa Mở), vì vậy, họ được phép đưa bạn vào tác phẩm mà không cần yêu cầu, + kể cả khi bạn đã tắt chức năng đồng sáng tác. + html: + creation: "%{creation_link} bởi %{pseud_links}" + edit_chapter: chỉnh sửa chương truyện + edit_series: chỉnh sửa bộ tác phẩm + edit_work: chỉnh sửa tác phẩm + remove_chapter: Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là tác giả, + bạn có thể %{edit_chapter_link} để loại bỏ mình khỏi danh sách tác giả + remove_series: Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là người + sáng tạo, bạn có thể %{edit_series_link} để loại bỏ mình khỏi danh sách + tác giả. + remove_work: Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là đồng tác + giả, bạn có thể %{edit_work_link} để loại bỏ mình khỏi danh sách đồng tác + giả. + intro_chapter: 'Người dùng %{archivist} đã thêm bút danh %{pseud} của bạn làm + đồng tác giả của chương truyện sau:' + intro_series: 'Người dùng %{archivist} đã thêm bút danh %{pseud} của bạn làm + đồng tác giả trong bộ tác phẩm sau:' + intro_work: 'Người dùng %{archivist} đã thêm bút danh %{pseud} của bạn làm đồng + tác giả của tác phẩm sau:' + subject: "[%{app_name}] Thông báo của chuyên viên lưu trữ về tư cách đồng tác + giả" + text: + creation: "%{title} (%{url}) bởi %{pseuds}" + remove_chapter: 'Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là đồng + tác giả, bạn có thể chỉnh sửa chương truyện để loại bỏ mình khỏi danh sách + tác giả: %{url}' + remove_series: 'Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là tác giả, + bạn có thể chỉnh sửa bộ tác phẩm để loại bỏ mình khỏi danh sách tác giả: + %{url}' + remove_work: 'Nếu bạn bị thêm nhầm hoặc không muốn được liệt kê là đồng tác + giả, bạn có thể chỉnh sửa tác phẩm để loại bỏ mình khỏi danh sách tác giả: + %{url}' + creatorship_request: + html: + creation: "%{creation_link} bởi %{pseud_links}" + instructions: Bạn có thể chấp nhận hoặc từ chối lời mời này tại trang %{page_name} + của bạn. + page_name: Co-Creator Requests (Lời Mời Hợp Tác) + intro_chapter: 'Người dùng %{inviting_user} đã mời bút danh %{pseud} của bạn + làm đồng tác giả của chương truyện sau:' + intro_series: 'Người dùng %{inviting_user} đã mời bút danh %{pseud} của bạn + làm đồng tác giả của bộ tác phẩm sau:' + intro_work: 'Người dùng %{inviting_user} đã mời bút danh %{pseud} của bạn làm + đồng tác giả của tác phẩm sau:' + subject: "[%{app_name}] Lời mời hợp tác" + text: + creation: "%{title} (%{url}) bởi %{pseuds}" + instructions: 'Bạn có thể chấp nhận hoặc từ chối lời mời này tại trang Co-Creator + Requests (Lời Mời Hợp Tác) của bạn: %{url}' + delete_work_notification: + attachment: Một bản sao tác phẩm của bạn được đính kèm nhằm phục vụ mục đích + tham khảo. + deleted_other: + html: Tác phẩm %{title} đã được xóa theo yêu cầu của %{pseud}. + text: Tác phẩm "%{title}" đã được xóa theo yêu cầu của %{pseud}. + deleted_yourself: + html: Tác phẩm %{title} đã được xóa theo yêu cầu của bạn. + text: Tác phẩm "%{title}" đã được xóa theo yêu cầu của bạn. + questions: + html: Nếu bạn có thắc mắc, vui lòng %{support}. + text: Nếu bạn có thắc mắc, vui lòng %{support} (%{url}). + subject: "[%{app_name}] Quản trị viên đã xóa tác phẩm của bạn" + support: liên hệ ban Hỗ Trợ Kỹ Thuật + invitation_to_claim: + access: + text: Tùy thuộc vào kho lưu trữ, các tác phẩm của bạn có thể đã được nhập + chỉ giới hạn cho người dùng đã đăng ký (để chúng không hiển thị trên các + tìm kiếm của Google). Trong trường hợp này, chỉ người dùng đã đăng nhập + có thể được truy cập vào tác phẩm trừ khi bạn chọn hiển thị chúng cho tất + cả mọi người. Nếu cần hỗ trợ mở khoá, tách riêng, hoặc xoá tác phẩm, vui + lòng liên hệ ban Hỗ trợ Kỹ thuật AO3. + claim_or_remove: + html: Nhận hoặc xóa tác phẩm của bạn ở đây. + text: 'Nhận hoặc xóa tác phẩm của bạn ở đây: %{claim_url}' + email_tips: Nếu bạn liên hệ với chúng tôi, vui lòng cho phép nhận email từ địa + chỉ @transformativeworks.org và kiểm tra mục thư rác để tìm phản hồi từ chúng + tôi. + html: + ao3_news: Tin tức AO3 + contact_open_doors: liên hệ Open Doors + contact_support: liên hệ ban Hỗ trợ Kỹ thuật AO3 + faq_page: trang Câu Hỏi Thường Gặp + tutorial_page: trang hướng dẫn + introduction: + text: Bạn nhận được e-mail này vì gần đây một kho lưu trữ đã được nhập vào + %{app_name} (%{app_short_name} - %{app_url}) bởi Cửa Mở (%{open_doors_link}), + và chúng tôi tin rằng các tác phẩm sau đây thuộc về bạn. Chúng tôi muốn + cho bạn cơ hội để nhận (hoặc xóa/tách riêng) những tác phẩm này nếu bạn + muốn. Nếu bạn chưa có tài khoản đăng ký dưới e-mail khác, chúng tôi muốn + mời bạn tạo tài khoản! + mistake: + text: Nếu chúng tôi nhầm lẫn và đây không phải tác phẩm của bạn, xin đừng + xóa chúng! Vui lòng liên hệ Open Doors (%{open_doors_link}) và chúng tôi + sẽ xử lý vấn đề này. + more_info: + text: Bạn có thể đọc thông báo về các lần nhập kho lưu trữ gần đây tại trang + tin tức của AO3 (%{news_link}), và tìm thêm thông tin ở trang FAQ (%{open_doors_faq_link}) + hoặc trang hướng dẫn (%{open_doors_tutorial_link}) của Open Doors. Đối với + bất kỳ câu hỏi nào không được trả lời trong trang FAQ, các hướng dẫn, hoặc + e-mail này, vui lòng liên hệ ban Hỗ trợ Kỹ thuật tại %{support_link}. + other_works: + text: Nếu bạn còn các tác phẩm nào khác trong kho lưu trữ được nhập dưới một + email bạn không thể truy cập được nữa, xin vui lòng liên hệ Open Doors với + bất kỳ thông tin nào có thể giúp xác minh danh tính của bạn. + questions: + text: Nếu còn thắc mắc nào khác, vui lòng liên hệ ban Hỗ trợ Kỹ thuật AO3 + tại %{support_link}. + redirects: Để lưu danh sách đề xuất và tác phẩm được đánh dấu, các địa chỉ của + kho lưu trữ đã nhập có thể sẽ chuyển hướng đến bản sao đã nhập của các tác + phẩm này trong một khoảng thời gian giới hạn (xem bài thông báo về kho lưu + trữ của bạn để xác nhận). Nếu bạn đã tải lên bản sao của các tác phẩm này + và bạn KHÔNG sử dụng tính năng nhập từ URL, sẽ có hai bản sao của cùng một + tác phẩm trong kho lưu trữ. + subject: "[%{app_name}] Lời mời nhận tác phẩm" + unwanted: + text: Nếu những tác phẩm này thuộc về bạn nhưng bạn không muốn nhận chúng, + bạn có thể tách riêng (chúng sẽ vẫn tồn tại trên AO3, nhưng bút danh của + bạn sẽ được xóa) hoặc xóa chúng (chúng sẽ bị gỡ bỏ hoàn toàn khỏi AO3). + Bạn không cần thêm tác phẩm vào bất kỳ tài khoản nào để tách riêng hoặc + xóa chúng - bạn có thể thực hiện việc này trực tiếp qua đường link nhận + tác phẩm ở trên. (Nếu cần trợ giúp, xin liên lạc ban Hỗ trợ qua %{support_link}.) + update_redirect: + text: Nếu bạn muốn Open Doors cập nhật đường link chuyển hướng để dẫn đến + tác phẩm đã có trước đó của bạn, vui lòng xóa bản copy đã được nhập và liên + lạc Open Doors qua %{open_doors_link} với tên tài khoản AO3 của bạn, tên + tài khoản của bạn trên kho lưu trữ đã được nhập, cùng với tiêu đề và URL + của tác phẩm bạn muốn chuyển hướng đến. (Nếu bạn muốn đổi đường link chuyển + hướng cho nhiều tác phẩm, bạn có thể liệt kê chúng trong cùng một email.) + uploaded_list: 'Tác phẩm được đăng tải bao gồm:' + invite_increase_notification: + html: + body: + other: 'Chúng tôi xin thông báo: bạn hiện đang có %{count} thư mời mới có + thể sử dụng để tạo tài khoản mới ở AO3. Bạn có thể gửi thư mời cho bạn + bè qua %{invitation_page_link}.' + invitation_page_link_text: trang Invitations (Thư Mời) của mình + subject: "[%{app_name}] Thư mời mới" + text: + body: + other: 'Chúng tôi xin thông báo: bạn hiện đang có %{count} thư mời mới có + thể sử dụng để tạo tài khoản mới ở AO3. Bạn có thể gửi thư mời cho bạn + bè qua %{invitation_page_url}.' + invite_request_declined: + main: + other: 'Chúng tôi rất tiếc phải thông báo: chúng tôi không thể thực hiện yêu + cầu thêm %{count} thư mời mới của bạn tại thời điểm này.' + reason: 'Yêu cầu của bạn là:' + subject: "[%{app_name}] Từ chối Yêu cầu Thêm Thư mời" + recipient_notification: + html: + collection: Một tác phẩm dành tặng bạn đã được đăng tải trong bộ sưu tập %{collection_link} + tại AO3! + no_collection: Một tác phẩm dành tặng bạn đã được đăng tải trên AO3! + subject: + collection: "[%{app_name}][%{collection_title}] Một tác phẩm dành tặng bạn + trong %{collection_title}" + no_collection: "[%{app_name}] Một tác phẩm dành tặng bạn" + text: + collection: Một tác phẩm dành tặng bạn đã được đăng tải trong bộ sưu tập"%{collection_title}" + (%{collection_url}) tại AO3! + signup_notification: + activate: + html: Hãy %{activate_account_link}. + text: 'Hãy đi theo đường link để kích hoạt tài khoản của bạn: %{activate_account_url}' + activate_your_account: theo đường link này để kích hoạt tài khoản của bạn + admin_posts: Tin tức AO3 + bye: Chúng tôi mong rằng bạn sẽ có trải nghiệm tốt nhất với AO3. + contact_support: liên hệ đội ngũ Hỗ trợ của chúng tôi + faq: FAQ + features: + html: Một khi tài khoản của bạn được xác nhận, bạn có thể đăng tác phẩm của + bạn, đăng kí theo dõi qua email để nhận được thông báo mỗi khi tác giả/tác + phẩm yêu thích của bạn có chương mới, cài đặt giao diện mới cho trang web, + lưu lại những tác phẩm bạn đã truy cập qua AO3 ở mục lịch sử, và nhiều hơn + thế. + text: Một khi tài khoản của bạn được xác nhận, bạn sẽ có thể đăng tác phẩm + của bạn, đăng kí theo dõi qua email để nhận được thông báo mỗi khi tác giả/tác + phẩm yêu thích của bạn có chương mới, cài đặt giao diện mới cho trang web, + lưu lại những tác phẩm bạn đã truy cập trên AO3 ở mục lịch sử, và nhiều + hơn thế. + information: + html: Có rất nhiều thông tin và lời khuyên về cách sử dụng AO3 trong mục %{faq_link}. + Bạn có thể tìm đọc những tin tức mới về quá trình phát triển trang web tại + mục %{admin_posts_link}. Nếu bạn cần trợ giúp, gặp trục trặc khi sử dụng + web, hoặc có câu hỏi hay lời góp ý nào, hãy %{contact_support_link}. Chúng + tôi luôn sẵn lòng giúp đỡ. + text: 'Xem thông tin thêm và hướng dẫn sử dụng Kho tàng trong mục ‘Những câu + hỏi thường gặp’ %{faq_url}. Bạn có thể tìm đọc những tin tức mới về quá + trình phát triển trang web ở mục AO3 News (Tin tức AO3) tại %{admin_posts_url}. + Nếu bạn cần giúp đỡ, gặp trục trặc khi sử dụng trang web, hoặc có câu hỏi + hay lời góp ý nào, hãy liên hệ đội ngũ Hỗ trợ của chúng tôi. Chúng tôi luôn + sẵn lòng giúp đỡ: %{contact_support_url}.' + welcome: Chào mừng đến với AO3, %{login}! diff --git a/config/locales/phrase-exports/zh-CN.yml b/config/locales/phrase-exports/zh-CN.yml new file mode 100755 index 0000000..729bc83 --- /dev/null +++ b/config/locales/phrase-exports/zh-CN.yml @@ -0,0 +1,360 @@ +--- +zh-CN: + activerecord: + attributes: + archive_warning: + name_with_colon: + other: 警告: + category: + name_with_colon: + other: 性向/性向分类: + character: + name_with_colon: + other: 角色: + fandom: + name_with_colon: + other: 同人圈: + freeform: + name_with_colon: + other: 其他标签: + rating: + name_with_colon: 分级: + relationship: + name_with_colon: + other: 配对: + work: + chapter_total_display: 章节 + summary: 简介 + models: + archive_warning: + other: 警告 + category: + other: 性向/性向分类 + chapter: + other: 章节 + character: + other: 角色 + fandom: + other: 同人圈 + freeform: + other: 其他标签 + rating: + other: 分级 + relationship: + other: 配对 + series: + other: 系列 + kudo_mailer: + batch_kudo_notification: + guest: + other: "%{count}名访客" + left_kudos: + html: + other: "%{givers_list}给您的作品%{commentable_link}点了赞。" + text: + other: "%{givers_list}给您的作品%{commentable_title}(%{commentable_url})点了赞。" + single_guest: + giver: 一名访客 + html: "%{giver}给您的作品%{commentable_link}点了赞。" + text: 一名访客给您的作品%{commentable_title}(%{commentable_url})点了赞。 + subject: "[%{app_name}] 您收到了点赞!" + layouts: + proxy_notice: + faux_heading: 重要提示: + point1: 您使用的是第三方开发的反向代理网站,此网站并非Archive of Our Own - AO3(AO3作品库)原站。 + point2: 代理网站的开发者能够获取您上传至该站点的全部内容,包括您的ip地址。如您通过代理登录AO3,对方将获得您的密码。 + mailer: + general: + closing: + formal: 此致敬礼 + informal: 祝好 + creation: + link_with_word_count: "%{creation_link}(%{word_count})" + title_with_chapter_number: "%{title}的第%{position}章" + title_with_word_count: '"%{creation_title}"(%{word_count})' + word_count: + other: "%{count} 字符" + footer: + general: + about: + html: AO3是由同人爱好者运作及支持、并由%{donate_link}资助运行的作品库。 + text: AO3是由同人爱好者运作及支持、并由您的捐赠资助运行的作品库:%{donate_url}。 + html: + donate_link_text: 您的捐赠 + support_link_text: 联系支持团队 + unwanted_email: + html: 如果这封邮件被误发给了您,请%{support_link}。 + text: 如果这封邮件被误发给了您,请于此联系支持团队:%{support_url}。 + sent_at: 于%{sent_at}发送。 + greeting: + formal_html: 尊敬的%{name}, + informal: + addressed_html: 您好,%{name}! + unaddressed: 您好! + introductory: Archive of Our Own – AO3(AO3作品库)向您问好! + metadata_label_indicator: ":" + signature: + abuse_team: AO3条款执行和违规行为处理团队 + app_short_name: AO3 + open_doors: Open Doors(Open Doors拯救计划)团队 + parent_org: Organization for Transformative Works – OTW(OTW再创作组织) + support: AO3支持委员会团队 + users: + mailer: + reset_password_instructions: + expiration: 此链接一周后失效,如果您届时仍未修改密码,则需要申请新的链接。 + intro: 有人提出了重设您的账号密码的申请。您可以进入下方的链接对密码进行更改: + link_title: 更改我的密码。 + subject: "[%{app_name}] 重设您的密码" + unrequested: 如果您没有申请重设密码,请忽略此邮件,继续使用您原本的密码。 + user_mailer: + admin_deleted_work_notification: + bye: 附件中为该作品副本,以供参考。 + contact_abuse: 联系条款执行与违反行为处理委员会 + deleted: + html: 您的作品%{title}已被网站管理员从AO3作品库中删除。 + text: 网站管理员从AO3作品库中删除您的作品%{title}。 + html: + tos_violation: 如果您的作品违反了AO3作品库的网站服务条款,请%{contact_abuse_link}。 + import_project: + html: 如果您的作品属于Open Doors(Open Doors拯救计划)的导入项目,请%{opendoors_link}提出有关疑问。 + text: 如果您的作品属于Open Doors(Open Doors拯救计划)的导入项目,请联系Open Doors拯救计划(%{opendoors_link})。 + opendoors: 联系Open Doors拯救计划 + subject: "[%{app_name}] 您的作品已被管理员删除" + text: + tos_violation: 如果您的作品违反了AO3作品库的网站服务条款,请联系条款执行和违反行为处理委员会(%{contact_abuse_url})。 + admin_hidden_work_notification: + access: 在作品被隐藏期间,您依然可以通过上方链接访问该作品,但它将不会显示在您的作品页,且其他AO3用户将无法访问。 + check_email: 条款执行和违反行为处理委员会可能已经联系您并对您作品被隐藏的原因进行了解释,因此请检查您的邮箱,包括垃圾邮件列表。 + contact_abuse: 联系条款执行和违反行为处理委员会 + html: + help: 如果您不确定为什么您的作品会被隐藏,并且没有收到有关此事的进一步联系,请直接%{contact_abuse_link}。 + hidden: 您的作品%{title}已被条款执行和违反行为处理委员会隐藏且无法再被公开访问。 + tos_violation: 如果您的作品是因为违反AO3的%{tos_link}而被隐藏,您会被要求采取行动以纠正违规行为。如果您无法让您的作品符合服务条款,您的作品可能会被从AO3作品库中删除。 + subject: "[%{app_name}] 您的作品已被条款执行和违反行为处理委员会隐藏" + text: + help: 如果您不确定为什么您的作品会被隐藏,并且没有收到有关此事的进一步联系,请直接联系条款执行和违反行为处理委员会:%{contact_abuse_url}。 + hidden: 您的作品"%{title}"(%{work_url})已被条款执行和违反行为处理委员会隐藏且无法再被公开访问。 + tos_violation: 如果您的作品是因为违反AO3的服务条款(%{tos_url})而被隐藏,您会被要求采取行动以纠正违规行为。如果您无法让您的作品符合服务条款,您的作品可能会被从AO3作品库中删除。 + tos: 服务条款 + anonymous_or_unrevealed_notification: + anonymous_info: 匿名作品在标签列表中可见,但不会显示在您的作品页面上。在作品页,您的用户名将被替换为"Anonymous"(佚名)。 + anonymous_unrevealed_info: 管理员随后可能会公开您的作品,但仍保留匿名。订阅您账户的用户不会收到相关改动提示。作品一经公开,即会被收录到标签列表中,但不会显示在您的作品页面。在作品页,您的用户名将被替换为"Anonymous"(佚名)。 + changed_status: + anonymous: + html: 作品集%{collection_link}的管理员已将您的作品%{work_link}设为匿名状态。 + text: 作品集%{collection_title}(%{collection_url})的管理员已将您的作品%{work_title}(%{work_url})设为匿名状态。 + anonymous_unrevealed: + html: 作品集%{collection_link}的管理员已将您的作品%{work_link} 设为匿名与非公开状态. + text: 作品集%{collection_title}(%{collection_url})的管理员已将您的作品%{work_title}(%{work_url})设为匿名与非公开状态。 + unrevealed: + html: 作品集%{collection_link}的管理员已将您的作品%{work_link}设为非公开状态。 + text: 作品集%{collection_title}(%{collection_url})的管理员已将您的作品%{work_title}(%{work_url})设为非公开状态。 + collection_items_link_text: Approved Collection Items(已通过作品集条目)页 + do_not_want: + anonymous: + html: 如果您想取消作品的匿名状态,请访问%{collection_items_link}将其从该作品集中移除。 + text: 如果您不希望作品保持匿名状态,请访问Approved Collection Items(已通过作品集条目)页,将其从该作品集中移除:%{collection_items_url} + anonymous_unrevealed: + html: 如果您不希望您的作品保持匿名与非公开状态,请访问%{collection_items_link}将其从作品集中移除。 + text: 如果您不希望作品保持匿名与非公开状态,请访问Approved Collection Items(已通过作品集条目)页,将其从该作品集中移除:%{collection_items_url} + unrevealed: + html: 如果您不希望您的作品保持非公开状态,请访问%{collection_items_link}将其从作品集中移除。 + text: 如果您不希望作品保持非公开状态,请访问Approved Collection Items(已通过作品集条目)页,将其从该作品集中移除:%{collection_items_url} + faq_link_text: 同人作品集常见问题 + more_info: + html: 详情请查阅%{faq_link}。 + text: 详情请查阅同人作品集常见问题:%{faq_url} + subject: + anonymous: "[%{app_name}] 您的作品被设为匿名状态" + anonymous_unrevealed: "[%{app_name}] 您的作品被设为匿名与非公开状态" + unrevealed: "[%{app_name}] 您的作品被设为非公开状态" + unrevealed_info: 非公开作品不会显示在标签列表或您的作品页面上。如果点击作品链接,用户将收到一则提示:作品当前未公开,无法获取内容。 + archivist_added_to_collection_notification: + approved_collection_items_page: Approved Collection Items (已批准作品集的作品) 页面 + archivist_notice: 因为作品集维护员拥有Open Doors (Open Doors拯救计划) 作品库管理员官方身份,所以即使您禁用了作品集邀请,他们也可以将您的作品添加到此作品集中。管理员只会将被导入作品库中的作品添加到作品集中。 + removal_instructions: + html: 如果您想从此作品集中删除您的作品,请访问您的%{approved_items_link}。 + text: 如果您想从此作品集中删除您的作品,请访问您的Approved Collection Items (已批准作品集的作品) 页面:%{approved_items_url}. + subject: "[%{app_name}][%{collection_title}]一位Open Doors (Open Doors拯救计划) 作品库管理员已将您的作品添加到一个作品集。" + work_added: + html: "%{collection_link}的作品集维护员已将您的作品%{work_link} 添加到他们的作品集。" + text: '"%{collection_title}" (%{collection_url})的作品集维护员已将您的作品"%{work_title}"(%{work_url})添加到他们的作品集!' + challenge_assignment_notification: + any: 任意 + assignment: + html: 您在AO3的%{link}写手挑战中收到了以下点文! + description: 描述: + due: 本篇点文的截止日期为: + html: + footer: 您之所以会收到这封邮件,是因为您报名参加了%{title}写手挑战。如果想了解本次挑战的相关信息以及管理员的联系方式,请前往%{footer_link}。 + footer_link: 写手挑战详情页面 + look_up: 查看本篇点文详情,请前往%{link}。 + look_up_link: 您的Assignments(点文)页面 + optional_tags: 可选标签: + prompts: 点梗: + prompt_url: 点梗链接: + recipient: 受赠者: + recipient_missing: 无受赠者:请联系写手挑战管理员。 + subject: "[%{app_name}][%{collection_title}] 您的点文!" + text: + assignment: 您在AO3的%{collection_title}写手挑战(%{collection_url})中收到了以下点文! + footer: 您之所以会收到这封邮件,是因为您报名参加了%{title}写手挑战(%{url})。如果您想了解本次挑战的相关信息以及管理员的联系方式,请前往%{profile_url}。 + look_up: 查看本篇点文详情,请前往您的Assignments(点文)页面%{link}。 + change_email: + changed: + html: "%{login},与您账号关联的邮箱地址已改为 %{email}" + text: "%{login},与您账号关联的邮箱地址已改为 %{email}" + subject: "[%{app_name}] 邮箱地址更换" + claim_notification: + access: + contact_support: 联系AO3支持委员会 + html: 出于被搬运作品库的要求,您的作品被搬运至AO3后可能仅向登录用户开放(以防它们出现在谷歌检索结果中)。在这种情况下,除非您选择面向所有访客打开权限,否则仅登录用户可以查看这些作品。关于如何解锁、遗弃或删除您的作品,请%{contact_support_link}。 + text: 出于被搬运作品库的要求,您的作品被搬运至AO3后可能仅向登录用户开放(以防它们出现在谷歌检索结果中)。在这种情况下,除非您选择面向所有访客打开权限,否则仅登录用户可以查看这些作品。关于如何解锁、遗弃或删除您的作品,请使用%{support_url},联系AO3支持委员会。 + email_tips: 如欲与我们取得联系,请将使用@transformativeworks.org这一域名的电邮地址添加至安全联系人列表,并检查您的垃圾邮件确认其中是否有我们的回复。 + introduction: + ao3_name: Archive of Our Own – AO3(AO3作品库) + html: 本邮件旨在通知您,包含您作品的同人作品库已被%{open_doors_name_link}搬运至 %{app_link}。由于此电邮地址与被搬运作品库的注册用户相关联,相关同人作品(如下)已被自动添加至您的AO3账号。 + open_doors_name: Open Doors(Open Doors拯救计划) + text: 本邮件旨在通知您,包含您作品的同人作品库已被Open Doors(Open Doors拯救计划)(%{open_doors_url})搬运至Archive + of Our Own – AO3(AO3作品库):%{app_url}。由于此电邮地址与被搬运作品库的注册用户相关联,相关同人作品(如下)已被自动添加至您的AO3账号。 + mistake: + contact_open_doors: 联系Open Doors拯救计划 + html: 如果存在错误,并且下列作品并非您的作品,请勿将其删除!请%{contact_open_doors_link},我们会帮助您解决。 + text: 如果存在错误,并且下列作品并非您的作品,请勿将其删除!请联系Open Doors拯救计划(%{open_doors_url}),我们会帮助您解决。 + more_info: + ao3_news: AO3新闻 + contact_support: 联系AO3支持委员会 + faq_page: 常见问题页面 + html: 您可以点击%{ao3_news_link}阅读近期的作品库搬运公告,亦可前往Open Doors拯救计划的%{faq_page_link}或%{tutorial_page_link}了解更多信息。对于常见问题、教程或此封邮件中未予解答的任何问题,请%{contact_support_link}。 + text: 您可以点击AO3新闻(%{news_url})阅读近期的作品库搬运公告,亦可前往Open Doors拯救计划的常见问题页面(%{open_doors_faq_url})或教程页面(%{open_doors_tutorial_url}),了解更多信息。对于常见问题、教程或此封邮件中未予解答的任何问题,请使用%{support_url}联系支持委员会。 + tutorial_page: 教程页面 + other_works: + contact_open_doors: 联系Open Doors拯救计划 + html: 如果您在被搬运作品库还拥有其他作品,但已无法访问上传时所用的电邮地址,请%{contact_open_doors_link}并提供任何有助于核验您身份的信息。 + text: 如果您在被搬运作品库还拥有其他作品,但已无法访问上传时所用的电邮地址,请联系Open Doors拯救计划并提供任何有助于核验您身份的信息。 + questions: + contact_support: 联系AO3支持委员会 + html: 如有其他疑问,请%{contact_support_link}。 + text: 如有其他疑问,请使用%{support_url}联系AO3支持委员会。 + redirects: + html: 为保留推荐列表和收藏,在有限的时间内,被搬运作品库的网址可能会被重定向至这些作品在AO3上的搬运副本(请查阅作品库搬运公告帖确认具体情况)。如果您已上传这些作品的副本,并且%{negation}使用"通过URL地址搬运"这一功能,同一作品在AO3上将有两份副本。 + subject: "[%{app_name}]作品上传通知" + update_redirect: + contact_open_doors: 联系Open Doors拯救计划 + html: 如果您希望由Open Doors拯救计划来更新重定向链接,导向您自行上传的作品副本,请删除搬运副本,并%{contact_open_doors_link},说明您的AO3账号用户名、您在被搬运作品库使用的用户名,以及希望重定向链接导向的同人作品标题和URL地址。(如果涉及多份作品,您可以在同一封邮件中全部列出。) + text: 如果您希望由Open Doors拯救计划来更新重定向链接,导向您已自行上传的作品副本,请删除搬运副本,并使用%{open_doors_url}联系Open + Doors拯救计划,说明您的AO3账号用户名、您在被搬运作品库使用的用户名,以及希望重定向链接导向的同人作品标题和URL地址。(如果涉及多份作品,您可以在同一封邮件中全部列出。) + works_by: 此邮箱(%{email})关联的作品如下: + work_info: + html: "%{work_link} (%{fandom})" + text: + no_fandom: "- %{work_title} %{work_url}" + with_fandom: "- %{work_title} %{work_url} (%{fandom})" + collection_notification: + assignments_sent: + complete: 所有任务已发送。 + subject: 任务已发送 + html: + received_message: 您收到一则有关您的作品集%{collection_link}的信息: + text: + received_message: 您收到一则有关您的作品集"%{collection_title}"(%{collection_url})的信息: + creatorship_notification: + explanation: 作为某一作品的共同创作者, 无论您在个人设置中是否允许他人邀请您成为共同创作者,您都可能被列为该作品新章节的创作者, 也会被列为该作品所属系列的创作者之一。 + html: + creation: 由%{pseud_links}所作的%{creation_link} + edit_chapter: 编辑章节 + edit_series: 编辑系列 + remove_chapter: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过%{edit_chapter_link}将自己从创作者名单中移除。 + remove_series: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过%{edit_series_link}将自己从创作者名单中移除。 + intro_chapter: 用户%{adding_user}将您 以别名%{pseud}列为了下述章节的共同创作者: + intro_series: 用户%{adding_user}将您以别名%{pseud}列为了下述系列的共同创作者: + subject: "[%{app_name}] 共同创作者提示" + text: + creation: 由%{pseuds}所作的%{title}(%{url}) + remove_chapter: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过编辑章节将自己从创作者名单中移除:%{url} + remove_series: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过编辑系列将自己从创作者名单中移除:%{url} + creatorship_notification_archivist: + explanation: 该用户作为Open Doors(Open Doors拯救计划)的作品库管理员,在相关工作需要时,可在不发送请求的情况下将您添加为共同创作者,即使您可能在个人设置中禁止了其他用户邀请您成为共同创作者。 + html: + creation: "%{creation_link},作者:%{pseud_links}" + edit_chapter: 编辑章节 + edit_series: 编辑系列 + edit_work: 编辑作品 + remove_chapter: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过%{edit_chapter_link},将自己从创作者名单中移除。 + remove_series: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过%{edit_series_link}将自己从创作者名单中移除。 + remove_work: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过%{edit_work_link},将自己从创作者名单中移除。 + intro_chapter: 用户%{archivist} 已将您以别名%{pseud}添加为下述章节的共同创作者: + intro_series: 用户%{archivist} 已将您以别名%{pseud}添加为下述系列的共同创作者: + intro_work: 用户%{archivist}已将您以别名%{pseud}添加为下述作品的共同创作者: + subject: "[%{app_name}]档案管理员添加共同创作者通知" + text: + creation: "%{title}(%{url}),作者:%{pseuds}" + remove_chapter: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过编辑章节将自己从创作者名单中移除:%{url} + remove_series: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过编辑系列将自己从创作者名单中移除:%{url} + remove_work: 如果您被误列为共同创作者,或者不想被列为创作者之一,您可以通过编辑作品将自己从创作者名单中移除:%{url} + creatorship_request: + html: + creation: 由%{pseud_links}所作的%{creation_link} + instructions: 您可以在您的%{page_name}页面接受或拒绝此邀请。 + page_name: Co-Creator Requests(共同创作者邀请) + intro_chapter: 用户%{inviting_user}向您发送了一则邀请,希望将您以别名%{pseud}列为下述章节的共同创作者: + intro_series: 用户%{inviting_user}向您发送了一则邀请,希望将您以别名%{pseud}列为下述系列的共同创作者: + intro_work: 用户%{inviting_user}向您发送了一则邀请,希望将您以别名%{pseud}列为下述作品的共同创作者: + subject: "[%{app_name}] 共同创作者邀请" + text: + creation: 由%{pseuds}所作的%{title}(%{url}) + instructions: 您可以在您的Co-Creator Requests(共同创作者邀请)页面接受或拒绝此邀请:%{url} + delete_work_notification: + attachment: 附件中为该作品副本,以供参考。 + deleted_other: + html: 应%{pseud}的要求,您的作品%{title}已被删除。 + text: 应%{pseud}的要求,您的作品%{title}已被删除。 + deleted_yourself: + html: 应您的要求,您的作品%{title}已被删除。 + text: 应您的要求,您的作品%{title}已被删除。 + questions: + html: 如果您有任何疑问,请%{support}。 + text: 如果您有任何疑问,请%{support} (%{url})。 + subject: "[%{app_name}] 您的作品已被删除" + support: 联系支持委员会 + invite_increase_notification: + html: + body: + other: 我们想通知您,您有%{count}份新邀请帖,该邀请帖用于创建AO3作品库的新帐户。您可以在%{invitation_page_link}邀请朋友。 + invitation_page_link_text: 您的Invitations(邀请帖)页面 + subject: "[%{app_name}] 新邀请帖" + text: + body: + other: 我们想通知您,您有%{count}份新邀请帖,该邀请帖用于创建AO3作品库的新帐户。您可以在(%{invitation_page_url})邀请朋友。 + invite_request_declined: + main: + other: 我们很遗憾地通知您,您提出的%{count}份新邀请码申请未能获批。 + reason: 您的申请为: + subject: "[%{app_name}] 额外邀请码申请拒函" + recipient_notification: + html: + collection: 您在AO3上收到了一篇来自于作品集 %{collection_link} 的赠文! + no_collection: 您在AO3上收到了一篇赠文! + subject: + collection: "[%{app_name}][%{collection_title}]来自于作品集 %{collection_title} + 的赠文" + no_collection: "[%{app_name}]您收到了一篇赠文" + text: + collection: 您在AO3上收到了一篇来自于作品集%{collection_title} (%{collection_url})的赠文! + signup_notification: + activate: + html: 请%{activate_account_link}。 + text: 请点击以下链接激活您的账户: %{activate_account_url} + activate_your_account: 点击以下链接激活您的账户 + admin_posts: AO3新闻 + bye: 祝您使用愉快。 + contact_support: 联系支持委员会 + faq: 常见问题 + features: + html: 激活账户后,即可使用本站诸多功能,包括发布同人作品;设置邮件订阅,在喜爱的创作者或作品更新时获取即时通知;进行偏好设置,定制网站界面和操作方式;保留浏览历史,追踪之前在AO3上阅读的作品。 + text: 激活账户后,即可使用本站诸多功能,包括发布同人作品;设置邮件订阅,在喜爱的创作者或作品更新时获取即时通知;进行偏好设置,定制网站界面和操作方式;保留浏览历史,追踪之前在AO3上阅读的作品。 + information: + html: 您可浏览本站%{faq_link},详细了解关于AO3使用方法的信息与建议;进入%{admin_posts_link}板块,了解网站建设的最新消息。如您需要更多帮助,遇到程序漏洞,存在疑问或想提出意见,请%{contact_support_link},该团队将竭诚为您服务。 + text: 您可浏览本站%{faq_url},详细了解关于AO3使用方法的信息与建议;进入%{admin_posts_url}板块,了解网站建设的最新消息。如您需要更多帮助,遇到程序漏洞,存在疑问或想提出意见,请%{contact_support_url},该团队将竭诚为您服务。 + welcome: 欢迎来到AO3, %{login}! diff --git a/config/locales/rails-i18n/locale/fil.yml b/config/locales/rails-i18n/locale/fil.yml new file mode 100755 index 0000000..68fe74a --- /dev/null +++ b/config/locales/rails-i18n/locale/fil.yml @@ -0,0 +1,202 @@ +--- +fil: + activerecord: + errors: + messages: + record_invalid: 'Nabigo ang pagpapatunay: %{errors}' + date: + abbr_day_names: + - Lin + - Lun + - Mar + - Miy + - Huw + - Biy + - Sab + abbr_month_names: + - + - Ene + - Peb + - Mar + - Abr + - May + - Hun + - Hul + - Ago + - Set + - Okt + - Nob + - Dis + day_names: + - Linggo + - Lunes + - Martes + - Miyerkules + - Huwebes + - Biyernes + - Sabado + formats: + default: "%d/%m/%Y" + long: ika-%d ng %B, %Y + short: ika-%d ng %b + month_names: + - + - Enero + - Pebrero + - Marso + - Abril + - Mayo + - Hunyo + - Hulyo + - Agosto + - Setyembre + - Oktubre + - Nobyembre + - Disyembre + order: + - :year + - :month + - :day + datetime: + distance_in_words: + about_x_hours: + one: humigit-kumulang isang oras + other: humigit-kumulang %{count} oras + about_x_months: + one: humigit-kumulang isang buwan + other: humigit-kumulang %{count} buwan + about_x_years: + one: humigit-kumulang isang taon + other: humigit-kumulang %{count} taon + almost_x_years: + one: halos isang taon + other: halos %{count} taon + half_a_minute: kalahating minuto + less_than_x_seconds: + one: mas mababa sa isang segundo + other: mas mababa sa %{count} segundo + less_than_x_minutes: + one: mas mababa sa isang minuto + other: mas mababa sa %{count} minuto + over_x_years: + one: higit sa isang taon + other: higit %{count} taon + x_seconds: + one: isang segundo + other: "%{count} segundo" + x_minutes: + one: isang minuto + other: "%{count} minuto" + x_days: + one: isang araw + other: "%{count} araw" + x_months: + one: isang buwan + other: "%{count} buwan" + prompts: + second: segundo + minute: minuto + hour: oras + day: araw + month: buwan + year: taon + errors: + format: "%{attribute} ay %{message}" + messages: + accepted: dapat na tanggapin + blank: hindi maaaring walang laman + confirmation: hindi tumutugma ang pagpapatunay + empty: hindi maaaring walang laman + equal_to: dapat na katumba sa %{count} + even: dapat maging even + exclusion: nakalaan na + greater_than: dapat na mas higit sa %{count} + greater_than_or_equal_to: dapat na mas higit sa o katumbas ng %{count} + inclusion: hindi kasama sa listahan + invalid: hindi wasto + less_than: dapat na mas mababa sa %{count} + less_than_or_equal_to: dapat na mas mababa sa o katumbas ng %{count} + not_a_number: hindi isang numero + not_an_integer: dapat na isang integer + odd: dapat maging odd + taken: ginagamit na + too_long: + one: masyadong mahaba (pinakamadami ay %{count} character) + other: masyadong mahaba (pinakamadami ay %{count} character) + too_short: + one: masyadong maikli (pinakakonti ay %{count} character) + other: masyadong maikli (pinakakonti ay %{count} character) + wrong_length: + one: ang maling haba (ito ay dapat eksaktong %{count} character) + other: ang maling haba (ito ay dapat eksaktong %{count} character) + template: + body: 'May mga problema sa mga sumusunod na patlang:' + header: + one: hindi maaaring i-save ang %{model} na ito dahil sa isang error + other: hindi maaaring i-save ang %{model} na ito dahil sa %{count} error + helpers: + select: + prompt: Mangyaring pumili + submit: + create: lumikha ng %{model} + submit: isumite ang %{model} + update: i-update ang %{model} + number: + currency: + format: + delimiter: "," + format: "%n %u" + precision: 2 + separator: "." + significant: false + strip_insignificant_zeros: false + unit: "₱" + format: + delimiter: "," + precision: 3 + separator: "." + significant: false + strip_insignificant_zeros: false + human: + decimal_units: + format: "%n %u" + units: + billion: bilyon + million: milyon + quadrillion: kuwadrilyon + thousand: libo + trillion: trilyon + unit: '' + format: + delimiter: '' + precision: 1 + significant: true + strip_insignificant_zeros: true + storage_units: + format: "%n %u" + units: + byte: + one: Byte + other: Bytes + gb: GB + kb: KB + mb: MB + tb: TB + percentage: + format: + delimiter: '' + precision: + format: + delimiter: '' + support: + array: + last_word_connector: ", at" + two_words_connector: " at " + words_connector: "," + time: + am: AM + formats: + default: "%A, ika-%d ng %B ng %Y %H:%M:%S %z" + long: ika-%d ng %B ng %Y %H:%M + short: "%d ng %b %H:%M" + pm: PM \ No newline at end of file diff --git a/config/locales/rails-i18n/locale/mr.yml b/config/locales/rails-i18n/locale/mr.yml new file mode 100755 index 0000000..515126f --- /dev/null +++ b/config/locales/rails-i18n/locale/mr.yml @@ -0,0 +1,207 @@ +--- +mr: + activerecord: + errors: + messages: + record_invalid: 'प्रमाणीकरण अयशस्वी: %{errors}' + restrict_dependent_destroy: + has_one: अवलंबून %{record} अस्तित्वात असल्याने रेकॉर्ड हटवू शकत नाही + has_many: अवलंबून %{record} अस्तित्वात असल्याने रेकॉर्ड हटवू शकत नाही + date: + abbr_day_names: + - सोम + - मंगळ + - बुध + - गुरु + - शुक्र + - शनि + - रवि + abbr_month_names: + - + - जाने + - फेब्रु + - मार्च + - एप्रि + - मे + - जून + - जुलै + - ऑग + - सेप्टें + - ऑक्टोबर + - नोव्हें + - डिसे + day_names: + - सोमवार + - मंगळवार + - बुधवार + - गुरुवार + - शुक्रवार + - शनिवार + - रविवार + formats: + default: "%d-%m-%Y" + long: "%d %B %Y" + short: "%d %b" + month_names: + - + - जानेवारी + - फेब्रुवारी + - मार्च + - एप्रिल + - मे + - जून + - जुलै + - ऑगस्ट + - सप्टेंबर + - ऑक्टोबर + - नोव्हेंबर + - डिसेंबर + order: + - :day + - :month + - :year + datetime: + distance_in_words: + about_x_hours: + one: सुमारे एक तास + other: सुमारे %{count} तास + about_x_months: + one: सुमारे %{count} महीना + other: सुमारे %{count} महिना + about_x_years: + one: सुमारे %{count} वर्ष + other: सुमारे %{count} वर्ष + almost_x_years: + one: जवळजवळ एक वर्ष + other: जवळजवळ %{count} वर्ष + half_a_minute: अर्धा मिनिट + less_than_x_seconds: + one: एक सेकंद पेक्षा कमी + other: "%{count} सेकंद पेक्षा कमी" + less_than_x_minutes: + one: एका मिनिटापेक्षा कमी + other: "%{count} मिनिटापेक्षा कमी" + over_x_years: + one: एका वर्षापेक्षा जास्त काळ + other: "%{count} वर्षापेक्षा जास्त काळ" + x_seconds: + one: एक सेकंद + other: "%{count} सेकंद" + x_minutes: + one: एक मिनिट + other: "%{count} मिनिट" + x_days: + one: एक दिवस + other: "%{count} दिवस" + x_months: + one: एक महिना + other: "%{count} महिना" + prompts: + second: सेकंद + minute: मिनिट + hour: तास + day: दिवस + month: महिना + year: वर्ष + errors: + format: "%{attribute} %{message}" + messages: + accepted: मान्य केले पाहिजे + blank: रिक्त ठेवता येणार नाही + confirmation: "%{attribute} जुळत नाही" + empty: रिक्त असू शकत नाही + equal_to: "%{count} समान असणे आवश्यक" + even: समांक असणे आवश्यक आहे + exclusion: राखीव आहे + greater_than: "%{count} पेक्षा जास्त असणे आवश्यक आहे" + greater_than_or_equal_to: "%{count} पेक्षा मोठे किंवा समान असणे आवश्यक आहे" + inclusion: यादीत समाविष्ट नाही + invalid: अवैध आहे + less_than: "%{count} पेक्षा कमी असणे आवश्यक" + less_than_or_equal_to: "%{count} पेक्षा कमी किंवा समान असणे आवश्यक आहे" + not_a_number: क्रमांक नाही + not_an_integer: पूर्णांक असणे आवश्यक आहे + odd: विषम संख्या असणे आवश्यक आहे + other_than: "%{count} पेक्षा इतर असणे आवश्यक आहे" + present: रिक्त असणे आवश्यक आहे + taken: यापूर्वीच घेतले गेले आहे + too_long: + one: खूप लांब आहे (जास्तीत जास्त एक वर्ण परवानगी आहे) + other: खूप लांब आहे (जास्तीत जास्त %{count} वर्ण परवानगी आहे) + too_short: + one: खूप लहान आहे (किमान एक वर्ण परवानगी आहे) + other: खूप लहान आहे (किमान %{count} वर्ण परवानगी आहे) + wrong_length: + one: लांबी चुक आहे (एक वर्ण असणे आवश्यक आहे) + other: लांबी चुक आहे (%{count} वर्ण असणे आवश्यक आहे) + template: + body: 'खालील फील्ड सह समस्या होते:' + header: + one: एक चूक ह्या %{model} ला जतन करण्यापासून प्रतिबंधित करत आहे + other: "%{count} चुका ह्या %{model} ला जतन करण्यापासून प्रतिबंधित करत आहे" + helpers: + select: + prompt: कृपया निवडा + submit: + create: "%{model} निर्माण करा" + submit: "%{model} जतन करा" + update: "%{model} अद्यतनित करा" + number: + currency: + format: + delimiter: "," + format: "%u%n" + precision: 2 + separator: "." + significant: false + strip_insignificant_zeros: false + unit: "₹" + format: + delimiter: "," + precision: 3 + separator: "." + significant: false + strip_insignificant_zeros: false + human: + decimal_units: + format: "%n %u" + units: + billion: अब्ज + million: दशलक्ष + quadrillion: एकावर १५ शून्य इतकी संख्या + thousand: हजार + trillion: एकावर १२ शून्ये इतकी संख्या + unit: '' + format: + delimiter: '' + precision: 3 + significant: true + strip_insignificant_zeros: true + storage_units: + format: "%n %u" + units: + byte: + one: Byte + other: Bytes + gb: GB + kb: KB + mb: MB + tb: TB + percentage: + format: + delimiter: '' + precision: + format: + delimiter: '' + support: + array: + last_word_connector: ", आणि " + two_words_connector: " आणि " + words_connector: ", " + time: + am: म.पू. + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + long: "%d %B %Y %H:%M" + short: "%d %b %H:%M" + pm: म.नं. \ No newline at end of file diff --git a/config/locales/rails-i18n/pluralization/fil.rb b/config/locales/rails-i18n/pluralization/fil.rb new file mode 100755 index 0000000..0229a24 --- /dev/null +++ b/config/locales/rails-i18n/pluralization/fil.rb @@ -0,0 +1,3 @@ +require "rails_i18n/common_pluralizations/one_with_zero_other" + +::RailsI18n::Pluralization::OneWithZeroOther.with_locale(:fil) diff --git a/config/locales/rails-i18n/pluralization/hr.rb b/config/locales/rails-i18n/pluralization/hr.rb new file mode 100755 index 0000000..75eea29 --- /dev/null +++ b/config/locales/rails-i18n/pluralization/hr.rb @@ -0,0 +1,41 @@ +# Croatian has categories "one", "few", and "other", according to the CLDR +# plural rules used by Phrase. However, the rails-i18n implementation also +# requires "many". +# +# Note that Croatian has rules for fraction digits, but like rails-i18n +# we will only handle integers for now. +# +# https://unicode-org.github.io/cldr-staging/charts/latest/supplemental/language_plural_rules.html#hr + +module RailsI18n + module Pluralization + module Croatian + def self.rule + lambda do |n| + n ||= 0 + mod10 = n % 10 + mod100 = n % 100 + + if mod10 == 1 && mod100 != 11 + :one + elsif [2, 3, 4].include?(mod10) && ![12, 13, 14].include?(mod100) + :few + else + :other + end + end + end + end + end +end + +{ + hr: { + i18n: { + plural: { + keys: [:one, :few, :other], + rule: RailsI18n::Pluralization::Croatian.rule + } + } + } +} diff --git a/config/locales/rails-i18n/pluralization/mr.rb b/config/locales/rails-i18n/pluralization/mr.rb new file mode 100755 index 0000000..17fb400 --- /dev/null +++ b/config/locales/rails-i18n/pluralization/mr.rb @@ -0,0 +1,3 @@ +require "rails_i18n/common_pluralizations/one_with_zero_other" + +::RailsI18n::Pluralization::OneWithZeroOther.with_locale(:mr) diff --git a/config/locales/validators/en.yml b/config/locales/validators/en.yml new file mode 100755 index 0000000..1bb5e43 --- /dev/null +++ b/config/locales/validators/en.yml @@ -0,0 +1,8 @@ +--- +en: + validators: + email: + blacklist: has been blocked at the owner's request. That means it can't be used in guest comments. Please check the address to make sure it's yours to use and contact AO3 Support if you have any questions. + format: + allow_blank: should look like an email address. Please use a different address or leave blank. + no_blank: should look like an email address. diff --git a/config/locales/views/en.yml b/config/locales/views/en.yml new file mode 100755 index 0000000..10e56be --- /dev/null +++ b/config/locales/views/en.yml @@ -0,0 +1,2565 @@ +--- +en: + a11y: + navigation: Navigation + abuse_reports: + new: + do_not_spam: + delay: it may take a while. + paragraph_html: "Our volunteer team is small, so it may take a while." + split: Please only report one user at a time, and do not submit multiple reports about the same user. + form: + comment: + content_policy: Content Policy + description_html: Explain how the content you are reporting violates the %{content_policy_link} or other parts of the %{tos_link}. Please be as specific as possible and %{include_link}. All information provided will remain confidential. + error: Please describe what you are reporting and why you are reporting it. + include: include all relevant links and other information in your report + label: Description of the content you are reporting (required) + tos: Terms of Service + email: + description: We cannot contact you if the email address you provide is invalid. + label: Your email (required) + landmark: + send: Send to Abuse Team + language: + label: Select language (required) + legend: + abuse: Link and Describe Abuse + link: + description: Please ensure this link leads to the page you intend to report. Enter only one URL here and include any other links in the description field below. + error: Please enter the link to the page you are reporting. + label: Link to the page you are reporting (required) + name: + label: Your name or username (optional) + submit: + active: Submit + summary: + description: Please specify why you are contacting us and/or what part of the Terms of Service is relevant to your complaint. (For example, "harassment", "not a fanwork", "commercial activities", etc.) + error: Please enter a subject line for your report. + label: Brief summary of Terms of Service violation (required) + heading: + page_title: Policy Questions & Abuse Reports + include: + evidence_html: links to any relevant sources or screenshots + intro: 'What to include in your report description:' + other_content: links to any of their other content that you would like to report + quote: a quote from or summary of the content that violates the Terms of Service + reported_username: username of the person you are reporting + sources: sources + username_html: . + languages: + delay: There will be an additional delay for responses in any language other than English. + intro_html: We can answer Abuse reports in %{list_html}. + page_content_landmark: Main Text + purview: + about_html: Please use this form for questions or reports about violations of the Terms of Service. For more information, please refer to the FAQ section 2. + contact_support_html: If you need technical support, want to report a work tagged with an incorrect language, or something else, please %{support_link}. + dmca: + abbreviated: DMCA + full: Digital Millennium Copyright Act + dmca_takedown_html: If you would like to file a DMCA request, please email me at femslashclub@proton.me. + fnok: Fannish Next-of-Kin + legal: review our DMCA Policy and contact our Legal team + support: contact our Support team + tos: Sunset Terms of Service + tos_faq: Terms of Service FAQ + reportable: + allowed: You would like to know whether specific content is allowed on Sunset. + content_policy: Content Policy + email: an email explaining why + hack: You believe that your Sunset account was hacked. + harassment: You have experienced or witnessed harassment taking place on Sunset. + intro_html: 'Potential reasons to submit a report to the Policy and Abuse team:' + pac: Policy & Abuse + suspended_html: You have been suspended or your work has been removed, and you have not received an email.. + tos: Terms of Service + violation_html: You have encountered content on Sunset that violates the %{content_policy_link} or other parts of the %{tos_link}. + admin: + activities: + index: + activities_table: + action: Action + admin: Admin + caption: Admin Activity + date: Date + summary: List of admin activity with links to full summaries. + target: Target + page_heading: Admin Activities + show: + action: Action + admin: Admin + date: Date + landmark: + details: Action Details + navigation: + index: Admin Activities + page_heading: Admin Activity + summary: Summary + target: Target + admin_invitations: + find: + email: All or part of an email address + invitations_for_html: Invitations for %{user_invitations_link} + page_heading: Track invitations + search: Search + token: Invite token + username: Username + index: + find: + email: All or part of an email address + heading: Track invitations + invite_token: Invite token + landmark_submit: Submit + search: Search + username: Username + grant_invites: + all: All + generate_invitations: Generate invitations + heading: Give invite codes to current users + landmark_submit: Submit + number_of_invitations: Number of invitations + users: Users + with_no_unused: With no unused invitations + invite_from_queue: + heading_html: Send invite codes to people in our %{invitations_queue_link} + invitations_queue: Invitations queue + invite_from_queue: Invite from queue + number_to_invite: Number of people to invite + requests_in_queue: + one: There is %{count} request in the queue. + other: There are %{count} requests in the queue. + navigation: + queue: Manage Queue + requests: Manage Requests + page_heading: Invite New Users + send_to_email: + description: Email address + heading: Send to Email + invite_by_email_title: Invite by email + invite_user: Invite user + admin_nav: + ao3_news: Sunset News + archive_faq: Archive FAQ + faq: + reorder_questions: Reorder Questions + known_issues: Known Issues + landmark: Admin Navigation + news: + delete_post: Delete Post + post_ao3_news: Post Sunset News + wrangling_guidelines: Wrangling Guidelines + admin_options: + delete: + bookmark: Delete Bookmark + confirmation: Are you sure you want to delete this? + external_work: Delete External Work + series: Delete Series + work: Delete Work + edit: + external_work: Edit External Work + edit_tags: Edit Tags and Language + hide: + bookmark: Hide Bookmark + external_work: Hide External Work + series: Hide Series + work: Hide Work + landmark: Admin Actions + not_spam: Mark Not Spam + remove_pseud: Remove Pseud + remove_pseud_confirmation: Are you sure you want to remove the creator's pseud from this work? + spam: Mark As Spam + unhide: + bookmark: Make Bookmark Visible + external_work: Make External Work Visible + series: Make Series Visible + work: Make Work Visible + admin_users: + confirm_delete_user_creations: + caution_html: Are you sure you want to delete all the works and comments created by this user, along with their %{bookmarks} bookmarks, %{series} series, and %{collections} collections? This cannot be undone. + confirm: Are you sure? Remember this will destroy ALL these objects! + page_heading: Delete Spammer Creations + submit: Yes, Delete All Spammer Creations + creations: + navigation: + admin_user: User Administration + creations: Creations + no_creations: This user has no works or comments. + page_heading: Works and Comments by %{user} + page_title: "%{login} - User Creations" + history: + heading: User History + table: + caption: History of User Actions + creation: + action: Account Created + details: System Generated + head: + action: Action + date: Date/Time + details: Details + sign_in: + current: + action: Current Login + no_details: No login recorded + details: 'IP Address: %{ip}' + last: + action: Previous Login + no_details: No previous login recorded + summary: Shows what notable actions, such as creating an account, a user performed, and when they did them. + index: + role: Role + settings: + label: Search settings + past: Include past usernames and emails + show: + fnok: + form: + email: Fannish next of kin's email + name: Fannish next of kin's username + submit: Update Fannish Next of Kin + heading: Fannish Next of Kin + info: + email: 'Email:' + heading: User Information + invitation: 'Invitation:' + no_invitation: Created without invitation + no_role: No roles + past_emails: + one: 'Past email:' + other: 'Past emails:' + past_logins: + one: 'Past username:' + other: 'Past usernames:' + role: + one: 'Role:' + other: 'Roles:' + navigation: + activate: Activate + creations: Creations + invitations: + add: Add Invitations + manage: Manage Invitations + rename: Rename + roles: Manage Roles + troubleshoot: Troubleshoot + note: To fix common errors with this user's Subscriptions and Stats pages, and to reindex their works and bookmarks, choose "Troubleshoot." + page_heading: 'User: %{login} (%{id})' + page_title: "%{login} - User Administration" + status: + form: + admin_action: + ban: Suspend permanently (ban user) + legend: Warnings and Suspensions + note: Record note + spamban: 'Spammer: ban and delete all creations' + suspend: 'Suspend: enter a whole number of days' + unban: Lift permanent suspension, effective immediately. + unsuspend: Lift temporary suspension, effective immediately. + warn: Record warning + notes: + legend: Notes + required: Required when adding or removing a warning or suspension to an account. + submit: Update + heading: Record Warnings, Suspensions, or Notes + api: + edit: + page_title: Edit API Token + index: + actions: + find: Find + page_heading: API Tokens + page_title: API Tokens + search_box: + label: Name + search_by_name: Search for an API token by name + table: + actions: + edit: Edit + caption: API Tokens + headings: + actions: Actions + banned: Banned? + created: Created + name: Name + token: Token + updated: Updated + summary: Existing API tokens along with the dates they were created and updated and options for editing them. + new: + page_title: New API Token + banners: + index: + actions: + active: Active + confirm_delete: Are you sure you want to delete this banner? + delete: Delete + edit: Edit + page_heading: Banners + navigation: + confirm_delete: Are you sure you want to delete this banner? + delete: Delete Banner + edit: Edit Banner + index: Banners + new: New Banner + blacklist: + emails_found: + one: one email found + other: "%{count} emails found" + blacklisted_emails: + create: + browser_title: Create Banned Email + index: + browser_title: Banned Emails + confirm_remove: Are you sure you want to remove %{email} from the banned emails list? + form: + new: + label: Email to ban + submit: Ban Email + search: + submit: Search Banned Emails + heading: + new: Ban email address + search: Find banned emails + notes: + canonical_format: All emails are stored in a single canonical format and common variants of the same address are not allowed (for instance, foo+whatever@example.com will not be allowed if foo@example.com is banned). + guest_comments: Banned email addresses cannot be used in guest comments and cannot be added to the invitation queue. + unaffected_users: They will not affect users with that address or prevent invitations sent to that email address from being used. + page_heading: Manage Banned Emails + header: + nav: + activities: Activities + api_tokens: API Tokens + banned_emails: Banned Emails + banners: Banners + invitations: + invitations: Invitations + new: Invite New Users + queue: Manage Queue + requests: Manage Requests + label: Admin + locales: Locales + posts: + admin_posts: Admin Posts + faqs: Archive FAQ + known_issues: Known Issues + news: Sunset News + post_news: Post Sunset News + wrangling_guidelines: Wrangling Guidelines + settings: Settings + skins: + approved: Approved Skins + queue: Approval Queue + rejected: Rejected Skins + skins: Skins + spam: Spam + users: + email_search: Bulk Email Search + manage: Manage Users + search: Find Users + wrangling: Tag Wrangling + passwords: + edit: + describedby: + password_length: "%{minimum} to %{maximum} characters" + label: + confirmation: Confirm new password + password: New password + landmark: + submit: Submit + page_heading: Set My Admin Password + submit: Set Admin Password + new: + instructions: If you've forgotten or would like to change your admin password, we can send instructions that will allow you to reset it. Please tell us the username for your admin account. + page_heading: Forgotten your admin password? + reset_login_html: Admin username + submit: Reset Admin Password + sessions: + new: + label: + login: Admin username + password: Admin password + landmark: + reset: Reset password + page_heading: Log In as Admin + reset_link: Forgot admin password? + submit: Log In as Admin + settings: + index: + fields: + account_age_threshold_for_comment_spam_check: How old (in days) accounts should be before we stop checking comments for spam + account_age_threshold_for_comment_spam_check_note: Enter 0 to turn off comment spam checks for all logged in users. + account_creation_enabled: Account creation enabled + cache_expiration: How often (in minutes) should we refresh caching + creation_requires_invite: Account creation requires invitation + days_to_purge_unactivated: How many weeks you have to activate your account before we purge it + disable_support_form: Turn off support form + disabled_support_form_text: Disabled support form text + downloads_enabled: Allow downloads + enable_test_caching: Turn on caching (currently experimental) + guest_comments_off: Turn off guest comments across the site + hide_spam: Automatically hide spam works + invite_from_queue_enabled: Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically) + invite_from_queue_frequency: How often (in hours) should we invite people from the queue + invite_from_queue_number: Number of people to invite from the queue at once + request_invite_enabled: Users can request invitations + suspend_filter_counts: Suspend some filter tracking due to high posting volume + tag_wrangling_off: Turn off tag wrangling for non-admins + heading: Archive Settings + last_updated_by_admin: Settings last updated on %{updated_at} by %{admin_name}. + legend: + account_and_invitations: Accounts and Invitations + actions: Actions + content: Content + disable_support_form: Turn Off Support Form + performance_and_misc: Performance and Misc + queue_status: + one: "%{count} person is scheduled to be sent an invitation at %{time}." + other: "%{count} people are scheduled to be sent invitations at %{time}." + queue_status_help: "(The automatic task that invites people from the queue runs at most every hour. Don't be alarmed if the time you see is within the last hour. Do be alarmed if the time you see is more than one hour in the past and the queue is supposed to be active.)" + update: Update + update: + success: Archive settings were successfully updated. + user_creations: + confirm_remove_pseud: + caution: Are you sure you want to remove the creator's pseud from this work? + choose: Please choose which creators' pseuds you would like to remove from this work. + page_heading: Remove Pseud + submit_multiple: Remove Pseuds + submit_one: Yes, Remove Pseud + admin_posts: + admin_post_form: + comment_permissions: + label: Who can comment on this news post + language: + label: Choose a language + tags: + label: Tags + translated_post: + footnote_comment_permissions: Comment permissions from the selected post will replace any permissions selected on this page. + footnote_tags: Tags from the selected post will replace any tags entered on this page. + label: Translation of + show: + navigation: + admin: + confirm_delete: Are you sure you want to delete this news post? + delete: Delete Post + edit: Edit Post + landmark: Admin Actions + unreviewed_comments: + one: Unreviewed Comments (%{count}) + other: Unreviewed Comments (%{count}) + landmark: News Post Navigation + next: Next Post + previous: Previous Post + page_heading: Sunset News + admins: + index: + confidentiality_reminder: You are now logged in as an admin. That means you will probably encounter information that is personal or confidential (e.g. usernames, email and IP addresses, creator names on anonymous works, etc). Please do not use this information in ways unrelated to your OTW role. If you have questions about what you can or cannot do with information you see here, contact your committee chair(s). + log_out_reminder: Please remember to log out before resuming your normal site activity! + page_title: Hi, %{login}! + responsibility: With great power comes great responsibility. + roles: + heading: 'Your admin roles:' + none: You currently have no admin roles assigned to you. + archive_faqs: + admin_index: + confirm_delete: Are you sure you want to delete this FAQ category? + created_date: Created at %{date_created} + delete: Delete + edit: Edit + manage_faqs: Manage Archive FAQs + new_faq_category: New FAQ Category + page_heading: Archive FAQ + reorder_faqs: Reorder FAQs + show: Show + show: + edit: Edit + elasticsearch_news: news post announcing the search and filter updates + elasticsearch_update_notice_html: Our search engine has recently been updated, and this FAQ is based on our old version. We're working on bringing you more up-to-date information, but in the meantime, you can find out more in our %{elasticsearch_news_link}! + no_category_entries: We're sorry, there are currently no entries in this category. + page_heading: Archive FAQ + screencast: 'Screencast:' + blocked: + block: Block + unblock: Unblock + users: + confirm_block: + block: block + button: Yes, Block User + cancel: Cancel + mute_users_instead_html: To hide a user's works, bookmarks, series, and comments from you, visit %{muted_users_link}. + muted_users_link_text: your Muted Users page + sure_html: Are you sure you want to %{block} %{username}? + title: Block %{name} + will: + commenting: commenting or leaving kudos on your works + gifting: giving you gift works outside of challenge assignments and claimed prompts + intro: 'Blocking a user prevents them from:' + replying: replying to your comments anywhere on the site + will_not: + comments_elsewhere: hide their comments elsewhere on the site + comments_on_works: delete or hide comments they previously left on your works; you can delete these individually + hide_works: hide their works or bookmarks from you + intro: 'Blocking a user will not:' + confirm_unblock: + button: Yes, Unblock User + cancel: Cancel + resume: + commenting: commenting or leaving kudos on your works + gifting: giving you gift works outside of challenge assignments and claimed prompts + intro: 'Unblocking a user allows them to resume:' + replying: replying to your comments anywhere on the site + sure_html: Are you sure you want to %{unblock} %{username}? + title: Unblock %{name} + unblock: unblock + index: + blocked_users: Blocked Users + button: Block + heading: + landmark: + blocked_users: Listing Blocked Users + label: User + legend: Block a user + mute_users_instead_html: To hide a user's works, bookmarks, series, and comments from you, visit %{muted_users_link}. + muted_users_link_text: your Muted Users page + none: You have not blocked any users. + title: Blocked Users + will: + commenting: commenting or leaving kudos on your works + gifting: giving you gift works outside of challenge assignments and claimed prompts + intro: + one: 'You can block up to %{block_limit} user. Blocking a user prevents them from:' + other: 'You can block up to %{block_limit} users. Blocking a user prevents them from:' + replying: replying to your comments anywhere on the site + will_not: + comments_elsewhere: hide their comments elsewhere on the site + comments_on_works: delete or hide comments they previously left on your works; you can delete these individually + hide_works: hide their works or bookmarks from you + intro: 'Blocking a user will not:' + bookmarks: + bookmark_user_module: + bookmarked_by_html: Bookmarked by %{pseud_link} + index: + advanced_search: try our advanced search + choose_fandom: choose a fandom + recent_bookmarks_html: These are some of the latest bookmarks created on the Archive. To find more bookmarks, %{choose_fandom_link} or %{advanced_search_link}. + challenge: + gift_exchange: + challenge_signups: + close_offers_html: Close Offers ↑ + close_requests_html: Close Requests ↑ + heading: + for_collection: Sign-ups for %{collection} + for_search: + one: Sign-up + other: Sign-ups + navigation: + download_csv: Download (CSV) + search: Search + search_by_pseud: Search by Pseud + no_sign_ups_yet: No sign-ups yet! + offers_html: Offers ↓ + requests_html: Requests ↓ + challenge_assignments: + to_default: + button: Default + confirmation: Are you sure? This will mark you as having defaulted and notify the collection maintainer! It cannot be undone. + to_fulfill: + button: Fulfill + challenge_signups: + signup_form: + notice: + preference: + gift_exchange: Signing up for this challenge will allow assigned users to gift works to you regardless of your preference settings. If you wish to receive additional gifts from users who are not assigned to you, please %{preferences_link} to allow gifts from anyone. You can always %{refuse_link}. + preferences_link_text: update your preferences + prompt_meme: Signing up for this challenge will allow any user who claims your prompt to gift you a work in response to your prompt regardless of your preference settings. If you wish to receive additional gifts from users who have not claimed your prompts, please %{preferences_link} to allow gifts from anyone. You can always %{refuse_link}. + refuse_link_text: refuse a gift + chapters: + chapter_form: + content_policy: Content Policy + post_notice_html: All works you post on Sunset must comply with our %{content_policy_link}. For more information, please refer to our %{tos_faq_link}. + tos_faq: Terms of Service FAQ + preview: + content_policy: Content Policy + post_notice_html: All works you post on Sunset must comply with our %{content_policy_link}. For more information, please refer to our %{tos_faq_link}. + tos_faq: Terms of Service FAQ + collection_items: + collection_item_form: + add: Add + add_bookmark_header: Add Bookmark to collections + add_work_header_html: Add %{title} to collections + invite: Invite + invite_header_html: Invite %{title} to collections + index: + collection: + notice: + unreviewed_by_user: Works and bookmarks listed here have been invited to this collection. Once a work's creator has approved inclusion in this collection, the work will be moved to "Approved." + page_heading_html: Items in %{collection_link} + navigation: + approved: Approved + rejected_by_collection: Rejected by Collection + rejected_by_user: Rejected by User + unreviewed_by_collection: Awaiting Collection Approval + unreviewed_by_user: Awaiting User Approval + no_items: Nothing to review here! + user: + notice: + unreviewed_by_collection: Works and bookmarks listed here have been added to a collection but need approval from a collection moderator before they are listed in the collection. + page_heading: Items by %{username} in Collections + collection_profile: + show: + meta: + collection_tags: 'Collection tags:' + collections: + collection_blurb: + collection_tags: 'Collection Tags:' + form: + icon: + delete: Delete collection icon and revert to our default. This will also remove the icon alt text and comment text. + multifandom: + footnote: Use this if your collection is not fandom-specific. + label: Multifandom + index: + page_heading: + challenges_subcollections_in: Challenges/Subcollections in %{collection} + collections_in_the: Collections in the %{archive} + collections_including: Collections including %{work} + users_collections: "%{user}'s Collections" + sidebar: + bookmarks: Bookmarked Items (%{count}) + challenge_settings: Challenge Settings + collection_settings: Collection Settings + dashboard: Dashboard + fandoms: Fandoms (%{count}) + faq: FAQ + landmark: + choices: Choices + contents: Contents + dashboard: Dashboard + manage_items: Manage Items + parent_collection: Parent Collection + people: People + profile: Profile + random_items: Random Items + rules: Rules + subcollections: Subcollections (%{count}) + tags: Tags + works: Works (%{count}) + comments: + comment_form: + anonymous_creator: Anonymous Creator + anonymous_forewarning: While this work is anonymous, comments you post will also be listed anonymously. + cancel_action: Cancel + choose_name_field_title: Choose Name + comment_as: Comment as + comment_field_title: Enter Comment + comment_too_long: must be less than %{count} characters long. + comment_too_short: Brevity is the soul of wit, but we need your comment to have text in it. + guest_email: Guest email + guest_email_failure: Please enter your email address. + guest_instructions: All fields are required. Your email address will not be published. + guest_name: Guest name + guest_name_failure: Please enter your name. + inbox_reference_html: to %{commentable_creator} on %{commentable_link} + landmark: + comment: Comment + note: Note + legend: Post Comment + processing_message: Please wait... + commentable: + actions: + comment: Comment + add_to_collections_link: Add to Collections + blocked: Sorry, you have been blocked by one or more of this work's creators. + guest_comments_disabled: Sorry, the Archive doesn't allow guests to comment right now. + invite_to_collections_link: Invite To Collections + logged_as_admin: Please log out of your admin account to comment. + permissions: + admin_post: + alt_action: You can however %{support_link} with any feedback or questions. + disable_all: Sorry, this news post doesn't allow comments. + disable_anon: Sorry, this news post doesn't allow non-Archive users to comment. + support_link: contact Support + moderated_commenting: + disable: Disable comment moderation + enable: Enable comment moderation + keep_current: Keep current comment moderation settings + label: Comment moderation + notice: + admin_post: Comments on this news post are moderated. Your comment will not appear until it has been approved. + work: This work's creator has chosen to moderate comments on the work. Your comment will not appear until it has been approved by the creator. + options: + disable_all: No one can comment + disable_anon: Only registered users can comment + enable_all: Registered users and guests can comment + keep_current: Keep current comment settings + label: Who can comment on this work + multiple_works_label: Who can comment on these works + work: + alt_action: You can however still leave Kudos! + disable_all: Sorry, this work doesn't allow comments. + disable_anon: Sorry, this work doesn't allow non-Archive users to comment. + hidden: Sorry, you can't add or edit comments on a hidden work. + unrevealed: Sorry, you can't add or edit comments on an unrevealed work. + edit: + back: Back + page_heading: Editing comment + show: Show + update: Update + show: + comment_on_html: Comment on %{commentable_link} + single_comment: + on_chapter_html: on %{commentable_link} + unreviewed: + approve_all: Approve All Unreviewed Comments + no_unreviewed: No unreviewed comments. + note: + admin_post: Please note that comments cannot be unapproved once you have approved them. After you delete any comments you do not wish to appear on the news post, you can approve all that remain. + work: Please note that comments cannot be unapproved once you have reviewed them. After you delete any comments you do not wish to appear on your work, you can approve all that remain. + page_heading_html: Unreviewed Comments on %{commentable_link} + downloads: + download_afterword: + afterword: Afterword + comment: drop by the Archive and comment + end_notes: End Notes + inspired_by: + restricted_html: "[Restricted Work] by %{creator_link}" + revealed_html: "%{work_link} by %{creator_link}" + title: Works inspired by this one + unrevealed: A work in an unrevealed collection + please_comment_html: Please %{comment_link} to let the creator know if you enjoyed their work! + download_chapter: + chapter_byline_html: Chapter by %{byline_names_link} + chapter_end_notes_with_chapter_notes: more notes + chapter_end_notes_without_chapter_notes: notes + chapter_notes: Chapter Notes + chapter_summary: Chapter Summary + section_chapter_end_notes: Chapter End Notes + see_chapter_end_notes_html: See the end of the chapter for %{chapter_end_notes_link} + download_preface: + byline_html: by %{byline_names_link} + chapters: 'Chapters: %{chapter_total_display}' + collections: 'Collections:' + completed: 'Completed: %{date}' + end_notes_with_work_notes: more notes + end_notes_without_work_notes: notes + inspired_by: + restricted_html: Inspired by [Restricted Work] by %{creator_link} + revealed_html: Inspired by %{work_link} by %{creator_link} + unrevealed: Inspired by a work in an unrevealed collection + language: 'Language:' + notes: Notes + originally_posted_html: Posted originally on the %{archive_link} at %{work_url}. + preface: Preface + published: 'Published: %{date}' + see_end_notes_html: See the end of the work for %{end_notes_link} + series: 'Series:' + series_list_html: Part %{position} of %{series_link} + stats: 'Stats:' + summary: Summary + tag_type: "%{tag_type}:" + translated_to: + restricted_html: 'Translation into %{language} available: [Restricted Work] by %{creator_link}' + revealed_html: 'Translation into %{language} available: %{work_link} by %{creator_link}' + unrevealed_html: 'Translation into %{language} available: A work in an unrevealed collection' + translation_of: + restricted_html: A translation of [Restricted Work] by %{creator_link} + revealed_html: A translation of %{work_link} by %{creator_link} + unrevealed: A translation of a work in an unrevealed collection + updated: 'Updated: %{date}' + words: 'Words: %{count_with_delimiters}' + errors: + timeout_error: + contact_support: contact Support + html: If you still get this error after a few tries, you can %{contact_support_link}. + page_heading: Timeout Error + subtitle: The page was responding too slowly. Please try again after a few minutes. + external_works: + notice: This work isn't hosted on the Archive so this blurb might not be complete or accurate. + fandoms: + index: + page_heading: Fandoms + feedbacks: + new: + abuse: + contact: contact our Policy and Abuse team + reports: For reports of violations of the Terms of Service such as harassment, spam, or plagiarism, or if you believe your account has been hacked, please %{contact_link} instead. We cannot act on these reports or provide information about Policy and Abuse cases. + do_not_spam_html: "We respond to every report we receive, but we are a small volunteer team. For this reason, we ask you to not submit multiple reports regarding any one issue, or encourage other people to report the same issue, unless there is additional information to offer." + form: + comment: + description: Please be as specific as possible, including error messages and/or links + error: Please enter your feedback + label: Your question or problem (required) + email: + label: Your email (required) + language: + label: Select language (required) + legend: + contact_info: Contact Information + feedback: Describe Your Feedback + send: Send Your Feedback + name: + label: Your name (optional) + submit: + active: Send + disabled: Please wait... + summary: + error: Please enter a brief summary of your message + label: Brief summary of your question or problem (required) + heading: + instructions: Please use this form for questions about how to use the Archive and for reporting any technical problems. + landmark: + reference: Reference Links + page_title: Support and Feedback + languages_html: "We can answer Support inquiries in %{list}. Please allow for additional delay for responses in any language other than English." + navigation: + faqs: FAQs & Tutorials + known_issues: Known Issues + release_notes: Release Notes + reportable: + account_creation: Problems setting up your account + bugs: Bugs, errors, or unexpected site behavior + fnok: + concerning_html: Setting up, changing, or activating your %{fnok_link} + fnok: Fannish Next of Kin + intro: 'Some issues you can contact Support about include:' + lost_access: Lost password or email preventing access to your account + new_features: Feature requests for future development + orphaned_works: Questions about orphaned works + policy_questions: General site policy questions + site_questions: Questions about how to use the site + tag_changes: Requests to canonize or change tags + work_problems: Works labeled with the wrong language or duplicate works + status: + current: For current updates on Archive performance or downtime, please check the %{twitter_link} or %{tumblr_link}. + tumblr: femslashclub Tumblr + twitter: "@AO3_Status Twitter feed" + home: + about: + ao3: + github_repository: GitHub repository + html: The Sunset offers a noncommercial and nonprofit central hosting place for fanworks using open-source archiving software. + jira_project: Jira project + details: I love hosting shit and I basically just deployed this to see if I could do it. This is, disclaimer, NOT intended to be the same kind of site as AO3. It is a small personal archive with invitations moderated tightly. Please follow my rules and have a good time! + general: This is a site I made and host on an HP Envy in my bedroom. One singular person runs this website so be nice to me thanks. + heading: + html: About the %{otw} + otw: Sunset + otw_long: Sunset + major_projects: + fanlore: Link I don't know how to get rid of + fanlore_details_html: "%{fanlore_link} I don't know how to get rid of this" + legal_advocacy: Link I don't know how to get rid of + legal_details_html: "%{legal_advocacy_link} I don't know how to get rid of this." + open_doors: Link I don't know how to get rid of + open_doors_details_html: "%{open_doors_link}, I don't know how to get rid of this." + title: 'Thank you hehe' + twc: Link I don't know how to get rid of + twc_details_html: "%{twc_link}, I don't know how to get rid of this I'll figure it out later" + more_info: + communications_team: Communications team + faq_page: FAQ page + html: You can learn more about me and my other projects at alien.town. + transformative_works: transformativeworks.org + page_title: About the Sunset + content: + cc_attribution_4_0_international: Creative Commons Attribution 4.0 International License + commercial_promotion: + heading: II.C. Commercial Promotion + not_allowed: Promotion, solicitation, and advertisement of commercial products or activities are not allowed. + tos_faq: FAQ for Section II.C + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Commercial Promotion FAQ + content_policy: Content Policy and Rules + content_policy_heading: II. Content Policy + copyright_infringement: + epigraphs_small_quotations_allowed: Epigraphs and short quotations are allowed, as is Content that is set within or based on an existing work. + heading: II.D. Copyright Infringement + not_allowed: Reproductions of large excerpts of copyrighted works are not allowed without the consent of the copyright owner. This includes stories, artwork, songs, poems, transcripts, and other copyrighted material. Crediting the original creator does not give you the right to upload, podfic, or translate someone else's work without permission, regardless of whether the source is a fanwork or a professionally published work. + tos_faq: FAQ for Section II.D + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Copyright Infringement and Plagiarism FAQ + transformative_fanworks: transformative fanworks + transformative_works_legal_html: We believe that %{transformative_fanworks_link} are legal. Complaints about the mere existence of fanworks that mention trademarks or are based on copyrighted material will not be pursued. + effective: 'Effective: November 19, 2024' + fanworks: + bookmarks: Bookmarks + bookmarks_only_fanworks_html: "%{bookmarks_link} must only be created for fanworks. You may create %{external_bookmarks_link} for fanworks hosted on third-party sites." + external_bookmarks: external bookmarks + heading: II.B. Fanworks + must_be_fanworks_html: Works must be fanworks. Posting a Work that primarily consists of %{non_fanwork_content_link} is not allowed. + non_fanwork_content: non-fanwork Content + tos_faq: FAQ for Section II.B + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Fanworks and Non-Fanwork Content FAQ + harassment: + advocating_harm: + heading: Advocating Harm + text: Content that advocates specific, real, harmful actions towards real people is not allowed. This includes, but is not limited to, directing death threats or slurs at people outside of fiction, as well as encouraging others to harass or harm specific people or groups. + applies_to_all: it applies to all aspects of the Service + blocking: blocking + definition: Harassment is any behavior that produces a generally hostile environment for its target. Examples include bullying, threats, and personal attacks by or towards individuals or groups of people. + filtering: filtering + heading: II.H. Harassment + muting: muting + not_allowed_and_context: Harassment is not allowed. When judging whether a specific incident or item of Content constitutes harassment and/or when determining the appropriate severity of a penalty, the Policy & Abuse committee will consider relevant context. This includes whether the behavior was repeated, targeted, difficult to avoid encountering, or related to a general pattern of harassment by an individual or a group, among other factors. Additionally, submitting repeated and/or baseless complaints, particularly those targeting a specific user or group, may be considered harassment. + otw: + abbreviated: OTW + full: Organization for Transformative Works + policy_applicability_html: The Harassment Policy is primarily focused on user conduct and non-fictional Content. However, %{applies_to_all_link}, including interactions with the Policy & Abuse committee, the Support committee, and other AO3 or %{otw_abbreviation} volunteers. + rpf: + heading: Real-Person Fiction (RPF) + text: Creating RPF never constitutes harassment in and of itself. Posting works where someone dies, is subjected to slurs, or is otherwise harmed as part of the plot is usually not a violation of the Harassment Policy. However, deliberately posting such Content in a manner designed to be seen by the subject of the work, such as by gifting them the work, may result in a judgment of harassment. + threatening_versus_annoying_html: In general, threatening Content will be considered harassment, while Content that is merely rude or annoying will be allowed. Not everyone agrees about what is offensive and unacceptable. Users are encouraged to use tools such as %{blocking_link}, %{muting_link}, and %{filtering_link} to control their own environment on AO3. + tos_faq: FAQ for Section II.H + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Harassment FAQ + illegal_inappropriate_content: + automated_spam_check_html: We may use automated means to filter out spam. If you submit Content that is erroneously caught in a spam filter, please %{contact_ao3_administrators_link}. + conduct_threatening_technical_integrity_html: Conduct that threatens the %{technical_integrity_link} of AO3, for example attempting to hack AO3 or spread viruses through it, is prohibited. Uploading technically misnamed files or Content (such as non-image files with an image file extension used to disguise their actual format) constitutes a threat to the technical integrity of the site. + contact_ao3_administrators: contact AO3 administrators + heading: II.K. Illegal and Inappropriate Content + images_of_real_children: photographic or photorealistic images of real children + no_illegal_content_html: You may not upload Content that appears or purports to contain, link to, or provide instructions for obtaining sexually explicit or suggestive %{images_of_real_children_link}; malware, warez, cracks, hacks, or other executable files and their associated utilities; or trade secrets, restricted technologies, or other classified information. + report_it_to_us: email me at symphonicstarship at gmail.com to report it. + spamming_behavior: Spamming behavior is prohibited. Repeated identical or nearly identical posts in multiple places may be considered spam regardless of commercial content. + technical_integrity: technical integrity + tos_faq: FAQ for Section II.K + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Offensive Content vs Illegal Content FAQ + violates_us_law_html: If you encounter Content that you believe violates a specific law of the United States, you can %{report_it_to_us_link}. + impersonation: + function: function + heading: II.G. Impersonation + html: You may not impersonate or misrepresent your affiliation with any person, entity, or %{function_link}. Fiction clearly marked as such is not considered impersonation. + tos_faq: FAQ for Section II.G + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Fannish Identities and Impersonation FAQ + intro: + all_content_must_comply_html: All %{content_link} on Sunset must comply with our Content Policy. + archive_description: The Sunset exists to host transformative, non-commercial works created by fans from all over the world. + content: content + maximum_inclusiveness: maximum inclusiveness of fanwork content + our_goal_html: hi here are my site rules. wip + report_it_to_us: email me at symphonicstarship at gmail.com to report it. + review_before_posting_html: "%{all_content_must_comply_bold} Please review this page carefully before you begin posting. Answers to common questions about the Content Policy can be found in the %{tos_faq_link}." + tos_faq: TOS FAQ + we_do_not_prescreen: We do not prescreen content on Sunset. + you_can_report_html: If you encounter content that you believe violates our Content Policy, you can email me at symphonicstarship at gmail.com. %{we_do_not_prescreen_bold} + license_html: The Sunset %{terms_of_service_link}, including the %{content_policy_link} and %{privacy_policy_link}, are licensed under the %{cc_attribution_4_0_international_link}. + mandatory_tags: + any_archive_warning: any Archive Warning + ao3_may_designate_html: Sunset software may designate some tag fields (e.g. Rating, Archive Warnings, Fandom, or Language) as mandatory in order to post, import, or edit a Work using the appropriate forms. Tags entered into mandatory fields must meet the %{minimum_criteria_link} described in the TOS FAQ. + applying_nonspecific_tag_html: Applying a non-specific tag (such as "Not Rated", "Creator Chose Not To Use Archive Warnings", or "Unspecified Fandom") is always considered sufficient tagging for that field. A Work that is labeled with a non-specific Rating may contain Content of the highest rating. A Work that is labeled with a non-specific Archive Warning may contain Content pertaining to %{any_archive_warning_link}. + archive_warning: Archive Warning + choose_no_warnings_html: A creator may choose not to apply specific %{rating_link} and/or %{archive_warning_link} tags to their Work, but they must signal such choices by applying Sunset's %{non_specific_tags_link} indicating that they have opted out of choosing a specific Rating and/or Archive Warning. + heading: II.J. Mandatory Tags + minimum_criteria: minimum criteria + non_specific_tags: non-specific tag(s) + not_available: not available + rating: Rating + tags_applied_automatically_html: Some tags may be automatically applied to Works. In addition, Sunset administrators may determine that tags in a mandatory tag field on a Work are inaccurate or insufficient. In such cases, Sunset administrators may remove inaccurate tags; add non-specific tags to the Work; add specific tags to the Work in fields where non-specific tags are %{not_available_link}; require the creator to appropriately adjust the Work's tags; hide the Work; or take other appropriate action to address the matter. Refer to the %{tos_faq_link} for details about when Sunset administrators may enforce the presence or removal of tags in mandatory fields. + tos_faq: TOS FAQ + tos_faq_endnote: FAQ for Section II.J + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Ratings and Archive Warnings FAQ + offensive_content: + heading: II.A. Offensive Content + removal_not_just_offensiveness: Unless it violates some other policy, we will not remove Content for offensiveness. + tos_faq: FAQ for Section II.A + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Offensive Content vs Illegal Content FAQ + page_content_landmark: Main Text + page_heading: Content Policy + personal_information: + disclosing_personal_data_html: disclosing personal data, including %{special_categories_of_personal_data_link}. + heading: II.F. Personal Information and Fannish Identities + linking_fannish_identity: linking someone's fannish identity (such as their Sunset username) to their legal or professional identity (such as their "real life" name); + not_allowed: 'You may not upload Content that contains seemingly accurate, non-public information about another individual without authorization. This includes:' + orphaned: Orphaned + revealing_orphaned_creator_html: revealing the identity of the creator of an %{orphaned_link} fanwork; + right_to_hide_delete: We reserve the right to delete, hide, or otherwise make such Content unavailable. + rpf_exception: As Real-Person Fiction (RPF) is fictional, Content in RPF that would normally be deemed personal data (e.g. full names, usernames on social media services, city of residence, or birth date) will not ordinarily be considered as such. + sharing_sufficient_information: sharing information sufficient to identify someone else's legal or professional identity or their physical location (e.g. phone numbers, email addresses, residential addresses, or hotel room numbers); and + special_categories_of_personal_data: Special Categories of Personal Data + tos_faq: FAQ for Section II.F + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Fannish Identities and Impersonation FAQ + plagiarism: + heading: II.E. Plagiarism + html: Plagiarism is the use of someone else's words, or %{their_expressions_of_their_ideas_link}, without attribution. Minor alterations (such as replacing names, substituting synonyms, or rearranging a few words) are insufficient to make a work your own. Plagiarism is not allowed. Deliberately creating a work using the same general idea as another work is not plagiarism, but citation may be appropriate. + their_expressions_of_their_ideas: their expressions of their ideas + tos_faq: FAQ for Section II.E + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Copyright Infringement and Plagiarism FAQ + privacy_policy: Privacy Policy + terms_of_service: Terms of Service + toc: + header: Table of Contents for the Terms of Service (TOS) + intro: The Content Policy is the second part of the AO3 Terms of Service. + user_icons: + heading: II.I. User Icons + text: User icons must be appropriate for general audiences. They must not depict genital nudity, explicit sexual activity, hate symbols, or imagery that promotes, advocates, or causes harm. + tos_faq: FAQ for Section II.I + tos_faq_in_parens_html: "(%{tos_faq_link})" + tos_faq_link_label: Usernames, Icons, and Profiles FAQ + diversity_statement: + archive_description_html: This archive is a permanent, panfandom place for fanworks, built by fans for fans. Whichever way you use the Archive, you're part of this, powering it, shaping it through your use and %{your_feedback_link}. + archive_for_you: 'No matter your appearance, circumstances, configuration or take on the world: if you enjoy consuming, creating or commenting on fanworks, the Archive is for you.' + archive_team: the Archive team + diversity_statement: Diversity Statement + dreamwidth: Dreamwidth's + dreamwidth_remix_html: This is a remix of %{dreamwidth_link} %{diversity_statement_link}. + few_restrictions: few restrictions + license: + creative_commons_by_sa: Creative Commons Attribution-Share Alike 3.0 Unported License + html: This work is licensed under a %{creative_commons_by_sa_link}. + image_alt: Creative Commons License + some_essential_parts: some essential parts + still_missing_html: 'We know that there are %{some_essential_parts_link} that are still missing to make the Archive truly panfandom: the ability to host fanworks other than text, an interface in languages other than English, and more ways for you to connect with each other, to name just a few. But with your support, we''ll get there.' + terms_of_service: Terms of Service + we_build_for: We are building this archive for you. Come be a part of it. + welcome_header: You are welcome at the Archive of Our Own. + what_we_do_html: We, %{archive_team_link}, know that we won't get everything right on the first try, and we won't be able to make everyone equally happy. But we strive to find a good balance, and we promise to respectfully consider your feedback and to take it seriously. + why_we_build: We are building this archive because we believe it's possible for people of all opinions and persuasions to come together and share with each other. + you_can_html: You are free to express your creativity within the %{few_restrictions_link} needed to keep the service viable for other users. The Archive strives to protect your rights to free expression and privacy; you can read about the details in our %{terms_of_service_link}. + your_feedback: your feedback + dmca: + appeal: + cannot: cannot + copyright: Copyright infringement + dispute_html: you %{cannot_italic} reupload or repost the content unless you have filed a DMCA counternotice to dispute the takedown + heading: I was notified that my work was removed from AO3 due to a DMCA takedown notice. What can I do? + lumen: Lumen + notify: remove the content and notify you by email + plagiarism: plagiarism + removal_html: If the OTW receives a valid DMCA takedown notice for content you uploaded to AO3, we will %{notify_link}. We may also send a redacted version of the DMCA takedown notice to %{lumen_link} and other third parties at our discretion. + reupload_html: If your content was removed due to a DMCA takedown notice, %{dispute_bold}. If you reupload or repost the content without filing a DMCA counternotice, we may %{suspend_link}. + suspend: suspend your account + tos: Terms of Service + tos_faq: Terms of Service FAQ + violations_html: "%{copyright_link} and %{plagiarism_link} are violations of Sections II.D and II.E of our %{tos_link}, respectively. For more information, please refer to our %{tos_faq_link}." + counternotice_instructions: + address_attn: 'Attention: Legal' + address_org: Organization for Transformative Works + address_state: New York, NY 10003-1502 + address_street: '228 Park Ave S #18156' + consider_html: If you are considering whether to file a DMCA counternotice, we recommend that you contact an intellectual property lawyer licensed to practice in your jurisdiction, so that you are aware of your legal rights and obligations. You can also review the %{lumen_faq_link}. + contact_legal: the Legal committee's contact form + defend: you are willing to defend your use of the original copyrighted material in court + dispute_html: If you believe that your content does not infringe on the copyright owner's rights, you can file a DMCA counternotice to dispute the takedown. By filing a counternotice, you are indicating that %{defend_bold} if the party who submitted the original takedown notice chooses to pursue legal action against you. + heading: Filing a DMCA counternotice + initiate_html: 'To initiate a formal DMCA counter-notification request, contact the OTW''s designated agent using %{contact_legal_link}, via email to legal@transformativeworks.org, or by mailing a letter to:' + lumen_faq: Lumen DMCA Explanation and FAQ + prefer: We prefer to receive DMCA requests through the contact form or by email. + time_limit: You can file a DMCA counternotice at any point after your content has been removed; there is no time limit. + counternotice_process: + heading: DMCA counter-notification process + lumen: Lumen + notification_html: The original submitter will have 10 business days to prevent the restoration of your content by filing a lawsuit against you. If the original submitter does not file a lawsuit within 10 business days, the OTW will restore your content (or, if your content has already been deleted, allow you to reupload it) between 10 and 14 business days after we receive the counternotice. We may also send a redacted version of the DMCA counternotice to %{lumen_link} and other third parties at our discretion. + valid: If the OTW receives a valid DMCA counternotice, we will make reasonable efforts to notify the party who submitted the original takedown notice. + counternotice_requirements: + consent: 'a statement that you consent to the jurisdiction of a U.S. federal court in either:' + contact: your name, address, and phone number; + heading: Requirements of a DMCA counternotice + intro: 'The counternotice must substantially comply with the requirements of 17 U.S.C. § 512(g)(3). You are also required to consent to the jurisdiction of a United States court. The legal requirements of a valid DMCA counternotice include:' + liability: Per 17 U.S.C. § 512(f), you may be subject to liability if you knowingly and materially misrepresent your claim that the content was removed due to a mistake or misidentification. + mistake_html: a statement, %{perjury_bold}, that the content was removed due to a mistake or misidentification; + new_york: Manhattan, New York + non_us_resident_html: the district where the OTW is located (%{new_york_link}), if you are not in the U.S.; and + perjury: made under penalty of perjury + service: a statement that you will accept service of process from the party who submitted the original takedown notice. + signature: your physical or electronic signature; + url: the URL(s) of the content that was removed; + usa_resident: the district where you live, if you are in the U.S.; or + intro: + contact_legal: contact the OTW Legal committee + legality_html: The OTW will respond promptly to notices of alleged copyright infringement that substantially comply with all %{requirements_link}. However, we believe that %{transformative_works_legal_link}, and we reserve the right to review the allegedly infringing content and independently determine whether it is infringing. If you have any questions about our DMCA Policy, please %{contact_legal_link}. + purpose_html: The Digital Millennium Copyright Act (DMCA) establishes the procedure the Organization for Transformative Works (OTW) must follow when users of our sites, including the Archive of Our Own (AO3), %{reproduce_unauthorized_link}. Specifically, %{uscode_link} protects the OTW from potential liability when infringing content is present on our sites. + reproduce_unauthorized: reproduce copyrighted material without authorization + requirements: legal requirements + transformative_works_legal: transformative fanworks are legal + uscode: 17 U.S.C. § 512 + license: + cc_license: Creative Commons Attribution-ShareAlike 4.0 International License + credit_html: AO3's DMCA policy is licensed under the %{cc_license_link}. Material in this policy has been drawn from Dreamwidth, the Electronic Frontier Foundation, and Wikipedia. + page_heading: DMCA Policy + removal: + abuse_report_html: "%{submit_abuse_bold} Abuse reports are evaluated by the Policy & Abuse committee for violations of the %{tos_link}, and held to a very high %{confidentiality_link}. When submitting an Abuse report about copyright infringement, you must provide a link to the violating content on AO3 and clearly identify the original source in your report description. For more information, please refer to the %{tos_faq_link}." + confidentiality: standard of confidentiality + dmca_html: "%{file_dmca_bold} DMCA takedown notices can only be filed by the copyright owner or someone legally authorized to act on their behalf. DMCA notices must be sent to the OTW's designated agent and comply with all %{requirements_link}. DMCA notices are %{not_confidential_link}. The OTW reserves the right to make public all DMCA notices that we receive, though some information may be redacted for privacy." + do_not: do not + do_not_spam_html: Please %{do_not_bold} submit an Abuse report if you intend to file a DMCA notice. Submitting both an Abuse report and a DMCA notice about the same content may delay the processing of both requests. + file_dmca: File a DMCA takedown notice + file_dmca_html: "%{file_dmca_link}:" + heading: My work was posted on AO3 without my permission. What can I do? + intro: 'If you encounter content on AO3 that you believe infringes on your copyright, you have the following options:' + not_confidential: not subject to confidentiality + requirements: legal requirements + submit_abuse: Submit an Abuse report + submit_abuse_html: "%{submit_abuse_link}:" + tos: Sunset Terms of Service + tos_faq: Terms of Service FAQ + repeat: + heading: Repeat offenses + required_html: As required by 17 U.S.C. § 512(i)(1)(A), we may %{suspend_link} users who repeatedly violate others' copyright. The OTW has the discretion to decide what qualifies as a repeated offense. + suspend: suspend + takedown_instructions: + address_attn: 'Attention: Legal' + address_org: Organization for Transformative Works + address_state: New York, NY 10003-1502 + address_street: '228 Park Ave S #18156' + contact_legal: the Legal committee's contact form + heading: Filing a DMCA takedown notice + initiate_html: 'To initiate a formal DMCA takedown request, contact the OTW''s designated agent using %{contact_legal_link}, via email to legal@transformativeworks.org, or by mailing a letter to:' + prefer: We prefer to receive DMCA requests through the contact form or by email. + takedown_process: + counternotify: If the OTW receives a valid DMCA counternotice, we will make reasonable efforts to notify you. You will have 10 business days to file a lawsuit to prevent the restoration of the content. If you do not notify us within 10 business days that you have filed a lawsuit, we will allow the content to be restored in accordance with 17 U.S.C. § 512(g)(2)(B)-(C). + dispute: If the account owner believes that their content does not infringe upon your copyright, they may file a DMCA counternotice disputing the takedown. The account owner can file a DMCA counternotice at any point after the content has been removed; there is no time limit. + heading: DMCA takedown process + lumen: Lumen + notification_html: When the content is removed from AO3, the information you provided in the DMCA takedown notice will be forwarded to the owner of the account responsible for posting the content. We may also send a redacted version of the DMCA takedown notice to %{lumen_link} and other third parties at our discretion. + requirements: legal requirements + valid_html: If the OTW receives a DMCA takedown notice that fulfills all %{requirements_link}, we will remove the content once we review the validity of the infringement claim. + takedown_requirements: + accurate: a statement that the information you have provided is accurate. + authorized_html: a statement, %{perjury_bold}, that you are authorized to act on behalf of the copyright owner; and + contact: your contact information; + good_faith: a statement that you have a good-faith belief that the use of the content is not authorized by the copyright owner(s), their agent, or the law; + heading: Requirements of a DMCA takedown notice + intro: 'The takedown notice must substantially comply with the requirements of 17 U.S.C. § 512(c)(3)(A). You are also required to consent to the jurisdiction of a United States court. The legal requirements of a valid DMCA takedown notice include:' + liability: Per 17 U.S.C. § 512(f), you may be subject to liability if you knowingly and materially misrepresent your claim that the content infringes on your copyright. + perjury: made under penalty of perjury + signature: your physical or electronic signature; + source: identification of the copyrighted work being infringed upon (for example, a URL or publication listing); + url: the URL(s) of the specific content on our site that you believe to be infringing; + toc: + appeal: I was notified that my work was removed from AO3 due to a DMCA takedown notice. What can I do? + counternotice_instructions: Filing a DMCA counternotice + counternotice_process: DMCA counter-notification process + counternotice_requirements: Requirements of a DMCA counternotice + heading: Table of Contents + penalties: Repeat offenses + removal: My work was posted on AO3 without my permission. What can I do? + takedown_instructions: Filing a DMCA takedown notice + takedown_process: DMCA takedown process + takedown_requirements: Requirements of a DMCA takedown notice + donate: + general: + text: You can support Sunset financially. + title: Donations + money: + details_html: Sunset has ongoing running costs - electricity for the servers, mail servers, - and one-off costs. Any donation is a big help. You can donate at ko-fi.com/AgnestheAlien. (Don't worry, we'll never connect your Sunset username and your financial information.) + donation: donation to the OSunset + title: Donating Financially + page_title: Donate + time: + contribute_html: We also welcome community contributions to %{github_repository_link} for open tasks in our %{jira_project_link}. We also encourage you to browse through our %{volunteer_listings_link}, sign up to receive all our %{news_by_email_link} which includes our calls for volunteers, and apply for any volunteer roles that match your qualifications and interests. + github_repository: our GitHub repository + info_html: The %{otw_link} is the parent organization of the Archive of Our Own (AO3). We are often looking for volunteers to contribute to %{projects_link}. If you are interested in volunteering specifically to help the Archive of Our Own, the committees to look out for include Accessibility, Design, and Technology (AD&T); AO3 Documentation; Policy & Abuse; Support; Tag Wrangling; and Translation. + jira_project: Jira project + news_by_email: news by email + otw: Organization for Transformative Works + projects: our projects + title: Donating Your Time + volunteer_listings: volunteer position listings + fandoms: + all_fandoms: All Fandoms + first_login_help: + additional_info: + header: Additional Browsing Information + history_mark_later: + header: History and Mark for Later + history: History + history_faq: History and Mark for Later FAQ + html: You can access and manage your history by going to %{your_dashboard_link} and selecting the "%{history_link}" link in the side menu in the default browser skin or on top of the page in mobile devices. You can clear your history, or delete individual entries if you don't want these entries to show up in your history. You can also add works to the "Marked for Later" list in your history. For more information on History, please visit the %{history_faq_link}. + your_dashboard: your Dashboard + subscriptions: + header: Subscriptions + html: You can subscribe to a work, collection, series of works, or user by selecting the "Subscribe" link at the top or bottom of a work, or at the top or bottom of a collection or series page, or the user's profile page. You can check your subscriptions from %{your_dashboard_link} by selecting the "Subscriptions" link. For more information on Subscriptions, please visit the %{subscriptions_feed_faq_link}. + subscriptions_feed_faq: Subscriptions and Feeds FAQ + your_dashboard: your Dashboard + bookmarking_works: + bookmarks_faq: Bookmarks FAQ + header: Bookmarking Works + html: You can bookmark works on the Archive as well as works hosted on other sites. You can choose to make your bookmarks public or private. You can also mark a public bookmark as a rec (recommendation). Additionally, you can add notes and tags to the bookmark, and/or add it to a collection. For more instructions on managing your Bookmarks, please visit the %{bookmarks_faq_link}. + browsing: + all_fandoms: All Fandoms + fandoms: Fandoms + header: Browsing + html: You can start browsing works by going to the "%{fandoms_link}" tab at the top of any Archive page in the default skin and selecting either "%{all_fandoms_link}" or one of the subsets such as "%{movies_link}". Alternatively, you can use the %{search_feature_link} to look for specific fandoms, works, or users. You can use the "Sort and Filter" form to narrow down the results in any fandom page. For more instructions, please visit %{search_browse_faq_link} and the %{search_browse_tutorial_link}. + movies: Movies + search_browse_faq: Search and Browse FAQ + search_browse_tutorial: Searching and browsing tutorial + search_feature: search feature + editing_profile: + edit_my_profile: Edit My Profile + header: Editing Your Profile, Password, and Preferences + html: To add your info, go to %{your_dashboard_link}, select the "%{profile_link}" tab, and select "%{edit_my_profile_link}" from the range of options at the end of the page. Here, you can enter some basic personal information. It's also where to go to change your password. Refer to the %{profile_faq_link} for more information. + profile: Profile + profile_faq: Profile FAQ + your_dashboard: your Dashboard + logging_in_out: + forgot_password: forgot your password + header: Logging In and Logging Out + html: To log in, locate the login link and fill in your Username and Password. The link will be located at the top right of the screen and as indicated by your screenreader if you're using one. If you forget your password, then select "%{forgot_password_link}". To log out, select "Log Out" on the top right corner in the default browser skin. + posting_works: + header: Posting Works + html: To open the Post New Work page, just select the %{post_new_link} link from the menu of the Post tab located at the top right of the page in the default browser skin. Visit the %{posting_editing_faq_link} or check out our %{tutorial_link} for more information. + post_new: Post New + posting_editing_faq: Posting and Editing FAQ + tutorial: 'Tutorial: Posting a Work on AO3' + preferences: + edit_my_profile: Edit My Profile + header: Preferences + html: '"%{set_my_preferences_link}" is located next to the "%{edit_my_profile_link}" button, and allows you to adjust certain settings to personalize your experience on the site. The Preferences area controls both the Archive''s behavior (such as whether your history is saved) and the Archive''s appearance. Go to the %{preferences_faq_link} for more details.' + preferences_faq: Preferences FAQ + set_my_preferences: Set My Preferences + skins_detail_html: For more information on how to customize the skins and interface of the Archive, refer to the %{skins_faq_link} and %{tutorials_list_link}. + skins_faq: Skins and Archive Interface FAQ + tutorials_list: List of Tutorials + pseuds: + header: Pseuds + html: Pseuds are like pen names linked to your account. You can use different pseuds to post your works under the appropriate name while still managing them through the same account. You can %{manage_your_pseuds_link} through your profile page. For more information, please visit the %{pseuds_faq_link}. + manage_your_pseuds: manage your pseuds + pseuds_faq: Pseuds FAQ + support_and_feedback: + archive_faq: Archive FAQ + contact_support: contact Support + header: Support and Feedback + html: Some frequently asked questions about the Archive are answered in the broader %{archive_faq_link}. You may also like to check out our %{known_issues_link}. If you need more help, please %{contact_support_link}. If you want to know more about some user-created tools that work with the Archive, please visit the %{unofficial_tools_faq_link}. + known_issues: Known Issues + unofficial_tools_faq: Unofficial Browser Tools FAQ + table_of_contents: Table of Contents + tags: + header: Tags + html: All tags on the Archive—including those for fandoms, relationships, and characters—start out user-created. You can always use the existing tags by selecting from the autocomplete list. If you cannot find the tags you want to use, feel free to create new tags for your works. Behind the scenes, our tag wrangling team will match the tags up with their synonyms, so that people can find your work whether you tag it "AMTDI", "Aliens Made Them Do It", or "Sex Pollen". Refer to the %{tags_faq_link} to learn more. + tags_faq: Tags FAQ + tips_to_start: Here are some tips to help you get started. + tos: + additional_questions_html: If you have additional questions that are not covered here, please %{contact_abuse_link}. + contact_abuse: contact our Policy & Abuse team + content_policy: Content Policy + header: Terms of Service + info_html: You can learn about our policies and procedures by reviewing the %{tos_link}, including the %{content_policy_link} and %{privacy_policy_link}. Answers to common questions are available in the %{tos_faq_link}. + privacy_policy: Privacy Policy + tos: Terms of Service + tos_faq: Terms of Service FAQ + warnings: + archive_specific_warnings: Archive-specific warnings + description_html: 'The Archive defines four "primary" %{archive_specific_warnings_link}: "Graphic Depictions Of Violence", "Major Character Death", "Rape/Non-Con", and "Underage Sex". When posting a work, you have the option to explicitly select warnings for this content, deny the presence of such content ("No Archive Warnings Apply"), or choose not to apply warnings regardless of whether or not these warnings are applicable ("Creator Chose Not To Use Archive Warnings"). Remember, "No Archive Warnings Apply" only refers to the listed primary warnings.' + header: Warnings + symbols_html: When browsing the Archive, warnings will be displayed in the blurb of each work. Official warning tags are displayed in bold. A four square grid in the top left corner of each work's blurb indicates the work's rating, completion status, pairing category, and any Archive warnings that apply to it. Refer to the %{symbols_key_chart_link} for more information. + symbols_key_chart: Symbols Key Chart + welcome_header: Welcome to the %{app_name}! + index: + browse_or_favorite: + one: Browse fandoms by media or favorite up to %{count} tag to have it listed here! + other: Browse fandoms by media or favorite up to %{count} tags to have them listed here! + find_your_favorites: Find your favorites + media_navigation_label: Media + readings: + heading: + history_link: My History + title: Is it later already? + note: Some works you've marked for later. + social: + heading: Follow us + note_html: Follow the Archive on Twitter or Tumblr for status updates, and don't forget to check out the %{other_outlets_link} for updates on our other projects! + other_outlets: Organization for Transformative Works' news outlets + tumblr: femslashclub on Tumblr + twitter: "@AO3_Status on Twitter" + privacy: + account_termination: + backup_copies_html: '"Active records" do not include the backup copies of Content created for legal and/or disaster recovery purposes (refer to the %{general_principles_link}).' + deletion_after_termination_html: If for any reason you %{terminate_your_account_link}, as soon as reasonably possible we will destroy active records containing your Personal Information that are visible to the public or to Sunset users, with the exception of Personal Information entered as Content that you have not deleted. "Reasonably" here means no more than thirty business days from the termination of the account. + general_principles: General Principles + heading: III.G. Termination of account + legal_enforcement_retention: We will retain some Personal Information accessible to Sunset administrators for legal and TOS enforcement purposes. For example, if we terminate your service or suspend your account, we may retain enough Personal Information to prevent you from creating an account or using Sunset in the future. + orphan: Orphan + orphans_excluded_html: If you choose to %{orphan_link} your works during the account deletion process, and choose to keep your %{pseud_link} associated with the works when Orphaning them, then your pseud will remain visible on the works. + pseud: pseud + terminate_your_account: terminate your account with us + aggregate_anonymous_info: + anonymous_non_personal: Nothing in this Privacy Policy restricts our use of anonymous information or other information or data that does not qualify as "Personal Information". + heading: III.D. Aggregate and anonymous information + understand_ao3_usage: We may use Personal Information in the aggregate to understand how our users use Sunset. This is necessary for us to carry out our legitimate interests as a host of Content and a non-profit entity, including managing, maintaining, and ensuring the security of AO3 and our servers. Note that de-identified or aggregate information that is not linked with your other Personal Information, and does not otherwise identify you, will not be treated as Personal Information. + applicability: + consent_to_us_processing: By agreeing to this Privacy Policy, you consent to the processing of your Personal Information in the United States and in other jurisdictions in connection with our provision of AO3 and its related services to you. + global_subprocessors_html: While the OTW is a United States 501(c)(3) corporation, our users are global. Your use of AO3 may result in the transfer of Personal Information across international boundaries. For example, Personal Information collected within the European Economic Area (EEA) and Switzerland may be transferred to and processed in a country outside of the EEA and Switzerland, or by third-party %{subprocessors_link} located outside of the EEA and Switzerland, where you may have different legal rights in relation to your Personal Information. + heading: III.A. Applicability + policy_covers: This Privacy Policy covers the treatment of Personal Information submitted to AO3 or which we collect when you use our services. Except as otherwise stated in these Terms of Service, "Personal Information" (as used in this Privacy Policy) means information related to you that qualifies as "personal data" or "personal information" under the data privacy laws applicable to the Organization for Transformative Works (OTW). Changes to this Privacy Policy will only apply to the Personal Information that is processed by AO3 after the effective date of those changes. If you are concerned about how your Personal Information is used, you should review this Privacy Policy periodically. + subprocessors: Subprocessors + transfers_necessary_html: We make such transfers to the United States and the jurisdictions of our service providers with your consent or because it is necessary for the performance of a contract with you. %{consent_to_us_processing_bold} + cc_attribution_4_0_international: Creative Commons Attribution 4.0 International License + contact_us: + contact_pac: contact the Policy & Abuse committee + heading: III.I. Contact us + html: If you have any questions, concerns, or complaints about this Privacy Policy, or would like to submit a data request, please %{contact_pac_link}. + content_policy: Content Policy + effective: 'Effective: November 19, 2024' + information_scope: + collect_through_use: We may collect your Personal Information (such as your IP address and email address) when you request an AO3 invitation, register for an AO3 account, or otherwise access or use AO3. + content: Content + heading: III.B. Scope of Personal Information we process + information_in_content_html: Any Personal Information you include in your %{content_link} (including %{special_categories_link} and other types of Personal Information) may be accessible by AO3 administrators. It may also be accessible by the general public if the Content is made public, or by AO3 users if the Content is made available to AO3 users. + special_categories: Special Categories of Personal Data + intro: + answers_common_questions_html: Answers to common questions about the Privacy Policy can be found in the %{tos_faq_link}. + ao3_exists_to_host_html: 'AO3 exists to host content by and for fans from all over the world. To do so, we process certain data and information, including %{personal_information_link}. This is so that we can:' + archive_description: The Archive of Our Own (AO3) is a project of the Organization for Transformative Works (OTW), which is committed to fan privacy. + details_how_and_why_html: This Privacy Policy details how and why we collect and process this information. %{common_questions_bold} + enable_post_information: Enable you to post comments, kudos, bookmarks, and other information designed to be seen by other users + host_your_fanworks: Host or share your fanworks + personal_information: Personal Information + show_you_works: Show you works by other people + tos_faq: TOS FAQ + license_html: The AO3 %{terms_of_service_link}, including the %{content_policy_link} and %{privacy_policy_link}, are licensed under the %{cc_attribution_4_0_international_link}. + page_content_landmark: Main Text + page_heading: Privacy Policy + privacy_policy: Privacy Policy + privacy_policy_heading: III. Privacy Policy + retention_of_information: + heading: III.H. Retention of Personal Information + text: We will retain your Personal Information for no longer than reasonably necessary and proportionate to fulfill the purposes for which we originally collected or processed it, as set out in this Privacy Policy or as required by law. Once the purpose(s) for which the Personal Information was collected is/are no longer applicable, we will delete or otherwise dispose of that Personal Information. + terms_of_service: Terms of Service + third_parties: + do_not_sell_information: We will not sell, trade, or rent your Personal Information. We will not use your Personal Information to market third-party products and services to you. This means that we do not collect or use your Personal Information for targeted advertising, nor do we process Personal Information for automated decision-making purposes. If we begin to do so, that change will be reflected in this Privacy Policy, and you will have the right to restrict the use of that Personal Information accordingly. + heading: III.F. Information shared with third parties + sharing_exceptions: + challenge_signup: + challenge: Challenge + heading_html: 'If you sign up for a %{challenge_link}:' + text: We may share your email address with the maintainers of the Challenge. + external_processing: + heading: 'For external processing:' + html: We may use third-party services to store, process, or transmit data, or to perform other technical functions related to operating AO3. For example, we may use third-party email services. A list of third-party services is provided in our %{subprocessor_list_link}. We cannot guarantee other services' technical performance. We or the services we use may store or process your Personal Information in data centers which may be located in the United States or elsewhere. + subprocessor_list: Subprocessor List + handle_complaints: + dmca_notice: Digital Millennium Copyright Act (DMCA) notice + heading: 'To handle complaints submitted by you about TOS violations:' + html: If we receive a %{dmca_notice_link}, we reserve the right to disclose the information provided by the copyright owner or their legal representative to the subject of the complaint. If we receive a complaint from you about other matters, that information will be subject to the %{pac_confidentiality_policy_link}. + pac_confidentiality_policy: Policy & Abuse Confidentiality Policy + intro: 'We will not share your Personal Information with any third parties without your prior consent, except for the following cases:' + legal_reasons: + attempt_to_notify: We will attempt to notify you any time we disclose your Personal Information to a third party for legal reasons, unless legally prohibited from doing so or if, in our sole judgment, notification might hinder an ongoing investigation. In some cases, the Personal Information we have, such as an IP address, may be insufficient for us to notify you. + cooperating_law_enforcement: are cooperating with law enforcement authorities. + good_faith_comply: have a good-faith belief that such action is necessary to comply with a current judicial proceeding, court order, or legal process served on the OTW; or + heading: 'For legal reasons:' + intro: 'We may share Personal Information if we:' + law_enforcement_cooperation_details: We will cooperate with all investigations conducted by law enforcement authorities within the United States when legally required to do so. Cooperation with law enforcement authorities from other countries and cooperation when it is not legally required are at our sole discretion. Our discretion looks favorably on freedom and justice, and unfavorably on oppression and violence. + legally_compelled: are legally compelled to do so; + open_doors_import: + heading_html: 'If your work is imported via %{open_doors_link}:' + open_doors: Open Doors + text: If the email address associated with your AO3 account matches an email address that you used in connection with a non-AO3 archive that is being imported to AO3 via Open Doors, then we may share your email address with the entity that manages that imported archive. + third_party_tools: Third parties have developed applications, software, scripts, browser extensions, or other tools for use in connection with AO3. Such third parties may receive Personal Information from you if you use their tools to access AO3. This Privacy Policy does not cover your use of such tools. + toc: + header: Table of Contents for the Terms of Service (TOS) + intro: The Privacy Policy is the third part of the AO3 Terms of Service. + types_of_information: + cookies: + heading: 'Cookies:' + text: We and our Subprocessors use cookies to collect and store visitors' preferences; customize web pages' content based on visitors' preferences or other Personal Information that the visitor sends; prevent attacks on our servers; and record activity at AO3 in order to provide better service when visitors return to our site. AO3 has no access to cookies set by other sites. If you block or disable cookies, you may be unable to access or use AO3. + emails: + address_usage_html: We will use your email address internally for the purposes of managing AO3 and maintaining site integrity. We may occasionally send emails to you about AO3, your Content and account, or news that we reasonably believe to be of interest to our registered users. We will also send you your invitation to register for AO3 via email. By creating and maintaining an account on AO3, you consent to receiving such emails. We reserve the right to send you notice of complaints raised against you, or alleged violations of the TOS by you, as well as to reply to any email message you send to AO3 and/or its personnel. If you choose to participate in a %{challenge_link}, the Challenge maintainer(s) may have access to your email address for the purposes of communicating with you. + challenge: Challenge + collect_process_retain: We collect, process, and retain the email addresses of and from those who communicate with us via email, and any Content or Personal Information included in emails to us. We need this Personal Information so we can respond to you; so we can handle complaints about AO3 and any users who may have violated the TOS or other policies; and for other legal and accounting/audit reasons, including maintaining the integrity of AO3 and the Content that we host. + heading: 'Emails:' + unsubscribe: Although it is possible to unsubscribe from some emails (such as kudos updates and responses to comments), you cannot unsubscribe from receiving emails that we, in our sole discretion, deem necessary for legal purposes or to maintain the safety and integrity of your account or our services, including other OTW sites. + fnok: + heading: 'Fannish next-of-kin:' + text: We collect the contact information you and/or your fannish next-of-kin provide, and use it only to implement the fannish next-of-kin function. + heading: III.C. Types of Personal Information we collect and process + ip_addresses: + heading: 'IP addresses:' + text: We and our Subprocessors collect, process, and retain the IP addresses of AO3 visitors, including registered users. IP information may also be collected by our servers for logging purposes and used for limited technical assessments of AO3. We need this Personal Information so we can provide you with the Content that you are requesting; to allow you to submit Content to us; and for other legal, TOS enforcement, and accounting/audit reasons, including maintaining the integrity of AO3 and the Content that we host. + logs: + heading: 'Logs:' + text: We and our Subprocessors collect, process, and retain logs of server interactions. We need this Personal Information for legal, TOS enforcement, and accounting/audit reasons, including maintaining the integrity of AO3 and the Content that we host. + other_information: + heading: 'Other user-specific information:' + to_maintain_integrity: We and our Subprocessors collect, process, and retain Personal Information about what pages you access or visit, including your interactions with integral AO3 features such as comments, kudos, and bookmarks; referral information (i.e. data about what site you are coming to AO3 from); and whether there are errors in displaying Content to you. We need this Personal Information to maintain the integrity of AO3 and the Content that we host; to provide you with the Content that you are seeking; to prevent spam and abuse; and for other legal and accounting/audit reasons. + to_make_content_available_html: We and our Subprocessors collect, process, and retain Personal Information about Content that you submit to us. You consent to the collection of your Personal Information (such as your IP address) when you access AO3, including when you are not logged in. We use this Personal Information to make the Content you submit available to people who use AO3. By submitting Content to us, you are requesting that we make it available to those people and consenting to the use of your Content. For explanations of site features that use your Content and/or Personal Information and how they are used, please refer to the %{tos_faq_link}. + tos_faq: TOS FAQ + your_rights: + applicable_jurisdiction: applicable jurisdiction + heading: III.E. Your rights under applicable data privacy laws + other_rights: other rights regarding your Personal Information + potential_other_rights_html: You may have %{other_rights_link} under the laws of the jurisdiction in which you are located. We will not discriminate against you for making a request under the data privacy laws of applicable jurisdictions. + request_data_html: You can request that the OTW assemble the data that AO3 has about you, and provide you with a copy in electronic format. We agree to provide such data to you within a reasonable time if you are a resident or citizen of the European Union or another %{applicable_jurisdiction_link}. + require_user_specific_proof: We reserve the right to require user-specific proof of identity before providing Personal Information to a requester. This is necessary to protect the safety and privacy of our users and personnel. + site_map: + about: + ao3_news: Sunset News + archive_faq: Archive FAQ + content_policy: Content Policy + header: About the Sunset Archive + known_issues: Known Issues + privacy_policy: Privacy Policy + project_of_otw_html: The Sunset is a project of the %{otw_link} + terms_of_service: Terms of Service + tos_faq: Terms of Service FAQ + access_your_account: + drafts: Drafts + header: Access your account + my_bookmarks: My Bookmarks + my_collections_and_challenges: My Collections and Challenges + my_history: My History + my_home: My Home + my_inbox: My Inbox + my_series: My Series + my_subscriptions: My Subscriptions + my_works: My Works + post_new: Post New + set_my_preferences: Set My Preferences + change_your_account_settings: + delete_account_confirmation: This will permanently delete your account and cannot be undone. Are you sure? + delete_my_account: Delete My Account + edit_my_profile: Edit My Profile + header: Change your account settings + manage_my_pseuds: Manage My Pseuds + my_profile: My Profile + contact_us: + donations: Donations + header: Contact Us + policy_questions_and_abuse_reports: Policy Questions & Abuse Reports + technical_support_and_feedback: Technical Support & Feedback + explore: + additional_tags_cloud: Additional Tags Cloud + bookmarks: Bookmarks + collections_and_challenges: Collections and Challenges + fandoms: Fandoms + header: Explore + homepage: Homepage + languages: Languages + people: People + recent_works: Recent Works + otw: + abbreviated: Sunset + full: Sunset + page_heading: Site Map + tos: + abuse_policy: + answers_common_questions_html: Answers to common questions about the Abuse Policy can be found in the %{tos_faq_link}. + appeals: + appeal_decision: appeal a decision to the Policy & Abuse committee + heading: Appeals + html: The complainant or the subject of a complaint may %{appeal_decision_link}, in which case it will be reviewed by an additional PAC administrator. The original decision will remain in effect while an appeal is being reviewed. We will attempt to resolve appeals as speedily as possible, but we cannot guarantee any particular timeframe for a response. PAC's decisions are final. + content_policy: Content Policy + heading: I.I. Abuse Policy + no_prescreen_html: We do not prescreen Content for violations of the Terms of Service, including violations of the %{content_policy_link}. Complaints are investigated only when they are submitted through the appropriate channels and with the appropriate information. + penalties: + age_barred_individual: Age-Barred Individual + content_policy_ii_k_1: Subsection II.K.1 of the Content Policy + edit_post_while_suspended: A suspended user may not post or edit Content or create an account while they are suspended. A user who was suspended solely due to age may post Content or create an account once they are no longer an Age-Barred Individual. + heading: Penalties + illegal_inappropriate_content_policy: Illegal and Inappropriate Content Policy + non_violating_content_html: A suspended user's non-violating Content will not be automatically removed unless the user is an Age-Barred Individual or has violated the %{illegal_inappropriate_content_policy_link}. Suspended users retain the right to delete or Orphan their fanworks by contacting Sunset administrators. + open_doors_removal_html: ... + remove_resolve_lawsuit_html: We may determine that we need to remove Content to resolve a threatened or pending lawsuit or to mitigate other liability. If so, we will remove the Content. Unless said Content was submitted by an %{age_barred_individual_link} or otherwise violates the TOS, removal for such reasons will not lead to a suspension. + tos_faq: TOS FAQ + violations_warnings_suspensions_html: Violations of the TOS may result in warnings or suspensions ("penalties") for all accounts owned by the offending user. The determination of appropriate penalties, including the length of any suspensions, is subject to the discretion of the Policy & Abuse committee. PAC's discretion will be informed by the nature of the violation and the behavior of the user. For more information, please refer to the %{tos_faq_link}. + resolution_of_complaints: + add_or_edit_tags_html: AO3 administrators may also determine that tags need to be added to or edited on a Work, and may add or edit those tags. For more information, please refer to the %{mandatory_tags_policy_link}. + administrators_determine_content_removal_html: When AO3 administrators %{determine_removal_link}, it may be hidden from public view or removed from AO3. If the Content is a Work (defined as Content created via the New Work or Import Work forms, or imported via Open Doors) and the creator provided valid contact information, we will inform the creator as soon as possible. + determine_removal: determine that Content needs to be removed + heading: Resolution of complaints + illegal_and_inappropriate_content_policy: Illegal and Inappropriate Content Policy + immediate_removal: Non-Work Content, or any Content without valid contact information, that violates the TOS may be immediately removed. + mandatory_tags_policy: Mandatory Tags Policy + potentially_legitimate_fanwork_html: If the Content that needs to be removed is a Work that includes potentially legitimate fanwork, the default will be to hide the Work. The Policy & Abuse committee has sole discretion to determine necessary exceptions to this default rule, which may include repeated violations of the TOS, any violations of the %{illegal_and_inappropriate_content_policy_link}, or any circumstances where the OTW reasonably believes that the Content is unlawful, including when it contains a true threat. + voluntary_removal: When Content (whether a Work or otherwise) is hidden from public view, AO3 administrators may identify the nature of the problem with the Content and set a deadline for voluntary removal of the violating material. If the creator does not remove that material within the given deadline, AO3 administrators may permanently remove the Content. At the discretion of the Policy & Abuse committee, the creator may have the option to resubmit any non-violating material that was also removed. + submitting_a_complaint: + dmca_policy: DMCA Policy + heading: Submitting a complaint + html: Complaints may be submitted to the Policy & Abuse committee (PAC) via the %{policy_and_abuse_form_link}, except for Digital Millennium Copyright Act (DMCA) notices filed by the copyright owner or their legal representative. DMCA notices must be submitted to the Legal committee and are not governed by the Abuse Policy. Refer to the %{dmca_policy_link} for more information. + policy_and_abuse_form: Policy & Abuse reporting form + tos_faq: TOS FAQ + treatment_of_complaints: + heading: Treatment of complaints + html: Complaints are covered by the %{privacy_policy_link} and processed by PAC in accordance with the %{pac_confidentiality_policy_link}. Responses to complaints will be provided at the discretion of the OTW, in accordance with the Privacy Policy and other applicable terms of these TOS. + pac_confidentiality_policy: Policy & Abuse Confidentiality Policy + privacy_policy: Privacy Policy + age_policy: + addressing_violations: If AO3 administrators determine that an Age-Barred Individual has created an account or uploaded Content, they may suspend or delete the account, hide or delete the Content, or take other appropriate action to address the matter. + age_barred_not_permitted_html: Age-Barred Individuals are %{not_permitted_account_upload_link} to AO3. By submitting Content to AO3, you confirm that you are not an Age-Barred Individual. + ask_parent_to_upload: If you are a child under the age of eighteen (18) and not a resident or citizen of the European Union, you may ask your parent or legal guardian to upload your Content through their account. + country_disallowing_childrens_data: any country (including a European Economic Area country) which does not allow the processing of personal data from children of that age without written permission from a parent or legal guardian. + eu_country_html: a European Union country where the processing of %{special_categories_of_personal_data_link} from children of that age requires the consent of a parent or legal guardian, or + heading: I.H. Age Policy + individuals_under_13: individuals under the age of eighteen (18), and + individuals_under_16: 'individuals under the age of eighteen (18) who are not old enough, in their country of residence or citizenship, to consent to the processing of personal data. This includes individuals under the age of sixteen (16) who are residents or citizens of:' + intro: 'AO3 does not knowingly solicit or collect information from Age-Barred Individuals. Age-Barred Individuals are:' + not_permitted_account_upload: not permitted to have an account or upload Content + special_categories_of_personal_data: Special Categories of Personal Data + archive_description: The Sunset is a home for F/F, NB/F and NB/NB fanworks, including fanfiction based on books, movies, TV, comics, other media, and real-person fiction (RPF). + cc_attribution_4_0_international: Creative Commons Attribution 4.0 International License + content_policy: Content Policy + content_you_access: + content_policy: Content Policy + external_links_html: The OTW or users of its services may provide links to or content via sites that are owned or controlled by third parties, and may use such sites (including those identified %{here_link}) to communicate information about the OTW and its sites. If you follow links away from AO3, you should review those sites' terms and privacy policies, which may differ from AO3's. The OTW has no control over any third-party sites or their terms of use or privacy policies, and you agree that the OTW is not responsible for and does not endorse their content, terms, or availability. + heading: I.D. Content you access when using AO3 + here: here + hosted_by_third_party: embedded from and/or hosted by third-party sites + no_otw_endorsement_html: You recognize that the OTW does not endorse Content on AO3 in any way, except when such material appears as an %{official_statement_link} of the OTW. No members, volunteers, administrators, officers, or directors of the OTW are acting in an official capacity when they post fanworks, commentary, or other Content of the type generally provided by site users. + no_prescreen: You understand that the OTW does not prescreen Content or review it for purposes of compliance with the TOS. This includes (but is not limited to) a work's text, graphics, tags, comments, or any other material. Content, including User-Embedded Content, is the sole responsibility of the submitter. You understand that using AO3 may expose you to material that is offensive, atrocious, immoral, obscene, triggering, blasphemous, bigoted, erroneous, or objectionable in other ways. + official_statement: official statement + otw_not_liable: The OTW is not liable to you for any Content to which you are exposed on or because of AO3. + privacy_policy: Privacy Policy + third_party_content_html: Some of the Content displayed on or accessible via AO3 is not hosted on AO3 or by the OTW. Such content can include text, image, audio, or video files %{hosted_by_third_party_link} ("User-Embedded Content"). If you access a page that includes User-Embedded Content, the embedded file may share data with the hosted site as if you were on or at the hosted site. Although User-Embedded Content must comply with our %{content_policy_link}, it is not otherwise governed by these Terms of Service (including the AO3 %{privacy_policy_link}), and is instead governed by the terms of use or privacy policy of the service that hosts it. We reserve the right to provide an indicator to users that User-Embedded Content is present on or visible via your Content. + effective: 'Effective: November 19, 2024' + general_principles_heading: I. General Principles + general_terms: + agreement: + agreement: 'Agreement:' + any_other_form: any other form of content + content_policy: Content Policy + html: '%{agreement} AO3 hosts and shares content created by fans, for fans. Our %{content_policy_link} and %{privacy_policy_link} are part of these Terms of Service (TOS). By submitting a work; bookmark; comment; tag; link; text, image, audio, or video file; username; fannish next-of-kin; %{personal_information_link} (such as an email address); or %{any_other_form_link} ("Content") to the Archive of Our Own service (hereinafter "Service", "AO3", or "Archive"), or by creating an account and/or accessing Content on AO3, you affirm, confirm, and state that you comply with and assent to the TOS.' + personal_information: Personal Information + privacy_policy: Privacy Policy + entirety_of_agreement: + entirety_of_agreement: 'Entirety of agreement:' + html: "%{entirety_of_agreement} These Terms of Service constitute the entire agreement between you and the Organization for Transformative Works (OTW) and govern your use of AO3. They replace all prior agreements between you and the OTW concerning your use of AO3. They do not govern your use of any other OTW sites and/or projects, all of which are covered under separate agreements." + heading: I.A. General terms + jurisdiction: + html: "%{jurisdiction} The AO3 TOS, the relationship between you and the OTW, and all disputes arising out of or related to them shall be governed by the laws of the United States and specifically %{the_state_of_new_york_link}, without regard to any conflict-of-law provisions. You and the OTW agree to submit to the personal and exclusive jurisdiction of the courts located within New York County (Manhattan), New York, and to waive any objection to the laying of venue there." + jurisdiction: 'Jurisdiction:' + the_state_of_new_york: the State of New York + limitation_on_claims: + html: "%{limitation_on_claims} You agree that, regardless of any statute or law to the contrary, any claim or cause of action arising out of or related to any use of AO3 or its TOS must be filed within one (1) year after such claim or cause of action arose or be forever barred." + limitation_on_claims: 'Limitation on claims:' + no_assignment: + html: "%{no_assignment} These TOS are personal to you. You may not assign or transfer your rights or obligations under these TOS to any other person or entity, and any attempted assignment or transfer is void." + no_assignment: 'No assignment:' + non_severability: + html: "%{non_severability} The OTW's failure to enforce any part of the TOS will not waive the OTW's ability to enforce it. Any waiver with regard to a specific instance shall not constitute a waiver of any other breaches of the TOS, even with regard to the same user. If any provision of the TOS is found by a court of competent jurisdiction to be invalid, you agree that the court should give effect to the party's intentions as reflected in the provision, and that all other provisions of the TOS remain in full force and effect." + non_severability: 'Non-severability:' + license_html: The AO3 %{terms_of_service_link}, including the %{content_policy_link} and %{privacy_policy_link}, are licensed under the %{cc_attribution_4_0_international_link}. + page_content_landmark: Main Text + page_heading: Terms of Service + potential_problems: + account_termination_liability: You agree that the OTW shall not be liable to you or any third party for any limitations on, or termination of, your access to AO3. The OTW may change, put on hiatus, restrict or prohibit access to, or end AO3 or parts of its services at any time. + breach_notification: If we learn of a breach which compromises the security or confidentiality of the Personal Information of AO3 users, we will notify affected users and relevant supervisory authorities as required by law as soon as practicable. + content_access_liability: You agree that the OTW shall not be liable to you for any claim arising out of Content you make available, your connection to AO3, your use of AO3 or its TOS, or your violation of anyone else's rights. In other words, the OTW is not liable to you for allowing you to post, access, or download Content, or use or interact with AO3. The OTW does not assume whatever legal risks you face by posting, accessing, or doing other things with Content. + damage_liability: You expressly agree that, to the maximum extent permitted by law, the OTW shall not be liable to you for any damages of any kind (even if the OTW has been advised of the possibility of such damages) resulting from AO3, including but not limited to your use of or inability to use AO3; unauthorized access to or changes in Content or information you submit; and the actions and statements of third parties who use AO3. + disclaim_warranties_html: The OTW expressly disclaims all warranties of any kind, whether express or implied, including (but not limited to) the implied warranties of %{merchantability_link}, %{fitness_for_purpose_link}, and non-infringement. The TOS govern your use of AO3, and therefore no communication from anyone associated with the OTW will create any warranty that isn't expressly stated in the TOS. + fitness_for_purpose: fitness for a particular purpose + heading: I.C. Potential problems with AO3 + merchantability: merchantability + not_personal_storage_html: AO3 is not intended to be used as a personal storage or file recovery service. %{sole_backup_responsibility} + own_risk: Any material you access through AO3 in any way is at your own risk. You will be solely responsible for any damage or loss of data that results from accessing any such material. + service_as_is: The OTW provides services, including AO3, on an "as is" and "as available" basis. The OTW does not warrant (that is, does not make a legally binding promise) that our services will meet your requirements; that our services will be uninterrupted, timely, secure, or error-free; or that the results you get from using our services will be accurate, reliable, or satisfactory to you. + sole_backup_responsibility: You are solely responsible for backing up any Content that you submit to AO3. The OTW will not be liable for any lost or unrecoverable Content. + privacy_policy: Privacy Policy + registration_and_email_addresses: + agree_current_address_html: As part of your registration, you agree to provide an accurate and current email address and to update the address as necessary. If your email address is inaccurate or not current, we may %{suspend_your_account_link}. + email_is_yours_html: By registering or otherwise using an email address in connection with AO3, you assert that the email address is yours and that we may %{lawfully_communicate_with_you_link} as otherwise provided in the TOS. + heading: I.G. Registration and email addresses + lawfully_communicate_with_you: lawfully communicate with you + suspend_your_account: suspend your account + terms_of_service: Terms of Service + toc: + header: Table of Contents for the Terms of Service (TOS) + intro: There are three parts to the AO3 Terms of Service. The General Principles are the first part of the TOS. + updates_to_the_tos: + content_policy: Content Policy + heading: I.B. Updates to the Terms of Service + html: 'You can learn about changes to the TOS by visiting AO3. The TOS, including the %{content_policy_link} and %{privacy_policy_link}, may be modified at any time through the following process: Proposed changes will first be prominently disclosed on AO3 for a public comment period lasting at least two weeks. After the end of the comment period, proposed changes will be voted on by the OTW Board. If the OTW Board votes in favor, the changes will become effective when posted to the relevant Terms page(s). This is the only means by which the TOS may be altered. The TOS cannot be changed by emails or other communications with you.' + privacy_policy: Privacy Policy + what_we_believe: + ao3_run_by_html: Sunset is run by One Person on an HP Envy in its basement. Be nice to me! Be nice! + defending_fanworks: defending fanworks against legal challenges + faq: + abbreviated: FAQ + full: Frequently Asked Questions + header: Rules and Terms of Service + maximum_inclusiveness: maximum inclusiveness of fanwork content + on_the_otw_site: on the OTW site + our_goal_html: All existing members under the age of 18 will be grandfathered in; as of Sept 18, 2025, this website is 18+ only. Sorry! + readability_html: Don't plagiarize. Don't upload things like links to illegal material I don't want to get in trouble. Also NO KO-FI, PATREON, OR SIMILAR FINANCIAL DONATION LINKS PLEASE. I support you supporting yourself but it can land me in legal trouble. Uh what else. Don't harass anyone else, but hopefully you already know that! + tos_faq_html: TOS %{faq_abbreviation} + we_do_not_sell_html: DO NOT post sexual/nsfw RPF of minors on this site. DO NOT post hyperrealistic drawings of characters under the age of 14 occurring in sexual contexts. If you're not sure if a drawing will count as hyperrealistic, please email me. I COMPLETELY support freedom of fiction, but these are two things I don't feel comfortable hosting here for a variety of reasons. + what_we_do_with_content: + agree_otw_can_copy_html: You agree that we can make those copies and show your Content to other people. Specifically, by submitting Content, you grant the OTW a %{worldwide_royalty_free_nonexclusive_license_link} to make your Content available. "Making available" includes distributing, reproducing, performing, displaying, compiling, and modifying or adapting. %{modifying_or_adapting_link} here refers strictly to how your work is displayed, not how it is written, drawn, or otherwise created. User-provided tags may be modified or organized, which is a process we call %{tag_wrangling_link}. + challenge: Challenge + content_not_completely_controlled_html: You may provide Content to a part of AO3 that you do not completely control. For example, you may decide to %{orphan_link} a work; participate in a %{challenge_link}; comment on someone else's work; or comment on an official AO3 or OTW post, which may be %{subject_to_moderation_link}. Where this is the case, by submitting Content to those parts of AO3, you agree to the %{rules_for_removing_such_content_link} on those parts of AO3. + heading: I.E. What we do with Content + license_duration: Subject to the next paragraph of this policy, this license exists only for as long as you choose to continue to include such Content on AO3. It will terminate within a reasonable time after you remove (or the OTW removes) such Content from AO3. We will always strive to make your Content unavailable to users as soon as possible should you choose to delete it. However, if the Content is not attached to an account you control, you may be unable to delete that Content. Although removed Content will not be publicly available through AO3, we may retain backup copies for longer periods for legal and disaster recovery purposes. These copies may be accessible to AO3 and OTW administrators. If you delete Content from AO3 or edit Content in a manner that overwrites Content that you had previously submitted, we cannot restore it at your request. + modifying_or_adapting: Modifying or adapting + no_copyright_ownership_html: The OTW does not claim any copyright in or ownership of your Content. %{we_repeat} Nothing in this agreement changes that in any way. However, running AO3 requires us to make copies, and backup copies, on servers that may be located anywhere around the world. + open_doors: Open Doors + orphan: Orphan + preserve_for_legal_reasons_html: You acknowledge and agree that the OTW may preserve Content and may disclose Content if required to do so by law or in the good-faith belief that such preservation or disclosure is reasonably necessary to comply with legal processes; enforce the TOS; respond to claims that any Content violates the rights of third parties; or protect the rights, property, or personal safety of the OTW, users of the OTW's services, or the public. Refer to the %{privacy_policy_link} for details about when we may preserve and/or disclose your Personal Information. + privacy_policy: Privacy Policy + rules_for_removing_such_content: rules for removing and retaining such Content + some_content_open_doors_html: Some of the Content hosted on AO3 is imported via %{open_doors_link}. Open Doors' agreement with each collection's archivist is separate from AO3's TOS. If a work has been imported via Open Doors and its creator requests that the work be removed from AO3, we will remove it. If an archivist chooses to remove their imported collection, any imported works that have been claimed or Orphaned by their creators will remain on AO3. + subject_to_moderation: subject to moderation + tag_wrangling: tag wrangling + we_repeat: 'We repeat: we do not own your Content.' + worldwide_royalty_free_nonexclusive_license: worldwide, royalty-free, nonexclusive license + what_you_cant_do: + account_if_age_barred_html: to create an account if you are an %{age_barred_individual_link}; + age_barred_individual: Age-Barred Individual + break_applicable_law: to break any law that applies to you, including any rules or regulations having the force of law. As a general rule, AO3 follows U.S. law. Each user is responsible for knowing the laws of their own country. + commercial_activity_html: to conduct any commercial activity, whether for direct or indirect commercial advantage, including (without limitation) %{making_available_any_advertising_link}, spam, or other solicitation, or scraping Content in order to commercialize it; + comprehensive_trade_embargo: comprehensive trade embargo + content_policy: Content Policy + content_violating_policy_html: to make available any Content that violates the %{content_policy_link}; + copyright_infringement_html: to make available any Content that a court has ruled constitutes %{infringement_of_a_copyright_link}, patent, trademark, or trade secret; or that violates any other rights of a third party (as consistent with the OTW's %{position_on_fanwork_legality_link}); + forge_identifiers: to forge or otherwise manipulate identifiers (such as email headers or other information intended to route or authenticate Content) in order to disguise the origin of any Content transmitted to or through any OTW sites, servers, networks, or services; + function: function + heading: I.F. What you can't do + impersonate_any_person_or_entity: impersonate any person or entity + impersonate_person_or_entity_html: to %{impersonate_any_person_or_entity_link} (including, but not limited to, an AO3 or OTW representative or volunteer, or an AO3 %{function_link}), or to falsely state or otherwise misrepresent your affiliation with a person or entity; + infringement_of_a_copyright: infringement of a copyright + interfere_disrupt_ao3: interfere with or disrupt AO3 + interfere_disrupt_ao3_html: to %{interfere_disrupt_ao3_link}, any OTW-hosted Content, or any services, sites, servers, or networks connected to OTW sites; + making_available_any_advertising: making available any advertising + position_on_fanwork_legality: position on fanwork legality + resident_embargo_country_html: to create an account if you are a resident or national of any country with which the U.S. has prohibited transactions by mandating a %{comprehensive_trade_embargo_link}, as detailed by the Office of Foreign Assets Control; or + software_viruses: to make available any material that contains software viruses or other computer code, files, or programs designed to interrupt, destroy, or limit the functionality of any computer, hardware, or telecommunications equipment; + you_agree_not_to: 'You agree not to use AO3 (as well as the email addresses and URLs of OTW sites):' + tos_navigation: + content: Content Policy + privacy: Privacy Policy + top: "%{arrow} Top" + tos: Terms of Service + tos_faq: TOS FAQ + tos_toc: + content: + commercial_promotion: Commercial Promotion + copyright_infringement: Copyright Infringement + fanworks: Fanworks + harassment: Harassment + header: Content Policy + header_current: Content Policy (current section) + illegal_and_inappropriate_content: Illegal and Inappropriate Content + impersonation: Impersonation + intro: Content Policy Introduction + mandatory_tags: Mandatory Tags + offensive_content: Offensive Content + personal_information_and_fannish_identities: Personal Information and Fannish Identities + plagiarism: Plagiarism + user_icons: User Icons + privacy: + aggregate_and_anonymous_information: Aggregate and anonymous information + applicability: Applicability + contact_us: Contact us + header: Privacy Policy + header_current: Privacy Policy (current section) + information_shared_with_third_parties: Information shared with third parties + intro: Privacy Policy Introduction + retention_of_personal_information: Retention of Personal Information + scope_of_personal_information_we_process: Scope of Personal Information we process + termination_of_account: Termination of account + types_of_personal_information_we_collect_and_process: Types of Personal Information we collect and process + your_rights_under_applicable_data_privacy_laws: Your rights under applicable data privacy laws + tos: + abuse_policy: Abuse Policy + age_policy: Age Policy + content_you_access: Content you access when using AO3 + general_terms: General terms + header: General Principles + header_current: General Principles (current section) + intro: General Principles Introduction + potential_problems: Potential problems with AO3 + registration_and_email_addresses: Registration and email addresses + updates_to_the_tos: Updates to the Terms of Service + what_we_do_with_content: What we do with Content + what_you_cant_do: What you can't do + invitations: + invitation: + copy_and_use: Copy and use + copy_link: Copy link + created_at: Created at + deleted_user: Deleted User + email_address_label: Enter an email address + invitation_token: Invitation token + last_resent_at: Last resent at + queue: queue + redeemed_at: Redeemed at + redeemed_by: Redeemed by + sender: Sender + sent_at: Sent at + sent_to: Sent to + user_id_deleted: User %{user_id} (Deleted) + user_invitations: + table: + actions: + copy_and_use: Copy and use + delete: Delete + delete_confirmation: Are you sure you want to delete this invitation? + caption: Invitation Information + headings: + copy_link: Copy Link + external_author: External Author + sent_to: Sent To + token: Token + username: Username + summary: List of your invitation tokens and information regarding who you shared them with, along with the option to share unused tokens. + invite_requests: + index_closed: + already_requested_html: If you have already requested an invitation, you can %{check_waitlist_position_link}. + check_waitlist_position: check your position on the waiting list + page_heading: Invitation Requests + queue_disabled: + closed: New invitation requests are currently closed. + html: "%{closed_bold} For more information, please check the %{news_link}." + news: '"Invitations" tag on Sunset News' + waiting_list_count: + one: There is %{count} person remaining on the waiting list. + other: There are %{count} people remaining on the waiting list. + index_open: + add_to_list: Add me to the list + already_requested_html: If you have already requested an invitation, you can %{check_waitlist_position_link}. + check_waitlist_position: check your position on the waiting list + content_policy: Content Policy + details_html: To get a free Sunset account, you need an Invitation. By submitting your email address to our invitation queue, you confirm that you are at least 18 years old. We will use the email address you submit only to send you an Invitation and to process/manage your account activation. Please don't request an Invitation unless you've read our %{tos_link}, including the %{content_policy_link}, and agree to abide by those Terms. + frequency: + one: hour + other: "%{count} hours" + invitation_number: + one: "%{count} invitation" + other: "%{count} invitations" + invitation_send_rate: We are sending out %{queue_invitation_number} every %{queue_frequency}. + page_heading: Invitation Requests + privacy_policy: Privacy Policy + request_invitation_header: Request an invitation + tos: Terms of Service + waiting_list_count: + one: There is currently %{count} person on the waiting list. + other: There are currently %{count} people on the waiting list. + invitation: + after_cooldown_period: + not_resent: + one: Because your invitation was sent more than an hour ago, you can have your invitation resent. + other: Because your invitation was sent more than %{count} hours ago, you can have your invitation resent. + resent_html: + one: Because your invitation was resent more than an hour ago, you can have your invitation resent again, or you may want to %{contact_support_link}. + other: Because your invitation was resent more than %{count} hours ago, you can have your invitation resent again, or you may want to %{contact_support_link}. + before_cooldown_period: + one: If it has been more than an hour since you should have received your invitation, but you have not received it after checking your spam folder, you can visit this page to resend the invitation. + other: If it has been more than %{count} hours since you should have received your invitation, but you have not received it after checking your spam folder, you can visit this page to resend the invitation. + contact_support: contact Support + info: + not_resent: Your invitation was emailed to this address on %{sent_at}. If you can't find it, please check your email spam folder as your spam filters may have placed it there. + resent: Your invitation was emailed to this address on %{sent_at} and resent on %{resent_at}. If you can't find it, please check your email spam folder as your spam filters may have placed it there. + resend_button: Resend Invitation + title: Invitation Status for %{email} + invite_request: + date: 'At our current rate, you should receive an invitation on or around: %{date}.' + position_html: You are currently number %{position} on our waiting list! + title: Invitation Status for %{email} + no_invitation: + email_not_found: Sorry, we can't find the email address you entered. + show: + instructions_html: To check on the status of your invitation, go to the %{status_link} and enter your email in the space provided. + status: + frequency: + one: hour + other: "%{count} hours" + heading: Invitation Request Status + invitation_number: + one: "%{count} invitation" + other: "%{count} invitations" + invitation_send_rate: We are sending out %{queue_invitation_number} every %{queue_frequency}. + search: Look me up + waiting_list: + one: There is currently %{count} person on the waiting list. + other: There are currently %{count} people on the waiting list. + kudos: + guest_header: + one: "%{count} guest has also left kudos" + other: "%{count} guests have also left kudos" + user_links: + more_link: + one: "%{count} more user" + other: "%{count} more users" + languages: + form: + abuse_support_available: Abuse support available + name: Name + required_notice: Required information + short: Abbreviation + sortable_name: Name for alphabetical sorting + submit: + create: Create Language + update: Update Language + support_available: Support available + index: + language_code_format_html: "(%{code})" + navigation: + add: Add a Language + edit: Edit + suggest: Suggest a Language + page_heading: Work Languages + works_count: + one: "%{formatted_count} work" + other: "%{formatted_count} works" + layouts: + banner: + hide: hide banner + footer: + about: + content_policy: . + diversity_statement: Diversity Statement + dmca_policy: DMCA Policy + header: About the Archive + privacy_policy: . + site_map: Site Map + tos: Terms of Service + contact_us: + header: Contact Us + pac: Policy Questions & Abuse Reports + support: Technical Support & Feedback + customize: + default: Default + header: Customize + development: + archive_version: otwarchive %{version_number} + gpl_2_0_or_later: GPL-2.0-or-later + header: Development + known_issues: Known Issues + license_details_html: "%{license_link} by the OTW" + view_license: View License + landmark: Footer + otw: + abbreviated: Sunset + full: Sunset + header: + collections: + new: New Collection + javascript: While we've done our best to make the core functionality of this site accessible without JavaScript, it will work better with it enabled. Please consider turning it on! + login: Log In + nav: + about: About + browse: Browse + fandoms: Fandoms + label: Site + search: Search + proxy_notice: + button: Dismiss Notice + faux_heading: 'Important message:' + point1: You are using a proxy site that is not part of the Archive of Our Own. + point2: The entity that set up the proxy site can see what you submit, including your IP address. If you log in through the proxy site, it can see your password. + tos_prompt: + agree_and_consent: I agree/consent to these Terms + content: Content + content_policy: Content Policy + data_processing_agreement: By checking this box, you consent to the processing of your personal data in the United States and other jurisdictions in connection with our provision of Sunset and its related services to you. You acknowledge that the data privacy laws of such jurisdictions may differ from those provided in your jurisdiction. For more information about how your personal data will be processed, please refer to our Privacy Policy. + learn_more_html: To learn more, check out our %{tos_link}. + page_heading: Sunset + privacy_policy: Privacy Policy + read_and_understood: I have read & understood the 2025 Terms of Service, including the Content Policy and Privacy Policy. + summary_html: On the Sunset, users can create femslash (F/F, NB/F, NB/NB) works, bookmarks, comments, tags, and other %{content_link}. Any information you publish on Sunset may be accessible by the public, Sunset users, and/or Sunset personnel. Be mindful when sharing personal information, including but not limited to your name, email, age, location, personal relationships, gender or sexual identity, racial or ethnic background, religious or political views, and/or account usernames for other sites. You also agree to be nice to the admin, as the admin is one person who runs this website singlehandedly. + tos: Terms of Service + media: + index: + all: All %{media_type}... + page_heading: Fandoms + menu: + menu_about: + about_us: About Us + donate: Donate + faq: FAQ + news: News + wrangling_guidelines: Wrangling Guidelines + menu_browse: + bookmarks: Bookmarks + collections: Collections + tags: Tags + works: Works + menu_fandoms: + all: All Fandoms + menu_search: + bookmarks: Bookmarks + people: People + tags: Tags + works: Works + muted: + mute: Mute + muted_items_notice_html: You have muted some users on the Archive. Some items may not be shown, and any counts may be inaccurate. You can mute or unmute users on %{muted_users_link}. + muted_users_link_text: your Muted Users page + unmute: Unmute + users: + confirm_mute: + block_users_instead_html: To prevent a user from commenting on your works or replying to your comments elsewhere on the site, visit %{blocked_users_link}. + blocked_users_link_text: your Blocked Users page + button: Yes, Mute User + cancel: Cancel + mute: mute + restore_site_skin_faq_link_text: instructions for reverting to the default site skin + site_skin_warning_html: Please note that if you are not using the default site skin, muting may not work properly. The Skins and Archive Interface FAQ has %{restore_site_skin_faq_link}. + sure_html: Are you sure you want to %{mute} %{username}? + title: Mute %{name} + will: + intro: 'Muting a user:' + seeing_content: completely hides their works, series, bookmarks, and comments from you; there will be no empty space, placeholder text, or other indication something has been removed + will_not: + hide_content_for_others: hide their works, series, bookmarks, and comments from anyone else + intro: 'Muting a user will not:' + prevent_emails: prevent you from receiving comment or subscription emails from this user + confirm_unmute: + button: Yes, Unmute User + cancel: Cancel + resume: + intro: 'Unmuting a user allows you to:' + see_content: see their works, series, bookmarks, and comments on the site + sure_html: Are you sure you want to %{unmute} %{username}? + title: Unmute %{name} + unmute: unmute + index: + block_users_instead_html: To prevent a user from commenting on your works or replying to your comments elsewhere on the site, visit %{blocked_users_link}. + blocked_users_link_text: your Blocked Users page + button: Mute + heading: + landmark: + muted_users: Listing Muted Users + label: User + legend: Mute a user + muted_users: Muted Users + none: You have not muted any users. + restore_site_skin_faq_link_text: instructions for reverting to the default site skin + site_skin_warning_html: Please note that if you are not using the default site skin, muting may not work properly. The Skins and Archive Interface FAQ has %{restore_site_skin_faq_link}. + title: Muted Users + will: + intro: + one: 'You can mute up to %{mute_limit} user. Muting a user:' + other: 'You can mute up to %{mute_limit} users. Muting a user:' + seeing_content: completely hides their works, series, bookmarks, and comments from you; there will be no empty space, placeholder text, or other indication something has been removed + will_not: + hide_content_for_others: hide their works, series, bookmarks, and comments from anyone else + intro: 'Muting a user will not:' + prevent_emails: prevent you from receiving comment or subscription emails from this user + orphans: + orphan_user: + orphaning_bylines_only_message_html: Orphaning will automatically remove your personal information from bylines only. It will not automatically remove your personal information from anywhere else in the work(s). Social media accounts, contact information, email addresses, names, and any other personal information posted in the title, summary, notes, tags, work body, or comment text will not be automatically removed. Comments posted by other users will also not be affected by Orphaning. If you want information removed from these places, you should edit or delete it prior to Orphaning. Once you Orphan the work(s), you will no longer be able to delete information in these places yourself. + orphaning_works_message_html: 'Orphaning will permanently remove your username and/or pseud from the bylines of: the following work(s), their chapters, associated series, and any comments you may have left on them while logged into this account.' + pagy: + aria_label: + nav: Pagination + next: Next → + prev: "← Previous" + preferences: + index: + browser_page_title_format: Browser page title format + collections_challenges_gifts: + allow_collection_invitation: Allow others to invite my works to collections. + allow_gifts: Allow anyone to gift me works. + heading: Collections, Challenges and Gifts + legend: Collections, Challenges and Gifts + turn_off_collection_emails: Turn off emails from collections. + turn_off_collection_inbox: Turn off inbox messages from collections. + turn_off_gift_emails: Turn off emails about gift works. + comments: + guest_replies_off: Do not allow guests to reply to my comments on news posts or other users' works (you can still control the comment settings for your works separately). + heading: Comments + legend: Comments + turn_off_copies_own_comments: Turn off copies of your own comments. + turn_off_emails: Turn off emails about comments. + turn_off_inbox: Turn off messages to your inbox about comments. + turn_off_kudos_emails: Turn off emails about kudos. + display: + heading: Display + hide_additional_tags: Hide additional tags (you can still choose to show them). + hide_warnings: Hide warnings (you can still choose to show them). + hide_work_skins: Hide work skins (you can still choose to show them). + legend: Display + show_adult_content: Show me adult content without checking. + show_whole_work_default: Show the whole work by default. + misc: + heading: Misc + legend: Misc + turn_off_banner_every_page: Turn off the banner showing on every page. + turn_on_history: Turn on History. + turn_on_new_user_help: Turn the new user help banner back on. + navigation: + blocked_users: Blocked Users + change_email: Change Email + change_password: Change Password + change_username: Change Username + edit_my_profile: Edit My Profile + landmark: Navigation + manage_my_pseuds: Manage My Pseuds + muted_users: Muted Users + page_heading: Set My Preferences + privacy: + allow_co_creator_invite: Allow others to invite me to be a co-creator. + heading: Privacy + hide_share_buttons: Hide the share buttons on my work. + hide_work_from_search_engines: Hide my work from search engines when possible. + legend: Privacy + public_site_skins: Public Site Skins + your_locale: Your locale + your_site_skin: Your site skin + your_time_zone: Your time zone + profile: + pseud_list: + more_pseuds: + one: "%{count} more pseud" + other: "%{count} more pseuds" + pseuds: + delete_preview: + cancel: Cancel + confirm: Are you sure? This can't be undone! + delete: + one: Delete this bookmark + other: Delete these bookmarks + heading: Pseud deletion + notice: When you delete your pseud, any works, series, or comments you have created under it will be transferred to your default pseud. + saved_bookmarks: + one: You have saved %{count} bookmark using this pseud. You can choose whether to delete it or transfer it to your default pseud. + other: You have saved %{count} bookmarks using this pseud. You can choose whether to delete them or transfer them to your default pseud. + transfer: + one: Transfer this bookmark to the default pseud + other: Transfer these bookmarks to the default pseud + pseud_blurb: + confirm_delete: Are you sure? + default_pseud: Default Pseud + delete_html: Delete%{landmark_span} + delete_landmark_text: " %{pseud}" + edit_html: Edit%{landmark_span} + edit_landmark_text: " %{pseud}" + orphan_html: Orphan Works%{landmark_span} + orphan_landmark_text: " by %{pseud}" + user_actions: User Actions + pseuds_form: + cannot_change_matching_pseud_html: You cannot change the pseud that matches your username. However, you can %{change_username_link} instead. + change_username: change your username + description: Description + icon: Icon + icon_alt: Icon alt text + icon_comment: Icon comment text + icon_delete: Delete your icon and revert to our default. This will also remove your icon alt text and comment text. + icon_notes: + current: This is your icon. + format: Icons can be in png, jpeg or gif form. + limit: You can have one icon for each pseud. + size: Icons should be sized 100x100 pixels for best results. + icon_upload: Upload a new icon + make_default: Make this name default + name: Name + submit: Submit + readings: + index: + history: + landmark: List of History Items + page_heading: History + marked_for_later: + landmark: List of Marked for Later Items + page_heading: Marked for Later + related_works: + index: + page_heading: "%{login}'s Related Works" + series: + series_order: + draft_work_title: "%{title} (DRAFT)" + skins: + confirm_delete: + confirm_html: Are you sure you want to delete the skin "%{skin_title}"? + revert_skin_form: + revert_to_default: Revert to Default Skin + subscriptions: + confirm_delete_all: + caution_html: Are you sure you want to delete all your subscriptions? This cannot be undone. + page_heading: + all: Delete All Subscriptions + series: Delete All Series Subscriptions + users: Delete All User Subscriptions + works: Delete All Work Subscriptions + submit: + all: Yes, Delete All Subscriptions + series: Yes, Delete All Series Subscriptions + users: Yes, Delete All User Subscriptions + works: Yes, Delete All Work Subscriptions + index: + button_html: Unsubscribe from %{name} + byline_html: by %{creators} + heading: + landmark: + list: List of Subscriptions + navigation: + all: All Subscriptions + delete_all: + all: Delete All Subscriptions + series: Delete All Series Subscriptions + users: Delete All User Subscriptions + works: Delete All Work Subscriptions + series: Series Subscriptions + user: User Subscriptions + work: Work Subscriptions + page_heading: + all: My Subscriptions + series: My Series Subscriptions + users: My User Subscriptions + works: My Work Subscriptions + series: "(Series)" + work: "(Work)" + tag_wranglers: + show: + last_wrangled_html: "%{wrangler_login} last wrangled at %{time}." + tags_wrangled_csv: Tags Wrangled (CSV) + tag_wranglings: + wrangler_dashboard: + characters_by_fandom: Characters by fandom (%{count}) + fandoms_by_media: Fandoms by media (%{count}) + freeforms_by_fandom: Freeforms by fandom (%{count}) + new_tag: New Tag + relationships_by_fandom: Relationships by fandom (%{count}) + search_tags: Search Tags + tag_type: + character: Characters + fandom: Fandoms + freeform: Freeforms + merger: Mergers + relationship: Relationships + subtag: SubTags + tag_type_and_count: "%{tag_type} (%{count})" + unsorted_tags: Unsorted Tags (%{count}) + use_type: + bookmarks: Bookmarks + collections: Collections + drafts: Drafts + external_works: External Works + private_bookmarks: Private Bookmarks + taggings_count: Taggings Count + works: Works + use_type_and_count: "%{use_type} (%{count})" + wranglers: Wranglers + wrangling_home: Wrangling Home + wrangling_tools: Wrangling Tools + tags: + edit: + save_changes: Save changes + submit_legend: Submit + index: + about: + popular: These are some of the most popular tags used on the Archive. To find more tags, %{search_tags_link}. + popular_in_collection: These are some of the most popular tags used in the collection. + random: These are some random tags used on the Archive. To find more tags, %{search_tags_link}. + random_in_collection: These are some random tags used in the collection. + search_tags: try our tag search + search_form: + fandoms: Fandoms + fandoms_footnote: Find tags wrangled to specific canonical fandoms. + search_tags: Search Tags + sort_by: Sort by + sort_direction: Sort direction + status_option: + any_status: Any status + canonical: Canonical + canonical_or_synonymous: Canonical or synonymous + noncanonical: Non-canonical + noncanonical_and_nonsynonymous: Non-canonical and non-synonymous + synonymous: Synonymous + tag_name: Tag name + type: Type + wrangling_status: Wrangling status + show: + canonical_html: It's a %{canonical_tag_link}. You can use it to %{filter_works_link} and to %{filter_bookmarks_link}. + canonical_tag: canonical tag + fandom_relationship_tags: Relationship tags in this fandom + filter_bookmarks: filter bookmarks + filter_works: filter works + list_fandom_tags_html: You can also access a list of %{fandom_relationship_tags_link}. + time: + formats: + date_short_html: %a %d %b %Y + troubleshooting: + show: + fix_associations: + description: Try to delete invalid associations involving this tag (e.g., parents of the wrong type, children of the wrong type, duplicate parents/children/metatags/subtags, etc.). Most of these impossible relationships appear on tag landing pages. + title: Fix Tag Associations + fix_counts: + description: Try to recalculate some counts associated with this tag (both filter counts and taggings counts). Keep in mind that the tag counts listed in the fandom lists include unrevealed works and drafts, so if the count is only a little off it may just be unrevealed works or drafts. + title: Fix Tag Counts + fix_meta_tags: + description: Try to recalculate inherited metatags. Use this option if this tag has grandparent metatags (i.e., a metatag with its own metatag), and the works aren't showing up in the grandparent's listing. You might also try this if you've removed a metatag, but the works are still showing up in the former metatag's listing. If the works still don't go away, ask a staffer to run "Update Tag Filters" on this tag. + title: Fix Metatags + page_description: + tag: If this tag is exhibiting undesirable behavior, try one of these options to fix it. + work: If this work is exhibiting undesirable behavior, try one of these options to fix it. + page_title: + tag: Troubleshoot Tag + work: Troubleshoot Work + reindex_tag: + description: Reindex this tag and all related works, bookmarks, series, pseuds, and external works. Use this option if none of the others have worked. It will not fix autocomplete issues. + title: Reindex Tag + reindex_work: + description: Send in this work to be reindexed. Use this option if the work isn't appearing in searches, or is appearing in searches that it shouldn't. (e.g. If someone has orphaned their work and it can still be found with the old name, or if it's not behaving as expected when you filter crossovers, completion status, word count, etc.) + title: Reindex Work + update_tag_filters: + description: Recalculate filters for all works directly tagged with this tag or one of its synonyms. Does not include subtags. Use this option if the filters include old canonical tags that have been renamed or old parent tags that works aren't tagged with, or if the tag counts are wildly off. Also use this option if the works from a synonym are not showing on the works page of the canonical within a half hour of the tag being synned. Keep in mind that the tags listed in the filters will never be 100% correct. + title: Update Tag Filters + update_work_filters: + description: Recalculate the filters for this work based on the current set of tags. Use this option if wrangling seems to have gone wrong. (e.g. If you synned one of this work's tags to a canonical but it's not showing up in the tag listings, or if the wrong tags are listed in the sidebar when you drill down to a search that includes only this work.) + title: Update Work Filters + users: + admin_change_username: + description: Change the name of this user to a generic name in the format user + their account ID. + navigation: + manage_user: Manage User + new_username_footnote: This username cannot be edited. If you need to change it to a different name, contact your chair. + page_heading: Change Username + ticket_id: Ticket ID + change_email: + caution: + check_spam_html: "%{must_confirm_bold} Please check your spam folder or %{contact_support_link} if you do not receive the confirmation email." + confirm_by: If you don't confirm your request by %{date}, your email address will not be changed. + contact_support: contact Support + must_confirm: You must use the link in the confirmation email in order to finish confirming your email change. + requested_change_html: You have requested to change your email address to %{unconfirmed_email}. A confirmation email has been sent to this address. + form: + confirm: Confirm New Email + current_email: Current email + email_again: Enter new email again + new_email: New email + password: Password + submit_landmark: Submit + heading: Change Email + invalidate: invalidate any pending email change requests + must_confirm: + one: You must use the link in the confirmation email in order to finish confirming your email change. If you don't confirm your request within %{count} day, the link will expire and your email address will not be changed. + other: You must use the link in the confirmation email in order to finish confirming your email change. If you don't confirm your request within %{count} days, the link will expire and your email address will not be changed. + request_for_confirmation: Changing your email will send a request for confirmation to your new email address and a notification to your current email address. + resubmission_html: Resubmitting this form with a new email address will %{invalidate_bold}. + change_username: + account_faq: Account FAQ + caution: Please use this feature with caution. + change_window: + one: You can change your username once per day. + other: You can change your username once every %{count} days. + confirm: Are you sure you want to change your username? + contact_support: contact Support + create_a_new_pseud: create a new Pseud + current_username: Current username + heading: Change Username + last_renamed: You last changed your username on %{renamed_at}. + legend: Change Username + more_info_html: For information on how changing your username will affect your account, please check out the %{account_faq_link}. Note that changes to your username may take several days or longer to appear. If you are still seeing your old username on your works, bookmarks, series, or collections after a week, please %{contact_support_link}. + new_pseud_instead_html: If that is not what you want, you can %{create_a_new_pseud_link} instead. + new_username: New username + page_heading: Change My Username + password: Password + submit: Change Username + submit_landmark: Submit + username_requirements: "%{minimum} to %{maximum} characters (A-Z, a-z, _, 0-9 only), no spaces, cannot begin or end with underscore (_)" + confirm_change_email: + are_you_sure_html: Are you sure you want to change your email address to %{unconfirmed_email}? A confirmation email will be sent to this address. + cancel: Cancel + confirm: Yes, Change Email + confirm_via_link_html: You must use the link in the confirmation email in order to finish confirming your email change. %{if_not_confirm_bold} + heading: Confirm New Email + if_not_confirm: + one: If you don't confirm your request within %{count} day, the link will expire and your email address will not be changed. + other: If you don't confirm your request within %{count} days, the link will expire and your email address will not be changed. + confirmation: + contact_support: contact Support + go_back: Return to Archive front page + important: Important! + must_activate: + one: You must activate your account within %{count} day, or your account will expire. If this happens, you can sign up again using the same invitation. + other: You must activate your account within %{count} days, or your account will expire. If this happens, you can sign up again using the same invitation. + no_email_html: If you haven't received this email within 24 hours, and you don't find our email in your spam filter or Social folder, please %{contact_support_link} for help. + page_heading: Almost Done! + receive_email_html: You should soon receive an activation email at the address you gave us. This will have the link you need to follow in order to activate your account and complete the account creation process. The activation email will come from %{return_address} -- you might want to add this to your address book to make sure you get the email. + delete_preview: + cancel: Cancel + co_creations: + legend: Works You Made With Others + orphan_info: You are not able to delete these as they are shared works, but you can %{orphan_link} them or remove yourself completely as a co-creator. + summary: 'You have %{work_count} work(s) co-created with the following users: %{co_creators}.' + confirm: Are you sure? This can't be undone! + heading: What do you want to do with your works? + options: + delete: Delete completely + keep_pseud: Leave my pseud but attach to the orphan account + orphan_pseud: Change my pseud to "orphan" and attach to the orphan account + remove: Remove me completely as co-creator + orphan: orphan + orphaning: orphaning + sole_creations: + collections_summary: 'You have %{collection_count} collection(s) under the following pseuds: %{pseuds}.' + legend: Works and Collections You Made By Yourself + options_info: You can delete them, but please consider %{orphaning_link} them instead! + works_summary: 'You have %{work_count} work(s) under the following pseuds: %{pseuds}.' + submit: Save + edit: + about_me: About Me + browser_title: Edit Profile + change_profile_landmark: Change Profile + page_heading: Edit My Profile + privacy_policy: Privacy Policy + public_information_notice_html: Any personal information you post on your public Sunset profile, including but not limited to your name, email, age, location, personal relationships, gender or sexual identity, racial or ethnic background, religious or political views, and/or account usernames for other sites, will be accessible by the general public. To learn more about what data Sunset collects when you're on the site and how we use it, check out our %{privacy_policy_link}. + title: Title + update: Update + edit_header_navigation: + change_email: Change Email + change_password: Change Password + change_username: Change Username + edit_default_pseud_and_icon: Edit Default Pseud and Icon + edit_profile: Edit Profile + edit_user_navigation: + change_email: Change Email + change_password: Change Password + change_username: Change Username + edit_default_pseud_and_icon: Edit Default Pseud and Icon + edit_my_profile: Edit My Profile + header_navigation: + admin_user: User Administration + edit_multiple: Edit Works + invitations: Invitations + new_work: Post New + passwords: + new: + email_or_username_html: Email address %{or} username + instructions: If you've forgotten your password, we can send instructions that will allow you to reset it. Please tell us the username or email address you used when you signed up for your Archive account. + or: or + page_heading: Forgotten your password? + reset_password: Reset Password + registrations: + legal: + agreement_confirm: Yes, I have read the Terms of Service, including the Content Policy and Privacy Policy, and agree to them. + agreement_required_html: Before you begin using Sunset, you must agree to our %{terms_of_service_link}, including the %{content_policy_link} and %{privacy_policy_link}. + content_policy: Content Policy (opens in new window) + data_processing_confirm: By checking this box, you consent to the processing of your personal data in the United States and other jurisdictions in connection with our provision of AO3 and its related services to you. You acknowledge that the data privacy laws of such jurisdictions may differ from those provided in your jurisdiction. For more information about how your personal data will be processed, please refer to our Privacy Policy. + over_thirteen_confirm: Yes, I am at least 18. + over_thirteen_required: You need to be at least 18 years old to become a registered member of the Archive. (Sorry to anyone younger! You'll be more than welcome when the time comes.) + privacy_policy: Privacy Policy (opens in new window) + terms_of_service: Terms of Service (opens in new window) + new: + cancel: Cancel + heading: Create Account + legend: + legal: Legal Agreements + user: User Details + submit: Create Account + wait: Please wait... + passwd: + confirm_password: Confirm password + confirm_password_validation: Please enter the same password in both fields. + password: Password + password_requirements: "%{minimum} to %{maximum} characters" + password_validation: Please enter a password! (At least %{minimum} letters long, please.) + username: Username + username_requirements: "%{minimum} to %{maximum} characters (A-Z, a-z, _, 0-9 only), no spaces, cannot begin or end with underscore (_)" + username_validation: You need a username! (At least %{minimum} letters long, please.) + valid_email: Valid email + sessions: + greeting: + nav: + assignments: My Assignments + bookmarks: My Bookmarks + collections: My Collections + dashboard: My Dashboard + greeting: Hi, %{current_user}! + history: My History + import: Import Work + label: User + log_out: Log Out + new_work: New Work + open_doors: Open Doors + post: Post + post_draft: From Draft + preferences: My Preferences + sign_ups: My Sign-ups + subscriptions: My Subscriptions + tag_wrangling: Tag Wrangling + works: My Works + new: + beta_reminder: + give_feedback: give us your feedback + reminder: 'Reminder:' + report_bugs: Please report any pesky bugs and %{give_feedback_link}! + warning: This site is in beta. Things may break or crash without notice. + login: + create_account: Create an account now + forgot: Forgot your password or username? %{reset_password_link}. + log_in: Log in + no_account: Don't have an account? %{join_link}. + request_invite: Request an invitation to join + reset_password: Reset password + restricted: + account_exists: If you already have a Sunset account, log in now. + commenting_unavailable: Commenting on this work is only available to registered users of the Archive. + no_account: If you don't have an account, you can %{request_invite_link}. + request_invite: request an invitation to join + signup: Or join us for free - it's easy. + sorry: Sorry! + work_unavailable: This work is only available to registered users of the Archive. + passwd: + landmark_submit: Submit + log_in: Log in + password: 'Password:' + remember_me: Remember me + username_or_email: 'Username or email:' + passwd_small: + create_an_account: Create an Account + forgot_password: Forgot password? + get_an_invitation: Get an Invitation + log_in: Log In + password: 'Password:' + remember_me: Remember Me + username_or_email: 'Username or email:' + show: + login_banner: + contact_abuse: contact our Policy & Abuse team + contact_support: contact our Support team + content_policy: Content Policy + dismiss: Dismiss permanently + help_html: If you need technical support, %{contact_support_link}. If you experience harassment or have questions about our %{tos_link} (including the %{content_policy_link} and %{privacy_policy_link}), %{contact_abuse_link}. + hide: Hide first login help banner + new_user_tips: useful tips for new users + our_faqs: our FAQs + privacy_policy: Privacy Policy + tos: Terms of Service + welcome_html: Hi! It looks like you've just logged in to Sunset for the first time. For help getting started on Sunset, check out some %{new_user_tips_link} or browse through %{our_faqs_link}. + sidebar: + catch: + history: History + inbox: Inbox (%{inbox_number}) + statistics: Statistics + subscriptions: Subscriptions + choices: + all_pseuds: All Pseuds (%{pseud_number}) + dashboard: Dashboard + preferences: Preferences + profile: Profile + pseud_switcher: Pseud Switcher + pseuds: Pseuds + skins: Skins + landmark: + catch: Catch + choices: Choices + pitch: Pitch + switch: Switch + pitch: + collections: Collections (%{coll_number}) + drafts: Drafts (%{drafts_number}) + switch: + assignments: Assignments (%{assignment_number}) + claims: Claims (%{claim_number}) + co_creator_requests: Co-Creator Requests (%{count}) + related_works: Related Works (%{related_works_number}) + sign_ups: Sign-ups (%{signup_number}) + works: + adult: + caution: This work could have adult content. If you continue, you have agreed that you are willing to see such content. + footnote: If you accept cookies from our site and you choose "Yes, Continue", you will not be asked again during this session (that is, until you close your browser). If you log in you can store your preference and never be asked again. + navigation: + back: No, Go Back + continue: Yes, Continue + preferences: Set your preferences now + page_title: Adult Content Warning + associations: + language: + choose: Choose a language + title: Associations + byline: + add_co-creators: Add co-creators + show_co-creator_options: Add co-creators? + edit_tags: + content_policy: Content Policy + post_notice_html: All works you post on Sunset must comply with our %{content_policy_link}. For more information, please refer to our %{tos_faq_link}. + tos_faq: Terms of Service FAQ + import: + draft_work_title_html: "%{work_link} (Draft)" + page_heading: Imported Works + success: We were able to successfully upload the following works. + index: + advanced_search: try our advanced search + choose_fandom: choose a fandom + recent_works_html: These are some of the latest works posted to the Archive. To find more works, %{choose_fandom_link} or %{advanced_search_link}. + meta: + original_creators: + one: 'Original Creator ID:' + other: 'Original Creator IDs:' + navigate: + page_heading_html: Chapter Index for %{work_link} by %{creators} + new_import: + content_policy: Content Policy + post_notice_html: All works you post on Sunset must comply with our %{content_policy_link}. For more information, please refer to our %{tos_faq_link}. + tos_faq: Terms of Service FAQ + permissions: + privacy: Privacy + visibility: + import_works_restricted: Only show imported works to registered users + keep_current: Keep current visibility settings + label: Visibility + multiple_works_restricted: Only show to registered users + restricted: Only show your work to registered users + unrestricted: Show to all + preface: + title: Preface + preview: + content_policy: Content Policy + post_notice_html: All works you post on Sunset must comply with our %{content_policy_link}. For more information, please refer to our %{tos_faq_link}. + tos_faq: Terms of Service FAQ + search_box: + a11y_label: Work + label: Work Search + submit: Search + tooltip_label: 'tip:' + search_form: + creator: Creator + show: + unposted_deletion_notice_html: This work is a draft and has not been posted. The draft will be scheduled for deletion on %{deletion_date}. + show_multiple: + draft: " (Draft)" + no_works: You have no works or drafts to edit. + skin: + select: Select work skin + standard_form: + content_policy: Content Policy + post_notice_html: All works you post on Sunset must comply with our %{content_policy_link}. For more information, please refer to our %{tos_faq_link}. + tos_faq: Terms of Service FAQ + work_approved_children: + inspired_by: + restricted_html: "[Restricted Work] by %{creator_link} (Log in to access.)" + revealed_html: "%{work_link} by %{creator_link}" + title: Works inspired by this one + unrevealed: A work in an unrevealed collection + work_header_notes: + inspired_by: + other_works_inspired_by_this_one: other works inspired by this one + restricted_html: Inspired by [Restricted Work] by %{creator_link} (Log in to access.) + revealed_html: Inspired by %{work_link} by %{creator_link} + unrevealed: Inspired by a work in an unrevealed collection + jump: + endnotes_and_related_works_html: "(See the end of the work for %{endnotes_link} and %{related_works_link}.)" + endnotes_html: "(See the end of the work for %{endnotes_link}.)" + more_notes: more notes + notes: notes + related_works_html: "(See the end of the work for %{related_works_link}.)" + translated_to: + restricted_html: 'Translation into %{language} available: [Restricted Work] by %{creator_link} (Log in to access.)' + revealed_html: 'Translation into %{language} available: %{work_link} by %{creator_link}' + unrevealed_html: 'Translation into %{language} available: A work in an unrevealed collection' + translation_of: + restricted_html: A translation of [Restricted Work] by %{creator_link} (Log in to access.) + revealed_html: A translation of %{work_link} by %{creator_link} + unrevealed: A translation of a work in an unrevealed collection + work_module: + draft_deletion_notice_html: This draft will be scheduled for deletion on %{deletion_date}. + wrangling_guidelines: + show: + edit: Edit + heading: Wrangling Guidelines + wrangling_guideline_form: + content_required: You need to post some content here. + content_too_long: + one: We salute your ambition! But sadly the content must be less than %{count} letter long. + other: We salute your ambition! But sadly the content must be less than %{count} letters long. + content_too_short: + one: Brevity is the soul of wit, but your content does have to be at least %{count} letter long. + other: Brevity is the soul of wit, but your content does have to be at least %{count} letters long. + guideline_text: Guideline text + html_editor: HTML + landmark: + post: Post + post: Post + required_information: Required information + rich_text_editor: Rich Text + rich_text_notes_html: Type or paste formatted text. + title: Title + title_failure: Please enter a title. diff --git a/config/locales/views/ru.yml b/config/locales/views/ru.yml new file mode 100755 index 0000000..780a245 --- /dev/null +++ b/config/locales/views/ru.yml @@ -0,0 +1,6 @@ +ru: + layouts: + proxy_notice: + faux_heading: "Важная информация:" + point1: "Вы используете прокси-сайт, который не является частью AO3 (Нашего Архива)." + point2: "Субъект, настроивший прокси-сайт, может видеть, что вы отправляете, включая ваш IP-адрес. Если вы авторизуетесь через прокси-сайт, он может видеть ваш пароль." diff --git a/config/locales/views/uk.yml b/config/locales/views/uk.yml new file mode 100755 index 0000000..ca9f62a --- /dev/null +++ b/config/locales/views/uk.yml @@ -0,0 +1,6 @@ +uk: + layouts: + proxy_notice: + faux_heading: "Важливе повідомлення:" + point1: "Ви використовуєте проксі-сайт, який не є частиною Archive of Our Own (Нашого Власного Архіву)." + point2: "Творці цього проксі-сайту можуть бачити Ваші дані та дії, а також Вашу IP-адресу. Якщо Ви входите до свого облікового запису, використовуючи проксі-сайт, його творці можуть бачити Ваш пароль." diff --git a/config/locales/views/zh-CN.yml b/config/locales/views/zh-CN.yml new file mode 100755 index 0000000..3022729 --- /dev/null +++ b/config/locales/views/zh-CN.yml @@ -0,0 +1,6 @@ +zh-CN: + layouts: + proxy_notice: + faux_heading: "重要提示:" + point1: "您使用的是第三方开发的反向代理网站,此网站并非Archive of Our Own - AO3(AO3作品库)原站。" + point2: "代理网站的开发者能够获取您上传至该站点的全部内容,包括您的ip地址。如您通过代理登录AO3,对方将获得您的密码。" diff --git a/config/redis-cucumber.conf.example b/config/redis-cucumber.conf.example new file mode 100755 index 0000000..e72c61e --- /dev/null +++ b/config/redis-cucumber.conf.example @@ -0,0 +1,14 @@ +# RAILS_ROOT/config/redis-cucumber.conf + +daemonize yes +pidfile log/redis-cucumber.pid +port 6398 +timeout 300 +save 900 1 +save 300 10 +save 60 10000 +dbfilename redis-cucumber-dump.rdb +dir . +loglevel debug +logfile stdout +databases 16 diff --git a/config/redis.example b/config/redis.example new file mode 100755 index 0000000..a51967d --- /dev/null +++ b/config/redis.example @@ -0,0 +1,24 @@ +redis_autocomplete: + test: dev.ao3.org:6398 + development: dev.ao3.org:6379 + production: redis.ao3.org:6379 +redis_general: + test: dev.ao3.org:6398 + development: dev.ao3.org:6379 + production: redis.ao3.org:6379 +redis_hits: + test: dev.ao3.org:6398 + development: dev.ao3.org:6379 + production: redis.ao3.org:6379 +redis_kudos: + test: dev.ao3.org:6398 + development: dev.ao3.org:6379 + production: redis.ao3.org:6379 +redis_resque: + test: dev.ao3.org:6398 + development: dev.ao3.org:6379 + production: redis.ao3.org:6379 +redis_rollout: + test: dev.ao3.org:6398 + development: dev.ao3.org:6379 + production: redis.ao3.org:6379 diff --git a/config/resque_schedule.yml b/config/resque_schedule.yml new file mode 100755 index 0000000..98da4b2 --- /dev/null +++ b/config/resque_schedule.yml @@ -0,0 +1,117 @@ +run_main_reindex_queues: + every: 1m + class: "ScheduledReindexJob" + queue: utilities + args: main + description: "Kick off a reindex of all main content indexing" + +run_background_reindex_queue: + every: 11m + class: "ScheduledReindexJob" + queue: utilities + args: background + description: "Kick off a reindex of all background reindexes" + +run_add_counts_to_queue: + every: 30m + class: "ScheduledTagJob" + queue: utilities + args: add_counts_to_queue + description: "update the cache of counts of usage for tags" + +# from https://github.com/resque/resque-scheduler/issues/613#issuecomment-351484064 +run_write_redis_to_database: + every: 2m + class: ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper + queue: tag_counts + args: + job_class: RedisJobSpawner + queue_name: tag_counts + arguments: ["TagCountUpdateJob"] + description: "Flush the count updates to mysql" + +run_stats_reindex_queue: + every: 30m + class: "ScheduledReindexJob" + queue: utilities + args: stats + description: "Kick off a reindex of works with stats updates" + +run_update_filter_counts_small: + every: 2m + class: "FilterCount" + queue: utilities + args: update_counts_for_small_queue + description: "Update filter counts for small filters" + +run_update_filter_counts_large: + every: 1h + class: "FilterCount" + queue: utilities + args: update_counts_for_large_queue + description: "Update filter counts for large filters" + +# from https://github.com/resque/resque-scheduler/issues/613#issuecomment-351484064 +update_stat_counters: + cron: "0,30 * * * *" + class: ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper + queue: stats + args: + job_class: RedisJobSpawner + queue_name: stats + arguments: ["StatCounterJob"] + description: "Update kudos/bookmark/comment counts on StatCounters." + +# from https://github.com/resque/resque-scheduler/issues/613#issuecomment-351484064 +save_recent_counts_to_database: + cron: "15,45 * * * *" + class: ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper + queue: hits + args: + job_class: RedisJobSpawner + queue_name: hits + arguments: ["HitCountUpdateJob"] + description: "Save recent hit counts to database." + +remove_old_hit_count_data: + cron: "0 12 * * *" + class: "RedisHitCounter" + queue: hits + args: remove_old_visits + description: "Remove old hit count information from redis." + +check_invite_queue: + every: 1h + class: "AdminSetting" + queue: utilities + args: check_queue + description: "Invite users from the queue if it's time to do so." + +# from https://github.com/resque/resque-scheduler/issues/613#issuecomment-351484064 +readings_to_database: + cron: "55 * * * *" + class: ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper + queue: readings + args: + job_class: RedisJobSpawner + queue_name: readings + arguments: ["ReadingsJob"] + description: "Transfer readings from redis to the database." + +cleanup_work_original_creators: + every: 1h + class: "WorkOriginalCreator" + queue: utilities + args: cleanup + description: >- + Remove original_creators for works orphaned/moved more than + ORIGINAL_CREATOR_TTL_HOURS hours ago. + +disable_admin_post_comments: + every: 1d + class: "AdminPost" + queue: utilities + args: disable_old_post_comments + description: >- + Disables all comments on admin (news) posts older than the + configured window. diff --git a/config/routes.rb b/config/routes.rb new file mode 100755 index 0000000..3a34eea --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,718 @@ +Rails.application.routes.draw do + devise_scope :admin do + get "admin/logout" => "admin/sessions#confirm_logout" + + # Rails emulates some HTTP methods over POST, so password resets (PUT /admin/password) + # look the same as password reset requests (POST /admin/password). + # + # To rate limit them differently at nginx, we set up an alias for + # the first request type. + put "admin/password/reset" => "admin/passwords#update" + end + + devise_for :admin, + module: "admin", + only: [:sessions, :passwords], + controllers: { + sessions: "admin/sessions", + passwords: "admin/passwords" + }, + path_names: { + sign_in: "login", + sign_out: "logout" + } + + devise_scope :user do + get "signup(/:invitation_token)" => "users/registrations#new", as: "signup" + get "users/logout" => "users/sessions#confirm_logout" + + # Rails emulate some HTTP methods over POST, so password resets (PUT /users/password) + # look the same as password reset requests (POST /users/password). + # + # To rate limit them differently at nginx, we set up an alias for + # the first request type. + put "users/password/reset" => "users/passwords#update" + end + + devise_for :users, + module: "users", + controllers: { + sessions: "users/sessions", + registrations: "users/registrations", + passwords: "users/passwords" + }, + path_names: { + sign_in: "login", + sign_out: "logout" + } + + #### ERRORS #### + + get '/403', to: 'errors#403' + get '/404', to: 'errors#404' + get '/422', to: 'errors#422' + get '/500', to: 'errors#500' + get '/auth_error', to: 'errors#auth_error' + get "/timeout_error", to: "errors#timeout_error" + get '/statuses', to: 'statuses#redirect_to_current_user' + get '/statuses/new', to: 'statuses#redirect_to_current_user_new' #### DOWNLOADS #### + + get 'downloads/:id/:download_title.:format' => 'downloads#show', as: 'download' + + #### OPEN DOORS #### + namespace :opendoors do + resources :tools, only: [:index] do + collection do + post :url_update + end + end + resources :external_authors do + member do + post :forward + end + end + end + + #### INVITATIONS #### + + resources :invitations + resources :user_invite_requests + resources :invite_requests, only: [:index, :create, :destroy] do + collection do + get :manage + get :status + post :resend + end + end + + get 'claim/:invitation_token' => 'external_authors#claim', as: 'claim' + post 'complete_claim/:invitation_token' => 'external_authors#complete_claim', as: 'complete_claim' + + #### TAGS #### + + resources :media do + resources :fandoms + end + resources :fandoms do + collection do + get :unassigned + end + get :show + end + resources :tag_wranglings do + collection do + post :wrangle + end + end + resources :tag_wranglers do + member do + get :report_csv + end + end + resources :unsorted_tags do + collection do + post :mass_update + end + end + resources :tags do + member do + get :feed + post :mass_update + get :remove_association + get :wrangle + end + collection do + get :show_hidden + get :search + end + resources :works + resources :bookmarks + resources :comments + resource :troubleshooting, controller: :troubleshooting, only: [:show, :update] + end + + resources :tag_sets, controller: 'owned_tag_sets' do + resources :nominations, controller: 'tag_set_nominations' do + collection do + put :update_multiple + delete :destroy_multiple + get :confirm_destroy_multiple + end + member do + get :confirm_delete + end + end + resources :associations, controller: 'tag_set_associations', only: [:index] do + collection do + put :update_multiple + end + end + member do + get :batch_load + put :do_batch_load + get :confirm_delete + end + collection do + get :show_options + end + end + resources :tag_nominations, only: [:update] + + resources :tag_wrangling_requests, only: [:index] do + collection do + patch :update_multiple + end + end + + #### ADMIN #### + resources :admin_posts do + resources :comments do + collection do + get :unreviewed + put :review_all + end + end + end + + namespace :admin do + resources :activities, only: [:index, :show] + resources :banners do + member do + get :confirm_delete + end + end + resources :blacklisted_emails, only: [:index, :create, :destroy] + resources :settings + resources :skins do + collection do + get :index_rejected + get :index_approved + end + end + resources :spam, only: [:index] do + collection do + post :bulk_update + end + end + resources :user_creations, only: [:destroy] do + member do + put :hide + put :set_spam + get :confirm_remove_pseud + put :remove_pseud + end + end + resources :users, controller: "admin_users", only: [:index, :show] do + member do + get :confirm_delete_user_creations + post :destroy_user_creations + post :activate + get :check_user + get :creations + end + collection do + get :bulk_search + post :bulk_search + post :update + post :update_status + post :update_next_of_kin + end + end + resources :invitations, controller: 'admin_invitations' do + collection do + post :invite_from_queue + post :grant_invites_to_users + get :find + end + end + resources :api + end + resources :admins, only: [:index] + + post '/admin/api/new', to: 'admin/api#create' + + #### USERS #### + + resources :people, only: [:index] do + collection do + get :search + end + end + + # When adding new nested resources, please keep them in alphabetical order + resources :users, except: [:new, :create] do + member do + get :change_email + put :confirm_change_email + post :changed_email + get :change_password + post :changed_password + get :change_username + post :changed_username + post :end_first_login + post :end_banner + post :end_tos_prompt + get :reconfirm_email + end + resources :assignments, controller: "challenge_assignments", only: [:index] + resources :claims, controller: "challenge_claims", only: [:index] + resources :bookmarks + resources :collection_items, only: [:index, :update] do + collection do + patch :update_multiple + end + end + resources :collections, only: [:index] + resources :comments do + member do + put :approve + put :reject + end + end + resource :creatorships, controller: "creatorships", only: [:show, :update] + resources :external_authors do + resources :external_author_names + end + resources :favorite_tags, only: [:create, :destroy] + resources :gifts, only: [:index] + resource :inbox, controller: "inbox" do + member do + get :reply + post :delete + end + end + resources :invitations do + collection do + post :invite_friend + end + collection do + get :manage + end + end + resources :nominations, controller: "tag_set_nominations", only: [:index] + resources :preferences, only: [:index, :update] + resource :profile, only: [:show], controller: "profile" do + collection do + get :pseuds + end + end + resources :pseuds do + resources :works + resources :series + resources :bookmarks + end + resources :readings do + collection do + post :clear + end + end + resources :related_works + resources :series do + member do + get :manage + end + resources :serial_works + end + resources :signups, controller: "challenge_signups", only: [:index] + resources :skins, only: [:index] + resources :stats, only: [:index] + resources :statuses + resources :subscriptions, only: [:index, :create, :destroy] do + collection do + get :confirm_delete_all + post :delete_all + end + end + resources :tag_sets, controller: "owned_tag_sets", only: [:index] + resources :works do + collection do + get :drafts + get :collected + get :show_multiple + post :edit_multiple + patch :update_multiple + post :delete_multiple + end + end + namespace :blocked do + resources :users, only: [:index, :create, :destroy] do + collection do + get :confirm_block + end + member do + get :confirm_unblock + end + end + end + namespace :muted do + resources :users, only: [:index, :create, :destroy] do + collection do + get :confirm_mute + end + member do + get :confirm_unmute + end + end + end + end + + #### WORKS #### + + resources :works do + collection do + post :import + get :search + end + member do + get :preview + post :post + put :post_draft + get :navigate + get :edit_tags + get :preview_tags + patch :update_tags + get :mark_for_later + get :mark_as_read + get :confirm_delete + get :share + end + resources :bookmarks + resources :chapters do + collection do + get :manage + post :update_positions + end + member do + get :preview + post :post + get :confirm_delete + end + resources :comments + end + resources :collections + resources :collection_items + resources :comments do + member do + put :approve + put :reject + end + collection do + get :unreviewed + put :review_all + end + end + resource :hit_count, controller: :hit_count, only: [:create] + resources :kudos, only: [:index] + resource :troubleshooting, controller: :troubleshooting, only: [:show, :update] + end + + resources :chapters do + member do + get :preview + post :post + end + resources :comments + end + + resources :external_works do + collection do + get :fetch + end + resources :bookmarks + resources :related_works + end + + resources :related_works + resources :serial_works + resources :series do + member do + get :confirm_delete + get :manage + post :update_positions + end + resources :bookmarks + end + + #### COLLECTIONS #### + + resources :gifts, only: [:index] do + member do + post :toggle_rejected + end + end + + resources :collections do + collection do + get :list_challenges + get :list_ge_challenges + get :list_pm_challenges + end + member do + get :confirm_delete + end + resource :profile, controller: "collection_profile" + resources :collections + resources :works + resources :gifts + resources :bookmarks + resources :media + resources :fandoms + resources :people + resources :prompts + resources :tags do + resources :works + end + resources :participants, controller: "collection_participants", only: [:index, :update, :destroy] do + collection do + get :add + get :join + end + end + resources :items, controller: "collection_items" do + collection do + patch :update_multiple + end + end + resources :signups, controller: "challenge_signups" do + collection do + get :summary + end + member do + get :confirm_delete + end + end + resources :assignments, controller: "challenge_assignments", only: [:index, :show] do + collection do + get :confirm_purge + get :generate + put :set + post :purge + get :send_out + put :update_multiple + get :default_all + end + member do + get :default + end + end + resources :claims, controller: "challenge_claims" do + collection do + patch :set + get :purge + end + end + resources :potential_matches do + collection do + get :generate + get :cancel_generate + get :regenerate_for_signup + end + end + resources :requests, controller: "challenge_requests" + # challenge types + resource :gift_exchange, controller: "challenge/gift_exchange" do + member do + get :confirm_delete + end + end + resource :prompt_meme, controller: "challenge/prompt_meme" do + member do + get :confirm_delete + end + end + end + + #### I18N #### + + # should stay below the main works mapping + resources :languages, except: [:show] do + resources :works + resources :admin_posts + end + get "/languages/:id", to: redirect("/languages/%{id}/works", status: 302) + resources :locales, except: :destroy + + #### API #### + + namespace :api do + namespace :v2 do + resources :bookmarks, only: [:create], defaults: { format: :json } + resources :works, only: [:create], defaults: { format: :json } + post 'bookmarks/search', to: 'bookmarks#search' + post 'works/search', to: 'works#search' + end + end + + #### MISC #### + + resources :comments do + member do + put :approve + put :freeze + put :hide + put :reject + put :review + put :unfreeze + put :unhide + end + collection do + get :hide_comments + get :show_comments + get :add_comment_reply + get :cancel_comment_reply + get :cancel_comment_edit + get :delete_comment + get :cancel_comment_delete + end + resources :comments + end + resources :bookmarks do + collection do + get :search + end + member do + get :confirm_delete + get :share + end + resources :collection_items + end + + resources :kudos, only: [:create] + + resources :skins do + member do + get :preview + get :set + get :confirm_delete + end + collection do + get :unset + end + end + resources :known_issues + resources :archive_faqs, path: "faq" do + member do + get :confirm_delete + end + collection do + get :manage + post :update_positions + end + resources :questions do + collection do + get :manage + post :update_positions + end + end + end + resources :wrangling_guidelines do + member do + get :confirm_delete + end + collection do + get :manage + post :update_positions + end + end + + resource :redirect, controller: "redirect", only: [:show] do + member do + get :do_redirect + end + end + + resources :abuse_reports, only: [:new, :create] + resources :external_authors do + resources :external_author_names + end + resources :orphans, only: [:index, :new, :create] + + get 'search' => 'works#search' + post 'support' => 'feedbacks#create', as: 'feedbacks' + get 'support' => 'feedbacks#new', as: 'new_feedback_report' + get "content" => "home#content" + get "privacy" => "home#privacy" + get "tos" => "home#tos" + get "tos_faq" => "home#tos_faq" + get 'unicorn_test' => 'home#unicorn_test' + get 'dmca' => 'home#dmca' + get 'diversity' => 'home#diversity' + get 'site_map' => 'home#site_map' + get 'site_pages' => 'home#site_pages' + get 'first_login_help' => 'home#first_login_help' + get 'token_dispenser' => 'home#token_dispenser' + get 'delete_confirmation' => 'users#delete_confirmation' + get 'activate/:id' => 'users#activate', as: 'activate' + get 'devmode' => 'devmode#index' + get 'donate' => 'home#donate' + get 'lost_cookie' => 'home#lost_cookie' + get 'about' => 'home#about' + get 'menu/browse' => 'menu#browse' + get 'menu/fandoms' => 'menu#fandoms' + get 'menu/search' => 'menu#search' + get 'menu/about' => 'menu#about' + + # The priority is based upon order of creation: + # first created -> highest priority. + root to: "home#index" + + # See how all your routes lay out with "rake routes" + + # These are allowlisted routes that are proven to be used throughout the + # application, which previously relied on a deprecated catch-all route definition + # (`get ':controller(/:action(/:id(.:format)))'`) to work. + # + # They are generally not RESTful and in some cases are *almost* duplicates of + # existing routes defined above, but due to how extensively they are used + # throughout the application must exist until forms, controllers, and tests + # can be refactored to not rely on their existence. + # + # Note written on August 1, 2017 during upgrade to Rails 5.1. + get '/invite_requests/show' => 'invite_requests#show', as: :show_invite_request + get '/user_invite_requests/update' => 'user_invite_requests#update' + + patch '/admin/skins/update' => 'admin_skins#update', as: :update_admin_skin + + get "/admin/admin_users/troubleshoot/:id" => "admin/admin_users#troubleshoot", as: :troubleshoot_admin_user + + # TODO: rewrite the autocomplete controller to deal with the fact that + # there are 21 different actions going on in there + %w[ + pseud + tag + fandom + character + relationship + freeform + character_in_fandom + relationship_in_fandom + tags_in_sets + associated_tags + noncanonical_tag + collection_fullname + open_collection_names + collection_parent_name + external_work + potential_offers + potential_requests + owned_tag_sets + site_skins + admin_posts + admin_post_tags + ].each do |action| + get "/autocomplete/#{action}" => "autocomplete##{action}" + end + get 'timeline', to: 'statuses#timeline', as: :timeline + get '/challenges/no_collection' => 'challenges#no_collection' + get '/challenges/no_challenge' => 'challenges#no_challenge' + + get '/works/clean_work_search_params' => 'works#clean_work_search_params' + get '/works/collected' => 'works#collected' + get '/works/drafts' => 'works#drafts' + + post '/works/edit_multiple/:id' => 'works#edit_multiple' + post '/works/confirm_delete_multiple/:id' => 'works#confirm_delete_multiple' + post '/works/delete_multiple/:id' => 'works#delete_multiple' + put '/works/update_multiple' => 'works#update_multiple' +end + diff --git a/config/s3.example b/config/s3.example new file mode 100755 index 0000000..34fc506 --- /dev/null +++ b/config/s3.example @@ -0,0 +1,4 @@ +bucket: mybucket +access_key_id: myaccesskey +secret_access_key: mysecret +s3_region: us-east-1 diff --git a/config/schedule.rb b/config/schedule.rb new file mode 100755 index 0000000..d90fcf2 --- /dev/null +++ b/config/schedule.rb @@ -0,0 +1,65 @@ +# Use this file to easily define all of your cron jobs. +# +# It's helpful, but not entirely necessary to understand cron before proceeding. +# http://en.wikipedia.org/wiki/Cron + +# Example: +# +# set :cron_log, "/path/to/my/cron_log.log" +# +# every 2.hours do +# command "/usr/bin/some_great_command" +# runner "MyModel.some_method" +# rake "some:great:rake:task" +# end +# +# every 4.days do +# runner "AnotherModel.prune_old_records" +# end + +# Learn more: http://github.com/javan/whenever + +# set your path in cron before the whenever section and use --update-crontab +set :set_path_automatically, false + +set :cron_log, "#{path}/log/whenever.log" + +# put a timestamp in the whenever log +every 1.days, at: 'midnight' do + command "date" +end + +# Purge user accounts that haven't been activated +every 1.days, at: '6:31 am' do + rake "admin:purge_unvalidated_users" +end + +# Unsuspend selected users +every 1.day, at: '6:51 am' do + rake "admin:unsuspend_users" +end + +# Delete unused tags +every 1.day, at: '7:10 am' do + rake "Tag:delete_unused" +end + +# Delete old drafts +every 1.day, at: '7:40 am' do + rake "work:purge_old_drafts" +end + +# Send kudos notifications +every 1.day, at: '10:00 am' do + rake "notifications:deliver_kudos" +end + +# Send subscription notifications +every 1.hour do + rake "notifications:deliver_subscriptions" +end + +# Rerun redis jobs +every 10.minutes do + rake "resque:run_failures" +end diff --git a/config/schedule_production.rb b/config/schedule_production.rb new file mode 100755 index 0000000..848ec7b --- /dev/null +++ b/config/schedule_production.rb @@ -0,0 +1,16 @@ +set :set_path_automatically, false +set :cron_log, "#{path}/log/whenever.log" + +# Resend signup emails +every 1.day, at: '6:41 am' do + rake "admin:resend_signup_emails" +end +# Send kudos notifications +every 1.day, at: '10:00 am' do + rake "notifications:deliver_kudos" +end + +# Send subscription notifications +every 1.hour do + rake "notifications:deliver_subscriptions" +end diff --git a/config/servers.yml b/config/servers.yml new file mode 100755 index 0000000..0526624 --- /dev/null +++ b/config/servers.yml @@ -0,0 +1,76 @@ +# Custom YAML configuration format for server objects in Capistrano per deploy stage. +# +# For example, this YAML snippet: +# +# production: +# - host: ao3-app15 +# roles: [app] +# options: +# primary: true +# +# is the same as adding this declaration in config/deploy/production.rb: +# +# server "ao3-app15", :app, primary: true +# +# The :primary attribute is used for tasks we only want to run on one machine. +# Refer to https://capistranorb.com/documentation/advanced-features/properties/. + +production: + - host: ao3-app01 + roles: [app, db, schedulers] + - host: ao3-app09 + roles: [app] + - host: ao3-app14 + roles: [app] + - host: ao3-app15 + roles: [app] + options: + primary: true + - host: ao3-app16 + roles: [app] + - host: ao3-app17 + roles: [app, workers, schedulers] + - host: ao3-app18 + roles: [app, workers, schedulers] + - host: ao3-app19 + roles: [app] + - host: ao3-app20 + roles: [app] + - host: ao3-app21 + roles: [app] + - host: ao3-app22 + roles: [app] + - host: ao3-app23 + roles: [app] + - host: ao3-app24 + roles: [app, workers, schedulers] + - host: ao3-app25 + roles: [app, workers, schedulers] + - host: ao3-app26 + roles: [app, workers, schedulers] + - host: ao3-app27 + roles: [app, workers, schedulers] + - host: ao3-app28 + roles: [app, workers, schedulers] + - host: ao3-front07 + roles: [web] + - host: ao3-front08 + roles: [web] + - host: ao3-front09 + roles: [web] + - host: ao3-front10 + roles: [web] + +staging: + - host: test-app13 + roles: [app, db, schedulers] + - host: test-app14 + roles: [app, schedulers] + - host: test-app15 + roles: [app, workers, schedulers] + options: + primary: true + - host: test-front11 + roles: [web] + - host: test-front12 + roles: [web] diff --git a/config/storage.yml b/config/storage.yml new file mode 100755 index 0000000..d3f05f1 --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,17 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Example AWS S3 configuration for ActiveStorage. +# This should be overridden by config/storage/.yml +# s3: + # service: S3 + # access_key_id: "" + # secret_access_key: "" + # region: "" + # bucket: "" + # public: true diff --git a/docker-compose-example.yml b/docker-compose-example.yml new file mode 100755 index 0000000..9083c94 --- /dev/null +++ b/docker-compose-example.yml @@ -0,0 +1,106 @@ +version: "3" +volumes: + esdata1: + redisdata1: +services: + db: + image: mariadb:10.5.4-focal + environment: + - MYSQL_ROOT_PASSWORD= change this + ports: + - "3306:3306" + command: + [ + "mysqld", + "--sql-mode=NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION", + ] + volumes: + - .:/var/lib/mysql:rw + redis: + image: redis:5 + ports: + - "6379:6379" + volumes: + - .:/var/lib/redis:rw + es: + image: docker.elastic.co/elasticsearch/elasticsearch:9.1.3 + ports: + - "9200:9200" + - "9300:9300" + - "9400:9400" + volumes: + - .:/usr/share/elasticsearch/data:rw + environment: + - RAILS_ENV=production + - cluster.name=change_me + - node.name=change_me-node + - http.port=9200 + - bootstrap.memory_lock=false + - "ES_JAVA_OPTS=-Xms4g -Xmx4g" + - discovery.type=single-node + # Silence "security features are not enabled" warnings + # https://github.com/elastic/elasticsearch/issues/78500 + - xpack.security.enabled=false + - network.host=0.0.0.0 + - transport.host=0.0.0.0 + - http.host=0.0.0.0 + mc: + image: memcached:1.5 + ports: + - "11211:11211" + web: + links: + - "es:elastic" + profiles: + - dev + build: + context: . + dockerfile: ./config/docker/Dockerfile + environment: + - RAILS_ENV=production + - ES_URL=es:9200 + command: bash -c "rm -f tmp/pids/server.pid && RAILS_ENV=production bundle exec rails server -p 3345 -b 0.0.0.0" + volumes: + - ./bundler_gems:/usr/local/bundle/ + - .:/otwa + ports: + - "3345:3345" + depends_on: + - db + - redis + - es + - mc + worker: + build: + context: . + dockerfile: ./config/docker/Dockerfile + environment: + - RAILS_ENV=production + - REDIS_URL=redis://redis:6379 + volumes: + - ./bunder_gems:/usr/local/bundle/ + - .:/otwa + depends_on: + - db + - redis + - es + - mc + entrypoint: ./entrypoints/worker-entrypoint.sh + sc: + build: + context: . + dockerfile: ./config/docker/Dockerfile + environment: + - RAILS_ENV=production + - REDIS_URL=redis://redis:6379 + volumes: + - ./bunder_gems:/usr/local/bundle/ + - .:/otwa + depends_on: + - db + - redis + - es + - mc + - worker + entrypoint: ./entrypoints/sc-entrypoint.sh + diff --git a/entrypoints/sc-entrypoint.sh b/entrypoints/sc-entrypoint.sh new file mode 100755 index 0000000..395b576 --- /dev/null +++ b/entrypoints/sc-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash + + set -e + bundle install + + if [ -f tmp/pids/server.pid ]; then + rm tmp/pids/server.pid + fi + + bundle exec rake resque:scheduler + diff --git a/entrypoints/worker-entrypoint.sh b/entrypoints/worker-entrypoint.sh new file mode 100755 index 0000000..bd79c60 --- /dev/null +++ b/entrypoints/worker-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/bash + + set -e + bundle install + + if [ -f tmp/pids/server.pid ]; then + rm tmp/pids/server.pid + fi + + QUEUE="*" bundle exec rake environment resque:work + diff --git a/factories/abuse_reports.rb b/factories/abuse_reports.rb new file mode 100755 index 0000000..8e9f748 --- /dev/null +++ b/factories/abuse_reports.rb @@ -0,0 +1,10 @@ +require 'faker' +FactoryBot.define do + factory :abuse_report do + email { Faker::Internet.email } + url { "http://archiveofourown.org/tags/2000%20AD%20(Comics)/works" } + comment { Faker::Lorem.paragraph(sentence_count: 1) } + summary { Faker::Lorem.sentence(word_count: 1) } + language { "Francais" } + end +end diff --git a/factories/admin.rb b/factories/admin.rb new file mode 100755 index 0000000..2df48ec --- /dev/null +++ b/factories/admin.rb @@ -0,0 +1,36 @@ +require 'faker' + +FactoryBot.define do + factory :admin do + login { generate(:login) } + password { SecureRandom.alphanumeric(10) } + password_confirmation { |u| u.password } + email { Faker::Internet.unique.email } + + factory :superadmin do + roles { ["superadmin"] } + end + + factory :policy_and_abuse_admin do + roles { ["policy_and_abuse"] } + end + + factory :support_admin do + roles { ["support"] } + end + + factory :tag_wrangling_admin do + roles { ["tag_wrangling"] } + end + + factory :open_doors_admin do + roles { ["open_doors"] } + end + end + + factory :admin_activity do + admin + action { "update_tags" } + summary { "MyActivity" } + end +end diff --git a/factories/admin_banner.rb b/factories/admin_banner.rb new file mode 100755 index 0000000..665131c --- /dev/null +++ b/factories/admin_banner.rb @@ -0,0 +1,13 @@ +require "faker" + +FactoryBot.define do + factory :admin_banner do + sequence(:content) { |n| "#{Faker::Lorem.paragraph} (#{n})" } + + active { false } + + trait :active do + active { true } + end + end +end diff --git a/factories/admin_blacklisted_email.rb b/factories/admin_blacklisted_email.rb new file mode 100755 index 0000000..a0121fa --- /dev/null +++ b/factories/admin_blacklisted_email.rb @@ -0,0 +1,7 @@ +require 'faker' + +FactoryBot.define do + factory :admin_blacklisted_email do + email { Faker::Internet.unique.email } + end +end diff --git a/factories/admin_post.rb b/factories/admin_post.rb new file mode 100755 index 0000000..109346b --- /dev/null +++ b/factories/admin_post.rb @@ -0,0 +1,10 @@ +require 'faker' + +FactoryBot.define do + factory :admin_post do + language { Language.default } + admin_id { FactoryBot.create(:admin).id } + title { "AdminPost Title" } + content { "AdminPost content long enough to pass validation" } + end +end diff --git a/factories/api_key.rb b/factories/api_key.rb new file mode 100755 index 0000000..c8524f1 --- /dev/null +++ b/factories/api_key.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +require 'faker' + +FactoryBot.define do + factory :api_key do + name { "API key name" } + end +end diff --git a/factories/archive_faqs.rb b/factories/archive_faqs.rb new file mode 100755 index 0000000..f6c08f6 --- /dev/null +++ b/factories/archive_faqs.rb @@ -0,0 +1,18 @@ +require "faker" + +FactoryBot.define do + sequence(:faq_title) do |n| + "The #{n} FAQ" + end + + factory :archive_faq do + title { generate(:faq_title) } + end + + factory :question do + question { Faker::Lorem.sentence } + anchor { Faker::Lorem.word } + content { Faker::Lorem.paragraph } + screencast { Faker::Internet.url } + end +end diff --git a/factories/bookmarks.rb b/factories/bookmarks.rb new file mode 100755 index 0000000..9e94868 --- /dev/null +++ b/factories/bookmarks.rb @@ -0,0 +1,19 @@ +require 'faker' + +FactoryBot.define do + factory :bookmark do + bookmarkable_type { "Work" } + bookmarkable_id { FactoryBot.create(:work).id } + pseud_id { FactoryBot.create(:pseud).id } + + factory :external_work_bookmark do + bookmarkable_type { "ExternalWork" } + bookmarkable_id { FactoryBot.create(:external_work).id } + end + + factory :series_bookmark do + bookmarkable_type { "Series" } + bookmarkable_id { FactoryBot.create(:series_with_a_work).id } + end + end +end diff --git a/factories/challenge_claims.rb b/factories/challenge_claims.rb new file mode 100755 index 0000000..14a8723 --- /dev/null +++ b/factories/challenge_claims.rb @@ -0,0 +1,5 @@ +require 'faker' +FactoryBot.define do + factory :challenge_claim do + end +end diff --git a/factories/challenges.rb b/factories/challenges.rb new file mode 100755 index 0000000..0372abd --- /dev/null +++ b/factories/challenges.rb @@ -0,0 +1,54 @@ +require 'faker' +FactoryBot.define do + factory :challenge_assignment do + collection { create(:collection, challenge: create(:gift_exchange)) } + + after(:build) do |assignment| + assignment.request_signup = create(:challenge_signup, collection: assignment.collection) + assignment.offer_signup = create(:challenge_signup, collection: assignment.collection) + end + end + + factory :challenge_signup, aliases: [:gift_exchange_signup] do + pseud { create(:user).default_pseud } + collection { create(:collection, challenge: create(:gift_exchange)) } + requests_attributes { [attributes_for(:request)] } + offers_attributes { [attributes_for(:offer)] } + end + + factory :prompt_meme_signup, class: "ChallengeSignup" do + pseud { create(:user).default_pseud } + collection { create(:collection, challenge: create(:prompt_meme)) } + requests_attributes { [attributes_for(:request)] } + end + + factory :potential_match do + collection { create(:collection, challenge: create(:gift_exchange)) } + + after(:build) do |potential_match| + potential_match.offer_signup = create(:challenge_signup, collection: potential_match.collection) + potential_match.request_signup = create(:challenge_signup, collection: potential_match.collection) + end + end + + factory :gift_exchange do + association :offer_restriction, factory: :prompt_restriction + association :request_restriction, factory: :prompt_restriction + + trait :open do + signups_open_at { Time.now - 1.day } + signups_close_at { Time.now + 1.day } + signup_open { true } + end + + trait :closed do + signups_open_at { Time.now - 2.days } + signups_close_at { Time.now - 1.day } + signup_open { false } + end + end + + factory :prompt_meme do + association :request_restriction, factory: :prompt_restriction + end +end diff --git a/factories/chapters.rb b/factories/chapters.rb new file mode 100755 index 0000000..960e307 --- /dev/null +++ b/factories/chapters.rb @@ -0,0 +1,24 @@ +require 'faker' + +FactoryBot.define do + factory :chapter do + content { "Awesome content!" } + work + posted { true } + + transient do + authors { work.pseuds } + end + + after(:build) do |chapter, evaluator| + evaluator.authors.each do |pseud| + chapter.creatorships.build(pseud: pseud) + end + end + + trait :draft do + content { "Draft content!" } + posted { false } + end + end +end diff --git a/factories/collections.rb b/factories/collections.rb new file mode 100755 index 0000000..12e3ed5 --- /dev/null +++ b/factories/collections.rb @@ -0,0 +1,60 @@ +require "faker" + +FactoryBot.define do + sequence(:collection_name) do |n| + "basic_collection_#{n}" + end + + sequence(:collection_title) do |n| + "Basic Collection #{n}" + end + + factory :collection_participant do + pseud + participant_role { "Owner" } + end + + factory :collection_preference do |f| + end + + factory :collection_profile do |f| + end + + factory :collection do |f| + name { generate(:collection_name) } + title { generate(:collection_title) } + + transient do + owner { build(:pseud) } + end + + after(:build) do |collection, evaluator| + collection.collection_participants.build(pseud: evaluator.owner, participant_role: "Owner") + end + + factory :anonymous_collection do + association :collection_preference, anonymous: true + end + + factory :unrevealed_collection do + association :collection_preference, unrevealed: true + end + + factory :anonymous_unrevealed_collection do + association :collection_preference, unrevealed: true, anonymous: true + end + + trait :closed do + association :collection_preference, closed: true + end + + trait :moderated do + association :collection_preference, moderated: true + end + end + + factory :collection_item do + item_type { "Work" } + collection + end +end diff --git a/factories/comments.rb b/factories/comments.rb new file mode 100755 index 0000000..ea3cf7f --- /dev/null +++ b/factories/comments.rb @@ -0,0 +1,37 @@ +require 'faker' + +FactoryBot.define do + factory :comment do + comment_content { Faker::Lorem.sentence(word_count: 25) } + commentable { create(:work).last_posted_chapter } + pseud { create(:user).default_pseud } + + trait :by_guest do + pseud { nil } + name { Faker::Name.first_name } + email { Faker::Internet.email } + end + + trait :on_admin_post do + commentable { create(:admin_post, comment_permissions: :enable_all) } + end + + trait :on_tag do + commentable { create(:fandom) } + end + + trait :on_work_with_guest_comments_on do + commentable { create(:work, :guest_comments_on).first_chapter } + end + + trait :unreviewed do + commentable { create(:work, moderated_commenting_enabled: true).last_posted_chapter } + unreviewed { true } + end + end + + factory :inbox_comment do + user { create(:user) } + feedback_comment { create(:comment) } + end +end diff --git a/factories/fannish_next_of_kin.rb b/factories/fannish_next_of_kin.rb new file mode 100755 index 0000000..3dc5a39 --- /dev/null +++ b/factories/fannish_next_of_kin.rb @@ -0,0 +1,9 @@ +require "faker" + +FactoryBot.define do + factory :fannish_next_of_kin do + user { create(:user) } + kin { create(:user) } + kin_email { |u| u.kin.email } + end +end diff --git a/factories/favorite_tags.rb b/factories/favorite_tags.rb new file mode 100755 index 0000000..21eb904 --- /dev/null +++ b/factories/favorite_tags.rb @@ -0,0 +1,8 @@ +require "faker" + +FactoryBot.define do + factory :favorite_tag do + tag_id { FactoryBot.create(:canonical_freeform).id } + user_id { FactoryBot.create(:user).id } + end +end diff --git a/factories/feedback.rb b/factories/feedback.rb new file mode 100755 index 0000000..94adc12 --- /dev/null +++ b/factories/feedback.rb @@ -0,0 +1,10 @@ +require 'faker' + +FactoryBot.define do + factory :feedback do + comment { Faker::Lorem.paragraph(sentence_count: 1) } + email { Faker::Internet.email } + summary { Faker::Lorem.sentence(word_count: 1) } + language { "English" } + end +end diff --git a/factories/gift.rb b/factories/gift.rb new file mode 100755 index 0000000..4902540 --- /dev/null +++ b/factories/gift.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "faker" + +FactoryBot.define do + factory :gift do + user { create(:user) } + work { create(:work) } + end +end diff --git a/factories/invitations.rb b/factories/invitations.rb new file mode 100755 index 0000000..58ff7e5 --- /dev/null +++ b/factories/invitations.rb @@ -0,0 +1,13 @@ +require "faker" + +FactoryBot.define do + factory :invite_request do + sequence :email do |n| + Faker::Internet.email(name: "#{Faker::Name.first_name}_#{n}") + end + end + + factory :invitation do + invitee_email { "default@email.com" } + end +end diff --git a/factories/known_issues.rb b/factories/known_issues.rb new file mode 100755 index 0000000..720c348 --- /dev/null +++ b/factories/known_issues.rb @@ -0,0 +1,8 @@ +require "faker" + +FactoryBot.define do + factory :known_issue do + title { Faker::Lorem.sentence } + content { Faker::Lorem.paragraph } + end +end diff --git a/factories/kudos.rb b/factories/kudos.rb new file mode 100755 index 0000000..9a34776 --- /dev/null +++ b/factories/kudos.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :kudo do + commentable { create(:work) } + ip_address { Faker::Internet.unique.public_ip_v4_address } + end +end diff --git a/factories/language.rb b/factories/language.rb new file mode 100755 index 0000000..b090dfd --- /dev/null +++ b/factories/language.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :language do + short { "nl" } + name { "Dutch" } + end +end diff --git a/factories/last_wrangling_activity.rb b/factories/last_wrangling_activity.rb new file mode 100755 index 0000000..7abb163 --- /dev/null +++ b/factories/last_wrangling_activity.rb @@ -0,0 +1,7 @@ +require "faker" + +FactoryBot.define do + factory :last_wrangling_activity do + user + end +end diff --git a/factories/locales.rb b/factories/locales.rb new file mode 100755 index 0000000..2ac7c25 --- /dev/null +++ b/factories/locales.rb @@ -0,0 +1,17 @@ +require "faker" + +FactoryBot.define do + sequence(:locale_iso) do |n| + "en-WAT#{n}" + end + + sequence(:locale_name) do |n| + "Locale #{n}" + end + + factory :locale do + language { Language.default } + iso { generate(:locale_iso) } + name { generate(:locale_name) } + end +end diff --git a/factories/prompt.rb b/factories/prompt.rb new file mode 100755 index 0000000..075d6a0 --- /dev/null +++ b/factories/prompt.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true +require 'faker' + +FactoryBot.define do + factory :prompt do + description { Faker::Lorem.sentence } + end + + factory :request, parent: :prompt, class: "Request" + factory :offer, parent: :prompt, class: "Offer" +end diff --git a/factories/prompt_restriction.rb b/factories/prompt_restriction.rb new file mode 100755 index 0000000..231a592 --- /dev/null +++ b/factories/prompt_restriction.rb @@ -0,0 +1,6 @@ +require 'faker' + +FactoryBot.define do + factory :prompt_restriction do + end +end diff --git a/factories/pseuds.rb b/factories/pseuds.rb new file mode 100755 index 0000000..30ac3a0 --- /dev/null +++ b/factories/pseuds.rb @@ -0,0 +1,8 @@ +require 'faker' + +FactoryBot.define do + factory :pseud do + name { Faker::Lorem.characters(number: 8) } + user + end +end diff --git a/factories/readings.rb b/factories/readings.rb new file mode 100755 index 0000000..0563e1d --- /dev/null +++ b/factories/readings.rb @@ -0,0 +1,14 @@ +require "faker" + +FactoryBot.define do + factory :reading do + user_id { FactoryBot.create(:user).id } + work_id { FactoryBot.create(:work).id } + + # A reading with a deleted work means a reading with a work_id that + # doesn't exist. Here we use 0 because it will never be used as an id. + trait :deleted_work do + work_id { 0 } + end + end +end diff --git a/factories/related_works.rb b/factories/related_works.rb new file mode 100755 index 0000000..17d2fb4 --- /dev/null +++ b/factories/related_works.rb @@ -0,0 +1,9 @@ +require 'faker' + +FactoryBot.define do + factory :related_work do + parent_type { "Work" } + parent_id { FactoryBot.create(:work).id } + work_id { FactoryBot.create(:work).id } + end +end diff --git a/factories/serial_work.rb b/factories/serial_work.rb new file mode 100755 index 0000000..5062bb3 --- /dev/null +++ b/factories/serial_work.rb @@ -0,0 +1,7 @@ +require 'faker' + +FactoryBot.define do + factory :serial_work do + work_id { FactoryBot.create(:work).id } + end +end diff --git a/factories/series.rb b/factories/series.rb new file mode 100755 index 0000000..a30e134 --- /dev/null +++ b/factories/series.rb @@ -0,0 +1,27 @@ +require "faker" + +FactoryBot.define do + sequence(:series_title) do |n| + "Awesome Series #{n}" + end + + factory :series do + title { generate(:series_title) } + + transient do + authors { [build(:pseud)] } + end + + after(:build) do |series, evaluator| + evaluator.authors.each do |pseud| + series.creatorships.build(pseud: pseud) + end + end + + factory :series_with_a_work do + after(:create) do |series| + create(:work, authors: series.pseuds, series: [series]) + end + end + end +end diff --git a/factories/skins.rb b/factories/skins.rb new file mode 100755 index 0000000..9e14ff7 --- /dev/null +++ b/factories/skins.rb @@ -0,0 +1,30 @@ +require 'faker' +FactoryBot.define do + sequence :skin_title do |n| + "#{Faker::Lorem.word} #{n}" + end + + factory :skin do + author_id { FactoryBot.create(:user).id } + title { generate(:skin_title) } + + trait :public do + add_attribute(:public) { true } + official { true } + end + end + + factory :work_skin do + author_id { FactoryBot.create(:user).id } + title { generate(:skin_title) } + + trait :private do + add_attribute(:public) { false } + end + + trait :public do + add_attribute(:public) { true } + official { true } + end + end +end diff --git a/factories/subscriptions.rb b/factories/subscriptions.rb new file mode 100755 index 0000000..00ace51 --- /dev/null +++ b/factories/subscriptions.rb @@ -0,0 +1,10 @@ +require 'faker' + +FactoryBot.define do + + factory :subscription do + subscribable_type { "Series" } + subscribable_id { FactoryBot.create(:series).id } + user + end +end diff --git a/factories/tags.rb b/factories/tags.rb new file mode 100755 index 0000000..2fbaec5 --- /dev/null +++ b/factories/tags.rb @@ -0,0 +1,143 @@ +require "faker" + +FactoryBot.define do + sequence(:tag_title) do |n| + "Owned Tag Set #{n}" + end + + sequence(:tag_name) do |n| + "The #{n} Tag" + end + + factory :common_tagging do + association :common_tag, factory: :relationship + association :filterable, factory: :canonical_fandom + end + + factory :meta_tagging do + association :meta_tag, factory: :canonical_freeform + association :sub_tag, factory: :canonical_freeform + end + + factory :tag_set do + tags { [create(:canonical_fandom)] } + end + + factory :owned_tag_set do + title { generate(:tag_title) } + nominated { true } + transient do + owned_set_taggings { [create(:owned_set_tagging)] } + owner { create(:pseud) } + tags { [create(:fandom)] } + end + + after(:build) do |owned_tag_set, evaluator| + owned_tag_set.build_tag_set + owned_tag_set.add_owner(evaluator.owner) + owned_tag_set.fandom_nomination_limit = 2 + owned_tag_set.owned_set_taggings << evaluator.owned_set_taggings + owned_tag_set.tags << evaluator.tags + end + end + + factory :owned_set_tagging do + set_taggable { create(:prompt_restriction) } + end + + factory :tag_set_nomination do + association :owned_tag_set + association :pseud + end + + factory :tag_set_association do + association :owned_tag_set + association :tag + association :parent_tag + end + + factory :tag_nomination do + type { "FandomNomination" } + + canonical { true } + association :owned_tag_set + + after(:build) do |nomination| + nomination.tagname ||= Fandom.last.name + end + end + + factory :tag do + name { generate(:tag_name) } + end + + factory :unsorted_tag do + sequence(:name) { |n| "Unsorted Tag #{n}" } + end + + factory :fandom do + sequence(:name) { |n| "The #{n} Fandom" } + + # Tags names used in mailer preview should be unique but recognizable as tag names + trait :for_mailer_preview do + name { "Fandom#{Faker::Alphanumeric.alpha(number: 8)}" } + end + + factory :canonical_fandom do + canonical { true } + end + end + + factory :character do + sequence(:name) { |n| "Character #{n}" } + + # Tags names used in mailer preview should be unique but recognizable as tag names + trait :for_mailer_preview do + name { "Character#{Faker::Alphanumeric.alpha(number: 8)}" } + end + + factory :canonical_character do + canonical { true } + end + end + + factory :relationship do + sequence(:name) { |n| "Jane#{n}/John#{n}" } + + # Tags names used in mailer preview should be unique but recognizable as tag names + trait :for_mailer_preview do + name { "Relationship#{Faker::Alphanumeric.alpha(number: 8)}" } + end + + factory :canonical_relationship do + canonical { true } + end + end + + factory :freeform do + sequence(:name) { |n| "Freeform #{n}" } + + # Tags names used in mailer preview should be unique but recognizable as tag names + trait :for_mailer_preview do + name { "Freeform#{Faker::Alphanumeric.alpha(number: 8)}" } + end + + factory :canonical_freeform do + canonical { true } + end + end + + factory :media do + sequence(:name) { |n| "Media #{n}" } + canonical { true } + end + + factory :banned do |f| + f.sequence(:name) { |n| "Banned #{n}" } + end + + factory :archive_warning do |f| + f.sequence(:name) { |n| "Archive Warning #{n}" } + canonical { true } + end +end diff --git a/factories/user_invite_requests.rb b/factories/user_invite_requests.rb new file mode 100755 index 0000000..7572faf --- /dev/null +++ b/factories/user_invite_requests.rb @@ -0,0 +1,10 @@ +require 'faker' +FactoryBot.define do + factory :user_invite_requests, class: "UserInviteRequest" do + user_id { FactoryBot.create(:user).id } + quantity { 5 } + reason { "Because reasons!" } + granted { false } + handled { false } + end +end diff --git a/factories/users.rb b/factories/users.rb new file mode 100755 index 0000000..36710c6 --- /dev/null +++ b/factories/users.rb @@ -0,0 +1,52 @@ +require "faker" + +FactoryBot.define do + sequence(:login) do |n| + "#{Faker::Lorem.characters(number: 8)}#{n}" + end + + factory :role do + sequence(:name) { |n| "#{Faker::Company.profession}_#{n}" } + end + + factory :user do + login { generate(:login) } + password { SecureRandom.alphanumeric(10) } + age_over_13 { "1" } + data_processing { "1" } + terms_of_service { "1" } + password_confirmation(&:password) + email { Faker::Internet.unique.email } + + # By default, create activated users who can log in, since we use + # devise :confirmable. + confirmed_at { Faker::Time.backward } + + trait :unconfirmed do + confirmed_at { nil } + end + + # Usernames used in mailer preview should be unique but recognizable as usernames + trait :for_mailer_preview do + login { "User#{Faker::Alphanumeric.alpha(number: 8)}" } + end + + # Roles + + factory :archivist do + roles { [Role.find_or_create_by(name: "archivist")] } + end + + factory :opendoors_user do + roles { [Role.find_or_create_by(name: "opendoors")] } + end + + factory :tag_wrangler do + roles { [Role.find_or_create_by(name: "tag_wrangler")] } + end + + factory :official_user do + roles { [Role.find_or_create_by(name: "official")] } + end + end +end diff --git a/factories/work_original_creators.rb b/factories/work_original_creators.rb new file mode 100755 index 0000000..59c08db --- /dev/null +++ b/factories/work_original_creators.rb @@ -0,0 +1,6 @@ +FactoryBot.define do + factory :work_original_creator do + work + user + end +end diff --git a/factories/works.rb b/factories/works.rb new file mode 100755 index 0000000..6530499 --- /dev/null +++ b/factories/works.rb @@ -0,0 +1,67 @@ +require 'faker' +FactoryBot.define do + + factory :work do + title { "My title is long enough" } + fandom_string { "Testing" } + rating_string { ArchiveConfig.RATING_DEFAULT_TAG_NAME } + archive_warning_string { ArchiveConfig.WARNING_NONE_TAG_NAME } + language_id { Language.default.id } + chapter_info = { content: "This is some chapter content for my work." } + chapter_attributes { chapter_info } + posted { true } + + transient do + authors { [build(:pseud)] } + end + + after(:build) do |work, evaluator| + evaluator.authors.each do |pseud| + work.creatorships.build(pseud: pseud) + end + end + + factory :no_authors do + authors { [] } + end + + factory :custom_work_skin do + work_skin_id { 1 } + end + + factory :draft do + posted { false } + end + + trait :guest_comments_on do + comment_permissions { :enable_all } + end + end + + factory :external_work do + title { "An External Work" } + author { "An Author" } + url { "http://www.example.org" } + + after(:build) do |work| + work.fandoms = [FactoryBot.build(:fandom)] if work.fandoms.blank? + end + end + + factory :moderated_work do + work_id { create(:work).id } + end + + factory :external_author do |f| + f.sequence(:email) { |n| "foo#{n}@external.com" } + end + + factory :external_author_name do |f| + f.association :external_author + end + + factory :external_creatorship do |f| + f.creation_type { 'Work' } + f.association :external_author_name + end +end diff --git a/factories/wrangling_assignments.rb b/factories/wrangling_assignments.rb new file mode 100755 index 0000000..1373dc4 --- /dev/null +++ b/factories/wrangling_assignments.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :wrangling_assignment do + user + fandom + end +end diff --git a/factories/wrangling_guideline.rb b/factories/wrangling_guideline.rb new file mode 100755 index 0000000..9128896 --- /dev/null +++ b/factories/wrangling_guideline.rb @@ -0,0 +1,17 @@ +require 'faker' + +FactoryBot.define do + + sequence(:wrangling_guideline_title) do |n| + "The #{n} Wrangling Guideline" + end + + sequence(:wrangling_guideline_content) do |n| + "This is the #{n} Wrangling Guideline" + end + + factory :wrangling_guideline do |f| + title { generate(:wrangling_guideline_title) } + content { generate(:wrangling_guideline_content) } + end +end diff --git a/features/admins/admin_email_blacklist.feature b/features/admins/admin_email_blacklist.feature new file mode 100755 index 0000000..2ed0068 --- /dev/null +++ b/features/admins/admin_email_blacklist.feature @@ -0,0 +1,95 @@ +@admin +Feature: Admin email blacklist + In order to prevent the use of certain email addresses in guest comments + As an an admin + I want to be able to manage a list of banned email addresses + +Scenario: Ban email address + Given I am logged in as a "policy_and_abuse" admin + Then I should see "Banned Emails" + When I follow "Banned Emails" + Then I should see "Find banned emails" + And I should see "Ban email address" + And I should see "Email to ban" + And I should see "Email to find" + When I fill in "Email to ban" with "foo@bar.com" + And I press "Ban Email" + Then I should see "Email address foo@bar.com banned." + And the address "foo@bar.com" should be banned + +Scenario: Remove email address from banned emails list + Given I am logged in as a "policy_and_abuse" admin + And I have banned the address "foo@bar.com" + When I follow "Banned Emails" + And I fill in "Email to find" with "bar" + And I press "Search Banned Emails" + Then I should see "email found" + And I should see "foo@bar.com" + When I follow "Remove" + Then I should see "Email address foo@bar.com removed from banned emails list." + And the address "foo@bar.com" should not be banned + +Scenario: Banned email addresses should not be usable in guest comments + Given I am logged in as a "policy_and_abuse" admin + And I have banned the address "foo@bar.com" + And I am logged in as "author" + And I post the work "New Work" + When I post the comment "I loved this" on the work "New Work" as a guest with email "foo@bar.com" + Then I should see "has been blocked at the owner's request" + And I should not see "Comments (1)" + When I fill in "Guest email" with "someone@bar.com" + And I press "Comment" + Then I should see "Comments (1)" + +Scenario: Variants of banned email addresses should not be usable + Given I am logged in as a "policy_and_abuse" admin + When I have banned the address "foo.bar+gloop@googlemail.com" + Then the address "foobar@gmail.com" should be banned + When I am logged out + Then I should not be able to comment with the address "foobar@gmail.com" + And I should not be able to comment with the address "foobar+baz@gmail.com" + And I should not be able to comment with the address "foo.bar@gmail.com" + And I should be able to comment with the address "whee@gmail.com" + +Scenario: Banning a user's email should not affect their ability to post comments + Given the user "author" exists and is activated + And I am logged in as a "policy_and_abuse" admin + And I have banned the address for user "author" + When I am logged in as "author" + And I post the work "New Work" + And I post a comment "here's a great comment" + Then I should see "Comment created!" + +Scenario: Banning a user's email should prevent requesting invites + Given I am logged in as a "policy_and_abuse" admin + When I have banned the address "foo@bar.com" + And I log out + And account creation requires an invitation + And the invitation queue is enabled + Then I should not be able to add the email "foo@bar.com" to the invite queue + +Scenario: Banning a user's email should prevent aliases requesting invites + Given I am logged in as a "policy_and_abuse" admin + When I have banned the address "foo+bar@gmail.com" + And I log out + And account creation requires an invitation + And the invitation queue is enabled + Then I should not be able to add the email "foo@gmail.com" to the invite queue + And I should not be able to add the email "fo.o@gmail.com" to the invite queue + And I should not be able to add the email "foo+baz@gmail.com" to the invite queue + And I should not be able to add the email "foo@googlemail.com" to the invite queue + +Scenario: User's email banned after joining invite queue should remove their email + Given I am a visitor + When I am on the homepage + And I follow "Get an Invitation" + And I fill in "Email" with "foo+bar@baz.com" + And I press "Add me to the list" + Then I should see "You've been added to our queue" + When I am logged in as a "policy_and_abuse" admin + And I go to the manage invite queue page + Then I should see "foo+bar@baz.com" + And I should not see "foo@baz.com" + When I have banned the address "foo+qux@baz.com" + And I go to the manage invite queue page + Then I should not see "foo+bar@baz.com" diff --git a/features/admins/admin_invitations.feature b/features/admins/admin_invitations.feature new file mode 100755 index 0000000..cf03977 --- /dev/null +++ b/features/admins/admin_invitations.feature @@ -0,0 +1,520 @@ +@admin +Feature: Admin Actions to Manage Invitations + In order to manage user account creation + As an an admin + I want to be able to require invitations for new users + + Scenario: Admin can set invite from queue number to a number greater than or equal to 1 + Given I am logged in as a "policy_and_abuse" admin + And I go to the admin-settings page + And I fill in "Number of people to invite from the queue at once" with "0" + And I press "Update" + Then I should see "Invite from queue number must be greater than 0. To disable invites, uncheck the appropriate setting." + When I fill in "Number of people to invite from the queue at once" with "1" + And I press "Update" + Then I should not see "Invite from queue number must be greater than 0." + + Scenario: Account creation enabled, invitations required, users can request invitations, and the queue is enabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I check "Account creation enabled" + And I check "Account creation requires invitation" + And I check "Users can request invitations" + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should see "Get Invited!" + And I should see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create An Account" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation enabled, invitations required, users can request invitations, and the queue is disabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I check "Account creation enabled" + And I check "Account creation requires invitation" + And I check "Users can request invitations" + And I uncheck "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + And I should see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation enabled, invitations required, users cannot request invitations, and the queue is enabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I check "Account creation enabled" + And I check "Account creation requires invitation" + And I uncheck "Users can request invitations" + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should see "Get Invited!" + And I should see "You can join by getting an invitation from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + When I go to account creation page + Then I should be on invite requests page + And I should see "To create an account, you'll need an invitation. One option is to add your name to the automatic queue below." + And I should see "Forgot password? Get an Invitation" within "div#small_login" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation enabled, invitations not required, users can request invitations, and the queue is enabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I check "Account creation enabled" + And I uncheck "Account creation requires invitation" + And I check "Users can request invitations" + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + And I should see "Create an Account!" + + Scenario: Account creation disabled, invitations required, users can request invitations, and the queue is enabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I uncheck "Account creation enabled" + And I check "Account creation requires invitation" + And I check "Users can request invitations" + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should see "Get Invited!" + And I should see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation enabled, invitations required, users cannot request invitations, and the queue is disabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I check "Account creation enabled" + And I check "Account creation requires invitation" + And I uncheck "Users can request invitations" + And I uncheck "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + And I should see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + When I go to account creation page + Then I should be on the home page + And I should see "Account creation currently requires an invitation. We are unable to give out additional invitations at present, but existing invitations can still be used to create an account." + And I should see "Forgot password?" within "div#small_login" + And I should not see "Get an Invitation" within "div#small_login" + + Scenario: Account creation enabled, invitations not required, users cannot request invitations, and the queue is enabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I check "Account creation enabled" + And I uncheck "Account creation requires invitation" + And I uncheck "Users can request invitations" + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should see "Create an Account!" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation disabled, invitations not required, users can request invitations, and the queue is enabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I uncheck "Account creation enabled" + And I uncheck "Account creation requires invitation" + And I check "Users can request invitations" + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + + Scenario: Account creation enabled, invitations not required, users can request invitations, and the queue is disabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I check "Account creation enabled" + And I uncheck "Account creation requires invitation" + And I check "Users can request invitations" + And I uncheck "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + And I should see "Create an Account!" + + Scenario: Account creation disabled, invitations required, users cannot request invitations, and the queue is enabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I uncheck "Account creation enabled" + And I check "Account creation requires invitation" + And I uncheck "Users can request invitations" + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should see "Get Invited!" + And I should see "You can join by getting an invitation from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation enabled, invitations not required, users cannot request invitations, and the queue is disabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I check "Account creation enabled" + And I uncheck "Account creation requires invitation" + And I uncheck "Users can request invitations" + And I uncheck "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + And I should see "Create an Account!" + When I go to account creation page + Then I should be on account creation page + And I should see "Create Account" + + Scenario: Account creation disabled, invitations required, users cannot request invitations, and the queue is disabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I uncheck "Account creation enabled" + And I check "Account creation requires invitation" + And I uncheck "Users can request invitations" + And I uncheck "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + And I should see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation disabled, invitations not required, users can request invitations, and the queue is disabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I uncheck "Account creation enabled" + And I uncheck "Account creation requires invitation" + And I check "Users can request invitations" + And I uncheck "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation disabled, invitations not required, users cannot request invitations, and the queue is enabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I uncheck "Account creation enabled" + And I uncheck "Account creation requires invitation" + And I uncheck "Users can request invitations" + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + When I go to account creation page + Then I should be on the home page + And I should see "Account creation is suspended at the moment. Please check back with us later." + And I should see "Forgot password? Get an Invitation" within "div#small_login" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: Account creation disabled, invitations not required, users cannot request invitations, and the queue is disabled + Given I am logged in as a super admin + And I go to the admin-settings page + And I uncheck "Account creation enabled" + And I uncheck "Account creation requires invitation" + And I uncheck "Users can request invitations" + And I uncheck "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + And I log out + When I go to the home page + Then I should not see "Get Invited!" + And I should not see "You can join by getting an invitation from another user or from our automated invite queue. All fans and fanworks are welcome!" + And I should not see "Create an Account!" + And I should not see "Joining the Archive currently requires an invitation; however, we are not accepting new invitation requests at this time." + + Scenario: An admin can send an invitation to a user via email + Given I am logged in as an admin + And all emails have been delivered + When I follow "Invite New Users" + And I fill in "invitation[invitee_email]" with "fred@bedrock.com" + And I press "Invite user" + Then I should see "An invitation was sent to fred@bedrock.com" + And 1 email should be delivered + + Scenario: An admin can't create an invite with invalid email + Given I am logged in as an admin + And all emails have been delivered + When I follow "Invite New Users" + And I fill in "invitation[invitee_email]" with "abcdefgh" + And I press "Invite user" + Then I should see "Invitee email should look like an email address. Please use a different address or leave blank." + And 0 emails should be delivered + + Scenario: An admin can't create an invite without an email address. + Given I am logged in as an admin + And all emails have been delivered + When I follow "Invite New Users" + And I press "Invite user" + Then I should see "Please enter an email address" + And 0 emails should be delivered + + Scenario: An admin can send an invitation to all existing users + Given the following activated users exist + | login | password | + | dax | lotsaspots | + | odo | mybucket9 | + And "dax" has "0" invitations + And "odo" has "3" invitations + And I am logged in as an admin + When I follow "Invite New Users" + And I fill in "Number of invitations" with "2" + And I select "All" from "Users" + And I press "Generate invitations" + Then "dax" should have "2" invitations + And "odo" should have "5" invitations + + Scenario: An admin can send invitations to only existing users who don't have unused invitations + Given the following activated users exist + | login | password | + | dax | lotsaspots | + | bashir | heytheredoc | + And "dax" has "5" invitations + And "bashir" has "0" invitations + And I am logged in as an admin + When I follow "Invite New Users" + And I fill in "Number of invitations" with "2" + And I select "With no unused invitations" from "Users" + And I press "Generate invitations" + Then "dax" should have "7" invitations + And "bashir" should have "2" invitations + + Scenario: An admin can see the invitation of an existing user via name or token + Given the user "dax" exists and is activated + And "dax" has "2" invitations + And I am logged in as an admin + When I follow "Invite New Users" + And I fill in "Username" with "dax" + And I press "Search" within "form.invitation.simple.search" + Then I should see "Copy and use" + And I should see "Delete" + When I follow "Invite New Users" + And I fill in "Invite token" with "dax's" invite code + And I press "Search" within "form.invitation.simple.search" + # Only certain admin roles have access to this page; other admins will see the following error message + When I follow the first invitation token url + Then I should see "Please log out of your admin account first!" + + Scenario: An admin can find all invitations via email partial match + Given I am logged in as an admin + And an invitation request for "fred@bedrock.com" + And an invitation request for "barney@bedrock.com" + And all emails have been delivered + And I follow "Invite New Users" + Then I should see "There are 2 requests in the queue." + When I fill in "Number of people to invite" with "2" + And I press "Invite from queue" + Then I should see "2 people from the invite queue are being invited" + When I fill in "All or part of an email address" with "@" + And I press "Search" within "form.invitation.simple.search" + Then I should see "fred@bedrock.com" + And I should see "barney@bedrock.com" + + Scenario: An admin can't find a invitation for a nonexistent user + Given I am logged in as an admin + And I follow "Invite New Users" + When I fill in "Username" with "dax" + And I press "Search" within "form.invitation.simple.search" + Then I should see "No results were found. Try another search" + When I fill in "Username" with "" + And I fill in "All or part of an email address" with "nonexistent@domain.com" + And I press "Search" within "form.invitation.simple.search" + Then I should see "No results were found. Try another search" + + Scenario: An admin can invite people from the queue + Given I am logged in as an admin + And an invitation request for "fred@bedrock.com" + And an invitation request for "barney@bedrock.com" + And all emails have been delivered + And I follow "Invite New Users" + Then I should see "There are 2 requests in the queue." + When I fill in "Number of people to invite" with "1" + And press "Invite from queue" + Then I should see "There is 1 request in the queue." + And I should see "1 person from the invite queue is being invited" + And 1 email should be delivered to "fred@bedrock.com" + + Scenario: When an admin invites from the queue, the invite is marked as being from the admin + Given I am logged in as a "support" admin + And an invitation request for "test@example.com" + And I follow "Invite New Users" + When I fill in "Number of people to invite" with "1" + And press "Invite from queue" + Then I should see "1 person from the invite queue is being invited" + When I press "Search" within "form.invitation.simple.search" + And I fill in "All or part of an email address" with "test@example.com" + And I press "Search" within "form.invitation.simple.search" + Then I should see "Copy and use" + And I should see "Delete" + When I follow the first invitation token url + Then I should see "Sender testadmin-support" + + Scenario: An admin can edit an invitation + Given the user "dax" exists and is activated + And "dax" has "2" invitations + And I am logged in as a "support" admin + When I follow "Invite New Users" + And I fill in "Username" with "dax" + And I press "Search" within "form.invitation.simple.search" + Then I should see "Copy and use" + And I should see "Delete" + When I follow "Invite New Users" + And I fill in "Invite token" with "dax's" invite code + And I press "Search" within "form.invitation.simple.search" + Then I should see "Copy and use" + And I should see "Delete" + When I follow the first invitation token url + Then I should see "Redeemed at -" + When I fill in "Enter an email address" with "oldman@ds9.com" + And I press "Update Invitation" + Then I should see "oldman@ds9.com" + And I should see "Invitation was successfully sent." + + Scenario: An admin can search the invitation queue, and search parameters are + kept even if deleting without JavaScript + Given I am logged in as a "policy_and_abuse" admin + And an invitation request for "streamtv@example.com" + And an invitation request for "livetv@example.com" + And an invitation request for "clearstream@example.com" + And an invitation request for "stre.a.mer@example.com" + And an invitation request for "dreamer@example.com" + When I am on the manage invite queue page + And I fill in "query" with "stream" + And I press "Search Queue" + Then I should see "streamtv@example.com" + And I should see "clearstream@example.com" + And I should see "stre.a.mer@example.com" + But I should not see "livetv@example.com" + And I should not see "dreamer@example.com" + When I press "Delete" + Then the "query" field should contain "stream" + And I should not see "dreamer@example.com" + And I should not see "livetv@example.com" + + Scenario: The invitations in the queue are paginated correctly + Given I am logged in as a "policy_and_abuse" admin + And there are 2 invite requests per page + And an invitation request for "andy@example.com" + And an invitation request for "beatrice@example.com" + And an invitation request for "carla@example.com" + And an invitation request for "devon@example.com" + And an invitation request for "eliot@example.com" + When I am on the manage invite queue page + Then the invite queue should list the following: + | position | email | + | 1 | andy@example.com | + | 2 | beatrice@example.com | + When I follow "Next" within ".pagination" + Then the invite queue should list the following: + | position | email | + | 3 | carla@example.com | + | 4 | devon@example.com | + When I follow "Next" within ".pagination" + Then the invite queue should list the following: + | position | email | + | 5 | eliot@example.com | + + Scenario: The positions in the queue shift when an invitation is sent out + Given I am logged in as a "policy_and_abuse" admin + And there are 2 invite requests per page + And an invitation request for "andy@example.com" + And an invitation request for "beatrice@example.com" + And an invitation request for "carla@example.com" + And an invitation request for "devon@example.com" + And an invitation request for "eliot@example.com" + When I follow "Invite New Users" + And I fill in "Number of people to invite" with "2" + And press "Invite from queue" + Then I should see "2 people from the invite queue are being invited" + When I am on the manage invite queue page + Then the invite queue should list the following: + | position | email | + | 1 | carla@example.com | + | 2 | devon@example.com | + When I follow "Next" within ".pagination" + Then the invite queue should list the following: + | position | email | + | 3 | eliot@example.com | + + Scenario: The invitations in the queue are numbered correctly when searching + Given I am logged in as a "policy_and_abuse" admin + And an invitation request for "andy-jones@example.com" + And an invitation request for "beatrice@example.com" + And an invitation request for "carla@example.com" + And an invitation request for "devon@example.com" + And an invitation request for "eliot-jones@example.com" + When I am on the manage invite queue page + Then the invite queue should list the following: + | position | email | + | 1 | andy-jones@example.com | + | 2 | beatrice@example.com | + | 3 | carla@example.com | + | 4 | devon@example.com | + | 5 | eliot-jones@example.com | + When I fill in "query" with "jones" + And I press "Search Queue" + Then the invite queue should list the following: + | position | email | + | 1 | andy-jones@example.com | + | 5 | eliot-jones@example.com | + + Scenario Outline: Viewing a user's invitation details + Given the user "creator" exists and is activated + And the user "invitee" exists and is activated + And an invitation created by "creator" and used by "invitee" + And I am logged in as a "" admin + When I go to creator's manage invitations page + Then I should see "invitee" + When I view the most recent invitation for "creator" + Then I should see "invitee" + When I follow "invitee" + Then I should see "User: invitee" + When I am logged in as "invitee" + And "invitee" deletes their account + And I am logged in as a "" admin + And I go to creator's manage invitations page + Then I should see "(Deleted)" + But I should not see "invitee" + When I view the most recent invitation for "creator" + Then I should see "User" + And I should see "(Deleted)" + But I should not see "invitee" + + Examples: + | role | + | superadmin | + | tag_wrangling | + | support | + | policy_and_abuse | + | open_doors | diff --git a/features/admins/admin_languages.feature b/features/admins/admin_languages.feature new file mode 100755 index 0000000..7fa078f --- /dev/null +++ b/features/admins/admin_languages.feature @@ -0,0 +1,52 @@ +Feature: Manipulate languages on the Archive + In order to be multicultural + As as an admin + I'd like to be able to manipulate languages on the Archive + +Scenario: An admin can add a language + + Given basic languages + And I am logged in as a "translation" admin + When I go to the languages page + And I follow "Add a Language" + And I fill in "Name" with "Klingon" + And I fill in "Abbreviation" with "tlh" + And I press "Create Language" + Then I should see "Language was successfully added." + And I should see "Work Languages" + And I should see "Klingon" + And I should see "Klingon (tlh)" + +Scenario: Adding Abuse support for a language + + Given the following language exists + | name | short | + | Arabic | ar | + | Espanol | es | + When I am logged in as a "policy_and_abuse" admin + And I go to the languages page + # Languages are sorted by short name, so the first "Edit" is for Arabic + And I follow "Edit" + And I check "Abuse support available" + And I press "Update Language" + Then I should see "Language was successfully updated." + When I follow "Policy Questions & Abuse Reports" + Then I should see "Arabic" within "select#abuse_report_language" + And I should not see "Espanol" within "select#abuse_report_language" + +Scenario: Adding a language to the Support form + + Given the following language exists + | name | short | + | Sindarin | sj | + | Klingon | tlh | + When I am logged in as a "support" admin + And I go to the languages page + # Languages are sorted by short name, so the first "Edit" is for Sindarin + And I follow "Edit" + And I check "Support available" + And I press "Update Language" + Then I should see "Language was successfully updated." + When I follow "Technical Support & Feedback" + Then I should see "Sindarin" within "select#feedback_language" + And I should not see "Klingon" within "select#feedback_language" diff --git a/features/admins/admin_locales.feature b/features/admins/admin_locales.feature new file mode 100755 index 0000000..b124953 --- /dev/null +++ b/features/admins/admin_locales.feature @@ -0,0 +1,25 @@ +@admin +Feature: Admin tasks + + Scenario: Add and edit a locale + Given the following language exists + | name | short | + | Dutch | nl | + And I am logged in as a "translation" admin + When I go to the locales page + Then I should see "English (US)" + When I follow "New Locale" + And I select "Dutch" from "Language" + And I fill in "locale_name" with "Dutch - Netherlands" + And I fill in "locale_iso" with "nl-nl" + And I check "Use this locale to send email" + And I press "Create Locale" + Then I should see "Dutch - Netherlands nl-nl" + When I follow "Edit" + And I select "English" from "Language" + And I fill in "locale_name" with "English (GB)" + And I check "Use this locale to send email" + And I check "Use this locale for the interface" + And I press "Update Locale" + Then I should see "Your locale was successfully updated." + And I should see "English (GB) en" diff --git a/features/admins/admin_post_faqs.feature b/features/admins/admin_post_faqs.feature new file mode 100755 index 0000000..6e3ab60 --- /dev/null +++ b/features/admins/admin_post_faqs.feature @@ -0,0 +1,198 @@ +@admin +Feature: Admin Actions to Post FAQs + As an an admin + I want to be able to manage the archive FAQ + + Scenario Outline: Authorized admin posts, edits and deletes a FAQ category + When I go to the archive_faqs page + Then I should see "Some commonly asked questions about the Archive are answered here" + And I should not see "Some text" + When I am logged in as a "" admin + And I follow "Admin Posts" + And I follow "Archive FAQ" within "#header" + Then I should not see "Some text" + When I follow "New FAQ Category" + And I fill in "Question*" with "What is AO3?" + And I fill in "Answer*" with "Some text, that is sufficiently long to pass validation." + And I fill in "Category name*" with "New subsection" + And I fill in "Anchor name*" with "whatisao3" + And I press "Post" + Then I should see "Archive FAQ was successfully created" + When I go to the archive_faqs page + And I follow "New subsection" + Then I should see "Some text, that is sufficiently long to pass validation" within ".userstuff" + When I follow "Edit" + And I fill in "Answer*" with "New Content, yay" + And I press "Post" + Then I should see "New Content, yay" + And I should not see "Some text" + When I go to the archive_faqs page + And I follow "Delete" + Then I should see "Are you sure you want to delete the FAQ Category" + When I press "Yes, Delete FAQ Category" + Then I should not see "New subsection" + + Examples: + | role | + | support | + | superadmin | + | docs | + + @javascript + Scenario Outline: Authorized admin deletes a FAQ question + Given 1 Archive FAQ with 1 question exists + And I am logged in as a "" admin + And I go to the archive_faqs page + And I follow "Edit" + And I follow "Remove Question" + And I press "Post" + Then I should see "Archive FAQ was successfully updated." + And I should see "We're sorry, there are currently no entries in this category." + + Examples: + | role | + | support | + | superadmin | + | docs | + + Scenario: Post a translated FAQ for a locale, then change the locale's code. + Given basic languages + And I am logged in as a "superadmin" admin + + # Post "en" FAQ + When I go to the archive_faqs page + And I follow "New FAQ Category" + And I fill in "Question*" with "What is AO3?" + And I fill in "Answer*" with "Some text, that is sufficiently long to pass validation." + And I fill in "Category name*" with "New subsection" + And I fill in "Anchor name*" with "whatisao3" + And I press "Post" + Then I should see "Archive FAQ was successfully created" + + # Translate FAQ to "de" + When I am logged in as a "translation" admin + And I follow "Admin Posts" + And I follow "Archive FAQ" + And I select "Deutsch" from "Language:" + And I press "Go" within "div#inner.wrapper" + And I follow "Edit" + And I fill in "Question*" with "Was ist AO3?" + And I fill in "Answer*" with "Einiger Text, der lang genug ist, um die Überprüfung zu bestehen." + And I fill in "Category name*" with "Neuer Abschnitt" + And I check "Question translated" + And I press "Post" + Then I should see "Archive FAQ was successfully updated." + And I should not see "New subsection" + And I should see "Neuer Abschnitt" + And I should see "Was ist AO3?" + And I should see "Einiger Text" + + # Change locale "de" to "ger" + When I go to the locales page + And I follow "Edit" + Then I should see "Deutsch" in the "Name" input + When I fill in "locale_iso" with "ger" + And I press "Update Locale" + Then I should see "Your locale was successfully updated." + And I should see "Deutsch ger" + + # The session preference is "de", which no longer exists; the default locale should be used + When I go to the archive_faqs page + Then "English (US)" should be selected within "Language:" + + # Log out and view FAQs; the default locale should be used + When I log out + And I go to the archive_faqs page + And I follow "New subsection" + Then I should see "What is AO3?" + And I should see "Some text" + + # Select "ger" + When I go to the archive_faqs page + And I select "Deutsch" from "Language:" + And I press "Go" within "div#inner.wrapper" + And I follow "Neuer Abschnitt" + Then I should see "Was ist AO3?" + And I should see "Einiger Text" + + Scenario: Links to create, reorder and delete FAQ categories are not shown for non-English language FAQs + Given basic languages + And 1 Archive FAQ exists + And I am logged in as a "superadmin" admin + When I go to the archive_faqs page + Then I should see "New FAQ Category" + And I should see "Reorder FAQs" + And I should see "Delete" + And I should see "Edit" + When I select "Deutsch" from "Language:" + And I press "Go" within "div#inner.wrapper" + Then I should not see "New FAQ Category" + And I should not see "Reorder FAQs" + And I should not see "Delete" + But I should see "Edit" + + @javascript + Scenario: Links to add, reorder and remove FAQ questions are not shown for non-English language FAQs + Given basic languages + And 1 Archive FAQ with 1 question exists + And I am logged in as a "superadmin" admin + When I go to the archive_faqs page + And I follow "Edit" + Then I should see "Reorder Questions" + And I should see "Remove Question" + And I should see "Add Question" + But I should not see "Question translated" + When I select "Deutsch" from "Language:" + And I press "Go" within "div#inner.wrapper" + And I follow "Edit" + Then I should not see "Reorder Questions" + And I should not see "Remove Question" + And I should not see "Add Question" + But I should see "Question translated" + + Scenario: Translation admins do not see links to edit English language FAQs + Given basic languages + And 1 Archive FAQ exists + And I am logged in as a "translation" admin + When I go to the archive_faqs page + Then I should not see "Edit" + And I should not see "New FAQ Category" + And I should not see "Reorder FAQs" + And I should not see "Delete" + When I follow "Show" + Then I should not see "Edit" within ".header" + When I go to the archive_faqs page + And I select "Deutsch" from "Language:" + And I press "Go" within "div#inner.wrapper" + Then I should see "Edit" + And I should not see "New FAQ Category" + And I should not see "Reorder FAQs" + And I should not see "Delete" + When I follow "Show" + Then I should see "Edit" within ".header" + + Scenario Outline: Links to create and edit FAQs are not shown to unauthorized admins + Given an archive FAQ category with the title "Very important FAQ" exists + And I am logged in as a "" admin + When I follow "Admin Posts" + Then I should not see "Archive FAQ" within "#header" + When I go to the archive_faqs page + Then I should not see "Edit" + And I should not see "New FAQ Category" + And I should not see "Reorder FAQs" + And I should not see "Delete" + But I should see "Available Categories" + When I follow "Very important FAQ" + Then I should not see "Edit" + + Examples: + | role | + | board | + | board_assistants_team | + | communications | + | development_and_membership | + | elections | + | legal | + | tag_wrangling | + | policy_and_abuse | + | open_doors | diff --git a/features/admins/admin_post_issues.feature b/features/admins/admin_post_issues.feature new file mode 100755 index 0000000..cdedac3 --- /dev/null +++ b/features/admins/admin_post_issues.feature @@ -0,0 +1,53 @@ +@admin +Feature: Admin Actions to Post Known Issues + As an an admin + I want to be able to report known issues + + Scenario Outline: Authorized admin posts, edits, and deletes known issues + Given I am logged in as a "" admin + When I follow "Admin Posts" + And I follow "Known Issues" within "#header" + And I follow "make a new known issues post" + And I fill in "known_issue_title" with "First known problem" + And I fill in "content" with "This is a bit of a problem" + # Suspect related to issue 2458 + And I press "Post" + Then I should see "Known issue was successfully created" + And I should see "First known problem" + When I follow "Admin Posts" + And I follow "Known Issues" within "#header" + And I follow "Show" + Then I should see "First known problem" + When I edit known issues + Then I should see "Known issue was successfully updated" + And I should not see "First known problem" + And I should see "This is a bit of a problem, and this is too" + When I delete known issues + Then I should not see "First known problem" + + Examples: + | role | + | support | + | superadmin | + + Scenario Outline: Links to edit and create known issues are not shown to unauthorized admins + Given I have posted known issues + And I am logged in as a "" admin + When I follow "Admin Posts" + Then I should not see "Known Issues" within "#header" + When I go to the known issues page + Then I should not see "Edit" within ".actions" + + Examples: + | role | + | board | + | board_assistants_team | + | communications | + | development_and_membership | + | docs | + | elections | + | legal | + | translation | + | tag_wrangling | + | policy_and_abuse | + | open_doors | diff --git a/features/admins/admin_post_news.feature b/features/admins/admin_post_news.feature new file mode 100755 index 0000000..8b35264 --- /dev/null +++ b/features/admins/admin_post_news.feature @@ -0,0 +1,279 @@ +@admin @comments +Feature: Admin Actions to Post News + In order to post news items + As an an admin + I want to be able to use the Admin Posts screen + + Scenario: Must be authorized to post + Given I am logged in as a "tag_wrangling" admin + When I go to the admin-posts page + Then I should not see "Post AO3 News" + + Scenario: Make an admin post + Given I am logged in as a "communications" admin + When I make an admin post + Then I should see "Admin Post was successfully created." + + Scenario: Receive comment notifications for comments posted to an admin post + Given I have posted an admin post + + # regular user replies to admin post + When I am logged in as "happyuser" + And I go to the admin-posts page + When all emails have been delivered + And I follow "Default Admin Post" + And I fill in "Comment" with "Excellent, my dear!" + And I press "Comment" + # notification to the admin list for admin post + Then 0 emails should be delivered to "testadmin-communications@example.org" + But 1 email should be delivered to "admin@example.org" + And the email should contain "Excellent" + + # regular user edits their comment + When all emails have been delivered + And I follow "Edit" + And I press "Update" + # notification to the admin list for admin post + Then 0 emails should be delivered to "testadmin-communications@example.org" + But 1 email should be delivered to "admin@example.org" + + Scenario: User views RSS of admin posts + + Given I have posted an admin post + When I am logged in + And I go to the admin-posts page + Then I should see "RSS Feed" + When I follow "RSS Feed" + Then I should see "Default Admin Post" + + Scenario: User views RSS of translated admin posts + Given I have posted an admin post + And basic languages + And I am logged in as a "translation" admin + When I make a translation of an admin post + And I am logged in as "ordinaryuser" + And I go to the admin-posts page + And I select "Deutsch" from "Language:" + And I press "Go" within "div#inner.wrapper" + And I follow "RSS Feed" + Then I should see "Deutsch Ankuendigung" + + Scenario: Make a translation of an admin post + Given I have posted an admin post + And basic languages + And I am logged in as a "translation" admin + When I make a translation of an admin post + And I am logged in as "ordinaryuser" + Then I should see a translated admin post + + Scenario: Make a translation of an admin post that doesn't exist + Given basic languages + And I am logged in as a "translation" admin + When I make a translation of an admin post + Then I should see "Sorry! We couldn't save this admin post because:" + And I should see "Translated post does not exist" + And the translation information should still be filled in + + Scenario: Make a translation of an admin post stop being a translation + Given I have posted an admin post + And basic languages + And I am logged in as a "translation" admin + And I make a translation of an admin post + When I follow "Edit Post" + And I fill in "Translation of" with "" + And I press "Post" + When I am logged in as "ordinaryuser" + Then I should not see a translated admin post + + Scenario: Log in as an admin and create an admin post with tags + Given I am logged in as a "communications" admin + When I follow "Admin Posts" + And I follow "Post AO3 News" + Then I should see "New AO3 News Post" + And I should see "Comment permissions from the selected post will replace any permissions selected on this page." + And I should see "Tags from the selected post will replace any tags entered on this page." + When I fill in "admin_post_title" with "Good news, everyone!" + And I fill in "content" with "I've taught the toaster to feel love." + And I fill in "Tags" with "quotes, futurama" + And I choose "No one can comment" + And I press "Post" + Then I should see "Admin Post was successfully created." + And I should see "toaster" within "div.admin.home" + And I should see "futurama" within "dd.tags" + + Scenario: Admin posts can be filtered by tags and languages + Given I have posted an admin post with tags "quotes, futurama" + And basic languages + And I am logged in as a "translation" admin + When I make a translation of an admin post + And I am logged in as "ordinaryuser" + Then I should see a translated admin post with tags "quotes, futurama" + + When I follow "News" + Then "futurama" should be an option within "Tag" + And "quotes" should be an option within "Tag" + And "Deutsch" should be an option within "Language" + And "English" should be selected within "Language" + + # No tag selected + When I press "Go" + Then I should see "Content of the admin post" + And I should not see "Deutsch Woerter" + And "English" should be selected within "Language" + + When I select "quotes" from "Tag" + And I select "Deutsch" from "Language" + And I press "Go" + Then I should not see "Content of the admin post" + And I should see "Deutsch Woerter" + And "quotes" should be selected within "Tag" + And "Deutsch" should be selected within "Language" + + Scenario: Translation of an admin post keeps tags of original post + Given I have posted an admin post with tags "original1, original2" + And basic languages + And I am logged in as a "translation" admin + When I make a translation of an admin post with tags "ooops" + Then I should see "original1 original2" within "dd.tags" + And I should not see "ooops" + When I follow "Edit Post" + Then I should not see the input with id "admin_post_tag_list" + And I should not see "Tags from the selected post will replace any tags entered on this page." + When I go to the admin-posts page + Then "ooops" should not be an option within "Tag" + When I follow "Edit" + Then I should see the input with id "admin_post_tag_list" + When I fill in "Tags" with "updated1, updated2" + And I press "Post" + And I am logged in as "ordinaryuser" + Then I should see a translated admin post with tags "updated1, updated2" + + Scenario: If an admin post has characters like & and < and > in the title, the escaped version will not show on the various admin post pages + Given I am logged in as a "communications" admin + When I follow "Admin Posts" + And I follow "Post AO3 News" + And I fill in "admin_post_title" with "App News & a Warning" + And I fill in "content" with "We're delaying it a week for every question we get." + When I press "Post" + Then I should see the page title "App News & a Warning" + And I should not see "App News & a <strong> Warning" + When I go to the admin-posts page + Then I should see "App News & a Warning" + And I should not see "App News & a <strong> Warning" + When I go to the home page + Then I should see "App News & a Warning" + And I should not see "App News & a <strong> Warning" + When I log out + And I go to the admin-posts page + Then I should see "App News & a Warning" + And I should not see "App News & a <strong> Warning" + + Scenario: Admin post should be shown on the homepage + Given I have posted an admin post + When I am on the homepage + Then I should see "News" + And I should see "All News" + And I should see "Default Admin Post" + And I should see "Published:" + And I should see "Comments:" + And I should see "Content of the admin post." + And I should see "Read more..." + When I follow "Read more..." + Then I should see "Default Admin Post" + And I should see "Content of the admin post." + + Scenario: Admin posts without paragraphs should have placeholder preview text on the homepage + Given I have posted an admin post without paragraphs + When I am on the homepage + Then I should see "Admin Post Without Paragraphs" + And I should see "No preview is available for this news post." + + Scenario: Edits to an admin post should appear on the homepage + Given I have posted an admin post without paragraphs + And I am logged in as a "communications" admin + When I go to the admin-posts page + And I follow "Edit" + And I fill in "admin_post_title" with "Edited Post" + And I fill in "content" with "

    Look! A preview!

    " + And I press "Post" + When I am on the homepage + Then I should see "Edited Post" + And I should see "Look! A preview!" + And I should not see "Admin Post Without Paragraphs" + And I should not see "No preview is available for this news post." + + Scenario: A deleted admin post should be removed from the homepage + Given I have posted an admin post + And I am logged in as a "communications" admin + When I go to the admin-posts page + And I follow "Delete" + When I go to the homepage + Then I should not see "Default Admin Post" + + Scenario: Log in as an admin and create an admin post in a rtl (right-to-left) language + Given I am logged in as a "communications" admin + And Persian language + When I follow "Admin Posts" + And I follow "Post AO3 News" + Then I should see "New AO3 News Post" + When I fill in "admin_post_title" with "فارسی" + And I fill in "content" with "چیزهایی هست که باید در حین ایجاد یک گزارش از آنها آگاه باشید" + And I select "Persian" from "Choose a language" + And I press "Post" + Then I should see "Admin Post was successfully created." + And I should see "باشید" within "div.admin.home div.userstuff" + And the user content should be shown as right-to-left + + Scenario: Moderating comments on an admin post + Given I am logged in as a "communications" admin + When I start to make an admin post + And I check "Enable comment moderation" + And I choose "Registered users and guests can comment" + And I press "Post" + Then I should see "Admin Post was successfully created." + And I should not see "Unreviewed Comments" + + # Leave a guest comment on a moderated admin post + When I log out + And I go to the "Default Admin Post" admin post page + Then I should see "Comments on this news post are moderated. Your comment will not appear until it has been approved." + When I fill in "Comment" with "Perfectly nice comment" + And I fill in "Guest name" with "lovely" + And I fill in "Guest email" with "email@example.com" + And I press "Comment" + Then I should see "Your comment was received! It will appear publicly after it has been approved." + And I should be on the "Default Admin Post" admin post page + And 1 email should be delivered to "admin@example.org" + + # Leave a logged in comment on a moderated admin post + When I am logged in as "commenter" + And I go to the "Default Admin Post" admin post page + Then I should see "Comments on this news post are moderated. Your comment will not appear until it has been approved." + When I fill in "Comment" with "Second perfectly nice comment" + And I press "Comment" + Then I should see "Your comment was received! It will appear publicly after it has been approved." + And I should see "Second perfectly nice comment" + + # Access unreviewed comments + When I am logged in as a "legal" admin + And I go to the "Default Admin Post" admin post page + And I follow "Unreviewed Comments (2)" + Then I should see "Unreviewed Comments on Default Admin Post" + And I should see "Please note that comments cannot be unapproved once you have approved them. After you delete any comments you do not wish to appear on the news post, you can approve all that remain." + + # Approve a single comment + When I press "Approve" + Then I should see "Comment approved." + And I should be on the unreviewed comments page for the admin post "Default Admin Post" + When I go to the "Default Admin Post" admin post page + Then I should see "Comments (1)" + And I should see "Unreviewed Comments (1)" + + # Approve All Unreviewed Comments + When I go to the unreviewed comments page for the admin post "Default Admin Post" + And I press "Approve All Unreviewed Comments" + Then I should see "All moderated comments approved." + And I should be on the "Default Admin Post" admin post page + And I should see "Comments (2)" + And I should not see "Unreviewed Comments" + diff --git a/features/admins/admin_reorder_faq.feature b/features/admins/admin_reorder_faq.feature new file mode 100755 index 0000000..0073cb5 --- /dev/null +++ b/features/admins/admin_reorder_faq.feature @@ -0,0 +1,19 @@ +@admin @faqs +Feature: Rearrange Archive FAQs + In order to manage the Archive FAQs + As an admin + I want to be able to reorder the FAQs + + Scenario: Rearrange FAQs + Given I am logged in as a "superadmin" admin + And 3 Archive FAQs exist + When I go to the FAQ reorder page + And I fill in "archive_faqs_1" with "3" + And I fill in "archive_faqs_2" with "1" + And I fill in "archive_faqs_3" with "2" + And I press "Update Positions" + Then I should see "Archive FAQs order was successfully updated" + When I follow "Reorder FAQs" + Then I should see "1. The 2 FAQ" + And I should see "2. The 3 FAQ" + And I should see "3. The 1 FAQ" diff --git a/features/admins/admin_reorder_faq_questions.feature b/features/admins/admin_reorder_faq_questions.feature new file mode 100755 index 0000000..2142bcc --- /dev/null +++ b/features/admins/admin_reorder_faq_questions.feature @@ -0,0 +1,28 @@ +@admin +Feature: Admin Actions to re-order questions in a FAQ Category + As an an admin + I want to be able to re-order the questions in a FAQ Category + +Scenario: Re-order the questions in a FAQ Category + Given I am logged in as a "superadmin" admin + And I make a multi-question FAQ post + When I go to the archive_faqs page + And I follow "Standard FAQ Category" + And I follow "Edit" + And I follow "Reorder Questions" + # First confirm the current order of the questions + Then I should see "1. Number 1 Question." + And I should see "2. Number 2 Question." + And I should see "3. Number 3 Question." + # Flip the order of the questions + And I fill in "questions_1" with "3" + And I fill in "questions_2" with "2" + And I fill in "questions_3" with "1" + And I press "Update Positions" + When I follow "Edit" + And I follow "Reorder Questions" + # Confirm the questions are in the new reversed order + Then I should see "1. Number 3 Question." + And I should see "2. Number 2 Question." + And I should see "3. Number 1 Question." + diff --git a/features/admins/admin_settings.feature b/features/admins/admin_settings.feature new file mode 100755 index 0000000..beb50a7 --- /dev/null +++ b/features/admins/admin_settings.feature @@ -0,0 +1,169 @@ +@admin +Feature: Admin Settings Page + In order to improve performance + As an admin + I want to be able to control downloading, tag wrangling and guest comments. + + Scenario: Turn off downloads + Given downloads are off + And I have a work "Storytime" + When I log out + And I view the work "Storytime" + Then I should not see "Download" + When I am logged in as "tester" + And I view the work "Storytime" + Then I should not see "Download" + + Scenario: Turn off tag wrangling + Given tag wrangling is off + And the following activated tag wrangler exists + | login | + | dizmo | + And a canonical character "Ianto Jones" + When I am logged in as "dizmo" + And I edit the tag "Ianto Jones" + Then I should see "Wrangling is disabled at the moment. Please check back later." + And I should not see "Synonym of" + + Scenario: Turn off Support form + Given the support form is disabled and its text field set to "Please don't contact us" + When I am logged in as a random user + And I go to the support page + Then I should see "Please don't contact us" + + Scenario: Turn on Support form + Given the support form is enabled + When I am logged in as a random user + And I go to the support page + Then I should see "We can answer Support inquiries in" + + Scenario Outline: Guests can comment when guest coments are enabled + Given guest comments are on + And I am logged out + And + And with guest comments enabled + And I view with comments + When I post a guest comment + Then I should see a link "Reply" + + Examples: + | commentable | + | the work "Generic Work" | + | the admin post "Generic Post" | + + Scenario Outline: Guests cannot comment when guest comments are disabled, even if works or admin posts allow comments + Given guest comments are off + And I am logged out + And + And with guest comments enabled + And a guest comment on + When I view with comments + Then I should see "Sorry, the Archive doesn't allow guests to comment right now." + And I should not see a link "Reply" + When I am logged in + And I view with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + When I am logged in as a super admin + And I view with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + + Examples: + | commentable | + | the work "Generic Work" | + | the admin post "Generic Post" | + + Scenario: Turn off guest comments (when the work itself does not allow guest comments) + Given guest comments are off + And I am logged in as "author" + And I set up the draft "Generic Work" + And I choose "Only registered users can comment" + And I post the work without preview + And a comment "Nice job" by "user" on the work "Generic Work" + When I am logged out + And I view the work "Generic Work" with comments + Then I should see "Sorry, the Archive doesn't allow guests to comment right now." + And I should not see a link "Reply" + When I am logged in + And I view the work "Generic Work" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + When I am logged in as a super admin + And I view the work "Generic Work" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + + Scenario: Turn off guest comments (when the admin post itself does not allow guest comments) + Given guest comments are off + And I have posted an admin post with guest comments disabled + And a comment "Nice job" by "user" on the admin post "Default Admin Post" + When I view the admin post "Default Admin Post" with comments + Then I should see "Sorry, the Archive doesn't allow guests to comment right now." + And I should not see a link "Reply" + When I am logged in + And I view the admin post "Default Admin Post" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + When I am logged in as a super admin + And I view the admin post "Default Admin Post" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + + Scenario: Turn off guest comments (when work itself does not allow any comments) + Given guest comments are off + And I am logged in as "author" + And I post the work "Generic Work" + And a guest comment on the work "Generic Work" + And I edit the work "Generic Work" + And I choose "No one can comment" + And I press "Post" + When I am logged out + And I view the work "Generic Work" with comments + Then I should see "Sorry, the Archive doesn't allow guests to comment right now." + And I should not see a link "Reply" + When I am logged in + And I view the work "Generic Work" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + When I am logged in as a super admin + And I view the work "Generic Work" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + + Scenario: Turn off guest comments (when the admin post itself does not allow any comments) + Given guest comments are off + And I have posted an admin post with comments disabled + And a comment "Nice job" by "user" on the admin post "Default Admin Post" + When I view the admin post "Default Admin Post" with comments + Then I should see "Sorry, the Archive doesn't allow guests to comment right now." + And I should not see a link "Reply" + When I am logged in + And I view the admin post "Default Admin Post" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + When I am logged in as a super admin + And I view the admin post "Default Admin Post" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + + Scenario: Tag comments are not affected when guest comments are turned off + Given guest comments are off + And a fandom exists with name: "Stargate SG-1", canonical: true + When I am logged in as a tag wrangler + And I view the tag "Stargate SG-1" with comments + Then I should not see "Sorry, the Archive doesn't allow guests to comment right now." + When I post the comment "Sent you a syn" on the tag "Stargate SG-1" + Then I should see "Comment created!" + + Scenario: Timestamp and admin for last update is not affected by invitation sending + Given time is frozen at 2025-04-12 17:00 + And the invitation queue is enabled + And an invitation request for "invitee@example.org" + And an invitation request for "invitee2@example.org" + And an invitation request for "invitee3@example.org" + And I am logged in as a "superadmin" admin + When I go to the admin-settings page + And I fill in "Number of people to invite from the queue at once" with "2" + And I fill in "How often (in hours) should we invite people from the queue" with "1" + And I press "Update" + Then I should see "Settings last updated on 2025-04-12 17:00:00 UTC by testadmin-superadmin." + And I should see "2 people are scheduled to be sent invitations at April 12, 2025 18:00." + When time is frozen at 2025-04-14 03:00 + And I go to the admin-settings page + Then I should see "Settings last updated on 2025-04-12 17:00:00 UTC by testadmin-superadmin." + And I should see "2 people are scheduled to be sent invitations at April 12, 2025 18:00." + When the scheduled check_invite_queue job is run + And I go to the admin-settings page + Then I should see "Settings last updated on 2025-04-12 17:00:00 UTC by testadmin-superadmin." + And I should see "2 people are scheduled to be sent invitations at April 14, 2025 04:00." diff --git a/features/admins/admin_skins.feature b/features/admins/admin_skins.feature new file mode 100755 index 0000000..a4b1359 --- /dev/null +++ b/features/admins/admin_skins.feature @@ -0,0 +1,151 @@ +@set-default-skin +Feature: Admin manage skins + + Scenario: Users should not be able to see the admin skins page + Given I am logged in as "skinner" + When I go to admin's skins page + Then I should see "I'm sorry, only an admin can look at that area" + + Scenario: Admin can cache and uncache a public skin + Given basic skins + And the approved public skin "public skin" + And I am logged in as a "superadmin" admin + When I follow "Approved Skins" + And I check "Cache" + Then I press "Update" + And I should see "The following skins were updated: public skin" + When I follow "Approved Skins" + And I check "Uncache" + And I press "Update" + Then I should see "The following skins were updated: public skin" + + Scenario: Admin can add a public skin to the chooser and then remove it + Given the approved public skin "public skin" + And the skin "public skin" is cached + When I am logged in as a "superadmin" admin + Then I should not see the skin chooser + When I follow "Approved Skins" + And I check "Chooser" + And I press "Update" + Then I should see "The following skins were updated: public skin" + And I should see the skin "public skin" in the skin chooser + When I follow "Approved Skins" + And I check "Not In Chooser" + And I press "Update" + Then I should see "The following skins were updated: public skin" + And I should not see the skin chooser + + Scenario: An admin can reject and unreject a skin + Given the unapproved public skin "public skin" + And I am logged in as a "superadmin" admin + When I go to admin's skins page + And I check "make_rejected_public_skin" + And I submit + Then I should see "The following skins were updated: public skin" + When I follow "Rejected Skins" + Then I should see "public skin" + When I check "make_unrejected_public_skin" + And I submit + Then I should see "The following skins were updated: public skin" + When I follow "Rejected Skins" + Then I should not see "public skin" + + Scenario: An admin can feature and unfeature skin + Given the approved public skin "public skin" + And I am logged in as a "superadmin" admin + When I follow "Approved Skins" + And I check "Feature" + And I submit + Then I should see "The following skins were updated: public skin" + When I follow "Approved Skins" + And I check "Unfeature" + And I submit + Then I should see "The following skins were updated: public skin" + + Scenario: Admins should be able to see public skins in the admin skins page + Given the unapproved public skin "public skin" + And I am logged in as a "superadmin" admin + When I go to admin's skins page + Then I should see "public skin" within "table#unapproved_skins" + + Scenario: Admins should not be able to edit unapproved skins + Given the unapproved public skin "public skin" + And I am logged in as a "superadmin" admin + When I go to "public skin" skin page + Then I should not see "Edit" + And I should not see "Delete" + When I go to "public skin" edit skin page + Then I should see "Sorry, you don't have permission" + + Scenario: Admins should be able to approve public skins + Given the unapproved public skin "public skin" + And I am logged in as a "superadmin" admin + When I go to admin's skins page + And I check "public skin" + And I submit + Then I should see "The following skins were updated: public skin" + When I follow "Approved Skins" + Then I should see "public skin" within "table#approved_skins" + + Scenario: Admins should be able to edit but not delete public approved skins + Given the approved public skin "public skin" with css "#title { text-decoration: blink;}" + And I am logged in as a "superadmin" admin + When I go to "public skin" skin page + Then I should see "Edit" + But I should not see "Delete" + When I follow "Edit" + And I fill in "CSS" with "#greeting.logged-in { text-decoration: blink;}" + And I fill in "Description" with "Blinky love (admin modified)" + And I submit + Then I should see an update confirmation message + And I should see "(admin modified)" + And I should see "#greeting.logged-in" + And I should not see "#title" + Then the cache of the skin on "public skin" should expire after I save the skin + + Scenario: Admins should be able to unapprove public skins, which should also + remove them from preferences + Given "skinuser" is using the approved public skin "public skin" with css "#title { text-decoration: blink;}" + When I unapprove the skin "public skin" + Then I should see "The following skins were updated: public skin" + And I should see "public skin" within "table#unapproved_skins" + When I am logged in as "skinuser" + And I am on skinuser's preferences page + Then "Default" should be selected within "preference_skin_id" + And I should not see "#title" + And I should not see "text-decoration: blink;" + + Scenario: Admin can change the default skin + Given basic skins + And the approved public skin "strange skin" with css "#title { text-decoration: underline;}" + And the approved public skin "public skin" with css "#title { text-decoration: blink;}" + And I am logged in as "skinner" + And the user "KnownUser" exists and is activated + When I am on skinner's preferences page + And I select "strange skin" from "preference_skin_id" + And I submit + Then I should see "{ text-decoration: underline; }" in the page style + When I am logged in as a "superadmin" admin + Then I should not see "{ text-decoration: blink; }" in the page style + When I follow "Approved Skins" + And I fill in "set_default" with "public skin" + And I press "Update" + Then I should see "Default skin changed to public skin" + And I should see "{ text-decoration: blink; }" in the page style + When I am logged in as "skinner" + Then I should see "{ text-decoration: underline; }" in the page style + # A user created before changing the default skin will still have the same skin + When I am logged in as "KnownUser" + Then I should not see "{ text-decoration: blink; }" in the page style + + Scenario: Admin can edit a skin with the word "archive" in the title + Given the approved public skin "official archive skin" has reserved words in the title + And I am logged in as a "superadmin" admin + When I go to "official archive skin" skin page + And I follow "Edit" + And I fill in "CSS" with "#greeting.logged-in { text-decoration: blink;}" + And I fill in "Description" with "all your skin are belong to us" + And I submit + Then I should see an update confirmation message + And I should see "all your skin are belong to us" + And I should see "#greeting.logged-in" diff --git a/features/admins/admin_spam.feature b/features/admins/admin_spam.feature new file mode 100755 index 0000000..f3946ac --- /dev/null +++ b/features/admins/admin_spam.feature @@ -0,0 +1,74 @@ +@admin +Feature: Admin spam management + In order to manage spam works + As an an admin + I want to be able to view and update works marked as spam + +Scenario: Review spam when spam works are already hidden + Given the following admin settings are configured: + | hide_spam | 1 | + And the spam work "Spammity Spam" + And the spam work "Totally Legit" + And the work "Spammity Spam" should be hidden + And the work "Totally Legit" should be hidden + And I am logged in as a "superadmin" admin + And all emails have been delivered + Then I should see "Spam" + When I follow "Spam" + Then I should see "Works Marked as Spam" + And I should see "Spammity" + And I should see "Totally Legit" + When I check "spam_1" + And I check "ham_2" + And I press "Update Works" + Then I should not see "Spammity" + And I should not see "Totally Legit" + And the work "Spammity Spam" should be hidden + And the work "Totally Legit" should not be hidden + And 0 emails should be delivered + + +Scenario: Review spam when spam works are not already hidden + Given the following admin settings are configured: + | hide_spam | 0 | + And the spam work "Spammity Spam" + And the spam work "Totally Legit" + And the work "Spammity Spam" should not be hidden + And the work "Totally Legit" should not be hidden + And I am logged in as a "superadmin" admin + And all emails have been delivered + Then I should see "Spam" + When I follow "Spam" + Then I should see "Works Marked as Spam" + And I should see "Spammity" + And I should see "Totally Legit" + When I check "spam_3" + And I check "ham_4" + And I press "Update Works" + Then I should not see "Spammity" + And I should not see "Totally Legit" + And the work "Spammity Spam" should be hidden + And the work "Totally Legit" should not be hidden + And 1 email should be delivered + And the email should contain "has been flagged by our automated system as spam" + +Scenario: Translated work hidden as spam email + Given I am logged in as "spammer" + And the work "Spammity Spam Work" by "spammer" + And a locale with translated emails + And the user "spammer" enables translated emails + And I add the co-author "Another" to the work "Spammity Spam Work" + When I am logged in as a "policy_and_abuse" admin + And all emails have been delivered + And I view the work "Spammity Spam Work" + Then I should see "Mark As Spam" + When I follow "Mark As Spam" + Then I should see "marked as spam and hidden" + And I should see "Mark Not Spam" + And the work "Spammity Spam Work" should be marked as spam + And the work "Spammity Spam Work" should be hidden + And 2 emails should be delivered + And the email to "spammer" should contain "has been flagged by our automated system as spam" + And the email to "spammer" should be translated + And the email to "Another" should contain "has been flagged by our automated system as spam" + And the email to "Another" should be non-translated diff --git a/features/admins/admin_tasks.feature b/features/admins/admin_tasks.feature new file mode 100755 index 0000000..b53ee80 --- /dev/null +++ b/features/admins/admin_tasks.feature @@ -0,0 +1,12 @@ +@admin +Feature: Admin tasks + Scenario: admin goes to the Support page + + Given I am logged in as an admin + Then cookie "admin_credentials" should be like "1" + When I go to the support page + Then I should see "Support and Feedback" + And I should see "testadmin@example.org" in the "feedback_email" input + When I log out + And I am on the home page + Then cookie "admin_credentials" should be deleted diff --git a/features/admins/admin_works.feature b/features/admins/admin_works.feature new file mode 100755 index 0000000..c1bbf5e --- /dev/null +++ b/features/admins/admin_works.feature @@ -0,0 +1,641 @@ +@admin +Feature: Admin Actions for Works, Comments, Series, Bookmarks + As an admin + I should be able to perform special actions + + Scenario: Can troubleshoot works + Given the work "Just a work you know" + When I am logged in as a "support" admin + And I view the work "Just a work you know" + And I follow "Troubleshoot" + And I check "Reindex Work" + And I press "Troubleshoot" + Then I should see "Work sent to be reindexed." + + Scenario Outline: Can hide works + Given I am logged in as "regular_user" + And I post the work "ToS Violation" + And a locale with translated emails + And the user "regular_user" enables translated emails + And I add the co-author "Another" to the work "ToS Violation" + When I am logged in as a "" admin + And all emails have been delivered + And I view the work "ToS Violation" + And I follow "Hide Work" + Then I should see "Item has been hidden." + And the work "ToS Violation" should be hidden + And "regular_user" should see their work "ToS Violation" is hidden + And 2 emails should be delivered + And the email to "regular_user" should contain "you will be required to take action to correct the violation" + And the email to "regular_user" should be translated + And the email to "Another" should contain "you will be required to take action to correct the violation" + And the email to "Another" should be non-translated + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario Outline: Can hide works already marked as spam + Given the work "ToS Violation + Spam" by "regular_user" + And the work "ToS Violation + Spam" is marked as spam + When I am logged in as a "" admin + And all emails have been delivered + And I view the work "ToS Violation + Spam" + And I follow "Hide Work" + Then I should see "Item has been hidden." + And logged out users should not see the hidden work "ToS Violation + Spam" by "regular_user" + And logged in users should not see the hidden work "ToS Violation + Spam" by "regular_user" + And "regular_user" should see their work "ToS Violation + Spam" is hidden + And 1 email should be delivered + And the email should contain "you will be required to take action to correct the violation" + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario Outline: Can unhide works + Given the work "ToS Violation" by "regular_user" + When I am logged in as a "" admin + And I view the work "ToS Violation" + And I follow "Hide Work" + And all indexing jobs have been run + And all emails have been delivered + Then I should see "Item has been hidden." + When I follow "Make Work Visible" + And all indexing jobs have been run + Then I should see "Item is no longer hidden." + And logged out users should see the unhidden work "ToS Violation" by "regular_user" + And logged in users should see the unhidden work "ToS Violation" by "regular_user" + And 0 emails should be delivered + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario: Deleting works as a Policy & Abuse admin + Given I am logged in as "regular_user" + And I post the work "ToS Violation" + And a locale with translated emails + And the user "regular_user" enables translated emails + And I add the co-author "Another" to the work "ToS Violation" + When I am logged in as a "policy_and_abuse" admin + # Don't let the admin password email mess up the count. + And all emails have been delivered + And I view the work "ToS Violation" + And I follow "Delete Work" + And all indexing jobs have been run + Then I should see "Item was successfully deleted." + And 2 emails should be delivered + And the email to "regular_user" should contain "deleted from the Archive by a site admin" + And the email to "regular_user" should be translated + And the email to "Another" should contain "deleted from the Archive by a site admin" + And the email to "Another" should be non-translated + When I visit the last activities item + Then I should see "destroy" + And I should see "#" admin + And I am on bad_user's bookmarks page + When I follow "Hide Bookmark" + And all indexing jobs have been run + Then I should see "Item has been hidden." + And I should see "Make Bookmark Visible" + And I should see "Rude comment" + When I am logged in as "regular_user" with password "password1" + And I am on bad_user's bookmarks page + Then I should not see "Rude comment" + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario Outline: Deleting bookmarks + Given the work "A Nice Work" + When I am logged in as "bad_user" + And I view the work "A Nice Work" + When I follow "Bookmark" + And I fill in "bookmark_notes" with "Rude comment" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + When I am logged in as a "" admin + And I am on bad_user's bookmarks page + And I follow "Delete Bookmark" + Then I should see "Item was successfully deleted." + When I am logged in as "bad_user" + And I am on bad_user's bookmarks page + Then I should not see "Rude comment" + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario: Can edit tags on works + Given I am logged in as "regular_user" + And I post the work "Changes" with fandom "User-Added Fandom" with freeform "User-Added Freeform" with category "M/M" + When I am logged in as a "policy_and_abuse" admin + And I view the work "Changes" + And I follow "Edit Tags and Language" + When I select "Mature" from "Rating" + And I uncheck "No Archive Warnings Apply" + And I check "Choose Not To Use Archive Warnings" + And I fill in "Fandoms" with "Admin-Added Fandom" + And I fill in "Relationships" with "Admin-Added Relationship" + And I fill in "Characters" with "Admin-Added Character" + And I fill in "Additional Tags" with "Admin-Added Freeform" + And I uncheck "M/M" + And I check "Other" + When I press "Post" + Then I should not see "User-Added Fandom" + And I should see "Admin-Added Fandom" + And I should not see "User-Added Freeform" + And I should see "Admin-Added Freeform" + And I should not see "M/M" + And I should see "Other" + And I should not see "No Archive Warnings Apply" + And I should see "Creator Chose Not To Use Archive Warnings" + And I should not see "Not Rated" + And I should see "Mature" + And I should see "Admin-Added Relationship" + And I should see "Admin-Added Character" + When I follow "Activities" + Then I should see "Admin Activities" + When I visit the last activities item + Then I should see "No Archive Warnings Apply" + And I should see "Old tags" + And I should see "User-Added Fandom" + And I should not see "Admin-Added Fandom" + + Scenario: Can edit external works + Given basic languages + And I am logged in as "regular_user" + And I bookmark the external work "External Changes" + When I am logged in as a "policy_and_abuse" admin + And I view the external work "External Changes" + And I follow "Edit External Work" + When I fill in "Creator" with "Admin-Added Creator" + And I fill in "Title" with "Admin-Added Title" + And I fill in "Creator's Summary" with "Admin-added summary" + And I select "Mature" from "Rating" + And I check "No Archive Warnings Apply" + And I fill in "Fandoms" with "Admin-Added Fandom" + And I fill in "Relationships" with "Admin-Added Relationship" + And I fill in "Characters" with "Admin-Added Character" + And I fill in "Additional Tags" with "Admin-Added Freeform" + And I check "M/M" + And I select "Deutsch" from "Language" + And it is currently 1 second from now + When I press "Update External work" + Then I should see "Admin-Added Creator" + And I should see "Admin-Added Title" + And I should see "Admin-added summary" + And I should see "Mature" + And I should see "No Archive Warnings" + And I should see "Admin-Added Fandom" + And I should see "Admin-Added Character" + And I should see "Admin-Added Freeform" + And I should see "M/M" + And I should see "Language: Deutsch" + + Scenario Outline: Hiding and un-hiding external works + Given I am logged in as "regular_user" + And I bookmark the external work "External Changes" + When I am logged in as a "" admin + And I view the external work "External Changes" + And I follow "Hide External Work" + Then I should see "Item has been hidden." + And I should see "Make External Work Visible" + When I follow "Make External Work Visible" + Then I should see "Item is no longer hidden." + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario Outline: Deleting external works + Given I am logged in as "regular_user" + And I bookmark the external work "External Changes" + When I am logged in as a "" admin + And I view the external work "External Changes" + And I follow "Delete External Work" + Then I should see "Item was successfully deleted." + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario: Can mark a comment as spam + Given I have no works or comments + And the following activated users exist + | login | password | + | author | password | + | commenter | password | + + # set up a work with a genuine comment + + When I am logged in as "author" + And I post the work "The One Where Neal is Awesome" + When I am logged in as "commenter" + And I view the work "The One Where Neal is Awesome" + And I fill in "Comment" with "I loved this!" + And I press "Comment" + Then I should see "Comment created!" + + # comment from registered user cannot be marked as spam. + # If registered user is spamming, this goes to Abuse team as ToS violation + When I am logged in as a "policy_and_abuse" admin + Then I should see "Successfully logged in" + When I view the work "The One Where Neal is Awesome" + And I follow "Comments (1)" + Then I should not see "Spam" within "#feedback" + + # now mark a comment as spam + When I post the comment "Would you like a genuine rolex" on the work "The One Where Neal is Awesome" as a guest + And I am logged in as a "policy_and_abuse" admin + And I view the work "The One Where Neal is Awesome" + And I follow "Comments (2)" + Then I should see "rolex" + And I should see "Spam" within "#feedback" + And it is currently 1 second from now + When I follow "Spam" within "#feedback" + # Can see link to unmark + Then I should see "Not Spam" + And I should see "Hide Comments (1)" + # Admin can still see spam comment + And I should see "rolex" + And I should see "This comment has been marked as spam." + # proper content should still be there + And I should see "I loved this!" + + # user can't see spam comment + When I log out + And I view the work "The One Where Neal is Awesome" + Then I should see "Comments (1)" + When I follow "Comments (1)" + Then I should not see "rolex" + And I should see "I loved this!" + + # author can't see spam comment + When I am logged in as "author" with password "password" + And I view the work "The One Where Neal is Awesome" + Then I should see "Comments (1)" + When I follow "Comments (1)" + Then I should not see "rolex" + And I should see "I loved this!" + + # now mark comment as not spam + When I am logged in as a "policy_and_abuse" admin + And I view the work "The One Where Neal is Awesome" + And I follow "Comments (1)" + And it is currently 1 second from now + And I follow "Not Spam" + Then I should see "Hide Comments (2)" + And I should not see "Not Spam" + And I should not see "This comment has been marked as spam." + + # user can see comment again + When I log out + And I view the work "The One Where Neal is Awesome" + Then I should see "Comments (2)" + When I follow "Comments (2)" + Then I should see "rolex" + And I should not see "This comment has been marked as spam." + + # author can see comment again + When I am logged in as "author" with password "password" + And I view the work "The One Where Neal is Awesome" + Then I should see "Comments (2)" + When I follow "Comments (2)" + Then I should see "rolex" + And I should not see "This comment has been marked as spam." + + Scenario: Moderated comments cannot be approved by admin + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Test comment" on the work "Moderation" + When I am logged in as a "superadmin" admin + And I view the work "Moderation" + Then I should see "Unreviewed Comments (1)" + And the comment on "Moderation" should be marked as unreviewed + When I follow "Unreviewed Comments (1)" + Then I should see "Test comment" + And I should not see an "Approve All Unreviewed Comments" button + And I should not see an "Approve" button + + Scenario: Admin can edit language on works when posting without previewing + Given basic languages + And the work "Wrong Language" + When I am logged in as a "policy_and_abuse" admin + And I view the work "Wrong Language" + And I follow "Edit Tags and Language" + Then I should see "Edit Work Tags and Language for " + When I select "Deutsch" from "Choose a language" + And I press "Post" + Then I should see "Deutsch" + And I should not see "English" + + Scenario: Admin can edit language on works when previewing first + Given basic languages + And the work "Wrong Language" + When I am logged in as a "policy_and_abuse" admin + And I view the work "Wrong Language" + And I follow "Edit Tags and Language" + When I select "Deutsch" from "Choose a language" + And I press "Preview" + Then I should see "Preview Tags and Language" + When I press "Update" + Then I should see "Deutsch" + And I should not see "English" + + Scenario: can mark a work as spam + Given the work "Spammity Spam" + And I am logged in as a "policy_and_abuse" admin + And I view the work "Spammity Spam" + And all emails have been delivered + Then I should see "Mark As Spam" + When I follow "Mark As Spam" + Then I should see "marked as spam and hidden" + And I should see "Mark Not Spam" + And the work "Spammity Spam" should be marked as spam + And the work "Spammity Spam" should be hidden + And 1 email should be delivered + And the email should contain "has been flagged by our automated system as spam" + + + Scenario: can mark a spam work as not-spam + Given the spam work "Spammity Spam" + And I am logged in as a "policy_and_abuse" admin + And I view the work "Spammity Spam" + Then I should see "Mark Not Spam" + When I follow "Mark Not Spam" + Then I should see "marked not spam and unhidden" + And I should see "Mark As Spam" + And the work "Spammity Spam" should not be marked as spam + And the work "Spammity Spam" should not be hidden + + Scenario Outline: Admin can hide a series (e.g. if the series description or notes contain a TOS Violation) + Given I am logged in as "tosser" + And I add the work "Legit Work" to series "Violation" + When I am logged in as a "" admin + And I view the series "Violation" + And I follow "Hide Series" + Then I should see "Item has been hidden." + And I should see the image "title" text "Hidden by Administrator" + And I should see "Make Series Visible" + When I log out + And I go to tosser's series page + Then I should see "Series (0)" + And I should not see "Violation" + When I view the series "Violation" + Then I should see "Sorry, you don't have permission to access the page you were trying to reach." + When I am logged in as "other_user" + And I go to tosser's series page + Then I should see "Series (0)" + And I should not see "Violation" + When I view the series "Violation" + Then I should see "Sorry, you don't have permission to access the page you were trying to reach." + When I am logged in as "tosser" + And I go to tosser's series page + Then I should see "Series (0)" + And I should not see "Violation" + When I view the series "Violation" + Then I should see the image "title" text "Hidden by Administrator" + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario Outline: Admin can un-hide a series + Given I am logged in as "tosser" + And I add the work "Legit Work" to series "Violation" + And I am logged in as a "" admin + And I view the series "Violation" + And I follow "Hide Series" + When I follow "Make Series Visible" + Then I should see "Item is no longer hidden." + And I should not see the image "title" text "Hidden by Administrator" + And I should see "Hide Series" + When I log out + And I go to tosser's series page + Then I should see "Series (1)" + And I should see "Violation" + When I view the series "Violation" + Then I should see "Violation" + When I am logged in as "other_user" + And I go to tosser's series page + Then I should see "Series (1)" + And I should see "Violation" + When I view the series "Violation" + Then I should see "Violation" + When I am logged in as "tosser" + And I go to tosser's series page + Then I should see "Series (1)" + And I should see "Violation" + When I view the series "Violation" + Then I should see "Violation" + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario Outline: Deleting series + Given I am logged in as "tosser" + And I add the work "Legit Work" to series "Violation" + And I am logged in as a "" admin + When I view the series "Violation" + And I follow "Delete Series" + Then I should see "Item was successfully deleted." + When I log out + And I go to tosser's series page + Then I should see "Series (0)" + And I should not see "Violation" + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario: Admins can see when a work has too many tags + Given the user-defined tag limit is 7 + And the work "Under the Limit" + And the work "Over the Limit" + And the work "Over the Limit" has 2 fandom tags + And the work "Over the Limit" has 2 character tags + And the work "Over the Limit" has 2 relationship tags + And the work "Over the Limit" has 2 freeform tags + When I am logged in as an admin + And I view the work "Under the Limit" + Then I should see "Over Tag Limit: No" + When I view the work "Over the Limit" + Then I should see "Over Tag Limit: Yes" + + Scenario Outline: Certain admins can see original work creators + Given a work "Orphaned" with the original creator "orphaneer" + When I am logged in as a "" admin + And I view the work "Orphaned" + Then I should see the original creator "orphaneer" + + Examples: + | role | + | superadmin | + | legal | + | policy_and_abuse | + + Scenario Outline: Certain admins can remove orphan_account pseuds from works + Given I have an orphan account + And the work "Bye" by "Leaver" + And "Leaver" orphans and keeps their pseud on the work "Bye" + When I am logged in as a "" admin + And I view the work "Bye" + Then I should see "Remove Pseud" + When I follow "Remove Pseud" + Then I should see "Are you sure you want to remove the creator's pseud from this work?" + # Expire byline cache + When it is currently 1 second from now + And I press "Yes, Remove Pseud" + Then I should see "Successfully removed pseud Leaver (orphan_account) from this work." + And I should see "orphan_account" within ".byline" + But I should not see "Leaver" within ".byline" + + Examples: + | role | + | superadmin | + | policy_and_abuse | + | support | + + @javascript + Scenario Outline: Removing orphan_account pseuds from works with JavaScript shows a confirmation pop-up instead of a page + Given I have an orphan account + And the work "Bye" by "Leaver" + And "Leaver" orphans and keeps their pseud on the work "Bye" + When I am logged in as a "" admin + And I view the work "Bye" + Then I should see "Remove Pseud" + # Expire byline cache + When it is currently 1 second from now + And I follow "Remove Pseud" + And I confirm I want to remove the pseud + Then I should see "Successfully removed pseud Leaver (orphan_account) from this work." + And I should see "orphan_account" within ".byline" + But I should not see "Leaver" within ".byline" + + Examples: + | role | + | superadmin | + | policy_and_abuse | + | support | + + Scenario: When removing orphan_account pseuds from a work with multiple pseuds admins choose which pseud to remove + Given I have an orphan account + And I am logged in as "Leaver" + And I post the work "Bye" + And I add the co-author "Another" to the work "Bye" + And it is currently 1 second from now + And I add the co-author "Third" to the work "Bye" + And "Leaver" orphans and keeps their pseud on the work "Bye" + And "Another" orphans and keeps their pseud on the work "Bye" + And "Third" orphans and keeps their pseud on the work "Bye" + When I am logged in as a "policy_and_abuse" admin + And I view the work "Bye" + Then I should see "Remove Pseud" + When I follow "Remove Pseud" + Then I should see "Please choose which creators' pseuds you would like to remove from this work." + And I should see "Third (orphan_account)" + When I check "Leaver (orphan_account)" + And I check "Another (orphan_account)" + # Expire byline cache + And it is currently 1 second from now + And I press "Remove Pseud" + Then I should see "Successfully removed pseuds Leaver (orphan_account) and Another (orphan_account) from this work." + And I should see "orphan_account, " within ".byline" + And I should see "Third (orphan_account)" within ".byline" + But I should not see "Leaver" within ".byline" + And I should not see "Another" within ".byline" + When I go to the admin-activities page + Then I should see 1 admin activity log entry + And I should see "remove orphan_account pseuds" + + Scenario: The Remove pseud option is only shown on orphaned works with non-default pseuds + Given I have an orphan account + And the work "Bye" by "Leaver" + And "Leaver" orphans and takes their pseud off the work "Bye" + And the work "Hey" by "Leaver" + When I am logged in as a "superadmin" admin + And I view the work "Hey" + Then I should not see "Remove Pseud" + When I view the work "Bye" + Then I should not see "Remove Pseud" + + Scenario Outline: The Remove pseud option is not shown to admins who don't have permissions to remove pseuds + Given I have an orphan account + And the work "Bye" by "Leaver" + And "Leaver" orphans and keeps their pseud on the work "Bye" + When I am logged in as a "" admin + And I view the work "Bye" + Then I should not see "Remove Pseud" + + Examples: + | role | + | board | + | board_assistants_team | + | communications | + | development_and_membership | + | docs | + | elections | + | legal | + | translation | + | tag_wrangling | + | open_doors | diff --git a/features/admins/authenticate_admins.feature b/features/admins/authenticate_admins.feature new file mode 100755 index 0000000..8877c70 --- /dev/null +++ b/features/admins/authenticate_admins.feature @@ -0,0 +1,163 @@ +@admin +Feature: Authenticate Admin Users + + Scenario: Admin cannot log in as an ordinary user. + Given the following admin exists + | login | password | + | Zooey | adminpassword | + When I go to the home page + And I fill in "Username or email" with "Zooey" + And I fill in "Password" with "adminpassword" + And I press "Log In" + Then I should see "The password or username you entered doesn't match our records" + + Scenario: Ordinary user cannot log in or reset password as admin. + Given the following activated user exists + | login | password | + | dizmo | wrangulator | + When I go to the admin login page + And I fill in "Admin username" with "dizmo" + And I fill in "Admin password" with "wrangulator" + And I press "Log In as Admin" + Then I should not see "Successfully logged in" + And I should see "The password or admin username you entered doesn't match our records." + When I am logged in as "dizmo" with password "wrangulator" + And I go to the new admin password page + Then I should be on the homepage + And I should see "Please log out of your user account first!" + When I go to the edit admin password page + Then I should be on the homepage + And I should see "Please log out of your user account first!" + + Scenario: Admin gets email with password reset link on account creation. + Given the following admin exists + | login | email | + | admin | admin@example.com | + Then 1 email should be delivered to admin@example.com + When I follow "follow this link to set your password" in the email + Then I should see "Set My Admin Password" + When I fill in "New password" with "newpassword" + And I fill in "Confirm new password" with "newpassword" + And I press "Set Admin Password" + Then I should see "Your password has been changed successfully. You are now signed in." + And I should see "Hi, admin!" + + Scenario: Set password link expires. + Given the following admin exists + | login | password | email | + | admin | testpassword | admin@example.com | + Then 1 email should be delivered to "admin@example.com" + When it is past the admin password reset token's expiration date + And I follow "follow this link to set your password" in the email + Then I should see "Set My Admin Password" + When I fill in "New password" with "newpassword" + And I fill in "Confirm new password" with "newpassword" + And I press "Set Admin Password" + Then I should see "Reset password token has expired, please request a new one" + + Scenario: Admin can log in. + Given I have no users + And the following admin exists + | login | password | + | Zooey | adminpassword | + When I go to the admin login page + And I fill in "Admin username" with "Zooey" + And I fill in "Admin password" with "adminpassword" + And I press "Log In as Admin" + Then I should see "Successfully logged in" + + Scenario: Admin username is case insensitive. + Given the following admin exists + | login | password | + | TheMadAdmin | adminpassword | + When I go to the admin login page + And I fill in "Admin username" with "themadadmin" + And I fill in "Admin password" with "adminpassword" + And I press "Log In as Admin" + Then I should see "Successfully logged in" + + Scenario: Admin cannot log in with wrong password. + Given the following admin exists + | login | password | + | Zooey | adminpassword | + When I go to the admin login page + And I fill in "Admin username" with "Zooey" + And I fill in "Admin password" with "wrongpassword" + And I press "Log In" + Then I should see "The password or username you entered doesn't match our records." + + Scenario: Admin resets password. + Given the following admin exists + | login | password | email | + | admin | testpassword | admin@example.com | + And all emails have been delivered + And it is currently 2025-04-12 17:00 UTC + When I go to the admin login page + And I follow "Forgot admin password?" + Then I should see "Forgotten your admin password?" + When I fill in "Admin username" with "admin" + And I press "Reset Admin Password" + Then I should see "Check your email for instructions on how to reset your password." + And 1 email should be delivered to "admin@example.com" + When I follow "Change my password" in the email + And all emails have been delivered + Then I should see "Set My Admin Password" + When I fill in "New password" with "newpassword" + And I fill in "Confirm new password" with "newpassword" + And I press "Set Admin Password" + Then I should see "Your password has been changed successfully. You are now signed in." + And I should see "Hi, admin!" + And 1 emails should be delivered to "admin@example.com" + And the email should have "Your admin password has been changed" in the subject + And the email should contain "The password for your AO3 admin account was changed on Sat, 12 Apr 2025 17:00:\d+ \+0000" + + Scenario: Reset password link expires. + Given the following admin exists + | login | password | email | + | admin | testpassword | admin@example.com | + And all emails have been delivered + When I go to the admin login page + And I follow "Forgot admin password?" + Then I should see "Forgotten your admin password?" + When I fill in "Admin username" with "admin" + And I press "Reset Admin Password" + Then I should see "Check your email for instructions on how to reset your password." + And 1 email should be delivered to "admin@example.com" + When it is past the admin password reset token's expiration date + And I follow "Change my password" in the email + Then I should see "Set My Admin Password" + When I fill in "New password" with "newpassword" + And I fill in "Confirm new password" with "newpassword" + And I press "Set Admin Password" + Then I should see "Reset password token has expired, please request a new one" + + Scenario: Locked admin cannot sign in. + Given the admin "admin" is locked + When I go to the admin login page + And I fill in "Admin username" with "admin" + And I fill in "Admin password" with "adminpassword" + And I press "Log In as Admin" + Then I should see "Your account is locked." + And I should not see "Hi, admin!" + + Scenario: Locked admin is not automatically logged in after password change. + Given the admin "admin" is locked + And all emails have been delivered + And I am on the admin login page + When I follow "Forgot admin password?" + And I fill in "Admin username" with "admin" + And I press "Reset Admin Password" + Then I should see "Check your email for instructions on how to reset your password." + And 1 email should be delivered + When I follow "Change my password" in the email + Then I should see "Set My Admin Password" + When I fill in "New password" with "newpassword" + And I fill in "Confirm new password" with "newpassword" + And I press "Set Admin Password" + Then I should see "Your password has been changed successfully. Your account is locked." + When the admin "admin" is unlocked + And I fill in "Admin username" with "admin" + And I fill in "Admin password" with "newpassword" + And I press "Log In as Admin" + Then I should see "Successfully logged in." + And I should see "Hi, admin!" diff --git a/features/admins/users/admin_abuse_users.feature b/features/admins/users/admin_abuse_users.feature new file mode 100755 index 0000000..a0a8547 --- /dev/null +++ b/features/admins/users/admin_abuse_users.feature @@ -0,0 +1,242 @@ +@admin +Feature: Admin Abuse actions + In order to manage user accounts + As an admin + I want to be able to manage abusive users + + Background: + Given the user "mrparis" exists and is activated + And I have an orphan account + And I am logged in as a "policy_and_abuse" admin + When I go to the user administration page for "mrparis" + + Scenario: An admin adds a note to a user + Given I choose "Record note" + And I fill in "Notes" with "This user is suspicious." + When I press "Update" + Then I should see "Note was recorded." + And I should see "Note Added" + And I should see "This user is suspicious." + + Scenario: A user is given a warning with a note + Given I choose "Record warning" + And I fill in "Notes" with "Next time, the brig." + When I press "Update" + Then I should see "Warning was recorded." + And I should see "Warned" + And I should see "Next time, the brig." + + Scenario: A user cannot be given a warning without a note + Given I choose "Record warning" + When I press "Update" + Then I should see "You must include notes in order to perform this action." + + Scenario: orphan_account cannot get a note + When I go to the user administration page for "orphan_account" + And I choose "Record note" + And I fill in "Notes" with "This user is suspicious." + When I press "Update" + Then I should see "orphan_account cannot be warned, suspended, or banned." + + Scenario: orphan_account cannot be warned + When I go to the user administration page for "orphan_account" + And I choose "Record warning" + And I fill in "Notes" with "Next time, the brig." + When I press "Update" + Then I should see "orphan_account cannot be warned, suspended, or banned." + + Scenario: orphan_account cannot be suspended + When I go to the user administration page for "orphan_account" + And I choose "Suspend: enter a whole number of days" + And I fill in "suspend_days" with "30" + And I fill in "Notes" with "Disobeyed orders." + When I press "Update" + Then I should see "orphan_account cannot be warned, suspended, or banned." + + Scenario: orphan_account cannot be banned + When I go to the user administration page for "orphan_account" + And I choose "Suspend permanently (ban user)" + And I fill in "Notes" with "To the New Zealand penal colony with you." + When I press "Update" + Then I should see "orphan_account cannot be warned, suspended, or banned." + + Scenario: orphan_account cannot be spambanned + When I go to the user administration page for "orphan_account" + And I choose "Spammer: ban and delete all creations" + When I press "Update" + Then I should see "orphan_account cannot be warned, suspended, or banned." + + Scenario: A user is given a suspension with a note and number of days + Given I choose "Suspend: enter a whole number of days" + And I fill in "suspend_days" with "30" + And I fill in "Notes" with "Disobeyed orders." + When I press "Update" + Then I should see "User has been temporarily suspended." + And I should see "Suspended until" + And I should see "Disobeyed orders." + + Scenario: A user cannot be given a suspension without a number of days + Given I choose "Suspend: enter a whole number of days" + And I fill in "Notes" with "Disobeyed orders." + When I press "Update" + Then I should see "Please enter the number of days for which the user should be suspended." + + Scenario: A user cannot be given a suspension with a date but without a note + Given I choose "Suspend: enter a whole number of days" + And I fill in "suspend_days" with "30" + When I press "Update" + Then I should see "You must include notes in order to perform this action." + + Scenario: A user is banned with a note + Given I choose "Suspend permanently (ban user)" + And I fill in "Notes" with "To the New Zealand penal colony with you." + When I press "Update" + Then I should see "User has been permanently suspended." + And I should see "Suspended Permanently" + And I should see "To the New Zealand penal colony with you." + When all indexing jobs have been run + And I follow "Manage Users" + And I fill in "Name" with "mrparis" + And I press "Find" + Then I should see "1 user found" + When I follow "Details" + Then I should see "To the New Zealand penal colony with you." + + Scenario: A user cannot be banned without a note + Given the user "mrparis" exists and is activated + And I am logged in as a "policy_and_abuse" admin + When I go to the user administration page for "mrparis" + And I choose "Suspend permanently (ban user)" + When I press "Update" + Then I should see "You must include notes in order to perform this action." + + Scenario: A user's suspension is lifted with a note + Given the user "mrparis" is suspended + And I am logged in as a "policy_and_abuse" admin + When I go to the user administration page for "mrparis" + And I choose "Lift temporary suspension, effective immediately." + And I fill in "Notes" with "Good behavior." + When I press "Update" + Then I should see "Suspension has been lifted." + And I should see "Suspension Lifted" + And I should see "Good behavior." + + Scenario: A user's suspension cannot be lifted without a note + Given the user "mrparis" is suspended + And I am logged in as a "policy_and_abuse" admin + When I go to the user administration page for "mrparis" + And I choose "Lift temporary suspension, effective immediately." + When I press "Update" + Then I should see "You must include notes in order to perform this action." + + Scenario: A user's ban is lifted with a note + Given the user "mrparis" is banned + And I am logged in as a "policy_and_abuse" admin + When I go to the user administration page for "mrparis" + And I choose "Lift permanent suspension, effective immediately." + And I fill in "Notes" with "Need him to infiltrate the Maquis." + When I press "Update" + Then I should see "Suspension has been lifted." + And I should see "Suspension Lifted" + And I should see "Need him to infiltrate the Maquis." + + Scenario: A user's ban cannot be lifted without a note + Given the user "mrparis" is banned + And I am logged in as a "policy_and_abuse" admin + When I go to the user administration page for "mrparis" + And I choose "Lift permanent suspension, effective immediately." + When I press "Update" + Then I should see "You must include notes in order to perform this action." + + Scenario: A spammer can be permabanned and all their creations destroyed + Given I have a work "Not Spam" + And I am logged in as "Spamster" + And I post the work "Loads of Spam" + And I post the work "Even More Spam" + And I post the work "Spam 3: Tokyo Drift" + And I create the collection "Spam Collection" + And I bookmark the work "Not Spam" + And I add the work "Loads of Spam" to series "One Spam After Another" + And I post the comment "I like spam" on the work "Not Spam" + And I am logged in as a "policy_and_abuse" admin + When I go to the user administration page for "Spamster" + And I choose "Spammer: ban and delete all creations" + And I press "Update" + Then I should see "permanently suspended" + And the user "Spamster" should be permanently banned + And the page should have a dashboard sidebar + And I should see "Are you sure you want to delete" + And I should see "1 bookmarks" + And I should see "1 collections" + And I should see "1 series" + And I should see "Loads of Spam" + And I should see "Even More Spam" + And I should see "Spam 3: Tokyo Drift" + And I should see "I like spam" + When I press "Yes, Delete All Spammer Creations" + Then I should see "All creations by user Spamster have been deleted." + And the work "Loads of Spam" should be deleted + And the work "Even More Spam" should be deleted + And the work "Spam 3: Tokyo Drift" should be deleted + And "Spamster" should receive 3 emails + And the collection "Spam Collection" should be deleted + And the series "One Spam After Another" should be deleted + And the work "Not Spam" should not be deleted + And there should be no bookmarks on the work "Not Spam" + And there should be no comments on the work "Not Spam" + + Scenario: A permabanned spammer's comments' replies from others should stay visible + Given I have a work "Generic Work" + And a comment "I like spam" by "Spamster" on the work "Generic Work" + And a reply "I don't :(" by "NotSpamster" on the work "Generic Work" + And a comment "A thread of spams" by "Spamster" on the work "Generic Work" + And a reply "more spam" by "Spamster" on the work "Generic Work" + When I am logged in as a "policy_and_abuse" admin + And I go to the user administration page for "Spamster" + And I choose "Spammer: ban and delete all creations" + And I press "Update" + Then I should see "permanently suspended" + And the user "Spamster" should be permanently banned + And I should see "I like spam" + When I press "Yes, Delete All Spammer Creations" + Then I should see "All creations by user Spamster have been deleted." + When I go to the work comments page for "Generic Work" + Then I should not see "I like spam" + And I should see "(Previous comment deleted.)" + And I should see "I don't :(" + And I should not see "A thread of spams" + And I should not see "more spam" + + Scenario: A user's works cannot be destroyed unless they are banned + Given I am logged in as "Spamster" + And I post the work "Loads of Spam" + And I am logged in as a "policy_and_abuse" admin + And I go to the user administration page for "Spamster" + And I choose "Spammer: ban and delete all creations" + And I press "Update" + And the user "Spamster" is unbanned in the background + And I press "Yes, Delete All Spammer Creations" + Then I should see "That user is not banned" + And the work "Loads of Spam" should not be deleted + + Scenario: An already-banned user can have their works destroyed + Given the user "Spamster" is banned + And I am logged in as a "policy_and_abuse" admin + When I go to the user administration page for "Spamster" + And I choose "Spammer: ban and delete all creations" + And I press "Update" + Then I should see "Are you sure you want to delete" + When I press "Yes, Delete All Spammer Creations" + Then I should see "All creations by user Spamster have been deleted." + + Scenario: Rename a user with an inappropriate username + Given the user "otheruserstinks" exists and is activated + And I am logged in as a "policy_and_abuse" admin + And an abuse ticket ID exists + And all emails have been delivered + When I visit the change username page for otheruserstinks + And I fill in "Ticket ID" with "480000" + And I press "Change Username" + Then I should see "Username has been successfully updated." + But I should not see "otheruserstinks" within "h2.heading" + And 0 emails should be delivered diff --git a/features/admins/users/admin_find_users.feature b/features/admins/users/admin_find_users.feature new file mode 100755 index 0000000..ef28502 --- /dev/null +++ b/features/admins/users/admin_find_users.feature @@ -0,0 +1,160 @@ +Feature: Admin Find Users page + + Background: + Given the following activated users exist + | login | email | + | userA | a@ao3.org | + | userB | b@bo3.org | + | userCB | cb@bo3.org | + And the user "userB" exists and has the role "archivist" + And I am logged in as a super admin + And all emails have been delivered + And I go to the manage users page + + Scenario: The Find Users page shows no results before searching and all results with blank search + Then I should not see "userA" + And I should not see "userB" + And I should not see "userCB" + And I should not see "found" + When I submit + Then I should see "userA" + And I should see "userB" + And I should see "userCB" + + Scenario: The Find Users page performs a partial match on name with * wildcard + When I fill in "Name" with "u*er*" + And I submit + Then I should see "userA" + And I should see "userB" + And I should see "userCB" + + Scenario: The Find Users page performs an exact match on name by default + When I fill in "Name" with "user" + And I submit + Then I should see "0 users found" + When I fill in "Name" with "userA" + And I submit + Then the field labeled "user_email" should contain "a@ao3.org" + But I should not see "UserB" + + Scenario: The Find Users page searches past logins only if the option is selected + When I am logged in as "userA" + And I visit the change username page for userA + And I fill in "New username" with "userD" + And I fill in "Password" with "password" + And I press "Change" + Then I should get confirmation that I changed my username + When I am logged in as a "support" admin + And I go to the manage users page + And I fill in "Name" with "userA" + And I submit + Then I should see "0 users found" + When I check "Include past usernames and emails" + And I submit + Then I should see "1 user found" + And I should see "userD" + # Only selected admins can search past logins + When I am logged in as a "translation" admin + And I go to the manage users page + Then I should not see "Include past usernames and emails" + + Scenario: The Find Users page performs a partial match by email with * wildcard + When I fill in "Email" with "*bo3*" + And I submit + Then I should see "userB" + And I should see "userCB" + But I should not see "userA" + + Scenario: The Find Users page performs an exact match on email by default + When I fill in "Email" with "ao3" + And I submit + Then I should see "0 users found" + When I fill in "Email" with "a@ao3.org" + And I submit + Then I should see "userA" + But I should not see "UserB" + + Scenario: The Find Users page searches past emails if the option is selected + When I am logged in as "userA" + And I change my email to "d@ao3.org" + And I am logged in as a "policy_and_abuse" admin + And I go to the manage users page + And I fill in "Email" with "a@ao3.org" + And I submit + Then I should see "0 users found" + When I check "Include past usernames and emails" + And I submit + Then I should see "1 user found" + And I should see "userA" + And the field labeled "user_email" should contain "d@ao3.org" + + Scenario: The Find Users page performs an exact match by role + When I select "Archivist" from "Role" + And I submit + Then I should see "userB" + But I should not see "userA" + And I should not see "userCB" + + Scenario: The Find Users page performs an exact match by ID in addition to any other criteria + When the search criteria contains the ID for "userB" + And I submit + Then I should see "1 user found" + And I should see "userB" + But I should not see "userA" + And I should not see "userCB" + When I fill in "Name" with "*A" + And I submit + Then I should see "0 users found" + When I fill in "Name" with "*B" + And I submit + Then I should see "1 user found" + And I should see "userB" + + # Bulk email search + Scenario: The Bulk Email Search page finds all existing matching users + When I go to the Bulk Email Search page + And I fill in "Email addresses *" with + """ + b@bo3.org + a@ao3.org + """ + And I press "Find" + Then I should see "userB" + And I should see "userA" + But I should not see "userCB" + And I should not see "Not found" + + Scenario: The Bulk Email Search page lists emails found, not found and duplicates + When I go to the Bulk Email Search page + And I fill in "Email addresses *" with + """ + b@bo3.org + a@ao3.org + c@co3.org + C@CO3.org + """ + And I press "Find" + Then I should see "2 found" + And I should see "1 not found" + And I should see "1 duplicate" + And I should see "Not found" + + Scenario: The Bulk Email Search page finds an exact match + When I go to the Bulk Email Search page + And I fill in "Email addresses *" with "b@bo3.org" + And I press "Find" + Then I should see "userB" + But I should not see "userA" + And I should not see "userCB" + And I should not see "Not found" + + Scenario: Admins can download a CSV of found emails + When I go to the Bulk Email Search page + And I fill in "Email addresses *" with + """ + b@bo3.org + a@ao3.org + c@co3.org + """ + And I press "Download CSV" + Then I should download a csv file with 4 rows and the header row "Email Username" diff --git a/features/admins/users/admin_fnok.feature b/features/admins/users/admin_fnok.feature new file mode 100755 index 0000000..2181816 --- /dev/null +++ b/features/admins/users/admin_fnok.feature @@ -0,0 +1,124 @@ +@admin +Feature: Admin Fannish Next Of Kind actions + In order to manage user accounts + As an an admin + I want to be able to manage fannish next of kin for users + + Scenario: A valid Fannish Next of Kin is added for a user + Given the following activated users exist + | login | password | + | harrykim | diesalot | + | libby | stillalive | + And I am logged in as a "support" admin + When I go to the user administration page for "harrykim" + And I fill in "Fannish next of kin's username" with "libby" + And I fill in "Fannish next of kin's email" with "testy@foo.com" + And I press "Update Fannish Next of Kin" + Then I should see "Fannish next of kin was updated." + And the history table should show that "libby" was added as next of kin + + When I go to the manage users page + And I fill in "Name" with "harrykim" + And I press "Find" + Then I should see "libby" + + When I follow "libby" + Then I should be on libby's user page + + When I go to the user administration page for "libby" + Then the history table should show they were added as next of kin of "harrykim" + + Scenario: An invalid Fannish Next of Kin username is added + Given the fannish next of kin "libby" for the user "harrykim" + And I am logged in as a "support" admin + When I go to the user administration page for "harrykim" + And I fill in "Fannish next of kin's username" with "userididnotcreate" + And I press "Update Fannish Next of Kin" + Then I should see "Kin can't be blank" + + Scenario: A blank Fannish Next of Kin username can't be added + Given the fannish next of kin "libby" for the user "harrykim" + And I am logged in as a "support" admin + When I go to the user administration page for "harrykim" + And I fill in "Fannish next of kin's username" with "" + And I press "Update Fannish Next of Kin" + Then I should see "Kin can't be blank" + + Scenario: A blank Fannish Next of Kin email can't be added + Given the fannish next of kin "libby" for the user "harrykim" + And I am logged in as a "support" admin + When I go to the user administration page for "harrykim" + And I fill in "Fannish next of kin's email" with "" + And I press "Update Fannish Next of Kin" + Then I should see "Kin email can't be blank" + + Scenario: A Fannish Next of Kin is edited + Given the fannish next of kin "libby" for the user "harrykim" + And the user "newlibby" exists and is activated + And I am logged in as a "support" admin + When I go to the user administration page for "harrykim" + And I fill in "Fannish next of kin's username" with "newlibby" + And I fill in "Fannish next of kin's email" with "newlibby@foo.com" + And I press "Update Fannish Next of Kin" + Then I should see "Fannish next of kin was updated." + + Scenario: A Fannish Next of Kin is removed + Given the fannish next of kin "libby" for the user "harrykim" + And I am logged in as a "support" admin + When I go to the user administration page for "harrykim" + And I fill in "Fannish next of kin's username" with "" + And I fill in "Fannish next of kin's email" with "" + And I press "Update Fannish Next of Kin" + Then I should see "Fannish next of kin was removed." + And the history table should show that "libby" was removed as next of kin + When I go to the user administration page for "libby" + Then the history table should show they were removed as next of kin of "harrykim" + + Scenario: A Fannish Next of Kin updates when the next of kin user changes their username + Given the fannish next of kin "libby" for the user "harrykim" + And I am logged in as "libby" + When I visit the change username page for libby + And I fill in "New username" with "newlibby" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should get confirmation that I changed my username + When I am logged in as a "support" admin + And I go to the manage users page + And I fill in "Name" with "harrykim" + And I press "Find" + Then I should see "newlibby" + + Scenario: A Fannish Next of Kin stays with the user when the user changes their username + Given the fannish next of kin "libby" for the user "harrykim" + And I am logged in as "harrykim" + When I visit the change username page for harrykim + And I fill in "New username" with "harrykim2" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should get confirmation that I changed my username + When I am logged in as a "support" admin + And I go to the manage users page + And I fill in "Name" with "harrykim2" + And I press "Find" + Then I should see "libby" + + Scenario: A Fannish Next of Kin can update even after an invalid user is entered + Given the fannish next of kin "libby" for the user "harrykim" + And the user "harrysmom" exists and is activated + And I am logged in as a "support" admin + When I go to the user administration page for "harrykim" + And I fill in "Fannish next of kin's username" with "libbylibby" + And I fill in "Fannish next of kin's email" with "libbylibby@example.com" + And I press "Update Fannish Next of Kin" + Then I should see "Kin can't be blank" + And the "Fannish next of kin's username" input should be blank + And I should see "libbylibby@example.com" in the "Fannish next of kin's email" input + When I go to the user administration page for "harrykim" + And I should see "libby" in the "Fannish next of kin's username" input + And I should see "fnok@example.com" in the "Fannish next of kin's email" input + When I fill in "Fannish next of kin's username" with "harrysmom" + And I fill in "Fannish next of kin's email" with "harrysmom@example.com" + And I press "Update Fannish Next of Kin" + Then I should see "Fannish next of kin was updated." + And the "Fannish next of kin's username" field should contain "harrysmom" + And the "Fannish next of kin's email" field should contain "harrysmom@example.com" diff --git a/features/admins/users/admin_manage_users.feature b/features/admins/users/admin_manage_users.feature new file mode 100755 index 0000000..f6070f1 --- /dev/null +++ b/features/admins/users/admin_manage_users.feature @@ -0,0 +1,130 @@ +@admin +Feature: Admin Actions to manage users + In order to manage user accounts + As an an admin + I want to be able to edit individual users + + Scenario: Admin can update a user's email address and roles + Given the following activated user exists + | login | password | + | dizmo | wrangulator | + And the role "tag_wrangler" + When I am logged in as a super admin + And I go to the manage users page + And I fill in "Name" with "dizmo" + And I press "Find" + Then I should see "dizmo" within "#admin_users_table" + + # change user email + When I fill in "user_email" with "not even an email" + And I press "Update" + Then I should see "The user dizmo could not be updated: Email is invalid" + + When I fill in "user_email" with "dizmo@fake.com" + And I press "Update" + Then the "user_email" field should contain "dizmo@fake.com" + And I should see "User was successfully updated." + + # Adding and removing roles + When I check the "tag_wrangler" role checkbox + And I press "Update" + # Then show me the html + Then I should see "User was successfully updated" + And the "tag_wrangler" role checkbox should be checked + When I follow "Details" + Then I should see "Role: Tag Wrangler" within ".meta" + And I should see "Role Added: tag_wrangler" within "#user_history" + And I should see "Change made by testadmin-superadmin" + When I follow "Manage Roles" + And I uncheck the "tag_wrangler" role checkbox + And I press "Update" + Then I should see "User was successfully updated" + And the "tag_wrangler" role checkbox should not be checked + When I follow "Details" + Then I should see "Roles: No roles" within ".meta" + And I should see "Role Removed: tag_wrangler" within "#user_history" + + Scenario: Troubleshooting a user displays a message + Given the user "mrparis" exists and is activated + And I am logged in as a "support" admin + When I go to the user administration page for "mrparis" + And I follow "Troubleshoot" + Then I should see "User account troubleshooting complete." + + Scenario: A admin can activate a user account + Given the user "mrparis" exists and is not activated + And I am logged in as a "support" admin + When I go to the user administration page for "mrparis" + And I press "Activate" + Then I should see "User Account Activated" + And the user "mrparis" should be activated + + Scenario: An admin can view a user's last login date + Given the user "new_user" exists and is activated + And I am logged in as a "support" admin + When I go to the user administration page for "new_user" + Then I should see "Current Login No login recorded" + And I should see "Previous Login No previous login recorded" + When time is frozen at 1/1/2019 + And I am logged in as "new_user" + And I am logged out + And I jump in our Delorean and return to the present + And I am logged in as a "support" admin + And I go to the user administration page for "new_user" + Then I should not see "No login recorded" + And I should see "2019-01-01 12:00:00 UTC Current Login IP Address: 127.0.0.1" + And I should see "2019-01-01 12:00:00 UTC Previous Login IP Address: 127.0.0.1" + + Scenario: An admin can view a user's email address and invitation + Given the user "user" with the email "user@example.com" exists + And the user "user2" was created using an invitation + When I am logged in as a "superadmin" admin + And I go to the user administration page for "user" + Then I should see "Email: user@example.com" + And I should see "Invitation: Created without invitation" + When I go to the user administration page for "user2" + Then I should see the invitation id for the user "user2" + + Scenario: Admins can view past emails and usernames + Given the following activated user exists + | login | email | + | cats | d@fake.com | + And I am logged in as "cats" + And I want to edit my profile + And I change my email to "new@example.com" + And all emails have been delivered + And I change my username to "new_user" + When I am logged in as a super admin + And I go to the user administration page for "new_user" + Then I should see "Past email: d@fake.com" within ".meta" + And I should see "Past username: cats" within ".meta" + When I am logged in as a "translation" admin + And I go to the user administration page for "new_user" + Then I should not see "Past email: d@fake.com" + And I should not see "Past username: cats" + + Scenario: An admin can access a user's creations from their administration page + Given there is 1 user creation per page + And the user "lurker" exists and is activated + And I am logged in as "troll" + And I post the work "Creepy Gift" + And I post the work "NFW" + And I post the comment "Neener" on the work "Creepy Gift" + When I am logged in as a "support" admin + And I go to the user administration page for "lurker" + Then the page should have a dashboard sidebar + And I should not see "Creations" + When I am logged in as a "policy_and_abuse" admin + And I go to the user administration page for "lurker" + And I follow "Creations" + Then I should see "Works and Comments by lurker" + And I should see "This user has no works or comments." + And the page should have a dashboard sidebar + When I go to the user administration page for "troll" + And I follow "Creations" + Then I should see "Works and Comments by troll" + And I should see "1 - 1 of 2 Works" within "#works-summary" + And I should see "Creepy Gift" within "#works-summary" + And I should see "1 Comment" within "#comments-summary" + And I should see "Comment on the work Creepy Gift" within "#comments-summary" + And I should see "

    Neener

    " within "#comments-summary" diff --git a/features/bookmarks/bookmark_browse.feature b/features/bookmarks/bookmark_browse.feature new file mode 100755 index 0000000..01853ef --- /dev/null +++ b/features/bookmarks/bookmark_browse.feature @@ -0,0 +1,25 @@ +@bookmarks @search +Feature: Browse Bookmarks + + Scenario: Bookmarks appear on both the user's bookmark page and on the bookmark page for the pseud they used create the bookmark + + Given I am logged in as "ethel" + And "ethel" creates the pseud "aka" + And I bookmark the work "Bookmarked with Default Pseud" + And I bookmark the work "Bookmarked with Other Pseud" as "aka" + When I go to ethel's bookmarks page + Then I should see "Bookmarked with Default Pseud" + And I should see "Bookmarked with Other Pseud" + When I go to the bookmarks page for user "ethel" with pseud "ethel" + Then I should see "Bookmarked with Default Pseud" + And I should not see "Bookmarked with Other Pseud" + When I go to the bookmarks page for user "ethel" with pseud "aka" + Then I should see "Bookmarked with Other Pseud" + And I should not see "Bookmarked with Default Pseud" + + Scenario: Bookmark blurb includes an HTML comment containing the unix epoch of the updated time + Given time is frozen at 2025-04-12 17:00 UTC + And I am logged in as "ethel" + And I bookmark the work "Test" + When I go to ethel's bookmarks page + Then I should see an HTML comment containing the number 1744477200 within "li.bookmark.blurb" diff --git a/features/bookmarks/bookmark_create.feature b/features/bookmarks/bookmark_create.feature new file mode 100755 index 0000000..a5c3e97 --- /dev/null +++ b/features/bookmarks/bookmark_create.feature @@ -0,0 +1,460 @@ +@bookmarks +Feature: Create bookmarks + In order to have an archive full of bookmarks + As a humble user + I want to bookmark some works + +Scenario: Create a bookmark + Given I am logged in as "first_bookmark_user" + When I am on first_bookmark_user's user page + Then I should see "have anything posted under this name yet" + When I am logged in as "another_bookmark_user" + And I post the work "Revenge of the Sith" + When I go to the bookmarks page + Then I should not see "Revenge of the Sith" + When I am logged in as "first_bookmark_user" + And I go to the works page + And I follow "Revenge of the Sith" + Then I should see "Bookmark" + When I follow "Bookmark" + And I fill in "bookmark_notes" with "I liked this story" + And I fill in "bookmark_tag_string" with "This is a tag, and another tag," + And I check "bookmark_rec" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + And I should see "My Bookmarks" + When I am logged in as "another_bookmark_user" + And I go to the bookmarks page + Then I should see "Revenge of the Sith" + And I should see "This is a tag" + And I should see "and another tag" + And I should see "I liked this story" + When I am logged in as "first_bookmark_user" + And I go to first_bookmark_user's user page + Then I should not see "You don't have anything posted under this name yet" + And I should see "Revenge of the Sith" + When I edit the bookmark for "Revenge of the Sith" + And I check "bookmark_private" + And I press "Update" + And all indexing jobs have been run + Then I should see "Bookmark was successfully updated" + When I go to the bookmarks page + Then I should not see "I liked this story" + When I go to first_bookmark_user's bookmarks page + Then I should see "I liked this story" + + # privacy check for the private bookmark ' + When I am logged in as "another_bookmark_user" + And I go to the bookmarks page + Then I should not see "I liked this story" + When I go to first_bookmark_user's user page + Then I should not see "I liked this story" + + Scenario: Create bookmarks and recs on restricted works, check how they behave from various access points + Given the following activated users exist + | login | + | first_bookmark_user | + | another_bookmark_user | + And a fandom exists with name: "Stargate SG-1", canonical: true + And I am logged in as "first_bookmark_user" + And I post the locked work "Secret Masterpiece" + And I post the locked work "Mystery" + And I post the work "Public Masterpiece" + And I post the work "Publicky" + When I am logged in as "another_bookmark_user" + And I view the work "Secret Masterpiece" + And I follow "Bookmark" + And I check "bookmark_rec" + And I press "Create" + Then I should see "Bookmark was successfully created" + And I should see the image "title" text "Restricted" + And I should see "Rec" within ".rec" + When I view the work "Public Masterpiece" + And I follow "Bookmark" + And I check "bookmark_rec" + And I press "Create" + Then I should see "Bookmark was successfully created" + And I should not see the image "title" text "Restricted" + When I view the work "Mystery" + And I follow "Bookmark" + And I press "Create" + Then I should see "Bookmark was successfully created" + And I should not see "Rec" + When I view the work "Publicky" + And I follow "Bookmark" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + When I log out + And I go to the bookmarks page + Then I should not see "Secret Masterpiece" + And I should not see "Mystery" + But I should see "Public Masterpiece" + And I should see "Publicky" + When I go to another_bookmark_user's bookmarks page + Then I should not see "Secret Masterpiece" + When I am logged in as "first_bookmark_user" + And I go to another_bookmark_user's bookmarks page + Then I should see "Bookmarks (4)" + And I should see "Secret Masterpiece" + +Scenario: extra commas in bookmark form (Issue 2284) + + Given I am logged in as "bookmarkuser" + And I post the work "Some Work" + When I follow "Bookmark" + And I fill in "Your tags" with "Good tag, ,, also good tag, " + And I press "Create" + Then I should see "created" + +Scenario: Bookmark notes do not display images + Given I am logged in as "bookmarkuser" + And I post the work "Some Work" + When I follow "Bookmark" + And I fill in "Notes" with "Fantastic!" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + When I go to the bookmarks page + Then I should not see the image "src" text "http://example.com/icon.svg" + And I should see "Fantastic!" + +Scenario: bookmark added to moderated collection has flash notice only when not approved + Given the following activated users exist + | login | password | + | workauthor | password | + | bookmarker | password | + | otheruser | password | + And I have a moderated collection "Five Pillars" with name "five_pillars" + And I am logged in as "workauthor" with password "password" + And I post the work "Fire Burn, Cauldron Bubble" + When I log out + And I am logged in as "bookmarker" with password "password" + And I view the work "Fire Burn, Cauldron Bubble" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "five_pillars" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + And I should see "The collection Five Pillars is currently moderated." + When I go to bookmarker's bookmarks page + Then I should see "The collection Five Pillars is currently moderated." + When I log out + And I am logged in as "moderator" with password "password" + # Delay before approving to make sure the cache is expired + And it is currently 1 second from now + And I approve the first item in the collection "Five Pillars" + And all indexing jobs have been run + And I am logged in as "bookmarker" with password "password" + And I go to bookmarker's bookmarks page + Then I should not see "The collection Five Pillars is currently moderated." + +Scenario: bookmarks added to moderated collections appear correctly + Given the following activated users exist + | login | password | + | workauthor | password | + | bookmarker | password | + | otheruser | password | + And I have a moderated collection "JBs Greatest" with name "jbs_greatest" + And I have a moderated collection "Bedknobs and Broomsticks" with name "beds_and_brooms" + And I have a moderated collection "Death by Demographics" with name "death_by_demographics" + And I have a moderated collection "Murder a la Mode" with name "murder_a_la_mode" + And I have the collection "Mrs. Pots" with name "mrs_pots" + And I am logged in as "workauthor" with password "password" + And I post the work "The Murder of Sherlock Holmes" + When I log out + And I am logged in as "bookmarker" with password "password" + And I view the work "The Murder of Sherlock Holmes" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "jbs_greatest" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + And I should see "The collection JBs Greatest is currently moderated. Your bookmark must be approved by the collection maintainers before being listed there." + # UPDATE the bookmark and add it to a second MODERATED collection and + # recheck all the things + When I follow "Edit" + And I fill in "bookmark_collection_names" with "jbs_greatest,beds_and_brooms" + And I press "Update" + And all indexing jobs have been run + Then I should see "Bookmark was successfully updated." + And I should see "to the moderated collection 'Bedknobs and Broomsticks'." + When I follow "Edit" + And I fill in "bookmark_collection_names" with "jbs_greatest,beds_and_brooms,death_by_demographics,murder_a_la_mode" + And I press "Update" + And all indexing jobs have been run + Then I should see "You have submitted your bookmark to moderated collections (Death by Demographics, Murder a la Mode)." + When I go to bookmarker's bookmarks page + And I should see "The Murder of Sherlock Holmes" + And I should see "Bookmarker's Collections: JBs Greatest" + And I should see "The collection JBs Greatest is currently moderated. Your bookmark must be approved by the collection maintainers before being listed there." + When I go to the bookmarks page + And I should see "The Murder of Sherlock Holmes" + And I should see "Bookmarker's Collections: JBs Greatest" + And I should see "The collection JBs Greatest is currently moderated. Your bookmark must be approved by the collection maintainers before being listed there." + When I log out + # Users who do not own the bookmark should not see the notice, or see that it + # has been submitted to a specific collection + And I am logged in as "otheruser" with password "password" + And I go to bookmarker's bookmarks page + Then I should see "The Murder of Sherlock Holmes" + And I should not see "Bookmarker's Collections: JBs Greatest" + And I should not see "The collection JBs Greatest is currently moderated. Your bookmark must be approved by the collection maintainers before being listed there." + When I go to the bookmarks page + Then I should see "The Murder of Sherlock Holmes" + And I should not see "Bookmarker's Collections: JBs Greatest" + And I should not see "The collection JBs Greatest is currently moderated. Your bookmark must be approved by the collection maintainers before being listed there." + # Edit the bookmark and add it to a second, unmoderated collection, and recheck + # all the things + When I log out + And I am logged in as "bookmarker" with password "password" + And I view the work "The Murder of Sherlock Holmes" + And I follow "Edit Bookmark" + And I fill in "bookmark_collection_names" with "jbs_greatest,beds_and_brooms,mrs_pots" + And I press "Update" within "div#bookmark-form" + And all indexing jobs have been run + Then I should see "Bookmark was successfully updated." + And I should see "The collection JBs Greatest is currently moderated." + When I go to bookmarker's bookmarks page + Then I should see "The Murder of Sherlock Holmes" + And I should see "JBs Greatest" within "ul.meta" + And I should see "Mrs. Pots" within "ul.meta" + And I should see "The collection JBs Greatest is currently moderated." + When I go to the bookmarks page + Then I should see "The Murder of Sherlock Holmes" + And I should see "JBs Greatest" within "ul.meta" + And I should see "Mrs. Pots" within "ul.meta" + And I should see "The collection JBs Greatest is currently moderated." + When I log out + And I am logged in as "otheruser" with password "password" + And I go to bookmarker's bookmarks page + Then I should see "The Murder of Sherlock Holmes" + And I should not see "JBs Greatest" within "ul.meta" + And I should see "Bookmarker's Collections: Mrs. Pots" + And I should not see "The collection JBs Greatest is currently moderated." + When I go to the bookmarks page + Then I should see "The Murder of Sherlock Holmes" + And I should not see "JBs Greatest" within "ul.meta" + And I should see "Bookmarker's Collections: Mrs. Pots" + And I should not see "The collection JBs Greatest is currently moderated." + +Scenario: Adding bookmark to non-existent collection (AO3-4338) + Given I am logged in as "moderator" with password "password" + And I post the work "Programmed for Murder" + And I view the work "Programmed for Murder" + And I follow "Bookmark" + And I press "Create" + And I should see "Bookmark was successfully created" + Then I follow "Edit" + And I fill in "bookmark_collection_names" with "some_nonsense_collection" + And I press "Update" + And I should see "does not exist." + +Scenario: Adding bookmarks to closed collections (Issue 3083) + Given I am logged in as "moderator" + And I have a closed collection "Unsolved Mysteries" with name "unsolved_mysteries" + And I have a closed collection "Rescue 911" with name "rescue_911" + And I am logged in as "moderator" + And I post the work "Hooray for Homicide" + And I post the work "Sing a Song of Murder" + And I go to "Unsolved Mysteries" collection's page + # As a moderator, create a bookmark in a closed collection + When I view the work "Hooray for Homicide" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "unsolved_mysteries" + And I press "Create" + Then I should see "Bookmark was successfully created" + # Now, with the exising bookmark, as a mod, add it to a different closed collection + When I follow "Edit" + And I fill in "bookmark_collection_names" with "rescue_911" + And I press "Update" + Then I should see "Bookmark was successfully updated" + When I view the work "Sing a Song of Murder" + And I follow "Bookmark" + And I press "Create" + Then I should see "Bookmark was successfully created" + # Use the 'Add To Collections' button to add the bookmark to a closed collection AFTER creating said bookmark + When I follow "Add To Collection" + And I fill in "collection_names" with "unsolved_mysteries" + And I press "Add" + Then I should see "Added to collection(s): Unsolved Mysteries" + # Still as the moderator, try to edit the bookmark which is IN a closed collection already + When I follow "Edit" + And I fill in "bookmark_notes" with "This is my edited bookmark" + And I press "Update" + Then I should see "Bookmark was successfully updated." + # Log in as a regular (totally awesome!) user + When I am logged in as "RobertStack" + And I view the work "Sing a Song of Murder" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "rescue_911" + And I press "Create" + Then I should see "Sorry! We couldn't save this bookmark because:" + And I should see "The collection rescue_911 is not currently open." + When I view the work "Hooray for Homicide" + And I follow "Bookmark" + And I press "Create" + Then I should see "Bookmark was successfully created" + Then I follow "Add To Collection" + And I fill in "collection_names" with "rescue_911" + And I press "Add" + Then I should see "We couldn't add your submission to the following collection(s): Rescue 911 is closed to new submissions." + # Now, as a regular user try to add that existing bookmark to a closed collection from the 'Edit' page of a bookmark + When I follow "Edit" + And I fill in "bookmark_collection_names" with "rescue_911" + And I press "Update" + Then I should see "We couldn't add your submission to the following collections: Rescue 911 is closed to new submissions." + # Create a collection, put a bookmark in it, close the collection, then try + # to edit that bookmark + When I open the collection with the title "Rescue 911" + And I am logged in as "Scott" + And I view the work "Sing a Song of Murder" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "rescue_911" + And I press "Create" + Then I should see "Bookmark was successfully created" + When I close the collection with the title "Rescue 911" + And I am logged in as "Scott" + And I view the work "Sing a Song of Murder" + And I follow "Edit Bookmark" + And I fill in "bookmark_notes" with "This is a user editing a closed collection bookmark" + And I press "Update" + Then I should see "Bookmark was successfully updated." + +Scenario: Delete bookmarks of a work and a series + Given the following activated users exist + | login | password | + | wahlly | password | + | markymark | password | + And I am logged in as "wahlly" + And I add the work "A Mighty Duck" to series "The Funky Bunch" + And I add the work "A Mighty Duck2 the sequel" to series "The Funky Bunch" + When I log out + And I am logged in as "markymark" + And I view the work "A Mighty Duck2 the sequel" + And I follow "Bookmark" + And I press "Create" + And I view the work "A Mighty Duck" + And I follow "Bookmark" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created." + And I should see "Delete" + When I follow "Delete" + And I press "Yes, Delete Bookmark" + And all indexing jobs have been run + Then I should see "Bookmark was successfully deleted." + When I view the series "The Funky Bunch" + And I follow "Bookmark Series" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created." + When I follow "Delete" + And I press "Yes, Delete Bookmark" + And all indexing jobs have been run + Then I should see "Bookmark was successfully deleted." + When I go to markymark's bookmarks page + Then I should see "A Mighty Duck2 the sequel" + When I log out + And I am logged in as "wahlly" + And I delete the work "A Mighty Duck2 the sequel" + And all indexing jobs have been run + Then I should see "A Mighty Duck2 the sequel was deleted." + When I log out + And I am logged in as "markymark" + And I go to markymark's bookmarks page + Then I should see "This has been deleted, sorry!" + And I follow "Edit" + And I check "bookmark_private" + And I press "Update" + And all indexing jobs have been run + Then I should see "Bookmark was successfully updated" + When I follow "Delete" + And I press "Yes, Delete Bookmark" + Then I should see "Bookmark was successfully deleted." + +Scenario: Editing a bookmark's tags should expire the bookmark cache + Given I am logged in as "some_user" + And I post the work "Really Good Thing" + When I am logged in as "bookmarker" + And I view the work "Really Good Thing" + And I follow "Bookmark" + And I fill in "bookmark_notes" with "I liked this story" + And I fill in "bookmark_tag_string" with "Tag 1, Tag 2" + And I press "Create" + Then I should see "Bookmark was successfully created" + And the cache of the bookmark on "Really Good Thing" should not expire if I have not edited the bookmark + And the cache of the bookmark on "Really Good Thing" should expire after I edit the bookmark tags + +Scenario: User can't bookmark same work twice + Given the work "Haven" + And I am logged in as "Mara" + And "Mara" creates the pseud "Audrey" + And I bookmark the work "Haven" as "Mara" + When I bookmark the work "Haven" as "Mara" from new bookmark page + Then I should see "You have already bookmarked that." + When I bookmark the work "Haven" as "Audrey" from new bookmark page + Then I should see "You have already bookmarked that." + +Scenario: I cannot create a bookmark that I don't own + Given the work "Random Work" + When I attempt to create a bookmark of "Random Work" with a pseud that is not mine + Then I should not see "Bookmark was successfully created" + And I should see "You can't bookmark with that pseud." + +Scenario: I cannot edit an existing bookmark to transfer it to a pseud I don't own + Given I am logged in as "original_bookmarker" + And I have a bookmark for "Random Work" + When I attempt to transfer my bookmark of "Random Work" to a pseud that is not mine + Then I should not see "Bookmark was successfully updated" + And I should see "You can't bookmark with that pseud." + +Scenario: A bookmark with duplicate tags other than capitalization has only first version of tag saved + Given I am logged in as "bookmark_user" + When I post the work "Revenge of the Sith" + And I follow "Bookmark" + And I fill in "Your tags" with "my tags,My Tags" + And I press "Create" + Then I should see "Bookmark was successfully created" + And I should see "Bookmarker's Tags: my tags" + And I should not see "Bookmarker's Tags: My Tags" + + Scenario: Users can bookmark a work with too many tags + Given the user-defined tag limit is 2 + And the work "Over the Limit" + And the work "Over the Limit" has 3 fandom tags + And I am logged in as "bookmarker" + When I bookmark the work "Over the Limit" + Then I should see "Bookmark was successfully created" + + Scenario: Users can bookmark a pre-existing external work with too many tags + Given the user-defined tag limit is 2 + And I am logged in as "bookmarker1" + And I bookmark the external work "Over the Limit" + And the external work "Over the Limit" has 3 fandom tags + And I am logged in as "bookmarker2" + When I go to bookmarker1's bookmarks page + And I follow "Save" + And I press "Create" + Then I should see "Bookmark was successfully created" + + Scenario: Users cannot bookmark a new external work with too many tags + Given the user-defined tag limit is 5 + And I am logged in as "bookmarker" + When I set up an external work + And I fill in "Fandoms" with "Fandom 1, Fandom 2" + And I fill in "Characters" with "Character 1, Character 2" + And I fill in "Relationships" with "Relationship 1, Relationship 2" + And I press "Create" + Then I should see "Fandom, relationship, and character tags must not add up to more than 5. You have entered 6 of these tags, so you must remove 1 of them." + + Scenario: Archivists can add bookmarks to collections + Given I have an archivist "archivist" + And I am logged in as "archivist" + And I create the collection "My Collection" with name "MyCollection" + When I open a bookmarkable work + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "MyCollection" + And I press "Create" + Then I should see "Bookmark was successfully created" diff --git a/features/bookmarks/bookmark_external.feature b/features/bookmarks/bookmark_external.feature new file mode 100755 index 0000000..4fb4034 --- /dev/null +++ b/features/bookmarks/bookmark_external.feature @@ -0,0 +1,212 @@ +@bookmarks +Feature: Create bookmarks of external works + In order to have an archive full of bookmarks + As a humble user + I want to bookmark some works + + Scenario: A user can bookmark an external work using all the Creator's Tags fields (fandoms, rating, category, relationships, character) + Given basic tags + And mock websites with no content + And I am logged in as "bookmarker" + And I am on the new external work page + When I fill in "URL" with "http://example.org/200" + And I fill in "Creator" with "ao3testing" + And I fill in "Title" with "Some External Work" + And I fill in "Fandoms" with "Test Fandom" + And I select "General Audiences" from "Rating" + And I check "M/M" + And I fill in "Relationships" with "Character 1/Character 2" + And I fill in "Characters" with "Character 3, Character 4" + And I press "Create" + Then I should see "Bookmark was successfully created." + And I should see "Some External Work" + And I should see "ao3testing" + And I should see "Test Fandom" + And I should see "General Audiences" + And I should see "M/M" + And I should see "Character 1/Character 2" + And I should see "Character 3" + And I should see "Character 4" + + Scenario: A user must enter a fandom to create a bookmark on an external work + Given basic tags + And mock websites with no content + And I am logged in as "first_bookmark_user" + When I go to first_bookmark_user's bookmarks page + Then I should not see "Stuck with You" + When I follow "Bookmark External Work" + And I fill in "Creator" with "Sidra" + And I fill in "Title" with "Stuck with You" + And I fill in "URL" with "http://example.org/200" + And I press "Create" + Then I should see "Fandom tag is required" + When I fill in "Fandoms" with "Popslash" + And I press "Create" + And all indexing jobs have been run + Then I should see "This work isn't hosted on the Archive" + When I go to first_bookmark_user's bookmarks page + Then I should see "Stuck with You" + + Scenario: A user must enter a valid URL to create a bookmark on an external work + Given I am logged in as "first_bookmark_user" + And the default ratings exist + And mock websites with no content + When I go to first_bookmark_user's bookmarks page + Then I should not see "Stuck with You" + When I follow "Bookmark External Work" + And I fill in "Creator" with "Sidra" + And I fill in "Title" with "Stuck with You" + And I fill in "Fandoms" with "Popslash" + And I press "Create" + Then I should see "does not appear to be a valid URL" + When I fill in "URL" with "http://example.org/200" + And I press "Create" + And all indexing jobs have been run + Then I should see "This work isn't hosted on the Archive" + When I go to first_bookmark_user's bookmarks page + Then I should see "Stuck with You" + + # edit external bookmark + When I follow "Edit" + Then I should see "Editing bookmark for Stuck with You" + When I fill in "Notes" with "I wish this author would join AO3" + And I fill in "Your tags" with "WIP" + And I press "Update" + Then I should see "Bookmark was successfully updated" + + # delete external bookmark + When I follow "Delete" + Then I should see "Are you sure you want to delete" + And I should see "Stuck with You" + When I press "Yes, Delete Bookmark" + Then I should see "Bookmark was successfully deleted." + And I should not see "Stuck with You" + + Scenario Outline: A user can enter a valid non-ASCII URL to create a bookmark on an external work + Given I am logged in as "first_bookmark_user" + And the default ratings exist + And all pages on the host "" return status 200 + When I am on the new external work page + And I fill in "URL" with "" + And I fill in "Creator" with "foo" + And I fill in "Title" with "" + And I fill in "Fandoms" with "Popslash" + And I press "Create" + Then I should see "Bookmark was successfully created." + + Examples: + | url | title | + | https://example.com/ö | Ö | + | https://example.com/á | á | + | https://example.com/?utf8=✓ | check | + | https://example.com/a,b,c | comma | + + Scenario: Bookmark External Work link should be available to logged in users, but not logged out users + Given a fandom exists with name: "Testing BEW Button", canonical: true + And I am logged in as "markie" with password "theunicorn" + And I create the collection "Testing BEW Collection" + When I go to markie's bookmarks page + Then I should see "Bookmark External Work" + When I go to the bookmarks page + Then I should see "Bookmark External Work" + When I go to the bookmarks in collection "Testing BEW Collection" + Then I should see "Bookmark External Work" + When I log out + And I go to markie's bookmarks page + Then I should not see "Bookmark External Work" + When I go to the bookmarks page + Then I should not see "Bookmark External Work" + When I go to the bookmarks tagged "Testing BEW Button" + Then I should not see "Bookmark External Work" + When I go to the bookmarks in collection "Testing BEW Collection" + Then I should not see "Bookmark External Work" + + Scenario: Users can see external works, admins can also see only duplicates + Given basic tags + And I am logged in + # Bookmark the same URL twice + And I bookmark the external work "External Title" + And I bookmark the external work "Alternate Title" + + When I go to the external works page + Then I should see "External Title" + And I should see "Alternate Title" + And I should not see "Show duplicates" + + When I go to the external works page with only duplicates + Then I should see "Sorry, you don't have permission to access the page you were trying to reach." + + When I am logged in as an admin + And I go to the external works page + Then I should see "External Title" + And I should see "Alternate Title" + And I should see "Show duplicates (1)" + When I follow "Show duplicates (1)" + Then I should see "External Title" + And I should not see "Alternate Title" + + @javascript + Scenario: When using the bookmarklet on a URL that has already been bookmarked, the work information will be automatically filled in + Given "first_user" has bookmarked an external work + And I am logged in as "second_user" + When I use the bookmarklet on a previously bookmarked URL + And I press "Create" + Then I should see "Bookmark was successfully created." + And the work info for my new bookmark should match the original + + @javascript + Scenario: When using the autocomplete to select a URL that has already been bookmarked, the work information will be automatically filled in + Given "first_user" has bookmarked an external work + And I am logged in as "second_user" + When I go to the new external work page + And I choose a previously bookmarked URL from the autocomplete + And I press "Create" + Then I should see "Bookmark was successfully created." + And the work info for my new bookmark should match the original + + @javascript + Scenario: When getting an error (e.g. because the title is blank) after using the autocomplete to select a previously-bookmarked URL, any changes you made to the work information are not overridden on the edit page + Given "first_user" has bookmarked an external work + And I am logged in as "second_user" + When I go to the new external work page + And I choose a previously bookmarked URL from the autocomplete + And I fill in "Title" with "" + And I fill in "Creator" with "Different Author" + And I press "Create" + Then I should see "Sorry! We couldn't save this bookmark because:" + And I should see "Title can't be blank" + And the field labeled "Title" should contain "" + And the field labeled "Creator" should contain "Different Author" + When I fill in "Title" with "Different Title" + And I press "Create" + Then I should see "Bookmark was successfully created." + And the title and creator info for my new bookmark should vary from the original + And the summary and tag info for my new bookmark should match the original + + @javascript + Scenario: When using the autocomplete to select a URL that has already been bookmarked, any information you have entered will be overwritten + Given "first_user" has bookmarked an external work + And I am logged in as "second_user" + When I go to the new external work page + And I fill in "Creator" with "ao3testing" + And I fill in "Title" with "Some External Work" + And I fill in "Fandoms" with "Test Fandom" + And I select "General Audiences" from "Rating" + And I check "M/M" + And I fill in "Relationships" with "Character 1/Character 2" + And I fill in "Characters" with "Character 3, Character 4" + And I choose a previously bookmarked URL from the autocomplete + And I press "Create" + Then I should see "Bookmark was successfully created." + And the work info for my new bookmark should match the original + + Scenario: Bookmark of external work with HTTPS URL is saved as HTTPS + Given I am logged in as "bookmarker1" + And all pages on the host "https://example.com" return status 200 + And I set up an external work + And I fill in "URL" with "https://example.com/external_work" + And I press "Create" + Then I should see "Bookmark was successfully created" + When I follow "A Work Not Posted To The AO3" + Then I should see "This work isn't hosted on the Archive" + And I should see a link to "https://example.com/external_work" within "h4" diff --git a/features/bookmarks/bookmark_filter.feature b/features/bookmarks/bookmark_filter.feature new file mode 100755 index 0000000..e4c3a64 --- /dev/null +++ b/features/bookmarks/bookmark_filter.feature @@ -0,0 +1,19 @@ +@bookmarks +Feature: Filter bookmarks + In order to search an archive full of bookmarks + As a humble user + I want to filter some bookmarks + + Scenario: Filter a user's bookmarks by work language + Given "recengine" has bookmarks of works in various languages + And I am logged in as "recengine" + When I go to recengine's bookmarks page + And I select "Deutsch" from "Work language" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should not see "english work" + And I should see "german work" + When I follow "Clear Filters" + Then I should see "2 Bookmarks by recengine" + And I should see "english work" + And I should see "german work" diff --git a/features/bookmarks/bookmark_indexing.feature b/features/bookmarks/bookmark_indexing.feature new file mode 100755 index 0000000..e32a131 --- /dev/null +++ b/features/bookmarks/bookmark_indexing.feature @@ -0,0 +1,167 @@ +@bookmarks @search +Feature: Bookmark Indexing + + Scenario: Adding a new, out-of-fandom work to a series + Given I am logged in as "author" + And a canonical fandom "Veronica Mars" + And a canonical fandom "X-Files" + And I post the work "The Story Telling: Beginnings" with fandom "Veronica Mars" as part of a series "Telling Stories" + And I post the work "Unrelated Story" with fandom "X-Files" + And I am logged in as "bookmarker" + And I bookmark the work "Unrelated Story" + And I bookmark the series "Telling Stories" + When I go to the bookmarks tagged "X-Files" + And I select "Date Updated" from "Sort by" + And I press "Sort and Filter" + Then the 1st bookmark result should contain "Unrelated Story" + When I am logged in as "author" + And I post the work "The Story Returns" with fandom "X-Files" as part of a series "Telling Stories" + And I go to the bookmarks tagged "X-Files" + Then I should see "Telling Stories" + And I should not see "This tag has not been marked common and can't be filtered on (yet)." + When I select "Date Updated" from "Sort by" + And I press "Sort and Filter" + Then the 1st bookmark result should contain "Telling Stories" + And the 2nd bookmark result should contain "Unrelated Story" + When I go to bookmarker's user page + And I follow "Bookmarks (2)" + And I select "Date Updated" from "Sort by" + And I press "Sort and Filter" + Then the 1st bookmark result should contain "Telling Stories" + And the 2nd bookmark result should contain "Unrelated Story" + When I go to the bookmarks tagged "X-Files" + Then I should see "Telling Stories" + And I should not see "This tag has not been marked common and can't be filtered on (yet)." + When I select "Date Updated" from "Sort by" + And I press "Sort and Filter" + Then the 1st bookmark result should contain "Telling Stories" + And the 2nd bookmark result should contain "Unrelated Story" + + Scenario: When a work in a series is updated with a new tag, bookmarks of the + series should appear on the tag's bookmark listing; when a tag is removed, the + bookmarks should disappear from the tag listing + Given a canonical freeform "New Tag" + And I am logged in + And I post the work "Work" as part of a series "Series" + And I bookmark the series "Series" + When I edit the work "Work" + And I fill in "Additional Tags" with "New Tag" + And I press "Post" + And all indexing jobs have been run + And I go to the bookmarks tagged "New Tag" + Then the 1st bookmark result should contain "Series" + When I edit the work "Work" + And I fill in "Additional Tags" with "" + And I press "Post" + And all indexing jobs have been run + And I go to the bookmarks tagged "New Tag" + Then I should not see "Series" + + Scenario: Synning a canonical tag used on bookmarked series and external works + should move the bookmarks to the new canonical's bookmark listings; de-synning + should remove them + Given a canonical fandom "Veronica Mars" + And a canonical fandom "Veronica Mars (TV)" + And bookmarks of external works and series tagged with the fandom tag "Veronica Mars" + And I am logged in as a "tag_wrangling" admin + When I syn the tag "Veronica Mars" to "Veronica Mars (TV)" + And I go to the bookmarks tagged "Veronica Mars (TV)" + Then I should see "BookmarkedExternalWork" + And I should see "BookmarkedSeries" + When I de-syn the tag "Veronica Mars" from "Veronica Mars (TV)" + And the tag "Veronica Mars" is canonized + And I go to the bookmarks tagged "Veronica Mars (TV)" + Then I should not see "BookmarkedExternalWork" + And I should not see "BookmarkedSeries" + When I go to the bookmarks tagged "Veronica Mars" + Then I should see "BookmarkedExternalWork" + And I should see "BookmarkedSeries" + When I syn the tag "Veronica Mars" to "Veronica Mars (TV)" + And I go to the bookmarks tagged "Veronica Mars (TV)" + Then I should see "BookmarkedSeries" + And I should see "BookmarkedExternalWork" + + Scenario: Subtagging a tag used on bookmarked series and external works should + make the bookmarks appear in the metatag's bookmark listings; de-subbing + should remove them + Given a canonical character "Laura" + And a canonical character "Laura Roslin" + And bookmarks of external works and series tagged with the character tag "Laura Roslin" + And I am logged in as a tag wrangler + When I subtag the tag "Laura Roslin" to "Laura" + And I go to the bookmarks tagged "Laura" + Then I should see "BookmarkedExternalWork" + And I should see "BookmarkedSeries" + When I remove the metatag "Laura" from "Laura Roslin" + And I go to the bookmarks tagged "Laura" + Then I should not see "BookmarkedExternalWork" + And I should not see "BookmarkedSeries" + When I go to the bookmarks tagged "Laura Roslin" + Then I should see "BookmarkedExternalWork" + And I should see "BookmarkedSeries" + + Scenario: A bookmark of an external work should show on a tag's bookmark + listing once the tag is made canonical + Given basic tags + And I am logged in as "bookmarker" + And I bookmark the external work "Outside Story" with character "Mikki Mendoza" + When the tag "Mikki Mendoza" is canonized + And I go to the bookmarks tagged "Mikki Mendoza" + Then I should see "Outside Story" + + Scenario: New bookmarks of external works should appear in the bookmark listings for its tag's existing metatag, and removing the tag should remove the bookmark from both the tag's and metatag's bookmark listings + Given basic tags + And a canonical character "Ann" + And a canonical character "Ann Ewing" + And "Ann" is a metatag of the character "Ann Ewing" + When I am logged in + And I bookmark the external work "The Big D" with character "Ann Ewing" + And I go to the bookmarks tagged "Ann" + Then I should see "The Big D" + When the character "Ann Ewing" is removed from the external work "The Big D" + And I go to the bookmarks tagged "Ann Ewing" + Then I should not see "The Big D" + When I go to the bookmarks tagged "Ann" + Then I should not see "The Big D" + + Scenario: Adding a chapter to a work in a series should update the series, as + should deleting a chapter from a work in a series + Given I have bookmarks of old series to search + When a chapter is added to "WIP in a Series" + And I go to the search bookmarks page + And I select "Series" from "Type" + And I select "Date Updated" from "Sort by" + And I press "Search Bookmarks" + Then the 1st bookmark result should contain "Older WIP Series" + And the 2nd bookmark result should contain "Newer Complete Series" + When I delete chapter 2 of "WIP in a Series" + And I go to the search bookmarks page + And I select "Series" from "Type" + And I select "Date Updated" from "Sort by" + And I press "Search Bookmarks" + Then the 1st bookmark result should contain "Newer Complete Series" + And the 2nd bookmark result should contain "Older WIP Series" + + Scenario: When a wrangler edits a tag's merger using the "Synonym of" field, + the tag's bookmarks should be transfered to the new merger's bookmark listings + Given a canonical character "Ellie Ewing" + And a canonical character "Ellie Farlow" + And a synonym "Miss Ellie" of the tag "Ellie Ewing" + And bookmarks of all types tagged with the character tag "Miss Ellie" + And I am logged in as a tag wrangler + When I go to the bookmarks tagged "Ellie Ewing" + Then I should see "BookmarkedWork" + And I should see "BookmarkedSeries" + And I should see "BookmarkedExternalWork" + When I edit the tag "Miss Ellie" + And I fill in "Synonym of" with "Ellie Farlow" + And I press "Save changes" + And all indexing jobs have been run + And I go to the bookmarks tagged "Ellie Ewing" + Then I should not see "BookmarkedWork" + And I should not see "BookmarkedSeries" + And I should not see "BookmarkedExternalWork" + When I go to the bookmarks tagged "Ellie Farlow" + Then I should see "BookmarkedWork" + And I should see "BookmarkedSeries" + And I should see "BookmarkedExternalWork" diff --git a/features/bookmarks/bookmark_privacy.feature b/features/bookmarks/bookmark_privacy.feature new file mode 100755 index 0000000..7d5417b --- /dev/null +++ b/features/bookmarks/bookmark_privacy.feature @@ -0,0 +1,200 @@ +@bookmarks +Feature: Private bookmarks + In order to have an archive full of bookmarks + As a humble user + I want to bookmark some works privately + + @disable_caching + Scenario: private bookmarks on public and restricted works + + Given dashboard counts expire after 10 seconds + And a canonical fandom "Stargate SG-1" + And I am logged in as "workauthor" + And I post the locked work "Secret Masterpiece" + And I post the work "Public Masterpiece" + And I post the work "Another Masterpiece" + When I am logged in as "avid_bookmarker" + And "avid_bookmarker" creates the pseud "infrequent_bookmarker" + And I start a new bookmark for "Secret Masterpiece" + And I check "Rec" + And I check "Private bookmark" + And I press "Create" + Then I should see "Bookmark was successfully created" + And I should see the image "title" text "Restricted" + And I should not see "Rec" + And I should see "Private Bookmark" + And I should see "0" within ".count" + When I start a new bookmark for "Public Masterpiece" + And I check "Rec" + And I check "Private bookmark" + And I press "Create" + Then I should see "Bookmark was successfully created" + And I should not see the image "title" text "Restricted" + And I should not see "Rec" + And I should see "Private Bookmark" + And I should see "0" within ".count" + When I start a new bookmark for "Another Masterpiece" + And I select "infrequent_bookmarker" from "bookmark_pseud_id" + And I check "Private bookmark" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + And I should not see the image "title" text "Restricted" + And I should not see "Rec" + And I should see "Private Bookmark" + And I should see "0" within ".count" + + # Private bookmarks should not show on the main bookmark page, but should show on your own bookmark page + + When I go to the bookmarks page + Then I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I am on avid_bookmarker's bookmarks page + Then I should see "3 Bookmarks by avid_bookmarker" + And I should see "Bookmarks (0)" + And I should see "Public Masterpiece" + And I should see "Secret Masterpiece" + And I should see "Another Masterpiece" + When I wait 11 seconds + And I reload the page + Then I should see "Bookmarks (3)" + When I go to the bookmarks page for user "avid_bookmarker" with pseud "infrequent_bookmarker" + Then I should see "1 Bookmark by infrequent_bookmarker (avid_bookmarker)" + And I should see "Bookmarks (1)" + And I should see "Another Masterpiece" + But I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + + # Private bookmarks should not be visible when logged out + + When I log out + And I go to the bookmarks page + Then I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + And I should not see "avid_bookmarker" + When I go to avid_bookmarker's bookmarks page + Then I should see "Bookmarks (0)" + And I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to the bookmarks page for user "avid_bookmarker" with pseud "infrequent_bookmarker" + Then I should see "Bookmarks (0)" + And I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to the works page + Then I should not see "Secret Masterpiece" + And I should see "Public Masterpiece" + And I should not see "Bookmarks:" + And I should not see "Bookmarks: 1" + When I view the work "Public Masterpiece" + Then I should not see "Bookmarks:" + And I should not see "Bookmarks:1" + + # Private bookmarks should not be visible to other users + + When I am logged in as "otheruser" + And I go to the bookmarks page + Then I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to avid_bookmarker's bookmarks page + Then I should see "Bookmarks (0)" + And I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to the bookmarks page for user "avid_bookmarker" with pseud "infrequent_bookmarker" + Then I should see "Bookmarks (0)" + And I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to the works page + Then I should see "Public Masterpiece" + And I should see "Another Masterpiece" + And I should not see "Secret Masterpiece" + And I should not see "Bookmarks:" + And I should not see "Bookmarks: 1" + + # Private bookmarks should not be visible even to the author + + When I am logged in as "workauthor" + And I go to the bookmarks page + Then I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to avid_bookmarker's bookmarks page + Then I should see "Bookmarks (0)" + And I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to the bookmarks page for user "avid_bookmarker" with pseud "infrequent_bookmarker" + Then I should see "Bookmarks (0)" + And I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + + # Private bookmarks should not be visible when logged out, even if there are other bookmarks on that work + + When I am logged in as "otheruser" + And I view the work "Public Masterpiece" + And I rec the current work + And all indexing jobs have been run + When I log out + And I go to the bookmarks page + Then I should not see "Secret Masterpiece" + And I should not see "Another Masterpiece" + And I should see "Public Masterpiece" + And I should not see "avid_bookmarker" + And I should see "otheruser" + When I go to avid_bookmarker's bookmarks page + Then I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to the bookmarks page for user "avid_bookmarker" with pseud "infrequent_bookmarker" + Then I should see "Bookmarks (0)" + And I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to the works page + Then I should not see "Secret Masterpiece" + And I should see "Public Masterpiece" + And I should not see "Bookmarks: 2" + And I should see "Bookmarks: 1" + And I should see "Another Masterpiece" + When I view the work "Public Masterpiece" + Then I should not see "Bookmarks:2" + And I should see "Bookmarks:1" + When I follow "1" + Then I should see "List of Bookmarks" + And I should see "Public Masterpiece" + And I should see "otheruser" + And I should not see "avid_bookmarker" + + # Private bookmarks should not show on tag's page + + When I go to the bookmarks tagged "Stargate SG-1" + Then I should not see "Secret Masterpiece" + And I should see "Public Masterpiece" + And I should not see "Another Masterpiece" + And I should not see "avid_bookmarker" + And I should see "otheruser" + # This *should* be 1, because there's no way for a bookmark to appear on + # a tag bookmark page if the bookmarkable has a public_bookmark_count of + # 0. However, caching means that this is actually 0: + And I should see "0" within ".count" + And I should not see "2" within ".count" + + # Private bookmarks should not be visible to admins, but the admin + # should be able to see how many private bookmarks the user has + + When I am logged in as an admin + And I go to avid_bookmarker's bookmarks page + Then I should see "Bookmarks (3)" + But I should not see "Secret Masterpiece" + And I should not see "Public Masterpiece" + And I should not see "Another Masterpiece" + When I go to the bookmarks page for user "avid_bookmarker" with pseud "infrequent_bookmarker" + Then I should see "Bookmarks (1)" + But I should not see "Another Masterpiece" diff --git a/features/bookmarks/bookmark_search.feature b/features/bookmarks/bookmark_search.feature new file mode 100755 index 0000000..ec9ab52 --- /dev/null +++ b/features/bookmarks/bookmark_search.feature @@ -0,0 +1,257 @@ +@bookmarks @search +Feature: Search Bookmarks + In order to test search + As a humble coder + I have to use cucumber with elasticsearch + + Background: + Given I am on the search bookmarks page + + Scenario: Search bookmarks by tag + Given I have bookmarks to search + + # Only on bookmarks + When I fill in "Bookmarker's tags" with "rare" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Tags: rare" + And I should see "1 Found" + And I should see "second work" + When I follow "Edit Your Search" + Then the field labeled "Bookmarker's tags" should contain "rare" + + # Only on bookmarkables + When I am on the search bookmarks page + And I fill in "Work tags" with "rare" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Tags: rare" + And I should see "2 Found" + And I should see "First work" + And I should see "First Series" + When I follow "Edit Your Search" + Then the field labeled "Work tags" should contain "rare" + + # On bookmarks and bookmarkables, results should match both + When I am on the search Bookmarks page + And I fill in "Bookmarker's tags" with "rare" + And I fill in "Work tags" with "rare" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Tags: rare" + And I should see "No results found." + + Scenario: Search bookmarks by date bookmarked + Given I have bookmarks to search by dates + When I fill in "Date bookmarked" with "> 900 days ago" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Date bookmarked: > 900 days ago" + And I should see "3 Found" + And I should see "Old bookmark of old work" + And I should see "Old bookmark of old series" + And I should see "Old bookmark of old external work" + When I follow "Edit Your Search" + Then the field labeled "Date bookmarked" should contain "> 900 days ago" + + When I fill in "Date bookmarked" with "< 900 days ago" + And I press "Search Bookmarks" + Then I should see "You searched for: Date bookmarked: < 900 days ago" + And I should see "6 Found" + And I should see "New bookmark of old work" + And I should see "New bookmark of new work" + And I should see "New bookmark of old series" + And I should see "New bookmark of new series" + And I should see "New bookmark of old external work" + And I should see "New bookmark of new external work" + + Scenario: Search bookmarks by date updated + Given I have bookmarks to search by dates + When I fill in "Date updated" with "> 900 days ago" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Date updated: > 900 days ago" + And I should see "6 Found" + And I should see "Old bookmark of old work" + And I should see "New bookmark of old work" + And I should see "Old bookmark of old series" + And I should see "New bookmark of old series" + And I should see "Old bookmark of old external work" + And I should see "New bookmark of old external work" + When I follow "Edit Your Search" + Then the field labeled "Date updated" should contain "> 900 days ago" + + When I fill in "Date updated" with "< 900 days ago" + And I press "Search Bookmarks" + Then I should see "You searched for: Date updated: < 900 days ago" + And I should see "3 Found" + And I should see "New bookmark of new work" + And I should see "New bookmark of new series" + And I should see "New bookmark of new external work" + + Scenario: Search bookmarks for recs + Given I have bookmarks to search + When I check "Rec" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Rec" + And I should see "2 Found" + And I should see "First work" + And I should see "Second Series" + When I follow "Edit Your Search" + Then the "Rec" checkbox should be checked + + Scenario: Search bookmarks by any field + Given I have bookmarks to search by any field + + # Only on bookmarks + When I fill in "Any field on bookmark" with "more please" + And I press "Search Bookmarks" + Then I should see the page title "Bookmarks Matching 'more please'" + And I should see "You searched for: more please" + And I should see "6 Found" + And I should see "Hurt and that's it" + And I should see "Fluff" + And I should see "H/C Series" + And I should see "Ouchless Series" + And I should see "External Fix-It" + And I should see "External Whump" + When I follow "Edit Your Search" + Then the field labeled "Any field on bookmark" should contain "more please" + + # Only on bookmarkables + When I am on the search bookmarks page + And I fill in "Any field on work" with "hurt" + And I press "Search Bookmarks" + Then I should see the page title "Bookmarks Matching 'hurt'" + And I should see "You searched for: hurt" + And I should see "4 Found" + And I should see "Comfort" + And I should see "Hurt and that's it" + And I should see "H/C Series" + And I should see "External Whump" + When I follow "Edit Your Search" + Then the field labeled "Any field on work" should contain "hurt" + + # On bookmarks and bookmarkables, results should match both + When I am on the search bookmarks page + And I fill in "Any field on bookmark" with "more please" + And I fill in "Any field on work" with "hurt" + And I press "Search Bookmarks" + Then I should see the page title "Bookmarks Matching 'hurt, more please'" + And I should see "You searched for: hurt, more please" + And I should see "3 Found" + And I should see "Hurt and that's it" + And I should see "H/C Series" + And I should see "External Whump" + + Scenario: Search bookmarks by type + Given I have bookmarks to search + When I select "External Work" from "Type" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Type: External Work" + And I should see "1 Found" + And I should see "Skies Grown Darker" + When I follow "Edit Your Search" + Then "External Work" should be selected within "Type" + When I select "Series" from "Type" + And I press "Search Bookmarks" + Then I should see "You searched for: Type: Series" + And I should see "2 Found" + + Scenario: Search for bookmarks with notes, and then edit search to narrow + results by the note content + Given I have bookmarks to search + When I check "With notes" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: With Notes" + And I should see "3 Found" + And I should see "fifth" + And I should see "Skies Grown Darker" + And I should see "Second Series" + When I follow "Edit Your Search" + Then the "With notes" checkbox should be checked + When I fill in "Notes" with "broken heart" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Notes: broken heart, With Notes" + And I should see "1 Found" + And I should see "fifth" + When I follow "Edit Your Search" + Then the field labeled "Notes" should contain "broken heart" + And the "With notes" checkbox should be checked + + Scenario: If testuser has the pseud tester_pseud, searching for bookmarks by + the bookmarker testuser returns all of tester_pseud's bookmarks + Given I have bookmarks to search + When I fill in "Bookmarker" with "testuser" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Bookmarker: testuser" + And I should see "8 Found" + And I should see "First work" + And I should see "second work" + And I should see "third work" + And I should see "tester_pseud" + And I should see "fifth" + And I should see "Skies Grown Darker" + And I should see "First Series" + And I should see "Second Series" + When I follow "Edit Your Search" + Then the field labeled "Bookmarker" should contain "testuser" + + Scenario: Search for bookmarks by the bookmarkable item's completion status + Given I have bookmarks of various completion statuses to search + When I fill in "Any field on work" with "complete: true" + And I press "Search Bookmarks" + Then I should see "You searched for: complete: true" + And I should see "2 Found" + And I should see "Finished Work" + And I should see "Complete Series" + And I should not see "Incomplete Work" + And I should not see "Incomplete Series" + And I should not see "External Work" + When I follow "Edit Your Search" + Then the field labeled "Any field on work" should contain "complete: true" + When I fill in "Any field on work" with "complete: false" + And I press "Search Bookmarks" + Then I should see "You searched for: complete: false" + And I should see "2 Found" + And I should see "Incomplete Work" + And I should see "Incomplete Series" + And I should not see "Finished Work" + And I should not see "Complete Series" + And I should not see "External Work" + + Scenario: Search bookmarks by work language + Given "someuser" has bookmarks of works in various languages + # reload search page to bring new language-id mappings for dropdown + When I reload the page + And I select "Deutsch" from "Work language" + And I press "Search Bookmarks" + Then I should see the page title "Search Bookmarks" + And I should see "You searched for: Work language: Deutsch" + And I should see "1 Found" + And I should see "german work" + And I should not see "english work" + + Scenario: Search bookmarks by bookmarker + Given "testuser2" has a bookmark of a work titled "Test Title 2" + When I fill in "Bookmarker" with "testuser2" + And I press "Search Bookmarks" + Then I should see "You searched for: Bookmarker: testuser2" + And I should see "1 Found" + And I should see "Test Title 2" + When I follow "Edit Your Search" + And I fill in "Bookmarker" with "testuser" + And I press "Search Bookmarks" + Then I should see "You searched for: Bookmarker: testuser" + And I should see "No results found." + + Scenario: Inputting bad queries + Given I have bookmarks to search + When I fill in "Any field on work" with "bad~query~~!!!" + And I press "Search Bookmarks" + Then I should see "Your search failed because of a syntax error. Please try again." diff --git a/features/bookmarks/bookmark_share.feature b/features/bookmarks/bookmark_share.feature new file mode 100755 index 0000000..40e0e05 --- /dev/null +++ b/features/bookmarks/bookmark_share.feature @@ -0,0 +1,48 @@ +@bookmarks +Feature: Share Bookmarks + Testing the "Share" button on bookmarks, with JavaScript emulation + + # We need to load the site skin to make the share modal work properly: + @javascript @load-default-skin + Scenario: Share a bookmark + Given I am logged in as "tess" + And the work "Damp Gravel" by "tess" with fandom "Stargate SG-1" + And I have a bookmark for "Damp Gravel" + When I go to the first bookmark for the work "Damp Gravel" + Then I should see "Damp Gravel" + And I should see "Share" + When I follow "Share" + Then I should see "Copy and paste the following code to link back to this work" within "#share" + And I should see "or use the Tweet or Tumblr links to share the work" within "#share" + And I should see '<strong>Damp Gravel</strong></a> (8 words)' within "#share textarea" + And I should see 'by <a href="http://www.example.com/users/tess"><strong>tess</strong></a>' within "#share textarea" + And I should see 'Fandom: <a href="http://www.example.com/tags/Stargate%20SG-1">Stargate SG-1</a>' within "#share textarea" + And I should see "Rating: Not Rated" within "#share textarea" + And I should see "Warnings: No Archive Warnings Apply" within "#share textarea" + And the share modal should contain social share buttons + And I should not see "Series:" within "#share textarea" + And I should not see "Relationships:" within "#share textarea" + And I should not see "Characters:" within "#share textarea" + And I should not see "Summary:" within "#share textarea" + + Scenario: Share option is unavailable if bookmarkable is unrevealed. + Given there is a work "Hidden Figures" in an unrevealed collection "Backlist" + And I am logged in as the author of "Hidden Figures" + When I view the work "Hidden Figures" + Then I should see "Bookmark" + When I follow "Bookmark" + And I press "Create" + And all indexing jobs have been run + Then I should see "Bookmark was successfully created" + When I go to the first bookmark for the work "Hidden Figures" + Then I should see "Hidden Figures" + And I should see "Add To Collection" + And I should not see "Share" + + Scenario: Sharing a bookmark is not possible when logged out + Given I am logged in as "tess" + And I have a bookmark for "Damp Gravel" + When I am logged out + And I go to the first bookmark for the work "Damp Gravel" + Then I should see "Damp Gravel" + And I should not see "Share" diff --git a/features/bookmarks/delete_bookmarkable.feature b/features/bookmarks/delete_bookmarkable.feature new file mode 100755 index 0000000..2a5f98b --- /dev/null +++ b/features/bookmarks/delete_bookmarkable.feature @@ -0,0 +1,84 @@ +@bookmarks @search +Feature: Bookmarks of deleted items + + Scenario: Deleting a work shouldn't make its bookmarks disappear completely. + Given I am logged in as "Alice" + And I post the work "Mayfly" + And I am logged in as "Beth" + And I bookmark the work "Mayfly" with the note "The best yet!" + And I am logged in as "Alice" + And I delete the work "Mayfly" + And all indexing jobs have been run + And I am logged in as "Charlotte" + When I go to the search people page + And I fill in "Name" with "Beth" + And I press "Search People" + Then I should see "Beth" within "ol.pseud.group" + And I should see "1 bookmark" + When I follow "1 bookmark" + Then I should see "Bookmarks (1)" + And I should see "1 Bookmark by Beth" + And I should see "This has been deleted, sorry!" + And I should see "The best yet!" + But I should not see "Mayfly" + + Scenario: Deleting a series shouldn't make its bookmarks disappear completely. + Given I am logged in as "Alice" + And I post the work "Mayfly" as part of a series "Shorts" + And I am logged in as "Beth" + And I bookmark the series "Shorts" + And I am logged in as "Alice" + And I delete the series "Shorts" + And all indexing jobs have been run + And I am logged in as "Charlotte" + When I go to the search people page + And I fill in "Name" with "Beth" + And I press "Search People" + Then I should see "Beth" within "ol.pseud.group" + And I should see "1 bookmark" + When I follow "1 bookmark" + Then I should see "Bookmarks (1)" + And I should see "1 Bookmark by Beth" + And I should see "This has been deleted, sorry!" + But I should not see "Shorts" + + Scenario: Deleting an external work shouldn't make its bookmarks disappear completely. + Given basic tags + And I am logged in as "Alice" + And I bookmark the external work "Extremely Objectionable Content" + And I am logged in as a "policy_and_abuse" admin + And I view the external work "Extremely Objectionable Content" + And I follow "Delete External Work" + And all indexing jobs have been run + And I am logged in as "Beth" + When I go to the search people page + And I fill in "Name" with "Alice" + And I press "Search People" + Then I should see "Alice" within "ol.pseud.group" + And I should see "1 bookmark" + When I follow "1 bookmark" + Then I should see "Bookmarks (1)" + And I should see "1 Bookmark by Alice" + And I should see "This has been deleted, sorry!" + And I should not see "Extremely Objectionable Content" + + Scenario: Deleting a restricted work with bookmarks makes the public bookmark count on all bookmarker's pseuds increase. + Given I am logged in as "Alice" + And I post the locked work "Mayfly" + And I am logged in as "Beth" + And I bookmark the work "Mayfly" + When I am logged out + And I go to the search people page + And I fill in "Name" with "Beth" + And I press "Search People" + Then I should see "Beth" within "ol.pseud.group" + And I should not see "1 bookmark" + When I am logged in as "Alice" + And I delete the work "Mayfly" + And all indexing jobs have been run + And I am logged out + And I go to the search people page + And I fill in "Name" with "Beth" + And I press "Search People" + Then I should see "Beth" within "ol.pseud.group" + And I should see "1 bookmark" diff --git a/features/collections/collectible_closed_collection.feature b/features/collections/collectible_closed_collection.feature new file mode 100755 index 0000000..c43359b --- /dev/null +++ b/features/collections/collectible_closed_collection.feature @@ -0,0 +1,25 @@ +@bookmarks @collections @works +Feature: Collectible items in closed collections + As a moderator + I want users to be unable to add items to my closed collection + + Background: + Given I have a closed collection "Various Penguins" + And I am logged in as a random user + + Scenario: Add my work to a closed collection + When I post the work "Blabla" in the collection "Various Penguins" + Then I should see "is not currently open" + When the collection counts have expired + And I go to "Various Penguins" collection's page + Then I should see "Works (0)" within "#dashboard" + And I should not see "Blabla" + + Scenario: Add my bookmark to a closed collection + Given I have a bookmark for "Tundra penguins" + When I add my bookmark to the collection "Various_Penguins" + Then I should see "is closed" + When the collection counts have expired + And I go to "Various Penguins" collection's page + Then I should see "Bookmarked Items (0)" within "#dashboard" + And I should not see "Tundra penguins" diff --git a/features/collections/collectible_moderated_collection.feature b/features/collections/collectible_moderated_collection.feature new file mode 100755 index 0000000..98f37ea --- /dev/null +++ b/features/collections/collectible_moderated_collection.feature @@ -0,0 +1,47 @@ +@bookmarks @collections @works +Feature: Collectible items in moderated collections + As a user + I want to add my items to moderated collections + + Background: + Given I have a moderated collection "Various Penguins" + And I am logged in as a random user + + Scenario: Add my work to a moderated collection by editing the work + Given I post the work "Blabla" + When I edit the work "Blabla" + And I fill in "Post to Collections / Challenges" with "various_penguins" + And I press "Preview" + Then I should see "the moderated collection 'Various Penguins'" + When I press "Update" + Then I should see "the moderated collection 'Various Penguins'" + + Scenario: Add my bookmark to a moderated collection + Given I have a bookmark for "Tundra penguins" + When I add my bookmark to the collection "Various_Penguins" + Then I should see "until it has been approved by a moderator." + When the collection counts have expired + And I go to "Various Penguins" collection's page + Then I should see "Bookmarked Items (0)" within "#dashboard" + And I should not see "Tundra penguins" + + Scenario: Bookmarks of deleted items are included on a moderated collection's + Awaiting Approval Manage Items page + Given I have a bookmark of a deleted work + And I add my bookmark to the collection "Various_Penguins" + When I am logged in as the owner of "Various Penguins" + And I view the awaiting collection approval collection items page for "Various Penguins" + Then I should see "Bookmark of deleted item" + And I should see "This has been deleted, sorry!" + + Scenario: A work with too many tags can be approved + Given the user-defined tag limit is 2 + And I post the work "Over the Limit" to the collection "Various Penguins" + And the work "Over the Limit" has 3 fandom tags + When I am logged in as the owner of "Various Penguins" + And I approve the work "Over the Limit" in the collection "Various Penguins" + And I submit + Then I should see "Collection status updated!" + And I should not see "Over the Limit" + When I view the work "Over the Limit" + Then I should see "Various Penguins" diff --git a/features/collections/collectible_multiple_collections.feature b/features/collections/collectible_multiple_collections.feature new file mode 100755 index 0000000..a4c5340 --- /dev/null +++ b/features/collections/collectible_multiple_collections.feature @@ -0,0 +1,59 @@ +@bookmarks @collections @works + +Feature: Collectible items in multiple collections + As a user + I want to be unable to add items to more than one collection + + Scenario: Add a work that is already in a moderated collection to a second moderated collection + Given I have the moderated collection "ModeratedCollection" + And I have the moderated collection "ModeratedCollection2" + And I am logged in as a random user + And I set my preferences to allow collection invitations + And I post the work "Blabla" to the collection "ModeratedCollection" + When I edit the work "Blabla" to be in the collections "ModeratedCollection,ModeratedCollection2" + Then I should see "Work was successfully updated. You have submitted your work to moderated collections (ModeratedCollection, ModeratedCollection2). It will not become a part of those collections until it has been approved by a moderator." + + Scenario: Add my work to both moderated and unmoderated collections by editing + the work + Given I have the moderated collection "ModeratedCollection" + And I have the collection "UnModeratedCollection" + And I am logged in as a random user + And I post the work "RandomWork" to the collection "ModeratedCollection" + When I go to "ModeratedCollection" collection's page + Then I should not see "RandomWork" + When I edit the work "RandomWork" + # Fill in both the existing and new collection names or else this will + # remove it from the original collection by replacing the text in the + # field + And I fill in "Post to Collections / Challenges" with "ModeratedCollection, UnModeratedCollection" + And I press "Post" + Then I should see "Work was successfully updated. You have submitted your work to the moderated collection 'ModeratedCollection'. It will not become a part of the collection until it has been approved by a moderator." + And I should see "UnModeratedCollection" + When I go to "UnModeratedCollection" collection's page + Then I should see "RandomWork" + When I go to "ModeratedCollection" collection's page + Then I should not see "RandomWork" + + Scenario: Collection mod can't add an anonymous work to their collection using + the Add to Collections option on the work + Given I have the anonymous collection "AnonymousCollection" + And I have the collection "MyCollection" + And I am logged in as a random user + And I set my preferences to allow collection invitations + And I post the work "Some Work" to the collection "AnonymousCollection" + When I am logged in as the owner of "MyCollection" + And I view the work "Some Work" + And I fill in "Collection name(s):" with "MyCollection" + And I press "Invite" + Then I should see "We couldn't add your submission to the following collection(s):" + And I should see "MyCollection, because you don't own this item and the item is anonymous." + + Scenario: Work creator can add their own anonymous work to another collection + Given I have the anonymous collection "AnonymousCollection" + And I have the collection "OtherCollection" + And I am logged in as a random user + And I set my preferences to allow collection invitations + And I post the work "Some Work" to the collection "AnonymousCollection" + When I edit the work "Some Work" to be in the collections "AnonymousCollection,OtherCollection" + Then I should see "Work was successfully updated." + And I should see "OtherCollection" diff --git a/features/collections/collectible_open_collection.feature b/features/collections/collectible_open_collection.feature new file mode 100755 index 0000000..2ab70cc --- /dev/null +++ b/features/collections/collectible_open_collection.feature @@ -0,0 +1,89 @@ +@bookmarks @collections @works +Feature: Collectible items + As a user + I want to add my items to collections + + Background: + Given I have a collection "Various Penguins" + And I am logged in as "penguin_fan" + + Scenario: Post my work to a collection + Given I go to "Various Penguins" collection's page + And I post the work "Blabla" in the collection "Various Penguins" + When I go to "Various Penguins" collection's page + Then I should see "Works (0)" within "#dashboard" + And I should see "Blabla" + When the collection counts have expired + And I reload the page + Then I should see "Works (1)" within "#dashboard" + And I should see "Blabla" + + Scenario: Add my chaptered work to a collection + Given I go to "Various Penguins" collection's page + And I post the chaptered work "Blabla" in the collection "Various Penguins" + When I go to "Various Penguins" collection's page + Then I should see "Works (0)" within "#dashboard" + And I should see "Blabla" + When the collection counts have expired + And I reload the page + Then I should see "Works (1)" within "#dashboard" + And I should see "Blabla" + + Scenario: Add my bookmark to a collection + Given I go to "Various Penguins" collection's page + And I have a bookmark for "Tundra penguins" + When I add my bookmark to the collection "Various_Penguins" + Then I should see "Added" + When I go to "Various Penguins" collection's page + Then I should see "Bookmarked Items (0)" within "#dashboard" + And I should see "Tundra penguins" + When the collection counts have expired + And I reload the page + Then I should see "Bookmarked Items (1)" within "#dashboard" + And I should see "Tundra penguins" + + Scenario: Bookmarks of deleted items are included on the collection's Manage + Items page + Given I have a bookmark of a deleted work + And I add my bookmark to the collection "Various_Penguins" + When I am logged in as the owner of "Various Penguins" + And I view the approved collection items page for "Various Penguins" + Then I should see "Bookmark of deleted item" + And I should see "This has been deleted, sorry!" + + Scenario: Bookmarks of deleted items are included on the user's Manage + Collected Works page + Given I have a bookmark of a deleted work + When I add my bookmark to the collection "Various_Penguins" + Then I should see "Added" + When I go to penguin_fan's collection items page + And I follow "Approved" + Then I should see "Bookmark of deleted item" + And I should see "This has been deleted, sorry!" + + Scenario: Deleted works are not included on the user's Manage Collection Items + page + Given I post the work "Emperor Penguins" to the collection "Various Penguins" + And I delete the work "Emperor Penguins" + When I go to penguin_fan's collection items page + And I follow "Approved" + Then I should not see "Emperor Penguins" + + Scenario: Deleted works are not included on the collection's Manage Items page + Given I post the work "Emperor Penguins" to the collection "Various Penguins" + And I delete the work "Emperor Penguins" + When I am logged in as the owner of "Various Penguins" + And I view the approved collection items page for "Various Penguins" + Then I should not see "Emperor Penguins" + + Scenario: Drafts are included on the user's Manage Collection Items page + Given the draft "Sweater Penguins" in the collection "Various Penguins" + When I go to penguin_fan's collection items page + And I follow "Approved" + Then I should see "Sweater Penguins (Draft)" + + Scenario: Drafts are included on a collection's Manage Items page + Given the draft "Sweater Penguins" in the collection "Various Penguins" + When I am logged in as the owner of "Various Penguins" + And I view the approved collection items page for "Various Penguins" + Then I should see "Sweater Penguins (Draft)" diff --git a/features/collections/collection_anonymity.feature b/features/collections/collection_anonymity.feature new file mode 100755 index 0000000..3068d45 --- /dev/null +++ b/features/collections/collection_anonymity.feature @@ -0,0 +1,625 @@ +@collections +Feature: Collection + In order to run some fanfic festivals + As a humble user + I want to create a collection with anonymity and hidden-until-reveal works + + Scenario: Works in a hidden collection should be visible to the mod and author but not other users + Given I have the hidden collection "Hidden Treasury" + When I am logged in as "first_user" + And I set up the draft "Old Snippet" in collection "Hidden Treasury" + And I press "Preview" + Then I should see "Collections: Hidden Treasury" + And I should see "Draft was successfully created." + When I press "Post" + Then the work "Old Snippet" should be visible to me + And I should see "part of an ongoing challenge" + When I am logged in as "moderator" + Then the work "Old Snippet" should be visible to me + And I should see "part of an ongoing challenge" + When I am logged in as "second_user" + Then the work "Old Snippet" should be hidden from me + When I am logged out + Then the work "Old Snippet" should be hidden from me + + Scenario: The moderator can reveal all the works in a hidden collection + Given I have the hidden collection "Hidden Treasury" + And "second_user" subscribes to author "first_user" + And the user "third_user" exists and is activated + And the user "third_user" allows gifts + And all emails have been delivered + When I am logged in as "first_user" + And I post the work "New Snippet" to the collection "Hidden Treasury" as a gift for "third_user" + And subscription notifications are sent + Then 0 emails should be delivered + When I reveal works for "Hidden Treasury" + Then "third_user" should be emailed + # not anonymous + And the email to "third_user" should contain "first_user" + When subscription notifications are sent + Then "second_user" should be emailed + And the email to "second_user" should contain "first_user" + When I am logged out + Then the work "New Snippet" should be visible to me + When I view the collection "Hidden Treasury" + Then I should see "New Snippet" + And I should not see "Mystery Work" + When I am logged in as "second_user" + Then the work "New Snippet" should be visible to me + When I view the collection "Hidden Treasury" + Then I should see "New Snippet" + And I should not see "Mystery Work" + + Scenario: The moderator can reveal a single work in a hidden collection + Given I have the hidden collection "Hidden Treasury" + And "second_user" subscribes to author "first_user" + And the user "third_user" exists and is activated + And the user "fourth_user" exists and is activated + And the user "third_user" allows gifts + And the user "fourth_user" allows gifts + And all emails have been delivered + When I am logged in as "first_user" + And I post the work "First Snippet" to the collection "Hidden Treasury" as a gift for "third_user" + # Delay before posting to make sure first work is clearly older + And it is currently 1 second from now + And I post the work "Second Snippet" to the collection "Hidden Treasury" as a gift for "fourth_user" + And subscription notifications are sent + Then 0 emails should be delivered + When I am logged in as "moderator" + And I view the approved collection items page for "Hidden Treasury" + # items listed in date order so checking the second will reveal the older work + And I uncheck the 2nd checkbox with id matching "collection_items_\d+_unrevealed" + And I submit + Then "fourth_user" should not be emailed + When "AO3-2240: gift notifications not sent for individual reveals" is fixed + # Then "third_user" should be emailed + # And the email to "third_user" should contain "first_user" + When subscription notifications are sent + Then "second_user" should be emailed + And 1 emails should be delivered + And the email to "second_user" should contain "first_user" + And the email to "second_user" should contain "First Snippet" + And the email to "second_user" should not contain "Second Snippet" + When I am logged out + Then the work "First Snippet" should be visible to me + And the work "Second Snippet" should be hidden from me + When I view the collection "Hidden Treasury" + Then I should see "First Snippet" + + Scenario: Bookmarks for hidden works should not reveal the work to others + Given I have the hidden collection "Hidden Treasury" + And I am logged in as "first_user" + And I post the work "Hiding Work" to the collection "Hidden Treasury" + When I am logged in as "moderator" + And I bookmark the work "Hiding Work" + When I am logged out + And I go to the bookmarks page + Then I should see "List of Bookmarks" + And I should see "Mystery Work" + And I should not see "Hiding Work" + When I reveal works for "Hidden Treasury" + And I am logged out + And I go to the bookmarks page + Then I should not see "Mystery Work" + And I should see "Hiding Work" + + Scenario: The authors in an anonymous collection should only be visible to themselves and admins + Given I have the anonymous collection "Anonymous Hugs" + And I am logged in as "first_user" + And I post the work "Old Snippet" to the collection "Anonymous Hugs" + When I view the work "Old Snippet" + Then the author of "Old Snippet" should be visible to me on the work page + When I am logged out + Then the author of "Old Snippet" should be hidden from me + When I am logged in as "second_user" + Then the author of "Old Snippet" should be hidden from me + When I am logged in as an admin + Then the author of "Old Snippet" should be visible to me on the work page + # special case for moderator: can't see name on the work (to avoid unwanted spoilers) + # but can see names + titles on in the collection items management area + When I am logged in as "moderator" + Then the author of "Old Snippet" should be hidden from me + When I view the approved collection items page for "Anonymous Hugs" + Then I should see "Old Snippet" + And I should see "first_user" + + Scenario: Bookmarks should not reveal the authors of anonymous works + Given I have the anonymous collection "Anonymous Hugs" + And I am logged in as "first_user" + And I post the work "Old Snippet" to the collection "Anonymous Hugs" + When I am logged in as "second_user" + And I bookmark the work "Old Snippet" + And I go to the bookmarks page + Then I should see "Old Snippet by Anonymous" + And I should not see "first_user" + + Scenario: The moderator can reveal all the authors in an anonymous collection + Given I have the anonymous collection "Anonymous Hugs" + And "second_user" subscribes to author "first_user" + And the user "third_user" exists and is activated + And the user "third_user" allows gifts + And all emails have been delivered + When I am logged in as "first_user" + And I post the work "Old Snippet" to the collection "Anonymous Hugs" as a gift for "third_user" + Then "third_user" should be emailed + And the email to "third_user" should not contain "first_user" + And the email to "third_user" should contain "Anonymous" + When subscription notifications are sent + Then "second_user" should not be emailed + When all emails have been delivered + And I am logged in as "moderator" + And I reveal authors for "Anonymous Hugs" + Then the author of "Old Snippet" should be publicly visible + When subscription notifications are sent + Then "second_user" should be emailed + And the email to "second_user" should contain "first_user" + And "third_user" should not be emailed + + Scenario: The moderator can reveal a single author in an anonymous collection + Given I have the anonymous collection "Anonymous Hugs" + And "second_user" subscribes to author "first_user" + And the user "third_user" exists and is activated + And the user "third_user" allows gifts + And I am logged in as "first_user" + And I post the work "First Snippet" to the collection "Anonymous Hugs" as a gift for "third_user" + # Delay before posting to make sure first work is clearly older + And it is currently 1 second from now + And I post the work "Second Snippet" to the collection "Anonymous Hugs" as a gift for "not a user" + When subscription notifications are sent + Then "second_user" should not be emailed + When I am logged in as "moderator" + And I view the approved collection items page for "Anonymous Hugs" + # items listed in date order so checking the second will reveal the older work + And I uncheck the 2nd checkbox with id matching "collection_items_\d+_anonymous" + # Delay before submitting to make sure the cache is expired + And it is currently 1 second from now + And I submit + Then the author of "First Snippet" should be publicly visible + When subscription notifications are sent + Then "second_user" should be emailed + And the email to "second_user" should contain "first_user" + And the email to "second_user" should contain "First Snippet" + And the email to "second_user" should not contain "Second Snippet" + When I am logged out + Then the author of "First Snippet" should be publicly visible + And the author of "Second Snippet" should be hidden from me + + Scenario: Works should not be visible in series if unrevealed + Given I have the hidden collection "Hidden Treasury" + And I am logged in as "first_user" + And I post the work "Before" + And I add the work "Before" to series "New series" + And I post the work "Hiding Work" to the collection "Hidden Treasury" + And I add the work "Hiding Work" to series "New series" + And I post the work "After" + And I add the work "After" to series "New series" + When "AO3-1250: series anonymity issues" is fixed + ### even the author should not see the work listed within the series + # Then the work "Hiding Work" should be part of the "New series" series in the database + # And the work "Hiding Work" should not be visible on the "New series" series page + # And the series "New series" should not be visible on the "Hiding Work" work page + # And the neighbors of "Hiding Work" in the "New series" series should link over it + When I am logged out + Then the work "Hiding Work" should be part of the "New series" series in the database + And the work "Hiding Work" should not be visible on the "New series" series page + And the series "New series" should not be visible on the "Hiding Work" work page + When "AO3-1250: series anonymity issues" is fixed + # And I should not see "Mystery Work" + # And the neighbors of "Hiding Work" in the "New series" series should link over it + When I reveal works for "Hidden Treasury" + And I am logged out + Then the work "Hiding Work" should be visible on the "New series" series page + And the series "New series" should be visible on the "Hiding Work" work page + And the neighbors of "Hiding Work" in the "New series" series should link to it + + Scenario: Works should not be visible in series if anonymous + Given I have the anonymous collection "Anon Treasury" + And I am logged in as "first_user" + And I post the work "Before" + And I add the work "Before" to series "New series" + And I post the work "Anon Work" to the collection "Anon Treasury" + And I add the work "Anon Work" to series "New series" + And I post the work "After" + And I add the work "After" to series "New series" + Then the work "Anon Work" should be part of the "New series" series in the database + When "AO3-1250: series anonymity fixes" is fixed + # even the author should not see the work in the series + # And the work "Anon Work" should not be visible on the "New series" series page + # And the series "New series" should not be visible on the "Anon Work" work page + # And the neighbors of "Anon Work" in the "New series" series should link over it + When I am logged out + Then the work "Anon Work" should be part of the "New series" series in the database + When "AO3-1250: series anonymity fixes" is fixed + # And the work "Anon Work" should not be visible on the "New series" series page + # And the series "New series" should not be visible on the "Anon Work" work page + # And the neighbors of "Anon Work" in the "New series" series should link over it + When I reveal authors for "Anon Treasury" + And I am logged out + Then the work "Anon Work" should be visible on the "New series" series page + And the series "New series" should be visible on the "Anon Work" work page + And the neighbors of "Anon Work" in the "New series" series should link to it + + Scenario: Adding a co-author to (one chapter of) an anonymous work should still keep it anonymous + Given I have the anonymous collection "Various Penguins" + And I am logged in as "Jessica" + And I post the chaptered work "Cone of Silence" in the collection "Various Penguins" + When I edit the work "Cone of Silence" + And I follow "2" within "div#main.works-edit.region" + And I invite the co-author "Amos" + And I press "Post" + And the user "Amos" accepts all co-creator requests + Then the author of "Cone of Silence" should be visible to me on the work page + When I am logged out + Then the author of "Cone of Silence" should be hidden from me + + Scenario: A work is in two anonymous collections, and one is revealed + Given I have the anonymous collection "Permanent Mice" + And I have the anonymous collection "Temporary Mice" + And I am logged in as "a_nonny_mouse" + And I post the work "Cheesy Goodness" + And I edit the work "Cheesy Goodness" to be in the collections "Permanent_Mice,Temporary_Mice" + And "eager_fan" subscribes to author "a_nonny_mouse" + + When I am logged in as "moderator" + And I reveal authors for "Temporary Mice" + And subscription notifications are sent + + Then "eager_fan" should not be emailed + + Scenario: A work is in two unrevealed collections, and one is revealed + Given I have the hidden collection "Super-Secret" + And I have the hidden collection "Secret for Now" + And I am logged in as "classified" + And I post the work "Top-Secret Goodness" + And I edit the work "Top-Secret Goodness" to be in the collections "Super-Secret,Secret_for_Now" + And "eager_fan" subscribes to author "classified" + + When I am logged in as "moderator" + And I reveal works for "Secret for Now" + And subscription notifications are sent + + Then "eager_fan" should not be emailed + + Scenario: A work is in one anonymous and one hidden collection, and the anonymous collection is revealed + Given I have the hidden collection "Triple-Secret" + And I have the anonymous collection "Cheese Enthusiasts" + And I am logged in as "classified" + And I post the work "Half and Half" + And I edit the work "Half and Half" to be in the collections "Triple-Secret,Cheese_Enthusiasts" + And "eager_fan" subscribes to author "classified" + + When I am logged in as "moderator" + And I reveal authors for "Cheese Enthusiasts" + And subscription notifications are sent + + Then "eager_fan" should not be emailed + + Scenario: A work is in one anonymous and one hidden collection, and the hidden collection is revealed + Given I have the hidden collection "Hidden Dreams" + And I have the anonymous collection "Anons Anonymous" + And I am logged in as "classified" + And I post the work "Half and Half" + And I edit the work "Half and Half" to be in the collections "Hidden_Dreams,Anons_Anonymous" + And "eager_fan" subscribes to author "classified" + + When I am logged in as "moderator" + And I reveal works for "Hidden Dreams" + And subscription notifications are sent + + Then "eager_fan" should not be emailed + + Scenario: Creating a new work then immediately editing to add it to an + anonymous collection should not trigger a subscriber email. + + Given I have the anonymous collection "Anon Forever" + And the following activated users exist + | login | password | email | + | mysterious | password | mysterious@foo.com | + | subscriber | password | subscriber@foo.com | + And "subscriber" subscribes to author "mysterious" + And all emails have been delivered + + When I am logged in as "mysterious" + And I post the work "Anonymous Gift" + And I edit the work "Anonymous Gift" to be in the collection "Anon_Forever" + And subscription notifications are sent + + Then 0 emails should be delivered + + Scenario: When a creator views their own anonymous work, they should see a message explaining that their comment will be anonymous, and their comment should be anonymous. + + Given I have the anonymous collection "Anon Forever" + And I am logged in as "shy_author" + And I post the work "Hidden Masterpiece" to the collection "Anon Forever" + + When I view the work "Hidden Masterpiece" + Then I should see "While this work is anonymous, comments you post will also be listed anonymously." + + When I post a comment "Reply from the author." + And I am logged out + And I view the work "Hidden Masterpiece" with comments + Then I should see "Reply from the author." + And I should see "Anonymous Creator" + And I should not see "shy_author" + + Scenario: When a creator adds a work to an anonymous collection and previews the change, it should save correctly + + Given I have the anonymous collection "Anonymous Collection" + And I am logged in as "creator" + And I post the work "My Work" + + When I edit the work "My Work" + And I fill in "Post to Collections / Challenges" with "anonymous_collection" + And I press "Preview" + + Then I should see "Anonymous Collection" + And I should see "Anonymous [creator]" + + When I press "Update" + + Then I should see "Anonymous Collection" + And I should see "Anonymous [creator]" + + Scenario: When a creator adds a work to an anonymous collection and previews the change, it should cancel correctly + + Given I have the anonymous collection "Anonymous Collection" + And I am logged in as "creator" + And I post the work "My Work" + + When I edit the work "My Work" + And I fill in "Post to Collections / Challenges" with "anonymous_collection" + And I press "Preview" + + Then I should see "Anonymous Collection" + And I should see "Anonymous [creator]" + + When I press "Cancel" + + Then I should see "The work was not updated." + + When I view the work "My Work" + + # This is not the desired behavior (AO3-5556), but we want to make sure it doesn't get broken worse + Then I should see "Anonymous Collection" + And I should see "Anonymous [creator]" + + Scenario: When an anonymous collection is deleted, works in the collection stop being anonymous. + Given I have an anonymous collection "Anonymous Collection" + And I am logged in as "creator" + And I post the work "Secret Work" to the collection "Anonymous Collection" + + When I go to creator's works page + Then I should not see "Secret Work" + + When I am logged in as the owner of "Anonymous Collection" + And I go to "Anonymous Collection" collection edit page + And I follow "Delete Collection" + # Delay before deleting to make sure the cache is expired + And it is currently 1 second from now + And I press "Yes, Delete Collection" + And I go to creator's works page + Then I should see "Secret Work" + + Scenario: When an unrevealed collection is deleted, works in the collection stop being unrevealed. + Given I have a hidden collection "Hidden Collection" + And I am logged in as "creator" + And I post the work "Secret Work" to the collection "Hidden Collection" + + When I am logged out + Then the work "Secret Work" should be hidden from me + + When I am logged in as the owner of "Hidden Collection" + And I go to "Hidden Collection" collection edit page + And I follow "Delete Collection" + And I press "Yes, Delete Collection" + And I am logged out + Then the work "Secret Work" should be visible to me + + Scenario: When the moderator removes a work from an anonymous collection, the creator is revealed. + Given I have an anonymous collection "Anonymous Collection" + And I am logged in as "creator" + And I post the work "Secret Work" to the collection "Anonymous Collection" + + When I go to creator's works page + Then I should not see "Secret Work" + + When I am logged in as the owner of "Anonymous Collection" + And I view the approved collection items page for "Anonymous Collection" + And I check "Remove" + # Delay before submitting to make sure the cache is expired + And it is currently 1 second from now + And I submit + And I go to creator's works page + Then I should see "Secret Work" + + Scenario: When the moderator removes a work from an unrevealed collection, the work is revealed. + Given I have a hidden collection "Hidden Collection" + And I am logged in as "creator" + And I post the work "Secret Work" to the collection "Hidden Collection" + + When I am logged out + Then the work "Secret Work" should be hidden from me + + When I am logged in as the owner of "Hidden Collection" + And I view the approved collection items page for "Hidden Collection" + And I check "Remove" + And I submit + And I am logged out + Then the work "Secret Work" should be visible to me + + Scenario: Moving a work with two collections from an anonymous collection to a non-anonymous collection should reveal the creator. + Given an anonymous collection "Anonymizing" + And a collection "Fluffy" + And a collection "Holidays" + + When I am logged in as "creator" + And I set up the draft "Secret Work" + And I fill in "Collections" with "Anonymizing,Fluffy" + And I press "Post" + And I go to creator's works page + Then I should not see "Secret Work" + + When I edit the work "Secret Work" + And I fill in "Collections" with "Holidays,Fluffy" + # Delay before posting to make sure the cache is expired + And it is currently 1 second from now + And I press "Post" + And I go to creator's works page + Then I should see "Secret Work" + + Scenario: Changing a collection item to anonymous triggers a notification + Given a collection "Changeable" + And I am logged in as "creator" + And I post the work "Lovely" in the collection "Changeable" + And all emails have been delivered + + When I am logged in as the owner of "Changeable" + And I go to "Changeable" collection edit page + And I check "This collection is anonymous" + And I press "Update" + And I view the approved collection items page for "Changeable" + And I check "Anonymous" + And I submit + Then "creator" should be emailed + And the email should have "Your work was made anonymous" in the subject + And the email should contain "Anonymous works are included in tag listings, but not on your works page." + And the email should not contain "translation missing" + + Scenario: Changing a collection item to unrevealed triggers a notification + Given a collection "Changeable" + And I am logged in as "creator" + And I post the work "Lovely" in the collection "Changeable" + And all emails have been delivered + + When I am logged in as the owner of "Changeable" + And I go to "Changeable" collection edit page + And I check "This collection is unrevealed" + And I press "Update" + And I view the approved collection items page for "Changeable" + And I check "Unrevealed" + And I submit + Then "creator" should be emailed + And the email should have "Your work was made unrevealed" in the subject + And the email should contain "Unrevealed works are not included in tag listings or on your works page." + And the email should not contain "translation missing" + + Scenario: Changing a collection item to anonymous and unrevealed triggers a notification + Given a collection "Changeable" + And I am logged in as "creator" + And I post the work "Lovely" in the collection "Changeable" + And all emails have been delivered + + When I am logged in as the owner of "Changeable" + And I go to "Changeable" collection edit page + And I check "This collection is anonymous" + And I check "This collection is unrevealed" + And I press "Update" + And I view the approved collection items page for "Changeable" + And I check "Anonymous" + And I check "Unrevealed" + And I submit + Then "creator" should be emailed + And the email should have "Your work was made anonymous and unrevealed" in the subject + And the email should contain "Unrevealed works are not included in tag listings or on your works page." + And the email should contain "The collection maintainers may later reveal your work but leave it anonymous." + And the email should not contain "translation missing" + + # We need to load the site skin to make the share modal work: + @javascript @load-default-skin + Scenario: Work share modal should not reveal anonymous authors + Given I have the anonymous collection "Anonymous Hugs" + When I am logged in as "first_user" + And I post the work "Old Snippet" to the collection "Anonymous Hugs" + When I am logged out + And I view the work "Old Snippet" + Then I should see "Share" + When I follow "Share" + Then I should see "by Anonymous" within "#modal textarea" + + Scenario: Work share button should not display for unrevealed works + Given I have the hidden collection "Hidden Treasury" + When I am logged in as "first_user" + And I post the work "Old Snippet" to the collection "Hidden Treasury" + Then the work "Old Snippet" should be visible to me + And I should not see "Share" + When I am logged in as "moderator" + Then the work "Old Snippet" should be visible to me + And I should not see "Share" + + Scenario: Works that are over the tag limit can be revealed + Given the user-defined tag limit is 2 + And I have the hidden collection "Hidden Gems" + And I am logged in as "creator" + And I post the work "Over the Limit" in the collection "Hidden Gems" + And the work "Over the Limit" has 3 fandom tags + When I reveal works for "Hidden Gems" + And I log out + And I view the work "Over the Limit" + Then I should see "Over the Limit" + + Scenario: Mystery blurb collections contain only unrevealed (approved or unmoderated) collections + Given I have the hidden moderated collection "Hidden Moderated Approved" + And I have the hidden moderated collection "Hidden Moderated Not Approved" + And I have the hidden collection "Just Hidden" + And I have the anonymous collection "Just Anonymous" + And I have the hidden anonymous collection "Hidden and Anonymous" + And I have the collection "Welcome" + And I am logged in as "author" + And I post the work "Work" + And I edit the work "Work" to be in the collections "Welcome,Hidden_Moderated_Not_Approved" + + When I am logged out + And I go to "Welcome" collection's page + Then I should see "Mystery Work" + And I should not see "Part of" + + When I am logged in as "author" + And I edit the work "Work" to be in the collections "Welcome,Hidden_Moderated_Not_Approved,Hidden_Moderated_Approved,Just_Hidden,Just_Anonymous,Hidden_And_Anonymous" + And I am logged in as "moderator" + And I approve the work "Work" in the collection "Hidden Moderated Approved" + And I submit + + When I am logged out + And I go to "Welcome" collection's page + Then I should see "Mystery Work" + And I should see "Part of Hidden Moderated Approved, Just Hidden, Hidden and Anonymous" + And I should not see "Hidden Moderated Not Approved" + And I should not see "Just Anonymous" + And I should not see "Welcome" within ".mystery" + + Scenario: Unrevealed work collection message mentions collections relevant to user + Given I have the hidden moderated collection "Hidden Moderated 1" + And I have the hidden moderated collection "Hidden Moderated 2" + And I am logged in as "author" + And I post the chaptered work "Work" + And I edit the work "Work" to be in the collections "Hidden_Moderated_1,Hidden_Moderated_2" + + When I view the work "Work" + Then I should see "You can find details here: Hidden Moderated 1, Hidden Moderated 2" + When I view the work "Work" in full mode + Then I should see "You can find details here: Hidden Moderated 1, Hidden Moderated 2" + + When I am logged out + And I view the work "Work" + Then I should not see "You can find details here" + When I go to the work "Work" in full mode + And I should not see "You can find details here" + + When I am logged in as "moderator" + And I approve the work "Work" in the collection "Hidden Moderated 1" + And I submit + + When I view the work "Work" + Then I should see "You can find details here: Hidden Moderated 1" + And I should not see "Hidden Moderated 2" + When I go to the work "Work" in full mode + Then I should see "You can find details here: Hidden Moderated 1" + And I should not see "Hidden Moderated 2" + + When I am logged out + And I view the work "Work" + Then I should see "You can find details here: Hidden Moderated 1" + And I should not see "Hidden Moderated 2" + When I go to the work "Work" in full mode + Then I should see "You can find details here: Hidden Moderated 1" + And I should not see "Hidden Moderated 2" diff --git a/features/collections/collection_browse.feature b/features/collections/collection_browse.feature new file mode 100755 index 0000000..7881dab --- /dev/null +++ b/features/collections/collection_browse.feature @@ -0,0 +1,181 @@ +@collections +Feature: Collection + In order to have an archive full of collections + As a humble user + I want to locate and browse an existing collection + + Scenario: Collections index should have different links for logged in and logged out users + + Given I am logged in as "onlooker" + When I go to the collections page + Then I should see "Open Challenges" + And I should see "New Collection" + When I log out + And I go to the collections page + Then I should see "Open Challenges" + And I should not see "New Collection" + + Scenario: Filter collections index to only show prompt memes + + Given a set of collections for searching + When I go to the collections page + And I choose "Prompt Meme Challenge" + And I press "Sort and Filter" + Then I should see "On Demand" + And I should not see "Some Test Collection" + And I should not see "Some Other Collection" + And I should not see "Another Plain Collection" + And I should not see "Surprise Presents" + And I should not see "Another Gift Swap" + + Scenario: Filter collections index to only show gift exchanges + + Given a set of collections for searching + When I go to the collections page + And I choose "Gift Exchange Challenge" + And I press "Sort and Filter" + Then I should see "Surprise Presents" + And I should see "Another Gift Swap" + And I should not see "On Demand" + And I should not see "Some Test Collection" + And I should not see "Some Other Collection" + And I should not see "Another Plain Collection" + + Scenario: Filter collections index to only show non-challenge collections + + Given a set of collections for searching + When I go to the collections page + And I choose "No Challenge" + And I press "Sort and Filter" + Then I should see "Some Test Collection" + And I should see "Some Other Collection" + And I should see "Another Plain Collection" + And I should not see "Surprise Presents" + And I should not see "Another Gift Swap" + And I should not see "On Demand" + + Scenario: Filter collections index to only show closed collections + + Given a set of collections for searching + When I go to the collections page + And I choose "collection_filters_closed_true" + And I press "Sort and Filter" + Then I should see "Another Plain Collection" + And I should see "On Demand" + And I should not see "Some Test Collection" + And I should not see "Some Other Collection" + And I should not see "Surprise Presents" + And I should not see "Another Gift Swap" + + Scenario: Filter collections index to only show open collections + + Given a set of collections for searching + When I go to the collections page + And I choose "collection_filters_closed_false" + And I press "Sort and Filter" + Then I should see "Some Test Collection" + And I should see "Some Other Collection" + And I should see "Surprise Presents" + And I should see "Another Gift Swap" + And I should not see "Another Plain Collection" + And I should not see "On Demand" + + Scenario: Filter collections index to only show moderated collections + + Given a set of collections for searching + When I go to the collections page + And I choose "collection_filters_moderated_true" + And I press "Sort and Filter" + Then I should see "Surprise Presents" + And I should not see "Some Test Collection" + And I should not see "Some Other Collection" + And I should not see "Another Plain Collection" + And I should not see "Another Gift Swap" + And I should not see "On Demand" + + Scenario: Filter collections index to only show unmoderated collections + + Given a set of collections for searching + When I go to the collections page + And I choose "collection_filters_moderated_false" + And I press "Sort and Filter" + Then I should see "Some Test Collection" + And I should see "Some Other Collection" + And I should see "Another Plain Collection" + And I should see "Another Gift Swap" + And I should see "On Demand" + And I should not see "Surprise Presents" + + Scenario: Filter collections index to show open, moderated gift exchanges + + Given a set of collections for searching + When I go to the collections page + And I choose "collection_filters_closed_false" + And I choose "collection_filters_moderated_true" + And I choose "Gift Exchange Challenge" + And I press "Sort and Filter" + Then I should see "Surprise Presents" + And I should not see "Some Test Collection" + And I should not see "Some Other Collection" + And I should not see "Another Plain Collection" + And I should not see "Another Gift Swap" + And I should not see "On Demand" + + Scenario: Filter collections index by fandom + + Given I have the collection "Collection1" + And I have the collection "Collection2" + And a fandom exists with name: "Steven's Universe", canonical: true + And I am logged in as a random user + And I post the work "Stronger than you" with fandom "Steven's Universe" in the collection "Collection1" + When I go to the collections page + And I fill in "collection_filters_fandom" with "Steven's Universe" + And I press "Sort and Filter" + Then I should see "Collection1" + And I should not see "Collection2" + + Scenario: Clear filters applied on collections + + Given a set of collections for searching + And I am logged in as a random user + When I go to the collections page + And I choose "Gift Exchange Challenge" + And I choose "collection_filters_closed_false" + And I choose "collection_filters_moderated_true" + And I press "Sort and Filter" + Then I should see "1 Collection" + And I should see "Surprise Presents" + When I follow "Clear Filters" + Then I should see "6 Collections" + And the "Gift Exchange Challenge" checkbox within "#collection-filters" should not be checked + And the "No" checkbox within "#collection-filters" should not be checked + And the "Yes" checkbox within "#collection-filters" should not be checked + + Scenario: Look at a collection, see the rules and intro and FAQ + + Given a set of collections for searching + And I am logged in as "testuser" with password "testuser" + When I go to the collections page + Then I should see "Collections in the " + And I should see "Some Test Collection" + When I follow "Some Test Collection" + Then I should see "Some Test Collection" + And I should see "There are no works or bookmarks in this collection yet." + When I follow "Profile" + Then I should see "Welcome to the test collection" within "#intro" + And I should see "What is this test thing?" within "#faq" + And I should see "It's a test collection" within "#faq" + And I should see "Be nice to testers" within "#rules" + And I should see "About Some Test Collection (sometest)" + + + Scenario: Work blurb includes an HTML comment containing the unix epoch of the updated time + + Given time is frozen at 2025-04-12 17:00 UTC + And I have the collection "Collection1" + And a fandom exists with name: "Steven's Universe", canonical: true + And I am logged in as a random user + And I post the work "Stronger than you" with fandom "Steven's Universe" in the collection "Collection1" + When I go to the collections page + And I follow "Collection1" + Then I should see an HTML comment containing the number 1744477200 within "li.work.blurb" diff --git a/features/collections/collection_create.feature b/features/collections/collection_create.feature new file mode 100755 index 0000000..4cc5ded --- /dev/null +++ b/features/collections/collection_create.feature @@ -0,0 +1,226 @@ +@collections +Feature: Collection + In order to have an archive full of collections + As a humble user + I want to create a collection and post to it + +Scenario: Create a collection + + Given I am logged in as "first_user" + When I go to the collections page + Then I should see "Collections in the " + And I should not see "My Collection Thing" + When I follow "New Collection" + And I fill in "Display title" with "My Collection Thing" + And I fill in "Collection name" with "collection_thing" + And I fill in "Introduction" with "Welcome to the collection" + And I fill in "FAQ" with "<dl><dt>What is this thing?</dt><dd>It's a collection</dd></dl>" + And I fill in "Rules" with "Be nice to people" + And I check all the collection settings checkboxes + And I submit + Then I should see "Collection was successfully created" + When I follow "Profile" + Then I should see "Welcome to the collection" within "#intro" + And I should see "What is this thing?" within "#faq" + And I should see "It's a collection" within "#faq" + And I should see "Be nice to people" within "#rules" + When I follow "Collection Settings" + And I fill in "Collection name" with " " + And I submit + And I should see "Please enter a name for your collection" + When I fill in "Collection name" with "collection_thing2" + And I submit + And I should see "Collection was successfully updated" + And the name of the collection "My Collection Thing" should be "collection_thing2" + +Scenario: Post to collection from the work edit page + Given the collection "My Collection Thing" with name "collection_thing" + And I am logged in as "first_user" + When I post the work "collect-y work" + And I go to first_user's user page + Then I should see "collect-y work" + When I edit the work "collect-y work" + And I fill in "work_collection_names" with "collection_thing" + And I press "Preview" + And I press "Update" + Then I should see "collect-y work" + And I should see "Collections: My Collection Thing" + +Scenario: Post to collection from the collection home page + + Given I have the collection "My Collection Thing" with name "collection_thing" + And basic tags + And I am logged in as "first_user" + When I go to the collections page + And I follow "My Collection Thing" + And I follow "Post to Collection" + Then I should see "Post New Work" + And I should see "collection_thing" in the "Post to Collections / Challenges" input + When I fill in the basic work information for "My Collected Work" + And I press "Preview" + Then I should see "My Collection Thing" within "dd.collections" + When I press "Post" + Then I should see "My Collected Work" + And I should see "Collections: My Collection Thing" + +Scenario: Create a subcollection + + Given I am logged in as "first_user" + And I create the collection "My Collection Thing" with name "collection_thing" + When I go to the collections page + And I follow "New Collection" + And I fill in "collection_parent_name" with "collection_thing" + And I fill in "Display title" with "My SubCollection" + And I fill in "Collection name" with "subcollection_thing" + And I submit + Then I should see "Collection was successfully created" + +Scenario: Fill out new collection form with faulty data + + Given I am logged in as a random user + And I am on the collections page + + When I follow "New Collection" + And I fill in the following: + | Collection name | faulty name | + | Display title | Awesome Collection | + | Collection email | fangirl@example.org | + | Brief description | My Description | + | Introduction | My Introduction | + | FAQ | My FAQ | + | Rules | My Rules | + | Assignment notification message | My Message | + | Gift notification message | My Other Message | + + And I check "This collection is closed" + And I select "Gift Exchange" from "Type of challenge, if any" + And I submit + + Then I should see a save error message + And I should see "faulty name" in the "Collection name" input + And I should see "Awesome Collection" in the "Display title" input + And I should see "fangirl@example.org" in the "Collection email" input + And I should see "My Description" in the "Brief description" input + And I should see "My Introduction" in the "Introduction" input + And I should see "My FAQ" in the "FAQ" input + And I should see "My Rules" in the "Rules" input + And I should see "My Message" in the "Assignment notification message" input + And I should see "My Other Message" in the "Gift notification message" input + And the "This collection is closed" checkbox should not be disabled + And "Gift Exchange" should be selected within "Type of challenge, if any" + +Scenario: Create a collection with a malformed header URL + +Given I have the collection "Scotts Collection" with name "scotts_collection" + And I am logged in as "moderator" + And I am on "Scotts Collection" collection's page + And I follow "Collection Settings" + And I fill in "collection_header_image_url" with "fc00.deviantart.net/fs13/f/2007/004/a/7/Flooded_by_bingeling.jpg" + And I press "Update" + And I should see "Collection was successfully updated" + + Scenario: Update a collection with a HTTPS header URL + + Given I have the collection "Scotts Collection" with name "scotts_collection" + When I am logged in as "moderator" + And I am on "Scotts Collection" collection's page + And I follow "Collection Settings" + And I fill in "Custom header URL" with "https://example.com/image.png" + And I press "Update" + Then I should see "Collection was successfully updated" + When I follow "Collection Settings" + Then I should see "https://example.com/image.png" in the "Custom header URL" input + + Scenario: Delete a subcollection and then its parent collection + + Given I am logged in as "collector" + And I create the collection "Temporary Top" with name "temporary_top_collection" + When I go to the collections page + And I follow "New Collection" + And I fill in "collection_parent_name" with "temporary_top_collection" + And I fill in "Display title" with "Temporary Subcollection" + And I fill in "Collection name" with "temporary_subcollection" + And I press "Submit" + Then I should see "Collection was successfully created" + When I follow "Collection Settings" + And I follow "Delete Collection" + And I press "Yes, Delete Collection" + Then I should see "Collection was successfully deleted." + And I should see "Temporary Top" + When I follow "Temporary Top" + And I follow "Collection Settings" + When I follow "Delete Collection" + And I press "Yes, Delete Collection" + Then I should see "Collection was successfully deleted." + And I should not see "Temporary Top" + + Scenario: Delete a collection that has subcollections + + Given I am logged in as "collector" + And I create the collection "Parent" with name "parent_collection" + When I go to the collections page + And I follow "New Collection" + And I fill in "collection_parent_name" with "parent_collection" + And I fill in "Display title" with "Child" + And I fill in "Collection name" with "child_collection" + And I press "Submit" + Then I should see "Collection was successfully created" + When I go to the collections page + And I follow "Parent" + And I follow "Collection Settings" + When I follow "Delete Collection" + And I press "Yes, Delete Collection" + Then I should see "Collection was successfully deleted." + And I should not see "Parent" + + Scenario: Moderator cannot list one collection's subcollection as another + collection's parent + + Given I am logged in as "collector" + And I add the subcollection "Subcollection" to the parent collection named "parent_collection" + When I go to the new collection page + And I fill in "Parent collection (that you maintain)" with "subcollection" + And I fill in "Display title" with "Sub-Subcollection" + And I fill in "Collection name" with "sub_subcollection" + And I press "Submit" + Then I should see "Sorry, but Subcollection is a subcollection, so it can't also be a parent collection." + + Scenario: Moderator cannot specify a parent collection that does not exist + + Given I am logged in + When I go to the new collection page + And I fill in "Parent collection (that you maintain)" with "nonexistent_collection" + And I fill in "Display title" with "Collection" + And I fill in "Collection name" with "Collection" + And I press "Submit" + Then I should see "We couldn't find a collection with name nonexistent_collection." + + Scenario: Moderator cannot make a collection its own parent + + Given I am logged in + And I create the collection "Collection" with name "collection" + When I go to "Collection" collection edit page + And I fill in "Parent collection (that you maintain)" with "collection" + And I press "Update" + Then I should see "You can't make a collection its own parent." + + Scenario: Moderator cannot list a parent collection they do not own + + Given I am logged in as "collector" + And I create the collection "Collection" with name "collection" + When I am logged in as "other_collector" + And I go to the new collection page + And I fill in "Display title" with "Other Collection" + And I fill in "Collection name" with "other_collection" + And I fill in "Parent collection (that you maintain)" with "collection" + And I press "Submit" + Then I should see "You have to be a maintainer of collection to make a subcollection." + + Scenario: Collection display title can't contain commas + + Given I am logged in + And I am on the new collection page + When I fill in "Display title" with "Hey, You" + And I fill in "Collection name" with "hey_you" + And I press "Submit" + Then I should see "Sorry, the ',' character cannot be in a collection Display Title." diff --git a/features/collections/collection_dashboard.feature b/features/collections/collection_dashboard.feature new file mode 100755 index 0000000..e2a844b --- /dev/null +++ b/features/collections/collection_dashboard.feature @@ -0,0 +1,81 @@ +@collections +Feature: Collection + In order to browse a collection + As a humble user + I want to see a collection dashboard + + Scenario: When a collection has more works or bookmarks than the maximum displayed on dashboards (5), the listbox for that type of item should contain a link to the collection's page for that type of item (e.g. Works (6) or Bookmarks (10)). + + Given I have a collection "Dashboard Light" with name "dashboard_light" + And I am logged in as "user" + When I post the work "Work 1" in the collection "Dashboard Light" + And I post the work "Work 2" in the collection "Dashboard Light" + And I post the work "Work 3" in the collection "Dashboard Light" + And I post the work "Work 4" in the collection "Dashboard Light" + And I post the work "Work 5" in the collection "Dashboard Light" + And I post the work "Work 6" in the collection "Dashboard Light" + When I go to "Dashboard Light" collection's page + Then I should see "Works (6)" within "#collection-works" + When I follow "Works (6)" within "#collection-works" + And I follow "Work 1" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "dashboard_light" + And I press "Create" + Then I should see "Bookmark was successfully created." + And I should see "Dashboard Light" + When I follow "Dashboard Light" + And I follow "Works (6)" + And I follow "Work 2" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "dashboard_light" + And I press "Create" + Then I should see "Bookmark was successfully created." + When I go to "Dashboard Light" collection's page + And I follow "Works (6)" + And I follow "Work 3" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "dashboard_light" + And I press "Create" + Then I should see "Bookmark was successfully created." + When I go to "Dashboard Light" collection's page + And I follow "Works (6)" + And I follow "Work 4" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "dashboard_light" + And I press "Create" + Then I should see "Bookmark was successfully created." + When I go to "Dashboard Light" collection's page + And I follow "Works (6)" + And I follow "Work 5" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "dashboard_light" + And I press "Create" + Then I should see "Bookmark was successfully created." + When I go to "Dashboard Light" collection's page + And I follow "Works (6)" + And I follow "Work 6" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "dashboard_light" + And I press "Create" + Then I should see "Bookmark was successfully created." + When I go to "Dashboard Light" collection's page + Then I should see "Dashboard Light" + And I should see "Recent bookmarks" + And I should see "Bookmarks (6)" within "#collection-bookmarks" + + Scenario: Given that I am on a collection's homepage the "Random Items" button should work + + Given I have a collection "Dashboard Light" with name "dashboard_light" + And I am logged in as "user" + When I post the work "Work 1" in the collection "Dashboard Light" + And I post the work "Work 2" in the collection "Dashboard Light" + And I post the work "Work 3" in the collection "Dashboard Light" + And I post the work "Work 4" in the collection "Dashboard Light" + And I post the work "Work 5" in the collection "Dashboard Light" + And I post the work "Work 6" in the collection "Dashboard Light" + When I go to "Dashboard Light" collection's page + Then I should see "Random Items" + + When I go to "Dashboard Light" collection's page + And I follow "Random Items" + Then I should see "Random works" \ No newline at end of file diff --git a/features/collections/collection_invite.feature b/features/collections/collection_invite.feature new file mode 100755 index 0000000..6ab377f --- /dev/null +++ b/features/collections/collection_invite.feature @@ -0,0 +1,107 @@ +@collection @works + +Feature: Collection + In order to have a collection full of curated works + As a collection maintainer + I want to add and invite works to my collection + + Scenario: Invite a work to a collection where a user approves inclusion + Given I am logged in as "Scott" with password "password" + And I set my preferences to allow collection invitations + And I post the work "Murder in Milan" with fandom "Murder She Wrote" + When I have the collection "scotts collection" with name "scotts_collection" + And I am logged in as "moderator" with password "password" + And I invite the work "Murder in Milan" to the collection "scotts collection" + Then I should see "This work has been invited to your collection (scotts collection)." + And 1 email should be delivered to "Scott" + When I go to "scotts collection" collection's page + Then I should see "Works (0)" + When I follow "Manage Items" + And I follow "Awaiting User Approval" + Then I should see "Murder in Milan" + And I should see /Works and bookmarks listed here have been invited to this collection. Once a work's creator has approved inclusion in this collection, the work will be moved to "Approved\."/ + When I am logged in as "Scott" with password "password" + And "Scott" accepts the invitation for their work in the collection "scotts collection" + And I press "Submit" + Then I should not see "Murder in Milan" + When I follow "Approved" + Then I should see "Murder in Milan" + When I am logged in as "moderator" + And I am on "scotts collection" collection's page + And I follow "Manage Items" + Then I should not see "Murder in Milan" + When I follow "Approved" + Then I should see "Murder in Milan" + + Scenario: Collection invitation emails are translated + Given I am logged in as "Scott" + And I set my preferences to allow collection invitations + And a locale with translated emails + And the user "Scott" enables translated emails + And the user "Friend" allows co-creators + When I coauthored the work "Murder in Milan" as "Scott" with "Friend" + And the user "Friend" accepts all co-creator requests + And all emails have been delivered + When I have the collection "scotts collection" with name "scotts_collection" + And I am logged in as "moderator" + And I invite the work "Murder in Milan" to the collection "scotts collection" + Then 1 email should be delivered to "Scott" + And the email to "Scott" should be translated + And the email should have "Request to include work in a collection" in the subject + And 1 email should be delivered to "Friend" + And the email to "Friend" should be non-translated + And the email should have "Request to include work in a collection" in the subject + + Scenario: Invite another's work to a anonymous collection should not be allowed. + Given I am logged in + And I set my preferences to allow collection invitations + And I post the work "A Death in Hong Kong" + When I have the hidden collection "anon collection" with name "anon_collection" + And I am logged in as "moderator" + And I invite the work "A Death in Hong Kong" to the collection "anon collection" + Then I should see "because you don't own this item and the collection is anonymous or unrevealed" + And 0 emails should be delivered + When I view the approved collection items page for "anon collection" + Then I should not see "A Death in Hong Kong" + + Scenario: Invite another's work to a hidden collection should not be allowed. + Given I am logged in + And I set my preferences to allow collection invitations + And I post the work "A Death in Hong Kong" + When I have the hidden collection "hidden collection" with name "hidden_collection" + And I am logged in as "moderator" + And I invite the work "A Death in Hong Kong" to the collection "hidden collection" + Then I should see "because you don't own this item and the collection is anonymous or unrevealed" + And 0 emails should be delivered + When I view the approved collection items page for "hidden collection" + Then I should not see "A Death in Hong Kong" + + Scenario: Invite another's work to a hidden anonymous collection should not be allowed. + Given I am logged in + And I set my preferences to allow collection invitations + And I post the work "A Death in Hong Kong" + When I have the hidden anonymous collection "anon hidden collection" with name "anon_hidden_collection" + And I am logged in as "moderator" + And I invite the work "A Death in Hong Kong" to the collection "anon hidden collection" + Then I should see "because you don't own this item and the collection is anonymous or unrevealed" + And 0 emails should be delivered + When I view the approved collection items page for "anon hidden collection" + Then I should not see "A Death in Hong Kong" + + Scenario: A work with too many tags can be invited to a collection, and the user can accept the invitation + Given the user-defined tag limit is 2 + And the collection "Favorites" + And the work "Over the Limit" by "sky" + And the work "Over the Limit" has 3 fandom tags + And I am logged in as "sky" + And I set my preferences to allow collection invitations + When I am logged in as "moderator" + And I invite the work "Over the Limit" to the collection "Favorites" + Then I should see "This work has been invited to your collection (Favorites)." + When I am logged in as "sky" + And "sky" accepts the invitation for their work in the collection "Favorites" + And I submit + Then I should see "Collection status updated!" + And I should not see "Over the Limit" + When I view the work "Over the Limit" + Then I should see "Favorites" diff --git a/features/collections/collection_navigation.feature b/features/collections/collection_navigation.feature new file mode 100755 index 0000000..9b54cd6 --- /dev/null +++ b/features/collections/collection_navigation.feature @@ -0,0 +1,138 @@ +@collections +Feature: Basic collection navigation + + @disable_caching + Scenario: Create a collection and check the links + When I am logged in as "mod" with password "password" + And I go to the collections page + And I follow "New Collection" + And I fill in "Collection name" with "my_collection" + And I fill in "Display title" with "My Collection" + And I submit + Then I should see "Collection was successfully created." + And I should see "Works (0)" + And I should see "Fandoms (0)" + Given basic tags + And I have a canonical "TV Shows" fandom tag named "New Fandom" + And a freeform exists with name: "Free", canonical: true + When I follow "New Work" within "ul.user.navigation.actions" + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I fill in "Fandoms" with "New Fandom" + And I fill in "Additional Tags" with "Free" + And I fill in "Work Title" with "Work for my collection" + And I select "English" from "Choose a language" + And I fill in "content" with "First because I'm the mod" + And I fill in "Post to Collections / Challenges" with "my_collection" + And I press "Preview" + And I press "Post" + And the collection counts have expired + And I follow "My Collection" + When I follow "Profile" + Then I should see "About My Collection (my_collection)" + And I should see "Maintainers: mod" + When I follow "Subcollections (0)" + Then I should see "Challenges/Subcollections in My Collection" + And I should see "Sorry, there were no collections found." + When I follow "Fandoms (1)" + Then I should see "New Fandom (1)" + When I follow "Works (1)" + Then I should see "Work for my collection by mod" + And I should see "1 Work in My Collection" + When I follow "Bookmarked Items" within "#dashboard" + Then I should see "0 Bookmarked Items" + When I follow "Random Items" + Then I should see "Work for my collection by mod" + When I follow "People" within "div#dashboard" + Then I should see "Participants in My Collection" + And I should see "mod" + When I follow "Tags" within "div#dashboard" + Then I should see "Free" + When I follow "Collection Settings" + Then I should see "Edit Collection" + When I am logged out + And I am on the collections page + And I follow "My Collection" + Then I should not see "Settings" + + Scenario: A Collection's Fandoms should be in alphabetical order + Given I have the collection "My ABCs" with name "my_abcs" + And a canonical fandom "A League of Their Own" + And a canonical fandom "Merlin" + And a canonical fandom "Teen Wolf" + And a canonical fandom "The Borgias" + When I am logged in as "Scott" with password "password" + And I post the work "Sesame Street" in the collection "My ABCs" + And I edit the work "Sesame Street" + And I fill in "Fandoms" with "A League of Their Own, Merlin, Teen Wolf, The Borgias" + And I press "Post" + And the collection counts have expired + And I go to "My ABCs" collection's page + And I follow "Fandoms (" + Then "The Borgias" should appear before "A League of Their Own" + And "A League of Their Own" should appear before "Merlin" + And "Merlin" should appear before "Teen Wolf" + + Scenario: Collections can be filtered by media type + Given I have the collection "We all sing together" + And I have a canonical "TV Shows" fandom tag named "Steven's Universe" + And I have a canonical "Movies" fandom tag named "High School Musical" + When I am logged in as "Brian" with password "They called him Brian" + And I post the work "Stronger than you" with fandom "Steven's Universe" in the collection "We all sing together" + And I post the work "Breaking Free" with fandom "High School Musical" in the collection "We all sing together" + And I go to "We all sing together" collection's page + And I follow "Fandoms (" + And I select "Movies" from "media_id" + And I press "Show" + Then I should see "High School Musical" + And I should not see "Steven's Universe" + When I select "TV Shows" from "media_id" + And I press "Show" + Then I should not see "High School Musical" + And I should see "Steven's Universe" + + Scenario: A collection's fandom count shouldn't include inherited metatags. + Given I have the collection "MCU Party" + And a canonical fandom "The Avengers" + And a canonical fandom "MCU" + And "MCU" is a metatag of the fandom "The Avengers" + And I am logged in as "mcu_fan" + And I post the work "Ensemble Piece" with fandom "The Avengers" in the collection "MCU Party" + And the collection counts have expired + + When I go to the collections page + Then I should see "Fandoms: 1" + + When I go to "MCU Party" collection's page + Then I should see "Fandoms (1)" + + Scenario: Browse tags within a collection (or not) + Given I have a collection "Randomness" + And a canonical fandom "Naruto" + And a canonical freeform "Crack" + And I am logged in + And I post the work "Has some tags" with fandom "Naruto" with freeform "Crack" in the collection "Randomness" + And the collection counts have expired + + # Tag links from the work blurb in a collection should not be collection-scoped + When I go to "Randomness" collection's page + And I follow "Naruto" within "#collection-works" + Then I should be on the works tagged "Naruto" + + # Tag links from the work meta in a collection should not be collection-scoped + When I go to "Randomness" collection's page + And I follow "Has some tags" + And I follow "Naruto" + Then I should be on the works tagged "Naruto" + + # Tag links from a collection's fandoms page should be collection-scoped + When I go to "Randomness" collection's page + And I follow "Fandoms (1)" + And I follow "Naruto" + Then I should be on the works tagged "Naruto" in collection "Randomness" + + # Tag links from a collection's tags page should be collection-scoped + When I go to "Randomness" collection's page + And I follow "Tags" within "#dashboard" + And I follow "Crack" + Then I should be on the works tagged "Crack" in collection "Randomness" diff --git a/features/collections/collection_notification.feature b/features/collections/collection_notification.feature new file mode 100755 index 0000000..b5863d4 --- /dev/null +++ b/features/collections/collection_notification.feature @@ -0,0 +1,144 @@ +@collections @works + +Feature: Collectible items email + As a moderator + I want to get notifications when items are added to my collection + + @disable_caching + Scenario: Work added to collection sends notification email + Given I am logged in as "first_user" + And all emails have been delivered + When I go to the collections page + When I follow "New Collection" + And I fill in "Display title" with "Antarctic Penguins" + And I fill in "Collection name" with "AntarcticPenguins" + And I fill in "Collection email" with "test@archiveofourown.org" + And I check the 1st checkbox with id matching "collection_collection_preference_attributes_email_notify" + And I submit + Then I should see "Collection was successfully created" + When I go to the collections page + When I follow "New Collection" + And I fill in "Display title" with "Polar Bears" + And I fill in "Collection name" with "PolarBears" + And I fill in "Collection email" with "test2@archiveofourown.org" + And I check the 1st checkbox with id matching "collection_collection_preference_attributes_email_notify" + And I submit + Then I should see "Collection was successfully created" + When I post the work "collect-y work" + And I go to first_user's user page + When I edit the work "collect-y work" + And I fill in "work_collection_names" with "AntarcticPenguins" + And I press "Preview" + Then I should see "Preview" + And I press "Update" + Then I should see "Work was successfully updated." + And I should see "collect-y work" + And I should see "Antarctic Penguins" + And 1 email should be delivered to test@archiveofourown.org + And all emails have been delivered + When I edit the work "collect-y work" + And I fill in "work_collection_names" with "AntarcticPenguins, PolarBears" + And I press "Preview" + Then I should see "Preview" + And I press "Update" + Then I should see "Work was successfully updated." + And I should see "collect-y work" + And I should see "Polar Bears" + And I should see "Antarctic Penguins" + And 1 email should be delivered to test2@archiveofourown.org + + Scenario: Bookmark added to collection sends notification email + Given all email have been delivered + When I have the collection "Dont Bookmark Me Bro" with name "dont_bookmark_me_bro" + And I am logged in as "moderator" + And I go to "Dont Bookmark Me Bro" collection's page + And I follow "Collection Settings" + And I fill in "Collection email" with "test@archiveofourown.org" + And I check "Send a message to the collection email when a work is added" + And I press "Update" + When I post the work "Excessive Force" + And I am logged in as "bookmarker" + And I view the work "Excessive Force" + And I follow "Bookmark" + And I fill in "bookmark_collection_names" with "dont_bookmark_me_bro" + And I press "Create" + Then 1 email should be delivered + + Scenario: Archivist adds work to collection + Given I am logged in as "regular_user" + And I post the work "Collection Work" + And a locale with translated emails + And the user "regular_user" enables translated emails + And I have an archivist "archivist" + When all emails have been delivered + And I am logged in as "archivist" + And I create the collection "Open Doors Collection" with name "open_doors_collection" + And I view the work "Collection Work" + And I follow "Add to Collections" + And I fill in "collection_names" with "open_doors_collection" + And I press "Add" + Then I should see "Added to collection(s): Open Doors Collection" + And 1 email should be delivered + And the email to "regular_user" should be translated + + Scenario: Translated email is sent when the status of a Collection item is changed to anonymous + Given a locale with translated emails + And the user "user1" exists and is activated + And the user "user1" enables translated emails + And all emails have been delivered + When I have the collection "Collection1" + And I am logged in as "user1" + And I post the work "Test work" in the collection "Collection1" + When I am logged in as the owner of "Collection1" + And I go to "Collection1" collection's page + And I follow "Collection Settings" + And I check the 1st checkbox with id matching "collection_collection_preference_attributes_anonymous" + And I press "Update" + When I view the approved collection items page for "Collection1" + And I check the 1st checkbox with id matching "collection_items_\d+_anonymous" + And I submit + Then "user1" should be emailed + And the email should have "Your work was made anonymous" in the subject + And the email to "user1" should be translated + + Scenario: Translated email is sent when the status of a Collection item is changed to unrevealed + Given a locale with translated emails + And the user "user1" exists and is activated + And the user "user1" enables translated emails + And all emails have been delivered + When I have the collection "Collection1" + And I am logged in as "user1" + And I post the work "Test work" in the collection "Collection1" + When I am logged in as the owner of "Collection1" + And I go to "Collection1" collection's page + And I follow "Collection Settings" + And I check the 1st checkbox with id matching "collection_collection_preference_attributes_unrevealed" + And I press "Update" + When I view the approved collection items page for "Collection1" + And I check the 1st checkbox with id matching "collection_items_\d+_unrevealed" + And I submit + Then "user1" should be emailed + And the email should have "Your work was made unrevealed" in the subject + And the email to "user1" should be translated + + Scenario: Translated email is sent when the status of a Collection item is changed to anonymous and unrevealed + Given a locale with translated emails + And the user "user1" exists and is activated + And the user "user1" enables translated emails + And all emails have been delivered + When I have the collection "Collection1" + And I am logged in as "user1" + And I post the work "Test work" in the collection "Collection1" + When I am logged in as the owner of "Collection1" + And I go to "Collection1" collection's page + And I follow "Collection Settings" + And I check the 1st checkbox with id matching "collection_collection_preference_attributes_unrevealed" + And I check the 1st checkbox with id matching "collection_collection_preference_attributes_anonymous" + And I press "Update" + When I view the approved collection items page for "Collection1" + And I check the 1st checkbox with id matching "collection_items_\d+_unrevealed" + And I check the 1st checkbox with id matching "collection_items_\d+_anonymous" + And I submit + Then "user1" should be emailed + And the email should have "Your work was made anonymous and unrevealed" in the subject + And the email to "user1" should be translated diff --git a/features/collections/collection_participants.feature b/features/collections/collection_participants.feature new file mode 100755 index 0000000..2af84d4 --- /dev/null +++ b/features/collections/collection_participants.feature @@ -0,0 +1,77 @@ +@collection + + Feature: Collection + + Scenario: A collection owner can't remove the owner from a collection + Given I have the collection "Such a nice collection" + And I am logged in as the owner of "Such a nice collection" + When I am on the "Such a nice collection" participants page + And I press "Remove" + Then I should see "You can't remove the only owner!" + + Scenario: A collection owner can invite, update, and remove a collection member + Given a user exists with login: "sam" + And I have the collection "Such a nice collection" + And I am logged in as the owner of "Such a nice collection" + When I am on the "Such a nice collection" participants page + And I fill in "participants_to_invite" with "sam" + And I press "Submit" + Then I should see "New members invited: sam" + When I select "Owner" from "sam_role" + And I submit with the 4th button + Then I should see "Updated sam." + When I click the 2nd button + Then I should see "Removed sam from collection." + + Scenario: Owner can't invite a nonexistent user to the collection + Given I have the collection "Such a nice collection" + And I am logged in as the owner of "Such a nice collection" + When I am on the "Such a nice collection" participants page + And I fill in "participants_to_invite" with "sam" + And I press "Submit" + Then I should see "We couldn't find anyone new by that name to add." + + Scenario: Collection owner can't invite a banned user to a collection + Given a user exists with login: "sam" + And user "sam" is banned + And I have the collection "Such a nice collection" + And I am logged in as the owner of "Such a nice collection" + When I am on the "Such a nice collection" participants page + And I fill in "participants_to_invite" with "sam" + And I press "Submit" + Then I should see "sam cannot participate in challenges." + + Scenario: A user can ask to join a closed collection + Given I have a moderated closed collection "Such a nice collection" + And I am logged in as "sam" + When I go to "Such a nice collection" collection's page + And I press "Join" + Then I should see "You have applied to join Such a nice collection" + + Scenario: A collection owner can preapprove a user to join a closed collection + Given I have a moderated closed collection "Such a nice collection" + And I am in sam's browser + And I am logged in as "sam" + When I go to "Such a nice collection" collection's page + When I am in the moderator's browser + And I am logged in as the owner of "Such a nice collection" + And I am on the "Such a nice collection" participants page + And I fill in "participants_to_invite" with "sam" + And I press "Submit" + Then I should see "New members invited: sam" + When I select "Invited" from "sam_role" + And I submit with the 4th button + Then I should see "Updated sam." + When I am in sam's browser + And I press "Join" + Then I should see "You are now a member of Such a nice collection" + When I am in the default browser + +Scenario: Collection member should see correct button text + Given I have the moderated collection "ModeratedCollection" + And I have the moderated collection "ModeratedCollectionTheSequel" + And I am logged in as "sam" + And I have joined the collection "ModeratedCollection" as "sam" + When I am on the collections page + Then I should see "Leave" exactly 1 time + And I should see "Join" exactly 1 time diff --git a/features/comments_and_kudos/add_comment.feature b/features/comments_and_kudos/add_comment.feature new file mode 100755 index 0000000..855270a --- /dev/null +++ b/features/comments_and_kudos/add_comment.feature @@ -0,0 +1,316 @@ +@comments +Feature: Comment on work + In order to give feedback + As a reader + I'd like to comment on a work + +Scenario: Comment links from downloads and static pages + + Given the work "Generic Work" + When I am logged in as "commenter" + And I visit the new comment page for the work "Generic Work" + Then I should see the comment form + +Scenario: When logged in I can comment on a work + + Given the work "The One Where Neal is Awesome" + When I am logged in as "commenter" + And I view the work "The One Where Neal is Awesome" + And I fill in "Comment" with "I loved this! 😍🤩" + And I press "Comment" + Then I should see "Comment created!" + And I should see "I loved this! 😍🤩" within ".odd" + + Scenario: When a one-shot work becomes multi-chapter, all previous comments say "on Chapter 1" + Given the work "The One Where Neal is Awesome" + And I am logged in as "commenter" + And I post the comment "I loved this! 😍🤩" on the work "The One Where Neal is Awesome" + When I view the work "The One Where Neal is Awesome" with comments + Then I should not see "commenter on Chapter 1" within "h4.heading.byline" + When a chapter is added to "The One Where Neal is Awesome" + And I view the work "The One Where Neal is Awesome" in full mode + And I follow "Comments (1)" + When "AO3-4214" is fixed + # Then I should see "commenter on Chapter 1" within "h4.heading.byline" + +Scenario: When commenting on a multi-chapter work, there should be a link to the chapter on the comment + + Given the work "The One Where Neal is Awesome" + And a chapter is added to "The One Where Neal is Awesome" + And I am logged in as "commenter" + And I post the comment "I loved this! 😍🤩" on the work "The One Where Neal is Awesome" + Then I should see "commenter on Chapter 1" + And I should see a link "Chapter 1" within ".comment h4.heading.byline" + And I should see a page link to the 1st chapter of the work "The One Where Neal is Awesome" within ".comment h4.heading.byline" + When I follow "Thread" + Then I should see a link "Chapter 1" within ".comment h4.heading.byline" + And I should see a page link to the 1st chapter of the work "The One Where Neal is Awesome" within ".comment h4.heading.byline" + +Scenario: When commenting on a single-chapter work, there should not be a link to the chapter on the comment + + Given the work "The One Where Neal is Awesome" + And I am logged in as "commenter" + And I post the comment "I loved this! 😍🤩" on the work "The One Where Neal is Awesome" + Then I should see "commenter" + And I should not see "commenter on Chapter 1" + And I should not see a link "Chapter 1" within ".comment h4.heading.byline" + And I should not see a page link to the 1st chapter of the work "The One Where Neal is Awesome" within ".comment h4.heading.byline" + When I follow "Thread" + Then I should not see a link "Chapter 1" within ".comment h4.heading.byline" + And I should not see a page link to the 1st chapter of the work "The One Where Neal is Awesome" within ".comment h4.heading.byline" + +Scenario: I cannot comment with a pseud that I don't own + + Given the work "Random Work" + When I attempt to comment on "Random Work" with a pseud that is not mine + Then I should not see "Comment created!" + And I should not see "on Chapter 1" + And I should see "You can't comment with that pseud" + +Scenario: I cannot edit in a pseud that I don't own + + Given the work "Random Work" + When I attempt to update a comment on "Random Work" with a pseud that is not mine + Then I should not see "Comment was successfully updated" + And I should see "You can't comment with that pseud" + +Scenario: Comment editing + + When I am logged in as "author" + And I post the work "The One Where Neal is Awesome" + When I am logged in as "commenter" + And I post the comment "Mistaken comment" on the work "The One Where Neal is Awesome" + And it is currently 1 second from now + And I follow "Edit" + And I fill in "Comment" with "Actually, I meant something different" + And I press "Update" + Then I should see "Comment was successfully updated" + And I should see "Actually, I meant something different" + And I should not see "Mistaken comment" + And I should see Last Edited in the right timezone + +Scenario: Comment threading, comment editing + + When I am logged in as "author" + And I post the work "The One Where Neal is Awesome" + When I am logged in as "commenter" + And I post the comment "I loved this!" on the work "The One Where Neal is Awesome" + When I follow "Reply" + And I fill in "Comment" with "I wanted to say more." within ".odd" + And I press "Comment" within ".odd" + Then I should see "Comment created!" + And I should see "I wanted to say more." within ".even" + When I am logged in as "commenter2" + And I view the work "The One Where Neal is Awesome" + And I fill in "Comment" with "I loved it, too." + And I press "Comment" + Then I should see "Comment created!" + And I should see "I loved it, too." + When I am logged in as "author" + And I view the work "The One Where Neal is Awesome" + And I follow "Comments (3)" + And I follow "Reply" within ".even" + And I fill in "Comment" with "Thank you." within ".even" + And I press "Comment" within ".even" + Then I should see "Comment created!" + And I should see "Thank you." within "ol.thread li ol.thread li ol.thread li" + When I am logged in as "commenter" + And I view the work "The One Where Neal is Awesome" + And I follow "Comments (4)" + And I follow "Reply" within ".thread .thread .odd" + And I fill in "Comment" with "Mistaken comment" within ".thread .thread .odd" + And I press "Comment" within ".thread .thread .odd" + And it is currently 1 second from now + And I follow "Edit" within "ol.thread li ol.thread li ol.thread li ol.thread ul.actions" + And I fill in "Comment" with "Actually, I meant something different" + And I press "Update" + Then I should see "Comment was successfully updated" + And I should see "Actually, I meant something different" + And I should not see "Mistaken comment" + And I should see Last Edited in the right timezone + When I am logged in as "commenter3" + And I view the work "The One Where Neal is Awesome" + And I follow "Comments (5)" + And I follow "Reply" within ".thread .even" + And I fill in "Comment" with "This should be nested" within ".thread .even" + And I press "Comment" within ".thread .even" + Then I should see "Comment created!" + And I should not see "Mistaken comment" + And I should see "Actually, I meant something different" within "ol.thread li ol.thread li ol.thread li ol.thread" + And I should see "I loved it, too." within "ol.thread" + And I should see "Thank you." within "ol.thread li ol.thread li ol.thread" + And I should see "This should be nested" within "ol.thread li ol.thread li ol.thread" + And I should not see "This should be nested" within ".thread .thread .thread .thread" + And I should see "I loved this" within "ol.thread" + + Scenario: A leaves a comment, B replies to it, A deletes their comment, B edits the comment, A should not receive a comment edit notification email + + Given the work "Generic Work" by "creator" + And a comment "A's comment (to be deleted)" by "User_A" on the work "Generic Work" + And a reply "B's comment (to be edited)" by "User_B" on the work "Generic Work" + And 1 email should be delivered to "User_A" + And all emails have been delivered + When I am logged in as "User_A" + And I view the work "Generic Work" with comments + And I delete the comment + When I am logged in as "User_B" + And I view the work "Generic Work" with comments + And I follow "Edit" + And I fill in "Comment" with "B's improved comment (edited)" + And I press "Update" + Then 0 emails should be delivered to "User_A" + + Scenario: Try to post an invalid comment + + When I am logged in as "author" + And I post the work "Generic Work" + When I am logged in as "commenter" + And I view the work "Generic Work" + And I compose an invalid comment + And I press "Comment" + Then I should see "must be less than" + And I should see "Now, we can devour the gods, together!" + When I fill in "Comment" with "This is a valid comment" + And I press "Comment" + And I follow "Reply" within ".thread .odd" + And I compose an invalid comment within ".thread .odd" + And I press "Comment" within ".thread .odd" + Then I should see "must be less than" + And I should see "Now, we can devour the gods, together!" + When I fill in "Comment" with "This is a valid reply comment" + And I press "Comment" + And it is currently 1 second from now + And I follow "Edit" + And I compose an invalid comment + And I press "Update" + Then I should see "must be less than" + And I should see "Now, we can devour the gods, together!" + +Scenario: Don't receive comment notifications of your own comments by default + + When I am logged in as "author" + And I post the work "Generic Work" + When I am logged in as "commenter" + And I post the comment "Something" on the work "Generic Work" + Then "author" should be emailed + And "commenter" should not be emailed + +Scenario: Set preference and receive comment notifications of your own comments + + When I am logged in as "author" + And I post the work "Generic Work" + When I am logged in as "commenter" + And I set my preferences to turn on copies of my own comments + And I post the comment "Something" on the work "Generic Work" + Then "author" should be emailed + And "commenter" should be emailed + And 1 email should be delivered to "commenter" + +Scenario: Try to post a comment with a < angle bracket before a linebreak, without a space before the bracket + + Given the work "Generic Work" + And I am logged in as "commenter" + And I view the work "Generic Work" + When I fill in "Comment" with + """ + Here is a comment with a bracket + abc< + xyz + """ + And I press "Comment" + Then I should see "Comment created!" + +Scenario: Try to post a comment with a < angle bracket before a linebreak, with a space before the bracket + + Given the work "Generic Work" + And I am logged in as "commenter" + And I view the work "Generic Work" + When I fill in "Comment" with + """ + Here is a comment with a bracket + abc < + xyz + """ + And I press "Comment" + Then I should see "Comment created!" + +Scenario: Users with different time zone preferences should see the time in their own timezone + Given the work "Generic Work" + And I am logged in as "commenter" + And the user "commenter" sets the time zone to "UTC" + And I post the comment "Something" on the work "Generic Work" + And it is currently 1 second from now + And I follow "Edit" + And I fill in "Comment" with "Something else" + And I press "Update" + Then I should see "UTC" within ".posted.datetime" + And I should see "UTC" within ".edited.datetime" + When I am logged in as "reader" + And the user "reader" sets the time zone to "Brisbane" + And I view the work "Generic Work" with comments + Then I should see "AEST" within ".posted.datetime" + And I should see "AEST" within ".edited.datetime" + +Scenario: It hides comment actions when a reply form is open + Given the work "The One Where Neal is Awesome" + And I am logged in as "commenter" + And I post the comment "I loved this!" on the work "The One Where Neal is Awesome" + When I follow "Reply" + Then I should see "Comment as commenter" + And I should not see "Thread" + +@javascript +Scenario: It shows and hides cancel buttons properly + Given the work "Aftermath" by "creator" with guest comments enabled + And a comment "Ugh." by "pest" on the work "Aftermath" + When I view the work "Aftermath" + And I display comments + Then I should see "Ugh." + When I open the reply box + Then I should see "Cancel" + But I should not see "Reply" + When I cancel the reply box + Then I should not see "Cancel" + But I should see "Reply" + +@javascript +Scenario: It shows and hides cancel buttons properly even on a new page +Given the work "Aftermath" by "creator" with guest comments enabled + And a comment "Ugh." by "pest" on the work "Aftermath" + When I view the work "Aftermath" + And I display comments + Then I should see "Ugh." + # Go to /chapters/XX?add_comment_reply_id=YY&show_comments=true#comment_YY"; akin to a Ctrl+Click on "Reply" + When I reply on a new page + Then I should see "Cancel" + But I should not see "Reply" + When I cancel the reply box + Then I should not see "Cancel" + But I should see "Reply" + +Scenario: Cannot comment (no form) while logged as admin + + Given the work "Generic Work" by "creator" with guest comments enabled + And I am logged in as an admin + And I view the work "Generic Work" + Then I should see "Generic Work" + And I should not see "Post Comment" + And I should not see a "Comment" button + And I should see "Please log out of your admin account to comment." + +Scenario: Cannot reply to comments (no button) while logged as admin + + Given the work "Generic Work" by "creator" with guest comments enabled + When I am logged in as "commenter" + And I view the work "Generic Work" + And I post a comment "Woohoo" + When I am logged in as an admin + And I view the work "Generic Work" + And I follow "Comments (1)" + Then I should see "Woohoo" + And I should not see "Reply" + When I am logged out + And I view the work "Generic Work" + And I follow "Comments (1)" + Then I should see "Woohoo" + And I should see "Reply" diff --git a/features/comments_and_kudos/admin_info.feature b/features/comments_and_kudos/admin_info.feature new file mode 100755 index 0000000..5caed5e --- /dev/null +++ b/features/comments_and_kudos/admin_info.feature @@ -0,0 +1,51 @@ +Feature: Some admins can see IP addresses and emails for comments + Scenario: Admin info for comments isn't visible to logged-out users + Given the work "Random Work" + And a guest comment on the work "Random Work" + When I am a visitor + And I view the work "Random Work" with comments + Then I should not see "IP Address:" within ".work.meta" + And I should not see "IP Address:" within ".comment.group" + And I should not see "Email:" within ".comment.group" + + Scenario: Admin info for comments isn't visible to the work's owner + Given the work "Random Work" + And a guest comment on the work "Random Work" + When I am logged in as the author of "Random Work" + And I view the work "Random Work" with comments + Then I should not see "IP Address:" within ".work.meta" + And I should not see "IP Address:" within ".comment.group" + And I should not see "Email:" within ".comment.group" + + Scenario Outline: Only certain admins can see IP addresses and email addresses for comments + Given the work "Random Work" + And a guest comment on the work "Random Work" + When I am logged in as a "<role>" admin + And I view the work "Random Work" with comments + Then I <should_ip> see "IP Address:" within ".work.meta" + And I <should_ip> see "IP Address:" within ".comment.group" + And I <should_email> see "Email:" within ".comment.group" + + Examples: + | role | should_ip | should_email | + | superadmin | should | should | + | legal | should | should | + | policy_and_abuse | should | should | + | support | should not | should | + | board | should not | should not | + | communications | should not | should not | + | docs | should not | should not | + | elections | should not | should not | + | open_doors | should not | should not | + | tag_wrangling | should not | should not | + | translation | should not | should not | + + Scenario: No one can see email addresses for comments by registered users + Given the work "Random Work" + And I am logged in as "commenter" + And I post the comment "Hello" on the work "Random Work" + When I am logged in as a "superadmin" admin + And I view the work "Random Work" with comments + Then I should see "IP Address:" within ".work.meta" + And I should see "IP Address:" within ".comment.group" + But I should not see "Email:" within ".comment.group" diff --git a/features/comments_and_kudos/comment_blocking.feature b/features/comments_and_kudos/comment_blocking.feature new file mode 100755 index 0000000..25bc30d --- /dev/null +++ b/features/comments_and_kudos/comment_blocking.feature @@ -0,0 +1,113 @@ +Feature: Comment Blocking + Scenario: Blocked users cannot comment on their blocker's works, or edit existing comments + Given the work "Aftermath" by "creator" + And a comment "Ugh." by "pest" on the work "Aftermath" + And the user "creator" has blocked the user "pest" + When I am logged in as "pest" + And I view the work "Aftermath" with comments + Then I should see "Sorry, you have been blocked by one or more of this work's creators." + And I should not see a "Comment" button + And I should not see a link "Edit" + + Scenario: Blocked users cannot reply to others on their blocker's works + Given the work "Aftermath" by "creator" + And a comment "OMG!" by "commenter" on the work "Aftermath" + And the user "creator" has blocked the user "pest" + When I am logged in as "pest" + And I view the work "Aftermath" with comments + Then I should not see a link "Reply" + + Scenario Outline: Blocked users cannot reply to their blocker + Given <commentable> + And a comment "OMG!" by "commenter" on <commentable> + And the user "commenter" has blocked the user "pest" + When I am logged in as "pest" + And I view <commentable> with comments + Then I should see a "Comment" button + But I should not see a link "Reply" + + Examples: + | commentable | + | the work "Aftermath" | + | the admin post "Change Log" | + + Scenario Outline: Blocked users cannot edit existing replies to their blocker + Given <commentable> + And a comment "OMG!" by "commenter" on <commentable> + And a reply "Ugh." by "pest" on <commentable> + And the user "commenter" has blocked the user "pest" + When I am logged in as "pest" + And I view <commentable> with comments + Then I should not see a link "Edit" + + Examples: + | commentable | + | the work "Aftermath" | + | the admin post "Change Log" | + + Scenario: Blocked users can reply to their blocker on tags + Given the following activated tag wranglers exist + | login | + | commenter | + | pest | + And a canonical fandom "Controversial" + And a comment "OMG!" by "commenter" on the tag "Controversial" + And the user "commenter" has blocked the user "pest" + When I am logged in as "pest" + And I view the tag "Controversial" with comments + And I follow "Reply" + And I fill in "Comment" with "Ugh." within ".odd" + And I press "Comment" within ".odd" + Then I should see "Comment created!" + + Scenario: Blocked users can delete their existing comments on their blocker's works + Given the work "Aftermath" by "creator" + And a comment "Ugh." by "pest" on the work "Aftermath" + And the user "creator" has blocked the user "pest" + When I am logged in as "pest" + And I view the work "Aftermath" with comments + And I follow "Delete" + And I follow "Yes, delete!" + Then I should see "Comment deleted." + + Scenario: Blocked users can comment on works shared with their blocker + Given the user "creator" has blocked the user "nemesis" + And the work "Aftermath" by "creator" and "nemesis" + When I am logged in as "nemesis" + And I view the work "Aftermath" + And I fill in "Comment" with "I can still do this." + And I press "Comment" + Then I should see "Comment created!" + + Scenario: Blocked users can't reply to their blocker on works shared with their blocker + Given the user "creator" has blocked the user "nemesis" + And the work "Aftermath" by "creator" and "nemesis" + And a comment "OMG!" by "creator" on the work "Aftermath" + When I am logged in as "nemesis" + And I view the work "Aftermath" with comments + Then I should not see a link "Reply" + + Scenario: When a user is blocked, they cannot reply to their blocker on the homepage or the inbox + Given the work "Aftermath" by "pest" + And a comment "OMG!" by "commenter" on the work "Aftermath" + And the user "commenter" has blocked the user "pest" + When I am logged in as "pest" + And I go to the homepage + Then I should see "OMG!" + But I should not see a link "Reply" + When I go to pest's inbox page + Then I should see "OMG!" + But I should not see a link "Reply" + + Scenario: When a user is blocked by the work creator, they cannot reply on the homepage or the inbox + Given the work "Aftermath" by "creator" + And a comment "Ugh." by "pest" on the work "Aftermath" + And a reply "OMG!" by "commenter" on the work "Aftermath" + And the user "creator" has blocked the user "pest" + When I am logged in as "pest" + And I go to the homepage + Then I should see "OMG!" + But I should not see a link "Reply" + When I go to pest's inbox page + Then I should see "OMG!" + But I should not see a link "Reply" diff --git a/features/comments_and_kudos/comment_moderation.feature b/features/comments_and_kudos/comment_moderation.feature new file mode 100755 index 0000000..969b0ea --- /dev/null +++ b/features/comments_and_kudos/comment_moderation.feature @@ -0,0 +1,331 @@ +@comments +Feature: Comment Moderation + In order to avoid spam and troll comments + As an author + I'd like to be able to moderate comments + + + Scenario: Turn off comments from anonymous users who can still leave kudos + Given I am logged in as "author" + And I set up the draft "No Anons" + And I choose "Only registered users can comment" + And I post the work without preview + And I am logged out + When I view the work "No Anons" + Then I should see "Sorry, this work doesn't allow non-Archive users to comment." + When I press "Kudos ♥" + Then I should see "Thank you for leaving kudos" + + Scenario: Turn off comments from everyone, but everyone can still leave kudos + Given I am logged in as "author" + And I set up the draft "No Comments" + And I choose "No one can comment" + And I post the work without preview + When I am logged out + And I view the work "No Comments" + Then I should see "Sorry, this work doesn't allow comments." + When I press "Kudos ♥" + Then I should see "Thank you for leaving kudos" + When I am logged in as "fan" + And I view the work "No Comments" + Then I should see "Sorry, this work doesn't allow comments." + When I press "Kudos ♥" + Then I should see "Thank you for leaving kudos" + + Scenario: Turn on moderation + Given I am logged in as "author" + And I set up the draft "Moderation" + And I check "Enable comment moderation" + And I post the work without preview + And I post a chapter for the work "Moderation" + Then comment moderation should be enabled on "Moderation" + When I am logged in as "commenter" + And I go to the work "Moderation" in full mode + Then I should see "This work's creator has chosen to moderate comments on the work. Your comment will not appear until it has been approved by the creator." + When I go to the 2nd chapter of the work "Moderation" + Then I should see "This work's creator has chosen to moderate comments on the work. Your comment will not appear until it has been approved by the creator." + + Scenario: Post a moderated comment + Given the moderated work "Moderation" by "author" + When I am logged in as "commenter" + And I post the comment "Fail comment" on the work "Moderation" + Then I should see "Your comment was received! It will appear publicly after the work creator has approved it." + And I should see "Edit" + And I should see "Delete" + And I should see "Fail comment" + And I should not see "by author" + And the comment on "Moderation" should be marked as unreviewed + And I should not see "Unreviewed Comments (1)" + And I should not see "Comments:1" + And "author" should be emailed + And the email to "author" should contain "will not appear until you approve" + And the email to "author" should contain "Review comments on" + And the email to "author" should not contain "Reply" + When I post the comment "another comment" on the work "Moderation" as a guest + Then I should see "will appear publicly after the work creator has approved" + And I should be on the "Moderation" work page + And I should not see "Comments:1" + And I should not see "Comments:2" + And I should not see "another comment" + And I should not see "Edit" + And I should not see "Delete" + + @disable_caching + Scenario: Edit a moderated comment + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Fail comment" on the work "Moderation" + And it is currently 1 second from now + When I follow "Edit" + And I fill in "Comment" with "Edited unfail comment" + And I press "Update" + Then I should see "Comment was successfully updated" + When I reload the comments on "Moderation" + And I am logged in as "author" + And I view the work "Moderation" + And I follow "Unreviewed Comments (1)" + Then I should see "Edited unfail comment" + + Scenario: Author comments do not need to be approved + Given the moderated work "Moderation" by "author" + When I am logged in as "author" + And I post the comment "Fail comment" on the work "Moderation" + Then I should not see "It will appear publicly after the work creator has approved it." + And the comment on "Moderation" should not be marked as unreviewed + And I should see "Comment created" + And I should not see "Unreviewed Comments (1)" + And I should see "Comments:1" + + Scenario: Moderated comments can be approved by the author + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Test comment" on the work "Moderation" + When I am logged in as "author" + And I view the work "Moderation" + Then I should see "Unreviewed Comments (1)" + And the comment on "Moderation" should be marked as unreviewed + When I follow "Unreviewed Comments (1)" + Then I should see "Test comment" + When I press "Approve" + Then I should see "Comment approved" + When I am logged out + And I view the work "Moderation" + Then I should see "Comments:1" + And I should see "Comments (1)" + When I follow "Comments (1)" + Then I should see "Test comment" + And the comment on "Moderation" should not be marked as unreviewed + + Scenario: Moderated comments can be approved from the inbox + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Test comment" on the work "Moderation" + When I am logged in as "author" + And I go to author's inbox page + Then I should see "Test comment" + And I should not see "Reply" + And I should see "Unreviewed" + # we can only test the non-javascript version here + When I follow "Unreviewed Comments" + And I press "Approve" + And I go to author's inbox page + Then I should see "Reply" + And I should not see "Unreviewed" + And I should not see "Unread" + When I view the work "Moderation" + Then I should see "Comments:1" + And I should see "Comments (1)" + And I should not see "Unreviewed Comments (1)" + + Scenario: Comments can be approved from the home page inbox + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Test comment" on the work "Moderation" + When I am logged in as "author" + And I go to the home page + Then I should see "Test comment" + And I should see "Unreviewed" + And I should not see "Reply" + # we can only test the non-javascript version here + When I follow "Unreviewed Comments" + And I press "Approve" + And I view the work "Moderation" + Then I should see "Comments:1" + And I should see "Comments (1)" + And I should not see "Unreviewed Comments (1)" + + Scenario: Moderated comments can be deleted by the author + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Test comment" on the work "Moderation" + When I am logged in as "author" + And I view the unreviewed comments page for "Moderation" + # The following won't work until deleting comments without javascript is fixed + # And I delete the comment + # Then I should see "Comment deleted" + # And I should not see "Test comment" + # And I should see "No unreviewed comments" + + Scenario: Moderation should work on threaded comments + Given the moderated work "Moderation" by "author" + And I am logged in as "author" + And I post the comment "Test comment" on the work "Moderation" + When I am logged in as "commenter" + And I view the work "Moderation" + And I follow "Comments (1)" + And I follow "Reply" within ".odd" + And I fill in "Comment" with "A moderated reply" within ".odd" + And I press "Comment" within ".odd" + Then I should see "It will appear publicly" + And I should see "A moderated reply" + And I should not see "Test comment" + When I am logged in as "author" + And I view the unreviewed comments page for "Moderation" + Then I should see "A moderated reply" + When I press "Approve" + Then I should see "Comment approved" + When I view the work "Moderation" + And I follow "Comments (2)" + Then I should see "A moderated reply" within ".even" + + Scenario: The author cannot reply to unapproved comments + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Test comment" on the work "Moderation" + When I am logged in as "author" + And I view the unreviewed comments page for "Moderation" + Then I should not see "Reply" + + Scenario: The commenter can edit their unapproved comment + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I set my preferences to turn on copies of my own comments + And I post the comment "Test comment" on the work "Moderation" + Then "commenter" should be emailed + And the email to "commenter" should contain "will not appear until approved" + When I visit the thread for the comment on "Moderation" + Then I should see "Test comment" + And I should see "Delete" + When I edit a comment + Then I should see "Comment was successfully updated" + + Scenario: Users should not see unapproved replies to their own comments + Given the moderated work "Moderation" by "author" with the approved comment "Test comment" by "commenter" + And I am logged in as "new_commenter" + And I set my preferences to turn on copies of my own comments + When I view the work "Moderation" + And I follow "Comments (1)" + And I follow "Reply" within ".odd" + And I fill in "Comment" with "A moderated reply" within ".odd" + And I press "Comment" within ".odd" + # emails should only be delivered to author and new_commenter + Then "author" should be emailed + And "new_commenter" should be emailed + And "commenter" should not be emailed + When all emails have been delivered + And I am logged in as "commenter" + And I set my preferences to turn on copies of my own comments + And I go to commenter's inbox page + Then I should not see "A moderated reply" + When I view the work "Moderation" + And I follow "Comments (1)" + Then I should see "Test comment" + And I should not see "A moderated reply" + When I am logged in as "author" + And I view the unreviewed comments page for "Moderation" + And I press "Approve" + Then "commenter" should be emailed + And "author" should not be emailed + And "new_commenter" should not be emailed + When I am logged in as "commenter" + And I go to commenter's inbox page + Then I should see "A moderated reply" + + Scenario: When I turn off moderation, comments stay unreviewed + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Interesting Comment" on the work "Moderation" + When I am logged in as "author" + And I edit the work "Moderation" + And I uncheck "Enable comment moderation" + And I post the work without preview + Then comment moderation should not be enabled on "Moderation" + When I view the work "Moderation" + Then I should see "Unreviewed Comments" + And I should not see "Comments:1" + When I go to author's inbox page + Then I should not see "Reply" + When I am logged in as "commenter" + And I view the work "Moderation" + Then I should not see "has chosen to moderate comments" + And I should not see "Interesting Comment" + When I post the comment "New Comment" on the work "Moderation" + And I view the work "Moderation" + Then I should see "Comments:1" + When I follow "Comments (1)" + Then I should see "New Comment" + And I should not see "Interesting Comment" + + Scenario: When an approved comment is edited significantly it gets moderated again + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "Interesting Comment" on the work "Moderation" + And I am logged in as "author" + And I view the unreviewed comments page for "Moderation" + And I press "Approve" + When it is currently 1 second from now + And I am logged in as "commenter" + And I view the work "Moderation" + And I follow "Comments (1)" + And I follow "Edit" + And I fill in "Comment" with "Interesting Commentary" + And I press "Update" + When I reload the comments on "Moderation" + And I view the work "Moderation" + Then I should see "Comments (1)" + When I follow "Comments (1)" + Then I should see "Interesting Commentary" + When it is currently 1 second from now + And I follow "Edit" + And I fill in "Comment" with "AHAHAHA LOOK I HAVE TOTALLY CHANGED IT" + And it is currently 1 second from now + And I press "Update" + Then the comment on "Moderation" should be marked as unreviewed + And I should not see "Comments:" + And I should not see "Comments (1)" + + Scenario: I can approve multiple comments at once + Given the moderated work "Moderation" by "author" + And I am logged in as "commenter" + And I post the comment "One Comment" on the work "Moderation" + And I post the comment "Two Comment" on the work "Moderation" + And I post the comment "Three Comment" on the work "Moderation" + And I post the comment "Four Comment" on the work "Moderation" + When I am logged in as "author" + And I view the unreviewed comments page for "Moderation" + And I press "Approve All" + Then I should see "All moderated comments approved." + When I view the work "Moderation" + Then I should see "Comments (4)" + + Scenario: I can view the parent thread of an unreviewed comment + Given the moderated work "Moderation" by "author" with the approved comment "Test comment" by "commenter" + And I am logged in as "new_commenter" + When I view the work "Moderation" + And I follow "Comments (1)" + And I follow "Reply" within ".odd" + And I fill in "Comment" with "A moderated reply" within ".odd" + And I press "Comment" within ".odd" + When I am logged in as "author" + And I view the work "Moderation" + And I follow "Unreviewed Comments (1)" + And I follow "Parent Thread" + Then I should see "Test comment" + When I view the unreviewed comments page for "Moderation" + And I press "Approve" + When I am logged in as "new_commenter" + And I post the comment "Zero-depth comment" on the work "Moderation" + When I am logged in as "author" + And I view the work "Moderation" + And I follow "Unreviewed Comments (1)" + Then I should not see "Parent Thread" diff --git a/features/comments_and_kudos/comments_adminposts.feature b/features/comments_and_kudos/comments_adminposts.feature new file mode 100755 index 0000000..1cf460f --- /dev/null +++ b/features/comments_and_kudos/comments_adminposts.feature @@ -0,0 +1,142 @@ +@comments +Feature: Commenting on admin posts + As a user + I want to comment on admin posts + In order to communicate with admins and other users + + Scenario: Random user comments on an admin post + Given I have posted an admin post + And I am logged in as "regular" + And all emails have been delivered + When I comment on an admin post + Then "regular" should not be emailed + + Scenario: A user who receives copies of their own comments comments on an admin post + Given I have posted an admin post + And I am logged in as "narcis" + And I set my preferences to turn on copies of my own comments + And all emails have been delivered + When I comment on an admin post + Then 1 email should be delivered to "narcis" + + Scenario: Random user edits a comment on an admin post + Given I have posted an admin post + And I am logged in as "regular" + And I comment on an admin post + And all emails have been delivered + When I edit a comment + Then "regular" should not be emailed + + Scenario: A user who receives copies of their own comments edits a comment on an admin post + Given I have posted an admin post + And I am logged in as "narcis" + And I set my preferences to turn on copies of my own comments + And I comment on an admin post + And all emails have been delivered + When I edit a comment + Then 1 email should be delivered to "narcis" + + Scenario: Admin post with comments disabled + Given I have posted an admin post + And I am logged in as a "communications" admin + When I go to the admin-posts page + And I follow "Edit" + Then I should see "Who can comment on this" + And I should see "No one can comment" + When I choose "No one can comment" + And I press "Post" + Then I should see "successfully updated" + When I follow "Edit Post" + Then the "No one can comment" radio button should be checked + When I am logged out + And I go to the admin-posts page + And I follow "Default Admin Post" + Then I should see "Sorry, this news post doesn't allow comments." + When I am logged in as "regular" + And I go to the admin-posts page + And I follow "Default Admin Post" + Then I should see "Sorry, this news post doesn't allow comments." + + Scenario: Admin post with comments restricted to Archive users + Given I have posted an admin post + And I am logged in as a "communications" admin + When I go to the admin-posts page + And I follow "Edit" + Then I should see "Who can comment on this" + And I should see "Only registered users can comment" + When I choose "Only registered users can comment" + And I press "Post" + Then I should see "successfully updated" + When I follow "Edit Post" + Then the "Only registered users can comment" radio button should be checked + When I am logged out + And I go to the admin-posts page + And I follow "Default Admin Post" + Then I should see "Sorry, this news post doesn't allow non-Archive users to comment." + And I should see "You can however contact Support with any feedback or questions." + When I follow "contact Support" + Then I should be on the support page + When I am logged in as "regular" + And I go to the admin-posts page + And I follow "Default Admin Post" + And I fill in "comment[comment_content]" with "zug zug" + And I press "Comment" + Then I should see "Comment created!" + And I should see "zug zug" + + Scenario: Admin post with all comments enabled + Given I have posted an admin post + And I am logged in as a "communications" admin + When I go to the admin-posts page + And I follow "Edit" + Then I should see "Who can comment on this" + And I should see "Registered users and guests can comment" + When I choose "Registered users and guests can comment" + And I press "Post" + Then I should see "successfully updated" + When I follow "Edit Post" + Then the "Registered users and guests can comment" radio button should be checked + When I am logged out + And I go to the admin-posts page + And I follow "Default Admin Post" + And I fill in "comment[name]" with "tester" + And I fill in "comment[email]" with "tester@example.com" + And I fill in "comment[comment_content]" with "guz guz" + And I press "Comment" + Then I should see "Comment created!" + And I should see "guz guz" + When I am logged in as "regular" + And I go to the admin-posts page + And I follow "Default Admin Post" + And I fill in "comment[comment_content]" with "zug zug" + And I press "Comment" + Then I should see "Comment created!" + And I should see "zug zug" + + Scenario: Modifying the comment permissions of an admin post with translations + Given I have posted an admin post + And basic languages + And I am logged in as a "translation" admin + And I make a translation of an admin post + When I follow "Back to AO3 News Index" + And I follow "Show" + Then I should see "Sorry, this news post doesn't allow non-Archive users to comment." + When I follow "Deutsch" + Then I should see "Sorry, this news post doesn't allow non-Archive users to comment." + When I follow "Back to AO3 News Index" + And I follow "Edit" + And I choose "Registered users and guests can comment" + And I press "Post" + Then I should see "Please log out of your admin account to comment." + When I follow "Deutsch" + Then I should see "Please log out of your admin account to comment." + + Scenario: Translation of admin post with comments disabled + Given I have posted an admin post with comments disabled + And basic languages + And I am logged in as a "translation" admin + When I make a translation of an admin post + Then I should see "Sorry, this news post doesn't allow comments." + When I follow "Edit Post" + Then I should see "No one can comment" + # TODO: Test that the other options aren't available/selected in a non-brittle way diff --git a/features/comments_and_kudos/comments_delete.feature b/features/comments_and_kudos/comments_delete.feature new file mode 100755 index 0000000..bfd1a22 --- /dev/null +++ b/features/comments_and_kudos/comments_delete.feature @@ -0,0 +1,96 @@ +@comments +Feature: Delete a comment + In order to remove a comment from public view + As a user + I want to be able to delete a comment I added + As an author + I want to be able to delete a comment a reader added to my work + + Scenario: User deletes a comment they added to a work + When I am logged in as "author" + And I post the work "Awesome story" + When I am logged in as "commenter" + And I post the comment "Fail comment" on the work "Awesome story" + And I delete the comment + Then I should see "Comment deleted." + And I should not see "Comments:" + And I should not see a link "Hide Comments (1)" + + Scenario: User deletes a comment they added to a work and which is the parent of another comment + When I am logged in as "author" + And I post the work "Awesome story" + When I am logged in as "commenter1" + And I post the comment "Fail comment" on the work "Awesome story" + And I reply to a comment with "I didn't mean that" + And I delete the comment + Then I should see "Comment deleted." + And I should see "(Previous comment deleted.)" + And I should see "I didn't mean that" + And I should see "Comments:1" + And I should see a link "Hide Comments (1)" + + Scenario: Author deletes a comment another user added to their work + When I am logged in as "author" + And I post the work "Awesome story" + When I am logged in as "commenter" + And I post the comment "Fail comment" on the work "Awesome story" + When I am logged in as "author" + And I view the work "Awesome story" with comments + And I delete the comment + Then I should see "Comment deleted." + And I should not see "Comments:" + And I should not see a link "Hide Comments (1)" + + Scenario: Author deletes a parent comment that another user added to their work + When I am logged in as "author" + And I post the work "Awesome story" + When I am logged in as "commenter" + And I post the comment "Fail comment" on the work "Awesome story" + And I reply to a comment with "I didn't mean that" + When I am logged in as "author" + And I view the work "Awesome story" with comments + And I delete the comment + Then I should see "Comment deleted." + And I should see "(Previous comment deleted.)" + And I should see "I didn't mean that" + And I should see "Comments:1" + And I should see a link "Hide Comments (1)" + + Scenario: Deleting higher-level comments in a deep comment thread should still allow readers to access the deeper comments. + + Given the work "Testing" + And I am logged in as "commenter" + + When "commenter" posts a deeply nested comment thread on "Testing" + And I view the work "Testing" with comments + Then I should see "(2 more comments in this thread)" + And I should not see the deeply nested comments + + When I delete all visible comments on "Testing" + And I view the work "Testing" with comments + Then I should see "(Previous comment deleted.)" + And I should see "(2 more comments in this thread)" + And I should not see the deeply nested comments + + When I follow "2 more comments in this thread" + Then I should see the deeply nested comments + + Scenario: Deleting a comment followed by its reply should hide the deleted comment placeholder. + + Given the work "Amazing Story" + And I am logged in as "commenter" + And I post the comment "I love it!" on the work "Amazing Story" + And I reply to a comment with "Is there going to be a sequel?" + When I delete the comment + And I delete the reply comment + Then I should not see "(Previous comment deleted.)" + + Scenario: Deleting a reply comment followed by its parent should hide the deleted comment placeholder. + + Given the work "Amazing Story" + And I am logged in as "commenter" + And I post the comment "I love it!" on the work "Amazing Story" + And I reply to a comment with "Is there going to be a sequel?" + When I delete the reply comment + And I delete the comment + Then I should not see "(Previous comment deleted.)" diff --git a/features/comments_and_kudos/comments_pagination.feature b/features/comments_and_kudos/comments_pagination.feature new file mode 100755 index 0000000..25879a6 --- /dev/null +++ b/features/comments_and_kudos/comments_pagination.feature @@ -0,0 +1,36 @@ +@comments +Feature: Comments should be paginated + +Scenario: One-chapter work with many comments + Given the work with 34 comments setup + When I view the work "Blabla" + And I follow "Comments" + Then I should see "2" within ".pagination" + When I follow "Next" within ".pagination" + Then I should see "1" within ".pagination" + +Scenario: Multi-chapter work with many comments per chapter + + Given the chaptered work with 6 chapters with 50 comments "Epic WIP" + When I view the work "Epic WIP" + Then I should see "Comments (50)" + When I follow "Comments" + Then I should see "2" within ".pagination" + And I should not see "3" within ".pagination" + When I follow "Next" within ".pagination" + Then I should see "1" within ".pagination" + # All those comments were on the first chapter. Now put some more on + When I am logged in + And I view the work "Epic WIP" + And I view the 3rd chapter + And I post a comment "The third chapter is especially good." + And I post a comment "I loved the cliffhanger in chapter 3" + Then I should see "Comments (2)" + # Going to the work shows first chapter and only those comments + When I view the work "Epic WIP" + Then I should see "Comments (50)" + # Entire work shows all comments + When I follow "Entire Work" + Then I should see "Comments (52)" + When I follow "Comments (52)" + Then I should see "3" within ".pagination" diff --git a/features/comments_and_kudos/comments_redirect.feature b/features/comments_and_kudos/comments_redirect.feature new file mode 100755 index 0000000..ec20253 --- /dev/null +++ b/features/comments_and_kudos/comments_redirect.feature @@ -0,0 +1,119 @@ +@comments +Feature: Posting a comment should result in a friendly redirect + +# TOP LEVEL COMMENTS + +Scenario: Posting a top level comment on a one-chapter work + Given I have a work "Blabla" + And I am logged in as a random user + When I view the work "Blabla" + And I post a comment "blaaaaaa" + Then I should see "Blabla" + And I should see "blaaaaaa" + +Scenario: Posting top level comment on middle chapter of chaptered work, with default preferences + Given the chaptered work setup + And I am logged in as a random user + When I view the work "BigBang" + And I view the 2nd chapter + And I post a comment "Woohoo" + Then I should see "Woohoo" + And I should see "Chapter 2" within "div#chapters" + And I should not see "Chapter 1" within "div#chapters" + +Scenario: Posting top level comment on a chaptered work, while in temporary view full mode, with default preferences + Given the chaptered work setup + And I am logged in as a random user + When I view the work "BigBang" in full mode + And I post a comment "Woohoo" + Then I should see "Woohoo" + And I should see "Chapter 2" within "div#chapters" + And I should see "Chapter 3" within "div#chapters" + +Scenario: Posting top level comment on a chaptered work, with view full work in the preferences + Given the chaptered work setup + And I am logged in as a random user + And I set my preferences to View Full Work mode by default + When I view the work "BigBang" + And I post a comment "Woohoo" + Then I should see "Woohoo" + And I should see "Chapter 2" within "div#chapters" + And I should see "Chapter 3" within "div#chapters" + + Scenario: Posting top level comment on a middle chapter, while in temporary view by chapter mode, with view full work in the preferences + Given the chaptered work setup + And I am logged in as a random user + And I set my preferences to View Full Work mode by default + When I view the work "BigBang" in chapter-by-chapter mode + And I view the 2nd chapter + And I post a comment "Woohoo" + Then I should see "Woohoo" + And I should see "Chapter 2" within "div#chapters" + # Once you've commented, it defaults back to your preference + And I should see "Chapter 1" within "div#chapters" + +# REPLY COMMENTS + +Scenario: Posting a reply comment to a comment on a one-chapter work + Given the work with comments setup + And I am logged in as a random user + And I view the work "Blabla" + And I follow "Comments" + When I reply to a comment with "Supercalifragelistic" + Then I should see "Supercalifragelistic" + +Scenario: Posting a reply comment to a comment on the first chapter, with default preferences + Given the chaptered work with comments setup + And I am logged in as a random user + And I view the work "BigBang" + And I view the 1st chapter + And I follow "Comments" + When I reply to a comment with "Supercalifragelistic" + Then I should see "Supercalifragelistic" + +Scenario: Posting a reply comment to a comment on a middle chapter, with default preferences + Given the chaptered work with comments setup + And I am logged in as a random user + And I view the work "BigBang" + And I view the 2nd chapter + And I follow "Comments" + When I reply to a comment with "Supercalifragelistic" + Then I should see "Supercalifragelistic" + And I should see "Chapter 2" within "div#chapters" + And I should not see "Chapter 1" within "div#chapters" + +Scenario: Posting reply comment on a chaptered work, while in temporary view full mode, with default preferences + Given the chaptered work with comments setup + And I am logged in as a random user + And I view the work "BigBang" in full mode + And I follow "Comments" + Then I should see "Chapter 2" within "div#chapters" + When I reply to a comment with "Supercalifragelistic" + Then I should see "Supercalifragelistic" + And I should see "Chapter 2" within "div#chapters" + And I should see "Chapter 3" within "div#chapters" + +Scenario: Posting reply comment on a chaptered work, with view full work in the preferences + Given the chaptered work with comments setup + And I am logged in as a random user + And I set my preferences to View Full Work mode by default + And I view the work "BigBang" + And I follow "Comments" + When I reply to a comment with "Supercalifragelistic" + Then I should see "Supercalifragelistic" + And I should see "Chapter 2" within "div#chapters" + And I should see "Chapter 3" within "div#chapters" + +Scenario: Posting top level comment on a middle chapter, while in temporary view by chapter mode, with view full work in the preferences + Given the chaptered work with comments setup + And I am logged in as a random user + And I set my preferences to View Full Work mode by default + And I view the work "BigBang" in chapter-by-chapter mode + And I view the 2nd chapter + # this opens comments on that chapter only + And I follow "Comments" + When I reply to a comment with "Supercalifragelistic" + Then I should see "Supercalifragelistic" + And I should see "Chapter 2" within "div#chapters" + # Once you've commented, it defaults back to your preference + And I should see "Chapter 1" within "div#chapters" diff --git a/features/comments_and_kudos/frozen_comments.feature b/features/comments_and_kudos/frozen_comments.feature new file mode 100755 index 0000000..bf4fe9e --- /dev/null +++ b/features/comments_and_kudos/frozen_comments.feature @@ -0,0 +1,47 @@ +@comments +Feature: Comment freezing + + Scenario: Freezing a comment removes the reply option and adds an indicator + the comment is frozen. Unfreezing returns the reply option and removes the + indicator. This behavior is present on the comment itself, the inbox, and the + inbox module on the homepage. + + Given I am logged in as "author" + And I post the work "Popular Fic" + And I am logged out + And I am logged in as "commenter" + And I post the comment "My test comment!" on the work "Popular Fic" + And I am logged out + + When I am logged in as "author" + And I view the work "Popular Fic" with comments + And I press "Freeze Thread" + Then I should see "Comment thread successfully frozen!" + And I should see "Frozen" within "#comments_placeholder .comment ul.actions" + And I should not see "Reply" within "#comments_placeholder .comment ul.actions" + + When I go to the homepage + Then I should see "My test comment!" within "div.messages .comment" + And I should see "Frozen" within "div.messages .comment ul.actions" + And I should not see "Reply" within "div.messages .comment ul.actions" + + When I go to author's inbox page + Then I should see "My test comment!" within "#inbox-form .comment" + And I should see "Frozen" within "#inbox-form .comment ul.actions" + And I should not see "Reply" within "#inbox-form .comment ul.actions" + + When I view the work "Popular Fic" with comments + And I press "Unfreeze Thread" + Then I should see "Comment thread successfully unfrozen!" + And I should see "Reply" within "#comments_placeholder .comment ul.actions" + And I should not see "Frozen" within "#comments_placeholder .comment ul.actions" + + When I go to the homepage + Then I should see "My test comment!" within "div.messages .comment" + And I should see "Reply" within "div.messages .comment ul.actions" + And I should not see "Frozen" within "div.messages .comment ul.actions" + + When I go to author's inbox page + Then I should see "My test comment!" within "#inbox-form .comment" + And I should see "Reply" within "#inbox-form .comment ul.actions" + And I should not see "Frozen" within "#inbox-form .comment ul.actions" diff --git a/features/comments_and_kudos/guest_comment_replies.feature b/features/comments_and_kudos/guest_comment_replies.feature new file mode 100755 index 0000000..48fae1d --- /dev/null +++ b/features/comments_and_kudos/guest_comment_replies.feature @@ -0,0 +1,70 @@ +Feature: Disallowing guest comment replies + + Scenario Outline: Guests cannot reply to a user who has guest comments off on news posts and other users' works + Given <commentable> + And <commentable> with guest comments enabled + And the user "commenter" turns off guest comment replies + And a comment "OMG!" by "commenter" on <commentable> + When I view <commentable> with comments + Then I should see a "Comment" button + But I should not see a link "Reply" + When I am logged in as "reader" + And I view <commentable> with comments + Then I should see a "Comment" button + And I should see a link "Reply" + + Examples: + | commentable | + | the work "Aftermath" | + | the admin post "Change Log" | + + Scenario: Guests can reply to a user who has guest comments off on their own work + Given the work "Aftermath" by "creator" with guest comments enabled + And the user "creator" turns off guest comment replies + And a comment "OMG!" by "creator" on the work "Aftermath" + When I view the work "Aftermath" with comments + Then I should see a "Comment" button + And I should see a link "Reply" + When I am logged in as "reader" + And I view the work "Aftermath" with comments + Then I should see a "Comment" button + And I should see a link "Reply" + + Scenario: Guests can reply to a user who has guest comments off on works co-created by the user + Given the user "nemesis" turns off guest comment replies + And the work "Aftermath" by "creator" and "nemesis" with guest comments enabled + And a comment "OMG!" by "nemesis" on the work "Aftermath" + When I view the work "Aftermath" with comments + Then I should see a "Comment" button + And I should see a link "Reply" + When I am logged in as "reader" + And I view the work "Aftermath" with comments + Then I should see a "Comment" button + And I should see a link "Reply" + + Scenario: Users can reply to a user who has guest comments off on tags + Given the following activated tag wranglers exist + | login | + | commenter | + | wrangler | + And a canonical fandom "Controversial" + And the user "commenter" turns off guest comment replies + And a comment "OMG!" by "commenter" on the tag "Controversial" + When I am logged in as "wrangler" + And I view the tag "Controversial" with comments + And I follow "Reply" + And I fill in "Comment" with "Ugh." within ".odd" + And I press "Comment" within ".odd" + Then I should see "Comment created!" + + Scenario: Guests can reply to guests + Given the work "Aftermath" + And the work "Aftermath" with guest comments enabled + And a guest comment on the work "Aftermath" + When I view the work "Aftermath" with comments + Then I should see a "Comment" button + And I should see a link "Reply" + When I am logged in as "reader" + And I view the work "Aftermath" with comments + Then I should see a "Comment" button + And I should see a link "Reply" diff --git a/features/comments_and_kudos/guest_comments.feature b/features/comments_and_kudos/guest_comments.feature new file mode 100755 index 0000000..0a4cd50 --- /dev/null +++ b/features/comments_and_kudos/guest_comments.feature @@ -0,0 +1,45 @@ +@comments +Feature: Read guest comments + In order to tell guest comments from logged-in users' comments + As a user + I'd like to see the "guest" sign + +Scenario: View guest comments in homepage, inbox and works + Given I am logged in as "normal_user" + And I post the work "My very meta work about AO3" with guest comments enabled + And I am logged out + When I post a guest comment + Then I should see "(Guest)" + When I am logged in as "normal_user" + And I go to the home page + Then I should see "(Guest)" + When I follow "My Inbox" + Then I should see "(Guest)" + When I view the work "My very meta work about AO3" with comments + Then I should see "(Guest)" + +Scenario: View logged-in comments in homepage, inbox and works + Given I am logged in as "normal_user" + And I post the work "My very meta work about AO3" + And I am logged in as "logged_in_user" + When I post the comment ":)))))))" on the work "My very meta work about AO3" + Then I should not see "(Guest)" + When I am logged in as "normal_user" + And I go to the home page + Then I should not see "(Guest)" + When I follow "My Inbox" + Then I should not see "(Guest)" + When I view the work "My very meta work about AO3" with comments + Then I should not see "(Guest)" + +Scenario: Guest comments with embedded images are rendered as plain text + Given I am logged in as "normal_user" + And I post the work "foobar" with guest comments enabled + And I am logged out + When I view the work "foobar" + And I post a guest comment "Hello <img src='https://example.com/image.jpg' alt='baz'>" + Then I should see "Hello img src=" + And I should see "https://example.com/image.jpg" + And I should see "alt=" + And I should see "baz" + But I should not see the image "src" text "https://example.com/image.jpg" diff --git a/features/comments_and_kudos/hidden_comments.feature b/features/comments_and_kudos/hidden_comments.feature new file mode 100755 index 0000000..819f0b6 --- /dev/null +++ b/features/comments_and_kudos/hidden_comments.feature @@ -0,0 +1,88 @@ +@comments +Feature: Comment hiding + + Scenario: Hiding a comment replaces it with a placeholder message. + Given I am logged in as "author" + And I post the work "Popular Fic" + And I am logged out + And I am logged in as "commenter" + And I post the comment "A suspicious comment" on the work "Popular Fic" + And I am logged out + + # Delay to make sure the cache is expired when the comment is hidden: + When it is currently 1 second from now + And I am logged in as a super admin + And I view the work "Popular Fic" with comments + And I press "Hide Comment" + Then I should see "Comment successfully hidden!" + And I should see "This comment has been hidden by an admin." + And I should see "A suspicious comment" + And I should not see "This comment is under review by an admin and is currently unavailable." + When I go to the admin-activities page + Then I should see 1 admin activity log entry + And I should see "hide comment" + + When I am logged in as "author" + And I go to the home page + Then I should see "Find your favorites" + And I should not see "Unread messages" + And I should not see "This comment is under review by an admin and is currently unavailable." + And I should not see "A suspicious comment" + And I should not see "This comment has been hidden by an admin." + When I go to author's inbox page + Then I should not see "This comment is under review by an admin and is currently unavailable." + And I should not see "A suspicious comment" + And I should not see "This comment has been hidden by an admin." + When I view the work "Popular Fic" with comments + Then I should see "This comment is under review by an admin and is currently unavailable." + And I should not see "A suspicious comment" + And I should not see "This comment has been hidden by an admin." + And I should not see a "Make Comment Visible" button + + When I am logged in as "commenter" + And I view the work "Popular Fic" with comments + Then I should see "A suspicious comment" + And I should see "This comment has been hidden by an admin." + + When I am logged in as a super admin + And I view the work "Popular Fic" with comments + And I press "Make Comment Visible" + Then I should see "Comment successfully unhidden!" + When I go to the admin-activities page + Then I should see 2 admin activity log entry + And I should see "unhide comment" + + When I am logged in as "author" + And I go to the home page + Then I should see "A suspicious comment" + And I follow "My Inbox" + Then I should see "A suspicious comment" + And I view the work "Popular Fic" with comments + Then I should see "A suspicious comment" + And I should not see a "Hide Comment" button + + When I am logged in as "commenter" + And I view the work "Popular Fic" with comments + Then I should see "A suspicious comment" + And I should not see "This comment has been hidden by an admin." + + Scenario: Embedded images in hidden comments are replaced with their URLs. + Given the work "Popular Fic" + And I am logged in as "commenter" + And I post the comment "OMG! <img src= 'https://example.com/image.jpg'>" on the work "Popular Fic" + + # Delay to make sure the cache is expired when the comment is hidden: + When it is currently 1 second from now + And I am logged in as a super admin + And I view the work "Popular Fic" with comments + Then I should see the image "src" text "https://example.com/image.jpg" + And I should not see "OMG! img src=" + And I press "Hide Comment" + Then I should see "Comment successfully hidden!" + Then I should not see the image "src" text "https://example.com/image.jpg" + And I should see "OMG! img src=" + And I should see "https://example.com/image.jpg" + Then I press "Make Comment Visible" + And I should see "Comment successfully unhidden!" + Then I should see the image "src" text "https://example.com/image.jpg" + And I should not see "OMG! img src=" diff --git a/features/comments_and_kudos/hidden_works.feature b/features/comments_and_kudos/hidden_works.feature new file mode 100755 index 0000000..e5e2ea5 --- /dev/null +++ b/features/comments_and_kudos/hidden_works.feature @@ -0,0 +1,78 @@ +Feature: Comments on Hidden Works + + Scenario: When a work is hidden, admins and the creator can see (but not edit or add) comments, while everyone else is redirected. + Given I am logged in as "creator" + And I post the work "To Be Hidden" with guest comments enabled + And I post the comment "Can I change this?" on the work "To Be Hidden" + And I am logged in as "commenter" + And I post the comment "Do you see?" on the work "To Be Hidden" + And I am logged in as a "policy_and_abuse" admin + And I view the work "To Be Hidden" + And I follow "Hide Work" + + # As an admin + When I go to the work comments page for "To Be Hidden" + Then I should see "Do you see?" + But I should not see "Reply" + And I should not see "Post Comment" + And I should see "Sorry, you can't add or edit comments on a hidden work." + + When I am logged in as "creator" + And I go to the work comments page for "To Be Hidden" + Then I should see "Do you see?" + And I should see "Can I change this?" + But I should not see "Reply" + And I should not see "Post Comment" + And I should not see "Edit" + And I should see "Sorry, you can't add or edit comments on a hidden work." + + When I am logged in as "commenter" + And I go to the work comments page for "To Be Hidden" + Then I should not see "Do you see?" + And I should not see "Sorry, you can't add or edit comments on a hidden work." + But I should see "Sorry, you don't have permission to access the page you were trying to reach." + + When I am logged out + And I go to the work comments page for "To Be Hidden" + Then I should not see "Do you see?" + And I should not see "Sorry, you can't add or edit comments on a hidden work." + But I should see "Sorry, you don't have permission to access the page you were trying to reach." + + Scenario: When a work is unrevealed, admins and the creator can see (but not edit or add) comments, while everyone else is redirected. + Given I am logged in as "creator" + And I post the work "Murder, She Wrote" with guest comments enabled + And I post the comment "Can I change this?" on the work "Murder, She Wrote" + And I am logged in as "commenter" + And I post the comment "Do you see?" on the work "Murder, She Wrote" + And I am logged out + And I have the hidden collection "Dreamboat" + And I am logged in as "creator" + And I edit the work "Murder, She Wrote" to be in the collection "Dreamboat" + + # As the work's creator + When I go to the work comments page for "Murder, She Wrote" + Then I should see "Do you see?" + And I should see "Can I change this?" + But I should not see "Reply" + And I should not see "Post Comment" + And I should not see "Edit" + And I should see "Sorry, you can't add or edit comments on an unrevealed work." + + When I am logged in as an admin + And I go to the work comments page for "Murder, She Wrote" + Then I should see "Do you see?" + But I should not see "Reply" + And I should not see "Post Comment" + And I should see "Sorry, you can't add or edit comments on an unrevealed work." + + When I am logged in as "commenter" + And I go to the work comments page for "Murder, She Wrote" + Then I should not see "Do you see?" + And I should not see "Sorry, you can't add or edit comments on an unrevealed work." + But I should see "Sorry, you don't have permission to access the page you were trying to reach." + + When I am logged out + And I go to the work comments page for "Murder, She Wrote" + Then I should not see "Do you see?" + And I should not see "Sorry, you can't add or edit comments on an unrevealed work." + But I should see "Sorry, you don't have permission to access the page you were trying to reach." diff --git a/features/comments_and_kudos/image_safety_mode.feature b/features/comments_and_kudos/image_safety_mode.feature new file mode 100755 index 0000000..9df878e --- /dev/null +++ b/features/comments_and_kudos/image_safety_mode.feature @@ -0,0 +1,68 @@ +Feature: Image safety mode + In order to protect users + As a site owner + I'd like to control which comments can include images + + Scenario Outline: Images are embedded in comments when image safety mode is off. + Given the setup for testing image safety mode on <commentable> + And image safety mode is disabled for comments + When I view <commentable> with comments + Then I should see the image "src" text "https://example.com/image.jpg" + And I should not see "OMG! img src=" + When I go to the homepage + Then I should see the image "src" text "https://example.com/image.jpg" + And I should not see "OMG! img src=" + When I go to commentrecip's inbox page + Then I should see the image "src" text "https://example.com/image.jpg" + When image safety mode is enabled for comments on a "<parent_type>" + And I view <commentable> with comments + Then I should not see the image "src" text "https://example.com/image.jpg" + But I should see "OMG! img src=" + And I should see "https://example.com/image.jpg" + When I go to the homepage + Then I should not see the image "src" text "https://example.com/image.jpg" + But I should see "OMG! img src=" + And I should see "https://example.com/image.jpg" + When I go to commentrecip's inbox page + Then I should not see the image "src" text "https://example.com/image.jpg" + But I should see "OMG! img src=" + And I should see "https://example.com/image.jpg" + + Examples: + | commentable | parent_type | + | the admin post "Change Log" | AdminPost | + | the work "My Opus" | Chapter | + | the tag "No Fandom" | Tag | + + Scenario Outline: Embedded images in comments are replaced with their URLs when image safety mode is enabled. + Given the setup for testing image safety mode on <commentable> + And image safety mode is enabled for comments on a "<parent_type>" + When I view <commentable> with comments + Then I should not see the image "src" text "https://example.com/image.jpg" + But I should see "OMG! img src=" + And I should see "https://example.com/image.jpg" + When I go to the homepage + Then I should not see the image "src" text "https://example.com/image.jpg" + But I should see "OMG! img src=" + And I should see "https://example.com/image.jpg" + When I go to commentrecip's inbox page + Then I should not see the image "src" text "https://example.com/image.jpg" + But I should see "OMG! img src=" + And I should see "https://example.com/image.jpg" + When image safety mode is disabled for comments + And I view <commentable> with comments + Then I should see the image "src" text "https://example.com/image.jpg" + And I should not see "OMG! img src=" + When I go to the homepage + Then I should see the image "src" text "https://example.com/image.jpg" + And I should not see "OMG! img src=" + When I go to commentrecip's inbox page + Then I should see the image "src" text "https://example.com/image.jpg" + And I should not see "OMG! img src=" + + Examples: + | parent_type | commentable | + | AdminPost | the admin post "Change Log" | + | Chapter | the work "My Opus" | + | Tag | the tag "No Fandom" | + diff --git a/features/comments_and_kudos/inbox.feature b/features/comments_and_kudos/inbox.feature new file mode 100755 index 0000000..f94ade7 --- /dev/null +++ b/features/comments_and_kudos/inbox.feature @@ -0,0 +1,167 @@ +Feature: Get messages in the inbox + In order to stay informed about activity concerning my works and comments + As a user + I'd like to get messages in my inbox + + Scenario: I should not receive comments in my inbox if I have set my preferences to "Turn off messages to your inbox about comments." + Given I am logged in as "boxer" with password "10987tko" + And the work "Another Round" by "boxer" + And I set my preferences to turn off messages to my inbox about comments + When I am logged in as "cutman" + And I post the comment "You should not receive this in your inbox." on the work "Another Round" + When I am logged in as "boxer" with password "10987tko" + And I go to boxer's inbox page + Then I should not see "cutman on Another Round" + And I should not see "You should not receive this in your inbox." + + Scenario: I should receive comments in my inbox if I haven't set my preferences to "Turn off messages to your inbox about comments." + Given I am logged in as "boxer" with password "10987tko" + And the work "The Fight" by "boxer" + And I set my preferences to turn on messages to my inbox about comments + When I am logged in as "cutman" + And I post the comment "You should receive this in your inbox." on the work "The Fight" + When I am logged in as "boxer" with password "10987tko" + And I go to boxer's inbox page + Then I should see "cutman on The Fight" + And I should see "You should receive this in your inbox." + + Scenario: Logged in comments in my inbox should have timestamps + Given the work "Down for the Count" by "boxer" + When I am logged in as "cutman" + And I post the comment "It was a right hook... with a bit of a jab. (And he did it with his left hand.)" on the work "Down for the Count" + When I am logged in as "boxer" with password "10987tko" + And I go to boxer's inbox page + Then I should see "cutman on Down for the Count" + And I should see "less than 1 minute ago" + + Scenario: Inbox comments should display which chapter it's on, if and only if the work is multi-chapter + Given I am logged in as "author" + And I post the work "Single-chapter Work" + And I post the chaptered work "Multi-chapter Work" + And I set my preferences to turn on messages to my inbox about comments + When I am logged in as "commenter" + And I post the comment "You should receive this in your inbox." on the work "Single-chapter Work" + And I post the comment "And this one too." on the work "Multi-chapter Work" + When I am logged in as "author" + And I go to author's inbox page + Then I should see "on Single-chapter Work" + And I should not see "on Chapter 1 of Single-chapter Work" + And I should see "on Chapter 1 of Multi-chapter Work" + + Scenario: Comments in my inbox should be filterable + Given the work "Down for the Count" by "boxer" + When I post the comment "The fight game's complex." on the work "Down for the Count" as a guest + When I am logged in as "boxer" with password "10987tko" + And I go to boxer's inbox page + And I choose "Show unread" + And I press "Filter" + Then I should see "guest (Guest) on Down for the Count" + And I should see "less than 1 minute ago" + When I choose "Show read" + And I press "Filter" + Then I should not see "guest (Guest) on Down for the Count" + + Scenario: I can bulk edit comments in my inbox by clicking 'Select' + Given the work "The Fight" by "boxer" + When I am logged in as "cutman" + And I post the comment "You should receive this in your inbox." on the work "The Fight" + And I post the comment "A second message for your inbox!" on the work "The Fight" + When I am logged in as "boxer" + And I go to boxer's inbox page + Then I should see "cutman on The Fight" + And I should see "You should receive this in your inbox." + And I should see "A second message for your inbox!" + And I should see "Unread" within "li.comment:first-child" + And I should see "Unread" within "li.comment:last-child" + When I check "Select" within "li.comment:first-child" + And I check "Select" within "li.comment:last-child" + And I press "Mark Read" + Then I should not see "Unread" + + Scenario: A user can see some of their unread comments on the homepage + Given the work "Pre-Fight Coverage" by "boxer" + When I am logged in as "cutman" + And I post the comment "That's a haymaker? I actually never knew that." on the work "Pre-Fight Coverage" + When I am logged in as "boxer" with password "10987tko" + And I go to the homepage + Then I should see "Unread messages" + And I should see "My Inbox" + And I should see "The latest unread items from your inbox." + And I should see "cutman on Pre-Fight Coverage" + And I should see "That's a haymaker? I actually never knew that." + + Scenario: A user can delete an unread comment on the homepage + Given the work "The Gladiators of Old" by "boxer" + When I am logged in as "cutman" + And I post the comment "I can still make you cry, you know." on the work "The Gladiators of Old" + When I am logged in as "boxer" with password "10987tko" + And I go to the homepage + Then I should see "cutman on The Gladiators of Old" + And I should see "I can still make you cry, you know." + And I should see a "Delete" button + When I press "Delete" + Then I should see "Inbox successfully updated." + And I should be on the homepage + And I should not see "Unread messages" + And I should not see "My Inbox" + And I should not see "The latest unread items from your inbox." + And I should not see "cutman on the Gladiators of Old" + And I should not see "I can still make you cry, you know." + + Scenario: A user can mark an unread comment read on the homepage + Given the work "Special Coverage" by "boxer" + When I am logged in as "cutman" + And I post the comment "Is there anything we can do to make the fight go longer?" on the work "Special Coverage" + When I am logged in as "boxer" with password "10987tko" + And I go to the homepage + Then I should see "cutman on Special Coverage" + And I should see "Is there anything we can do to make the fight go longer?" + And I should see a "Mark Read" button + When I press "Mark Read" + Then I should see "Inbox successfully updated." + And I should be on the homepage + And I should not see "Unread messages" + And I should not see "My Inbox" + And I should not see "The latest unread items from your inbox." + And I should not see "cutman on Special Coverage" + And I should not see "Is there anything we can do to make the fight go longer?" + + Scenario: A user can reply to a comment from the home page without JavaScript + Given the work "Cat Thor's Bizarre Adventure" by "sewwiththeflo" + And I am logged in as "unbeatablesg" + And I post the comment "dude this is super great!!" on the work "Cat Thor's Bizarre Adventure" + When I am logged in as "sewwiththeflo" + And I go to the homepage + Then I should see "unbeatablesg on Cat Thor's Bizarre Adventure" + And I should see "dude this is super great!!" + And I should see a link "Reply" + When I reply to a comment with "Thank you! Please go to bed." + And I go to the homepage + Then I should not see "Unread messages" + And I should not see "dude this is super great!!" + When I am logged in as "unbeatablesg" + And I go to the homepage + Then I should see "sewwiththeflo on Cat Thor's Bizarre Adventure" + And I should see "Thank you! Please go to bed." + + @javascript + Scenario: A user can reply to a comment from the home page + Given the work "Cat Thor's Bizarre Adventure" by "sewwiththeflo" + And I am logged in as "unbeatablesg" + And I post the comment "dude this is super great!!" on the work "Cat Thor's Bizarre Adventure" + When I am logged in as "sewwiththeflo" + And I go to the homepage + Then I should see "unbeatablesg on Cat Thor's Bizarre Adventure" + And I should see "dude this is super great!!" + And I should see a link "Reply" + When I follow "Reply" within ".latest.messages.module" + And I fill in "Comment" with "Thank you! Please go to bed." within "#reply-to-comment" + And I press "Comment" within "#reply-to-comment" + And "AO3-5877" is fixed + # Then I should be on the homepage + # And I should not see "Unread messages" + # And I should not see "dude this is super great!!" + When I am logged in as "unbeatablesg" + And I go to the homepage + Then I should see "sewwiththeflo on Cat Thor's Bizarre Adventure" + And I should see "Thank you! Please go to bed." diff --git a/features/comments_and_kudos/kudos.feature b/features/comments_and_kudos/kudos.feature new file mode 100755 index 0000000..8d8590e --- /dev/null +++ b/features/comments_and_kudos/kudos.feature @@ -0,0 +1,261 @@ +Feature: Kudos + In order to show appreciation + As a reader + I want to leave kudos + + Background: + + Given the following activated users exist + | login | email | + | myname1 | myname1@foo.com | + | myname2 | myname2@foo.com | + | myname3 | myname3@foo.com | + And the work "Awesome Story" by "myname1" + + Scenario: Leaving kudos + + Given I am logged in as "myname2" + And all emails have been delivered + And I view the work "Awesome Story" + Then I should not see "left kudos on this work" + + # Note: this step cannot be put into the steps file because of the heart character + When I press "Kudos ♥" + Then I should see "myname2 left kudos on this work!" + # make sure no emails go out until notifications are sent + And 0 emails should be delivered + When kudos are sent + Then 1 email should be delivered to "myname1@foo.com" + And the email should contain "myname2" + And the email should contain "left kudos" + And the email should contain "." + And all emails have been delivered + When I press "Kudos ♥" + Then I should see "You have already left kudos here. :)" + And I should not see "myname2 and myname2 left kudos on this work!" + + When I am logged out + And I view the work "Awesome Story" + And I press "Kudos ♥" + Then I should see "Thank you for leaving kudos!" + And I should see "myname2 as well as 1 guest left kudos on this work!" + When I press "Kudos ♥" + Then I should see "You have already left kudos here. :)" + When kudos are sent + Then 1 email should be delivered to "myname1@foo.com" + And the email should contain "A guest" + And the email should contain "left kudos" + And the email should contain "." + + When I am logged in as "myname3" + And I view the work "Awesome Story" + And I press "Kudos ♥" + Then I should see "myname3 and myname2 as well as 1 guest left kudos on this work!" + When I am logged in as "myname1" + And I view the work "Awesome Story" + Then I should not see "Kudos ♥" + + When I go to the work kudos page for "Awesome Story" + Then I should see "2 Users Who Left Kudos on Awesome Story" + And I should see "1 guest has also left kudos" + And I should see "myname3 and myname2 left kudos on this work!" + + @javascript + Scenario: Leaving kudos with JavaScript enabled + + # As a registered user + When I am logged in as "myname2" + And I view the work "Awesome Story" + And I press "Kudos ♥" + Then I should see "Thank you for leaving kudos!" + And I should see "myname2 left kudos on this work!" + When I press "Kudos ♥" + Then I should see "You have already left kudos here. :)" + And I should not see "myname2 and myname2 left kudos on this work!" + + # As another registered user + When I am logged in as "myname3" + And I view the work "Awesome Story" + And I press "Kudos ♥" + Then I should see "Thank you for leaving kudos!" + And I should see "myname3 and myname2 left kudos on this work!" + When I press "Kudos ♥" + Then I should see "You have already left kudos here. :)" + + # As a guest user + When I am logged out + And I view the work "Awesome Story" + And I press "Kudos ♥" + Then I should see "Thank you for leaving kudos!" + And I should see "myname3 and myname2 as well as 1 guest left kudos on this work!" + When I press "Kudos ♥" + Then I should see "You have already left kudos here. :)" + + Scenario: Leaving kudos on a multi-chapter work + + Given I am logged in as "myname1" + And I post the chaptered work "Epic Saga" + And a draft chapter is added to "Epic Saga" + When I am logged in as "myname3" + And I view the work "Epic Saga" + And I press "Kudos ♥" + Then I should see kudos on every chapter + When I am logged in as "myname1" + And I view the work "Epic Saga" + Then I should see kudos on every chapter but the draft + + Scenario: Deleting user after leaving kudos should orphan them + + Given I am logged in as "myname3" + When "myname3" creates the default pseud "foobar" + And I view the work "Awesome Story" + And I press "Kudos ♥" + Then I should see "myname3 left kudos on this work!" + When "myname3" deletes their account + And I view the work "Awesome Story" + And "AO3-2195" is fixed + # Then I should see "1 guest left kudos on this work!" + + Scenario: Redirection when leaving kudos on a middle chapter, with default preferences + + Given the chaptered work setup + And I am logged in as a random user + When I view the work "BigBang" + And I view the 2nd chapter + And I press "Kudos ♥" + Then I should see "Chapter 2" within "div#chapters" + And I should not see "Chapter 1" within "div#chapters" + + Scenario: Redirection when leaving kudos in temporary "Entire Work" mode, with default preferences + + Given the chaptered work setup + And I am logged in as a random user + When I view the work "BigBang" in full mode + And I press "Kudos ♥" + Then I should see "Chapter 2" within "div#chapters" + And I should see "Chapter 3" within "div#chapters" + + Scenario: Batched kudos email + + Given the work "Another Awesome Story" by "myname1" + And the work "Meh Story" by "myname1" + And the work "Okay Story" by "myname1" + And all emails have been delivered + And the kudos queue is cleared + And I am logged in as "myname2" + And I leave kudos on "Awesome Story" + And I leave kudos on "Another Awesome Story" + And I leave kudos on "Okay Story" + And I am logged in as "someone_else" + And I leave kudos on "Awesome Story" + And I am logged out + And I leave kudos on "Awesome Story" + And I leave kudos on "Another Awesome Story" + And I leave kudos on "Meh Story" + When kudos are sent + Then 1 email should be delivered to "myname1@foo.com" + And the email should have "You've got kudos!" in the subject + And the email should contain "myname2" + And the email should contain "someone_else" + And the email should contain "a guest" + And the email should contain "A guest" + And the email should contain "Awesome Story" + And the email should contain "Another Awesome Story" + And the email should contain "Meh Story" + And the email should not contain "0 guests" + And the email should not contain "translation missing" + + Scenario: Translated kudos email + + Given a locale with translated emails + And the user "myname1" enables translated emails + And all emails have been delivered + And the kudos queue is cleared + And I am logged in as "myname2" + And I leave kudos on "Awesome Story" + When kudos are sent + Then 1 email should be delivered to "myname1@foo.com" + And the email should have "Translated subject" in the subject + And the email to "myname1" should contain "myname2" + And the email to "myname1" should contain "Awesome Story" + And the email to "myname1" should be translated + # AO3-6042: Emails should not obey user's locale preference when locales are deactivated + When the locale preference feature flag is disabled for user "myname1" + And all emails have been delivered + And I am logged in as "myname3" + And I leave kudos on "Awesome Story" + And kudos are sent + Then 1 email should be delivered to "myname1@foo.com" + And the email should have "You've got kudos!" in the subject + And the email to "myname1" should contain "myname3" + And the email to "myname1" should contain "Awesome Story" + And the email to "myname1" should be non-translated + + Scenario: Emails should not obey user's locale preference when localised emails for that locale are deactivated + + Given a locale with translated emails + And the user "myname1" enables translated emails + And all emails have been delivered + And the kudos queue is cleared + And I am logged in as "myname2" + And I leave kudos on "Awesome Story" + When kudos are sent + Then 1 email should be delivered to "myname1@foo.com" + And the email to "myname1" should be translated + When translated emails are disabled for the locale + And all emails have been delivered + And I am logged in as "myname3" + And I leave kudos on "Awesome Story" + And kudos are sent + Then 1 email should be delivered to "myname1@foo.com" + And the email to "myname1" should be non-translated + + Scenario: Blocked users should not see a kudos button on their blocker's works + Given the work "Aftermath" by "creator" + And the user "creator" has blocked the user "pest" + When I am logged in as "pest" + And I view the work "Aftermath" + Then I should not see a "Kudos ♥" button + + Scenario: Kudos cache expires periodically to ensure deleted users are removed and renamed users are updated + Given the work "Interesting beans" + And I am logged in as "oldusername1" with password "password" + When I view the work "Interesting beans" + And I press "Kudos ♥" + Then I should see "oldusername1 left kudos on this work!" + When I visit the change username page for oldusername1 + And I fill in "New username" with "newusername1" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should get confirmation that I changed my username + And I should see "Hi, newusername1" + When the kudos cache has expired + And I view the work "Interesting beans" + Then I should see "newusername1 left kudos on this work!" + And I should not see "oldusername1" + When I try to delete my account as newusername1 + And the kudos cache has expired + And I view the work "Interesting beans" + Then I should not see "newusername1 left kudos on this work!" + + Scenario: Cannot leave kudos (no button) while logged in as admin + Given I am logged in as an admin + And I view the work "Awesome Story" + Then I should see "Awesome Story" + And I should not see a "Kudos ♥" button + + @javascript + Scenario: Cannot leave kudos while logged in as a user with the official role + Given the user "clicker" exists and has the role "official" + And I am logged in as "clicker" + When I view the work "Awesome Story" + And I press "Kudos ♥" + Then I should see "Please log out of your official account!" + + @javascript + Scenario: Cannot leave kudos while logged in as a user with the archivist role + Given the user "clicker" exists and has the role "archivist" + And I am logged in as "clicker" + When I view the work "Awesome Story" + And I press "Kudos ♥" + Then I should see "Please log out of your archivist account!" diff --git a/features/comments_and_kudos/kudos_pagination.feature b/features/comments_and_kudos/kudos_pagination.feature new file mode 100755 index 0000000..51f04c8 --- /dev/null +++ b/features/comments_and_kudos/kudos_pagination.feature @@ -0,0 +1,67 @@ +Feature: Kudos Pagination + + Background: + Given the maximum number of kudos to show is 3 + + Scenario: Viewing one kudo + Given a work "Popular (1)" with 1 kudo + When I view the work "Popular (1)" + Then I should see "fan1 left kudos on this work!" + + Scenario: Viewing two kudos + Given a work "Popular (2)" with 2 kudos + When I view the work "Popular (2)" + Then I should see "fan2 and fan1 left kudos on this work!" + + Scenario: Viewing three kudos + Given a work "Popular (3)" with 3 kudos + When I view the work "Popular (3)" + Then I should see "fan3, fan2, and fan1 left kudos on this work!" + + @javascript + Scenario: Multiple pages of kudos with 1 kudo on the last page + Given a work "Popular (4)" with 4 kudos + When I view the work "Popular (4)" + Then I should see "fan4, fan3, fan2, and 1 more user left kudos on this work!" + When I follow "1 more user" + Then I should see "fan4, fan3, fan2, and fan1 left kudos on this work!" + + @javascript + Scenario: Multiple pages of kudos with 2 kudos on the last page + Given a work "Popular (5)" with 5 kudos + When I view the work "Popular (5)" + Then I should see "fan5, fan4, fan3, and 2 more users left kudos on this work!" + When I follow "2 more users" + Then I should see "fan5, fan4, fan3, fan2, and fan1 left kudos on this work!" + + @javascript + Scenario: Multiple pages of kudos with 3 kudos on the last page + Given a work "Popular (6)" with 6 kudos + When I view the work "Popular (6)" + Then I should see "fan6, fan5, fan4, and 3 more users left kudos on this work!" + When I follow "3 more users" + Then I should see "fan6, fan5, fan4, fan3, fan2, and fan1 left kudos on this work!" + + @javascript + Scenario: Three pages of kudos + Given a work "Popular (9)" with 9 kudos + When I view the work "Popular (9)" + Then I should see "fan9, fan8, fan7, and 6 more users left kudos on this work!" + When I follow "6 more users" + Then I should see "fan9, fan8, fan7, fan6, fan5, fan4, and 3 more users left kudos on this work!" + When I follow "3 more users" + Then I should see "fan9, fan8, fan7, fan6, fan5, fan4, fan3, fan2, and fan1 left kudos on this work!" + + Scenario: Three pages of kudos without javascript + Given a work "Popular (9)" with 9 kudos + When I view the work "Popular (9)" + Then I should see "fan9, fan8, fan7, and 6 more users left kudos on this work!" + When I follow "6 more users" + Then I should see "1 - 3 of 9 Users Who Left Kudos on Popular (9)" + And I should see "fan9, fan8, and fan7 left kudos on this work!" + When I follow "Next" + Then I should see "4 - 6 of 9 Users Who Left Kudos on Popular (9)" + And I should see "fan6, fan5, and fan4 left kudos on this work!" + When I follow "Next" + Then I should see "7 - 9 of 9 Users Who Left Kudos on Popular (9)" + And I should see "fan3, fan2, and fan1 left kudos on this work!" diff --git a/features/comments_and_kudos/official_comments.feature b/features/comments_and_kudos/official_comments.feature new file mode 100755 index 0000000..7173da7 --- /dev/null +++ b/features/comments_and_kudos/official_comments.feature @@ -0,0 +1,34 @@ +@comments +Feature: Read official comments + In order to tell genuine official accounts from impersonators + As a user + I'd like to see the "official" sign + +Scenario: View official comments in homepage, inbox and works + Given I am logged in as "normal_user" + And I post the work "My very meta work about AO3" + And the user "official_account" exists and has the role "official" + And I am logged in as "official_account" + When I post the comment ":)))))))" on the work "My very meta work about AO3" + Then I should see "(Official)" + When I am logged in as "normal_user" + And I go to the home page + Then I should see "(Official)" + When I follow "My Inbox" + Then I should see "(Official)" + When I view the work "My very meta work about AO3" with comments + Then I should see "(Official)" + +Scenario: View fake official comments in homepage, inbox and works + Given I am logged in as "normal_user" + And I post the work "My very meta work about AO3" + And I am logged in as "fake_official_account" + When I post the comment ":)))))))" on the work "My very meta work about AO3" + Then I should not see "(Official)" + When I am logged in as "normal_user" + And I go to the home page + Then I should not see "(Official)" + When I follow "My Inbox" + Then I should not see "(Official)" + When I view the work "My very meta work about AO3" with comments + Then I should not see "(Official)" diff --git a/features/comments_and_kudos/spam_comments.feature b/features/comments_and_kudos/spam_comments.feature new file mode 100755 index 0000000..9b01f1b --- /dev/null +++ b/features/comments_and_kudos/spam_comments.feature @@ -0,0 +1,196 @@ +@comments +Feature: Marking comments as spam + + Scenario: Spam comments are not included in a work's comment count + Given the work "Popular Fic" by "author" with guest comments enabled + And I view the work "Popular Fic" with comments + And I post a guest comment + And I post a spam comment + And all comments by "spammer" are marked as spam + + When I am logged in as "author" + And I go to the home page + Then I should see "This was really lovely!" + And I should not see "Buy my product!" + When I follow "My Inbox" + Then I should see "(1 comments, 1 unread)" + And I should see "This was really lovely!" + And I should not see "Buy my product!" + + When I go to author's user page + Then I should see "Popular Fic" + And I should see "Comments: 1" + + When I follow "Popular Fic" + Then I should see "Comments:1" + And I should see "Comments (1)" + + When I am logged in as "author" + And I go to author's stats page + Then I should see "Comment Threads: 1" + + Scenario: Spam comments are not included in an admin post's comment count + Given the admin post "Default Admin Post" + And I go to the admin-posts page + And I follow "Default Admin Post" + And I post a guest comment + And I post a spam comment + And all comments by "spammer" are marked as spam + + When I go to the admin-posts page + Then I should see "Default Admin Post (1)" + + When I follow "Default Admin Post" + Then I should see "Comments (1)" + + Scenario: Author can mark comments as spam + Given the work "Popular Fic" by "author" with guest comments enabled + When I view the work "Popular Fic" with comments + And I post a spam comment + And I post a guest comment + And I am logged in as "author" + And I view the work "Popular Fic" with comments + Then I should see "Comments (2)" + And I should see "Buy my product" + When I mark the comment as spam + Then I should see "Comments (1)" + And I should not see "Buy my product" + + @javascript + Scenario: If Javascript is enabled, there's a confirmation popup before marking a comment as spam + Given the work "Popular Fic" by "author" + And a guest comment on the work "Popular Fic" + And a guest comment on the work "Popular Fic" + When I am logged in as "author" + And I view the work "Popular Fic" with comments + Then I should see "Comments (2)" + When I mark the comment as spam + And I confirm I want to mark the comment as spam + And I view the work "Popular Fic" with comments + Then I should see "Comments (1)" + + Scenario Outline: Guest comments should be spam-checked + Given <commentable> + And <commentable> with guest comments enabled + When I view <commentable> with comments + And Akismet will flag any comment by "spammer" + And I try to post a spam comment + Then I should see "This comment looks like spam to our system, sorry!" + + Examples: + | commentable | + | the work "Generic Work" | + | the admin post "Generic Post" | + + Scenario Outline: New users' comments should be spam-checked on posting when the admin setting is enabled + Given <commentable> + And account age threshold for comment spam check is set to 5 days + And Akismet will flag any comment by "spammer" + When I am logged in as a new user "good_user" + And I view <commentable> with comments + And I post the comment "I don't like spam" on <commentable> + Then I should see "Comment created!" + When I am logged in as a new user "spammer" + And I post the comment "I like spam" on <commentable> + Then I should see "This comment looks like spam to our system, sorry!" + + Examples: + | commentable | + | the work "Generic Work" | + | the admin post "Generic Post" | + + Scenario Outline: New user's comments should be spam-checked on editing when the admin setting is enabled + Given <commentable> + And account age threshold for comment spam check is set to 5 days + And Akismet will flag any comment containing "spam" + When I am logged in as a new user "spammer" + And I view <commentable> with comments + And I post the comment "abcdefghijk" on <commentable> + Then I should see "Comment created!" + When I follow "Thread" + And I follow "Edit" + And I fill in "Comment" with "abcspamcccc" + And it is currently 1 second from now + And I press "Update" + Then I should see "Comment was successfully updated." + And I should see "abcspamcccc" + When I follow "Thread" + And I follow "Edit" + And I fill in "Comment" with "I like spam" + And it is currently 1 second from now + And I press "Update" + Then I should see "This comment looks like spam to our system, sorry!" + + Examples: + | commentable | + | the work "Generic Work" | + | the admin post "Generic Post" | + + Scenario Outline: Old users' comments should not be spam-checked when the admin setting is enabled + Given <commentable> + And account age threshold for comment spam check is set to 5 days + And Akismet will flag any comment by "spammer" + When I am logged in as a new user "good_user" + And it is currently 10 days from now + And I post the comment "I don't like spam" on <commentable> + Then I should see "Comment created!" + When I am logged in as a new user "spammer" + And it is currently 10 days from now + And I post the comment "I like spam" on <commentable> + Then I should see "Comment created!" + + Examples: + | commentable | + | the work "Generic Work" | + | the admin post "Generic Post" | + + Scenario Outline: New users' comments should not be spam-checked if the admin setting is disabled + Given <commentable> + And account age threshold for comment spam check is set to 0 days + And Akismet will flag any comment by "spammer" + When I am logged in as a new user "good_user" + And I post the comment "I don't like spam" on <commentable> + Then I should see "Comment created!" + When I am logged in as a new user "spammer" + And I post the comment "I like spam" on <commentable> + Then I should see "Comment created!" + + Examples: + | commentable | + | the work "Generic Work" | + | the admin post "Generic Post" | + + Scenario: New users' comments should not be spam-checked on tags + Given a canonical fandom "Stargate SG-1" + And the tag wrangler "spammer" with password "password" is wrangler of "Stargate SG-1" + And account age threshold for comment spam check is set to 5 days + And Akismet will flag any comment by "spammer" + When I am logged in as a new user "spammer" + And I view the tag "Stargate SG-1" with comments + And I post the comment "Sent you a syn" on the tag "Stargate SG-1" + Then I should see "Comment created!" + + Scenario: New users' comments should not be spam-checked on their own work + Given the work "Generic Work" by "spammer" + And account age threshold for comment spam check is set to 5 days + And Akismet will flag any comment by "spammer" + When I am logged in as a new user "spammer" + And I post the comment "I like spam" on the work "Generic Work" + Then I should see "Comment created!" + When I reply to a comment with "I still like spam" + Then I should see "Comment created!" + + Scenario: Old users' comments should not be spam-checked after they change their email + Given <commentable> + And account age threshold for comment spam check is set to 5 days + And Akismet will flag any comment by "spammer" + When I am logged in as a new user "spammer" + And it is currently 10 days from now + And I change my email to "newemail@example.com" + And I post the comment "I like spam" on <commentable> + Then I should see "Comment created!" + + Examples: + | commentable | + | the work "Generic Work" | + | the admin post "Generic Post" | diff --git a/features/fixtures/icon.bmp b/features/fixtures/icon.bmp new file mode 100755 index 0000000000000000000000000000000000000000..742d271d8007528250cd8968cfe667d00b15b9b9 GIT binary patch literal 10650 zcmeHLd6*Q%6@To)Ko5+74J^(s?1F#`EUdr+i}du&⁡CEXQ&mE{GsE!4Q=Isn*Zr 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 literal 0 HcmV?d00001 diff --git a/features/fixtures/icon.gif b/features/fixtures/icon.gif new file mode 100755 index 0000000000000000000000000000000000000000..cb4af6bc9eb5816ebfeccfcb7d58c6eec3edede7 GIT binary patch literal 2387 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 F06Rk}LlXc1 literal 0 HcmV?d00001 diff --git a/features/fixtures/icon.jpg b/features/fixtures/icon.jpg new file mode 100755 index 0000000000000000000000000000000000000000..8651bd1f9f60711da2f05461e4ba7ca8dd8e3910 GIT binary patch literal 5865 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 A-~a#s literal 0 HcmV?d00001 diff --git a/features/fixtures/icon.png b/features/fixtures/icon.png new file mode 100755 index 0000000000000000000000000000000000000000..2d631a261d61756898f78d47515d81da38a02f6c GIT binary patch literal 4311 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 FV1mm#TkHS; literal 0 HcmV?d00001 diff --git a/features/fixtures/skin_test_preview.png b/features/fixtures/skin_test_preview.png new file mode 100755 index 0000000000000000000000000000000000000000..2934d8828ca67c55d1d9aab05d3cfbf1c4c4d2ec GIT binary patch literal 3688 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 D9HZ%9 literal 0 HcmV?d00001 diff --git a/features/gift_exchanges/challenge_giftexchange.feature b/features/gift_exchanges/challenge_giftexchange.feature new file mode 100755 index 0000000..3f8bb00 --- /dev/null +++ b/features/gift_exchanges/challenge_giftexchange.feature @@ -0,0 +1,718 @@ +@collections +Feature: Gift Exchange Challenge + In order to have more fics for my fandom + As a humble user + I want to run a gift exchange + + Scenario: Create a collection to house a gift exchange + Given I am logged in as "mod1" + And I have standard challenge tags setup + When I set up the collection "My Gift Exchange" + And I select "Gift Exchange" from "challenge_type" + And I submit + Then "My Gift Exchange" gift exchange should be correctly created + + Scenario: Enter settings for a gift exchange + Given I am logged in as "mod1" + And I have set up the gift exchange "My Gift Exchange" + When I fill in gift exchange challenge options + And I submit + Then "My Gift Exchange" gift exchange should be fully created + + Scenario: Open signup in a gift exchange + Given I am logged in as "mod1" + And I have created the gift exchange "My Gift Exchange" + And I am on "My Gift Exchange" gift exchange edit page + When I check "Sign-up open?" + And I submit + Then I should see "Challenge was successfully updated" + And I should see "Sign-up: Open" within ".collection .meta" + And I should see "Sign-up Closes:" + + Scenario: Gift exchange appears in list of open challenges + Given I am logged in as "mod1" + And I have created the gift exchange "My Gift Exchange" + And I am on "My Gift Exchange" gift exchange edit page + When I check "Sign-up open?" + And I submit + When I view open challenges + Then I should see "My Gift Exchange" + + Scenario: Gift exchange also appears in list of open gift exchange challenges + Given I am logged in as "mod1" + And I have created the gift exchange "My Gift Exchange" + And I am on "My Gift Exchange" gift exchange edit page + When I check "Sign-up open?" + And I submit + When I view open challenges + And I follow "Gift Exchange Challenges" + Then I should see "My Gift Exchange" + + Scenario: Change timezone for a gift exchange + Given time is frozen at 1/1/2019 + And the gift exchange "My Gift Exchange" is ready for signups + When I go to "My Gift Exchange" gift exchange edit page + And I select "(GMT-08:00) Pacific Time (US & Canada)" from "Time zone" + And I submit + Then I should see "Challenge was successfully updated" + And I should see the correct time zone for "Pacific Time (US & Canada)" + And I jump in our Delorean and return to the present + + Scenario: Add a co-mod + Given the following activated users exist + | login | + | comod | + And I am logged in as "mod1" + And I have created the gift exchange "Awesome Gift Exchange" + And I open signups for "Awesome Gift Exchange" + When I go to "Awesome Gift Exchange" collection's page + And I follow "Membership" + And I fill in "participants_to_invite" with "comod" + And I press "Submit" + Then I should see "New members invited: comod" + + Scenario: Sign up for a gift exchange + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And I am logged in as "myname1" + When I sign up for "Awesome Gift Exchange" with combination A + Then I should see "Sign-up was successfully created" + # Invalid signup should warn the user + When I create an invalid signup in the gift exchange "Awesome Gift Exchange" + And I reload the page + Then I should see "sign-up is invalid" + + Scenario: I cannot sign up with a pseud that I don't own + Given the gift exchange "Awesome Gift Exchange" is ready for signups + When I attempt to sign up for "Awesome Gift Exchange" with a pseud that is not mine + Then I should not see "Sign-up was successfully created" + And I should see "You can't sign up with that pseud" + + Scenario: I cannot edit in a pseud that I don't own + Given the gift exchange "Awesome Gift Exchange" is ready for signups + When I attempt to update my signup for "Awesome Gift Exchange" with a pseud that is not mine + Then I should not see "Sign-up was successfully updated" + And I should see "You can't sign up with that pseud" + + Scenario: Optional tags should be saved when editing a signup (gcode issue #2729) + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And I edit settings for "Awesome Gift Exchange" challenge + And I check "Optional Tags?" + And I submit + When I am logged in as "myname1" + And I sign up for "Awesome Gift Exchange" with combination A + And I follow "Edit Sign-up" + And I fill in "Optional Tags:" with "My extra tag, Something else weird" + And I submit + Then I should see "Something else weird" + When I follow "Edit Sign-up" + And I submit + Then I should see "Something else weird" + + Scenario: HTTPS URL is saved as HTTPS when editing a signup + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And I edit settings for "Awesome Gift Exchange" challenge + And I check "gift_exchange[request_restriction_attributes][url_allowed]" + And I submit + When I am logged in as "myname1" + And I sign up for "Awesome Gift Exchange" with combination A + And I follow "Edit Sign-up" + And I fill in "Prompt URL:" with "https://example.com/url_for_prompt" + And I submit + Then I should see "URL: https://example.com/url_for_prompt" + + Scenario: Invalid URL is disallowed when editing a request in a signup + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And I edit settings for "Awesome Gift Exchange" challenge + And I check "gift_exchange[request_restriction_attributes][url_allowed]" + And I submit + When I am logged in as "myname1" + And I sign up for "Awesome Gift Exchange" with combination A + And I follow "Edit Sign-up" + And I fill in "Prompt URL:" with "i am broken." + And I submit + Then I should see "Request URL does not appear to be a valid URL." + + Scenario: Invalid URL is disallowed when editing an offer in a signup + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And I edit settings for "Awesome Gift Exchange" challenge + And I check "gift_exchange[offer_restriction_attributes][url_allowed]" + And I submit + When I am logged in as "myname1" + And I sign up for "Awesome Gift Exchange" with combination A + And I follow "Edit Sign-up" + And I fill in "Prompt URL:" with "i hereby offer you a bug." + And I submit + Then I should see "Offer URL does not appear to be a valid URL." + + Scenario: Sign-ups can be seen in the dashboard + Given the gift exchange "Awesome Gift Exchange" is ready for signups + When I am logged in as "myname1" + And I sign up for "Awesome Gift Exchange" with combination A + When I am on myname1's user page + Then I should see "Sign-ups (1)" + When I follow "Sign-ups (1)" + Then I should see "Awesome Gift Exchange" + + Scenario: Ordinary users cannot see other signups + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And I am logged in as "myname1" + When I sign up for "Awesome Gift Exchange" with combination A + And I go to the collections page + And I follow "Awesome Gift Exchange" + Then I should not see "Sign-ups" within "#dashboard" + + Scenario: Mod can view signups + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And everyone has signed up for the gift exchange "Awesome Gift Exchange" + When I am logged in as "mod1" + And I go to "Awesome Gift Exchange" collection's page + And I follow "Sign-ups" + Then I should see all the participants who have signed up + And I should see "Something else weird" + And I should see "Alternate Universe - Historical" + + Scenario: Mod can search signups by pseud + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And everyone has signed up for the gift exchange "Awesome Gift Exchange" + When I am logged in as "mod1" + And I go to "Awesome Gift Exchange" collection's page + And I follow "Sign-ups" + And I fill in "query" with "3" + And I press "Search by Pseud" + Then I should see "myname3" within "#main" + And I should not see "myname4" within "#main" + + Scenario: Cannot generate matches while signup is open + Given the gift exchange "Awesome Gift Exchange" is ready for signups + And everyone has signed up for the gift exchange "Awesome Gift Exchange" + When I am logged in as "mod1" + And I go to "Awesome Gift Exchange" collection's page + And I follow "Matching" + Then I should see "You can't generate matches while sign-up is still open." + And I should not see "Generate Potential Matches" + + Scenario: Matches can be generated and a translated email is sent + Given the gift exchange "Awesome Gift Exchange" is ready for matching + And I have added a co-moderator "mod2" to collection "Awesome Gift Exchange" + And a locale with translated emails + And the user "mod1" enables translated emails + When I close signups for "Awesome Gift Exchange" + And I follow "Matching" + And I press "Generate Potential Matches" + Then I should see "Beginning generation of potential matches. This may take some time, especially if your challenge is large." + And 1 email should be delivered to "mod1" + And the email to "mod1" should be translated + And the email should contain "finished generating potential assignments" + And the email should contain "you are an owner or moderator of the collection" + And 1 email should be delivered to "mod2" + And the email to "mod2" should be non-translated + And the email should contain "finished generating potential assignments" + And the email should contain "you are an owner or moderator of the collection" + When I reload the page + Then I should see "Reviewing Assignments" + And I should see "Complete" + + Scenario: Invalid signups are caught before generation and a translated email is sent + Given the gift exchange "Awesome Gift Exchange" is ready for matching + And I create an invalid signup in the gift exchange "Awesome Gift Exchange" + And I have added a co-moderator "mod2" to collection "Awesome Gift Exchange" + And a locale with translated emails + And the user "mod1" enables translated emails + When I close signups for "Awesome Gift Exchange" + And I follow "Matching" + And I press "Generate Potential Matches" + Then 1 email should be delivered to "mod1" + And the email to "mod1" should be translated + And the email should contain "invalid sign-up" + And the email should contain "you are an owner or moderator of the collection" + And 1 email should be delivered to "mod2" + And the email to "mod2" should be non-translated + And the email should contain "invalid sign-up" + And the email should contain "you are an owner or moderator of the collection" + When I go to "Awesome Gift Exchange" gift exchange matching page + Then I should see "Generate Potential Matches" + And I should see "invalid sign-ups" + + Scenario: Assignments can be updated and cannot be sent out until everyone is assigned + Given the gift exchange "Awesome Gift Exchange" is ready for matching + And I have generated matches for "Awesome Gift Exchange" + When I remove a recipient + And I press "Save Assignment Changes" + Then I should see "Assignments updated" + And I should see "No Recipient" + And I should see "No Giver" + When I press "Send Assignments" + Then I should see "aren't assigned" + When I follow "No Giver" + And I assign a pinch hitter + And I press "Save Assignment Changes" + Then I should see "Assignments updated" + And I should not see "No Giver" + When I follow "No Recipient" + And I assign a pinch recipient + And I press "Save Assignment Changes" + And I should not see "No Recipient" + When I press "Send Assignments" + Then I should see "Assignments are now being sent out" + + Scenario: Issues with assignments + Given the gift exchange "Awesome Gift Exchange" is ready for matching + And I have generated matches for "Awesome Gift Exchange" + When I assign a recipient to herself + And I press "Save Assignment Changes" + Then I should not see "Assignments updated" + And I should see "do not match" + When I manually destroy the assignments for "Awesome Gift Exchange" + And I go to "Awesome Gift Exchange" gift exchange matching page + Then I should see "Regenerate Assignments" + And I should see "Regenerate All Potential Matches" + And I should see "try regenerating assignments" + When I press "Regenerate Assignments" + And I reload the page + Then I should see "Reviewing Assignments" + And I should see "Complete" + + Scenario: Matches can be regenerated for a single signup + Given the gift exchange "Awesome Gift Exchange" is ready for matching + And I am logged in as "Mismatch" + And I sign up for "Awesome Gift Exchange" with a mismatched combination + When I am logged in as "mod1" + And I have generated matches for "Awesome Gift Exchange" + Then I should see "No Potential Givers" + And I should see "No Potential Recipients" + When I follow "No Potential Givers" + Then I should see "Regenerate Matches For Mismatch" + When I follow "Edit" + And I check the 1st checkbox with the value "Stargate Atlantis" + And I uncheck the 1st checkbox with the value "Bad Choice" + And I check the 2nd checkbox with the value "Stargate Atlantis" + And I uncheck the 2nd checkbox with the value "Bad Choice" + And I submit + And I follow "Matching" + And I follow "No Potential Recipients" + And I press "Regenerate Matches For Mismatch" + Then I should see "Matches are being regenerated for Mismatch" + When I reload the page + Then I should not see "No Potential Givers" + And I should not see "No Potential Recipients" + When I press "Regenerate Assignments" + And I reload the page + Then I should not see "No Potential Givers" + And I should not see "No Potential Recipients" + And I should see "Complete" + + Scenario: Assignments can be sent + Given the gift exchange "Awesome Gift Exchange" is ready for matching + And I have generated matches for "Awesome Gift Exchange" + When I press "Send Assignments" + Then I should see "Assignments are now being sent out" + When I reload the page + Then I should not see "Assignments are now being sent out" + # 4 users and the mod should get emails :) + And 1 email should be delivered to "mod1" + And the email should have "Assignments sent" in the subject + And the email should contain "You have received a message about your collection" + And the email should not contain "translation missing" + And 1 email should be delivered to "myname1" + And the email should contain "You have been assigned the following request" + And the email should contain "Fandom:" + And the email should contain "Stargate SG-1" + # Ratings and warnings don't show unless they've been selected to be something other than the default + And the email should not contain "Rating:" + And the email should not contain "Choose Not To Use Archive Warnings" + And the email should contain "Additional Tag" + And the email should contain "Something else weird" + And the email should not contain "translation missing" + And 1 email should be delivered to "myname2" + And 1 email should be delivered to "myname3" + And 1 email should be delivered to "myname4" + And the email should link to "Awesome Gift Exchange" collection's url + And the email should link to myname1's user url + And the email html body should link to the works tagged "Stargate Atlantis" + + Scenario: User signs up for two gift exchanges at once and can use the Fulfill + link to fulfill one assignment at a time + Given everyone has their assignments for "Awesome Gift Exchange" + And everyone has their assignments for "Second Challenge" + When I am logged in as "myname1" + And I start to fulfill my assignment + Then the "Awesome Gift Exchange (myname3)" checkbox should be checked + And the "Second Challenge (myname3)" checkbox should not be checked + + Scenario: User has more than one pseud on signup form + Given "myname1" has the pseud "othername" + Given I am logged in as "mod1" + And I have created the gift exchange "Sensitive Gift Exchange" + And I open signups for "Sensitive Gift Exchange" + When I am logged in as "myname1" + When I start to sign up for "Sensitive Gift Exchange" + Then I should see "othername" + + Scenario: User tries to change pseud on a challenge signup and should not be able to, as it would break matching + Given "myname1" has the pseud "othername" + Given I am logged in as "mod1" + And I have created the gift exchange "Sensitive Gift Exchange" + And I open signups for "Sensitive Gift Exchange" + When I am logged in as "myname1" + When I sign up for "Sensitive Gift Exchange" with combination A + Then I should see "Sign-up was successfully created" + And I should see "Sign-up for myname1" + When I edit my signup for "Sensitive Gift Exchange" + Then I should not see "othername" + + Scenario: Mod can see everyone's assignments, includind users' emails + Given I am logged in as "mod1" + And everyone has their assignments for "Awesome Gift Exchange" + When I go to the "Awesome Gift Exchange" assignments page + Then I should see "Assignments for Awesome" + When I follow "Open" + Then I should see "Open Assignments" + And I should see "myname1" + And I should see the image "alt" text "email myname1" + + Scenario: User can see their assignment, but no email links + Given everyone has their assignments for "Awesome Gift Exchange" + When I am logged in as "myname1" + And I go to myname1's user page + And I follow "Assignments" + Then I should see "Awesome Gift Exchange" + When I follow "Awesome Gift Exchange" + Then I should see "Requests by myname3" + But I should not see the image "alt" text "email myname3" + And I should see "Offers by myname1" + But I should not see the image "alt" text "email myname1" + + Scenario: User fulfills their assignment and it shows on their assigments page as fulfilled + + Given everyone has their assignments for "Awesome Gift Exchange" + When I am logged in as "myname1" + And I fulfill my assignment + When I go to myname1's user page + And I follow "Assignments" + Then I should see "Awesome Gift Exchange" + And I should not see "Not yet posted" + And I should see "Fulfilled Story" + When I am logged in as "mod1" + And I go to the "Awesome Gift Exchange" assignments page + And I follow "Complete" + Then I should see "myname1" + And I should see "Fulfilled Story" + + Scenario: A mod can default all incomplete assignments + + Given everyone has their assignments for "Awesome Gift Exchange" + And I am logged in as "myname1" + And I fulfill my assignment + When I am logged in as "mod1" + And I go to the "Awesome Gift Exchange" assignments page + And I press "Default All Incomplete" + Then I should see "All unfulfilled assignments marked as defaulting." + And I should see "Undefault myname2" + And I should see "Undefault myname3" + And I should see "Undefault myname4" + And I should not see "Undefault myname1" + + Scenario: User can default and a mod can undefault on their assignment + + Given everyone has their assignments for "Awesome Gift Exchange" + When I am logged in as "myname1" + And I go to the assignments page for "myname1" + And I press "Default" + Then I should see "We have notified the collection maintainers that you had to default on your assignment." + When I am logged in as "mod1" + And I go to the "Awesome Gift Exchange" assignments page + And I check "Undefault myname1" + And I press "Submit" + Then I should see "Assignment updates complete!" + And I should not see "Undefault" + When I am logged in as "myname1" + And I go to the assignments page for "myname1" + And I should see "Default" + + Scenario: User can default and a mod can assign a pinch hitter + + Given everyone has their assignments for "Awesome Gift Exchange" + When I am logged in as "myname1" + And I go to the assignments page for "myname1" + And I press "Default" + Then I should see "We have notified the collection maintainers that you had to default on your assignment." + When I am logged in as "mod1" + And I go to the "Awesome Gift Exchange" assignments page + And I fill in "Pinch Hitter:" with "nonexistent" + And I press "Submit" + Then I should see "We couldn't find the user nonexistent to assign that to." + When I fill in "Pinch Hitter:" with "myname1" + And I press "Submit" + Then I should see "No assignments to review!" + And I should see "Assignment updates complete!" + + Scenario: Refused story should still fulfill the assignment + + Given an assignment has been fulfilled in a gift exchange + And I reveal works for "Awesome Gift Exchange" + And I refuse my gift story "Fulfilled Story" + And I am logged in as "mod1" + And I go to the "Awesome Gift Exchange" assignments page + And I follow "Complete" + Then I should see "myname1" + And I should see "Fulfilled Story" + + Scenario: Download signups CSV + Given I am logged in as "mod1" + And I have created the gift exchange "My Gift Exchange" + + When I go to the "My Gift Exchange" signups page + And I follow "Download (CSV)" + Then I should download a csv file with the header row "Pseud Email Sign-up URL Request 1 Tags Request 1 Description Offer 1 Tags Offer 1 Description" + + Scenario: View a signup summary with no tags + Given the following activated users exist + | login | password | + | user1 | password | + | user2 | password | + | user3 | password | + | user4 | password | + | user5 | password | + | user6 | password | + When I am logged in as "mod1" + And I have created the tagless gift exchange "My Gift Exchange" + And I open signups for "My Gift Exchange" + When I am logged in as "user1" with password "password" + And I start to sign up for "My Gift Exchange" tagless gift exchange + When I am logged in as "user2" with password "password" + And I start to sign up for "My Gift Exchange" tagless gift exchange + When I am logged in as "user3" with password "password" + And I start to sign up for "My Gift Exchange" tagless gift exchange + When I am logged in as "user4" with password "password" + And I start to sign up for "My Gift Exchange" tagless gift exchange + When I am logged in as "user5" with password "password" + And I start to sign up for "My Gift Exchange" tagless gift exchange + When I am logged in as "user6" with password "password" + And I start to sign up for "My Gift Exchange" tagless gift exchange + When I am logged in as "mod1" + And I go to "My Gift Exchange" collection's page + And I follow "Sign-up Summary" + Then I should not see "Summary does not appear until at least" + And I should see "Tags were not used in this Challenge, so there is no summary to display here." + + Scenario: Sign-up Form link shows up in sidebar of moderated collections + Given I am logged in as "mod1" + And I have created the gift exchange "Cabbot Cove" + And I open signups for "Cabbot Cove" + When I am logged in as "Scott" with password "password" + And I go to "Cabbot Cove" collection's page + And I should see "Unmoderated" + And I should see "Sign-up Form" + Then I am logged in as "mod1" + And I go to "Cabbot Cove" collection's page + And I follow "Collection Settings" + And I check "This collection is moderated" + And I press "Update" + Then I am logged in as "Scott" with password "password" + And I go to "Cabbot Cove" collection's page + And I should see "Moderated" + And I should see "Sign-up Form" + + Scenario: Mod deletes a user's sign-up and a user deletes their own sign-up without JavaScript + Given I am logged in as "mod1" + And I have created the gift exchange "Awesome Gift Exchange" + And I open signups for "Awesome Gift Exchange" + And everyone has signed up for the gift exchange "Awesome Gift Exchange" + When I am logged in as "mod1" + And I go to the "Awesome Gift Exchange" signups page + And I delete the signup by "myname1" + Then I should see "Challenge sign-up was deleted." + When I am logged in as "myname2" + And I delete my signup for the gift exchange "Awesome Gift Exchange" + Then I should see "Challenge sign-up was deleted." + + Scenario: Assignment emails should contain all the information in the request + # Note: tag names are lowercased for the test so we could borrow the potential + # match steps, and due to the HTML, each tag must be looked for separate from + # its label or other tags of its type + Given I create the gift exchange "EmailTest" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + | fandoms | 1 | 1 | 0 | + | characters | 1 | 1 | 0 | + | freeforms | 0 | 2 | 0 | + | ratings | 0 | 1 | 0 | + | categories | 0 | 1 | 0 | + And the user "badgirlsdoitwell" signs up for "EmailTest" with the following prompts + | type | characters | fandoms | freeforms | ratings | categories | + | request | any | the show | fic, art | Mature | | + | offer | villain | the show | fic | | | + And the user "sweetiepie" signs up for "EmailTest" with the following prompts + | type | characters | fandoms | freeforms | ratings | categories | + | request | protag | the book | | | any | + | offer | protag | the book | fic | | | + When I have generated matches for "EmailTest" + And I have sent assignments for "EmailTest" + Then 1 email should be delivered to "sweetiepie" + And the email should contain "Fandom:" + And the email should contain "the show" + And the email should contain "Additional Tags:" + And the email should contain "fic" + And the email should contain "art" + And the email should contain "Character:" + And the email should contain "Any" + And the email should contain "Rating:" + And the email should contain "Mature" + And the email should not contain "Relationships:" + And the email should not contain "Warnings:" + And the email should not contain "Category:" + And the email should not contain "Optional Tags:" + Then 1 email should be delivered to "badgirlsdoitwell" + And the email should contain "Fandom:" + And the email should contain "the book" + And the email should contain "Character:" + And the email should contain "protag" + And the email should contain "Category:" + And the email should contain "Any" + And the email should not contain "Additional Tags:" + And the email should not contain "Relationships:" + And the email should not contain "Rating:" + And the email should not contain "Warnings:" + And the email should not contain "Optional Tags:" + + Scenario: A mod can delete a gift exchange without needing Javascript and all the assignments and + sign-ups will be deleted with it, but the collection will remain + Given everyone has their assignments for "Bad Gift Exchange" + And I am logged in as "mod1" + When I delete the challenge "Bad Gift Exchange" + Then I should see "Are you sure you want to delete the challenge from the collection Bad Gift Exchange? All sign-ups, assignments, and settings will be lost. (Works and bookmarks will remain in the collection.)" + When I press "Yes, Delete Challenge" + Then I should see "Challenge settings were deleted." + And I should not see the gift exchange dashboard for "Bad Gift Exchange" + And no one should have an assignment for "Bad Gift Exchange" + And no one should be signed up for "Bad Gift Exchange" + When I am on the collections page + Then I should see "Bad Gift Exchange" + + Scenario: A user can still access their Sign-ups page after a gift exchange + they were signed up for has been deleted + Given I am logged in as "mod1" + And I have created the gift exchange "Bad Gift Exchange" + And I open signups for "Bad Gift Exchange" + And everyone has signed up for the gift exchange "Bad Gift Exchange" + And the challenge "Bad Gift Exchange" is deleted + When I am logged in as "myname1" + And I go to myname1's signups page + Then I should see "Challenge Sign-ups" + And I should not see "Bad Gift Exchange" + + Scenario: A user can still access their Assignments page after a gift exchange + they had an unfulfilled assignment in has been deleted + Given everyone has their assignments for "Bad Gift Exchange" + And the challenge "Bad Gift Exchange" is deleted + When I am logged in as "myname1" + And I go to the assignments page for "myname1" + Then I should see "My Assignments" + And I should not see "Bad Gift Exchange" + + Scenario: A user can still access their Assignments page after a gift exchange + they had a fulfilled assignment in has been deleted + Given an assignment has been fulfilled in a gift exchange + And the challenge "Awesome Gift Exchange" is deleted + When I am logged in as "myname1" + And I go to the assignments page for "myname1" + Then I should see "My Assignments" + And I should not see "Awesome Gift Exchange" + + Scenario: A mod can purge assignments after they have been sent, but must + first confirm the action + Given everyone has their assignments for "Bad Gift Exchange" + And I am logged in as "mod1" + When I go to the "Bad Gift Exchange" assignments page + And I follow "Purge Assignments" + Then I should see "Are you sure you want to purge all assignments for Bad Gift Exchange?" + When I press "Yes, Purge Assignments" + Then I should see "Assignments purged!" + + Scenario: The My Assignments page that a user sees when they have multiple + assignments in a single exchange does not include an email link. + Given everyone has their assignments for "Bad Gift Exchange" + And I am logged in as "write_in_giver" + And "write_in_giver" has two pinchhit assignments in the gift exchange "Bad Gift Exchange" + When I go to "Bad Gift Exchange" collection's page + And I follow "My Assignments" within "#dashboard" + Then I should not see the image "src" text "/images/envelope_icon.gif" + + Scenario: A user who disallows gift works is cautioned about signing up for + an exchange, and a user who allows them is not. + Given the gift exchange "Some Gift Exchange" is ready for signups + And I am logged in as "participant" + And the user "participant" disallows gifts + When I go to "Some Gift Exchange" collection's page + And I follow "Sign-up Form" + Then I should see "assigned users to gift works to you regardless of your preference settings" + When the user "participant" allows gifts + And I go to "Some Gift Exchange" collection's page + And I follow "Sign-up Form" + Then I should not see "assigned users to gift works to you regardless of your preference settings" + + Scenario: If a work is connected to an assignment for a user who disallows + gifts, user is still automatically added as a gift recipient. The recipient + remains attached even if the work is later disconnected from the assignment. + Given basic tags + And the user "recip" exists and is activated + And the user "recip" disallows gifts + And I am logged in as "gifter" + And "gifter" has an assignment for the user "recip" in the collection "exchange_collection" + When I fulfill my assignment + Then I should see "For recip." + When I follow "Edit" + And I uncheck "exchange_collection (recip)" + And I press "Post" + Then I should see "For recip." + + Scenario: A user can explicitly give a gift to a user who disallows gifts if + the work is connected to an assignment. The recipient remains attached even if + the work is later disconnected from the assignment. + Given basic tags + And the user "recip" exists and is activated + And the user "recip" disallows gifts + And I am logged in as "gifter" + And "gifter" has an assignment for the user "recip" in the collection "exchange_collection" + When I start to fulfill my assignment + And I fill in "Gift this work to" with "recip" + And I press "Post" + Then I should see "For recip." + When I follow "Edit" + And I uncheck "exchange_collection (recip)" + And I press "Post" + Then I should see "For recip." + + Scenario: If a work is connected to an assignment for a user who blocked the gifter, + user is still automatically added as a gift recipient. The recipient + remains attached even if the work is later disconnected from the assignment. + Given basic tags + And the user "recip" exists and is activated + And the user "recip" allows gifts + And the user "recip" has blocked the user "gifter" + And I am logged in as "gifter" + And "gifter" has an assignment for the user "recip" in the collection "exchange_collection" + When I fulfill my assignment + Then I should see "For recip." + When I follow "Edit" + And I uncheck "exchange_collection (recip)" + And I press "Post" + Then I should see "For recip." + + Scenario: A user can explicitly give a gift to a user who blocked the gifter if + the work is connected to an assignment. The recipient remains attached even if + the work is later disconnected from the assignment. + Given basic tags + And the user "recip" exists and is activated + And the user "recip" allows gifts + And the user "recip" has blocked the user "gifter" + And I am logged in as "gifter" + And "gifter" has an assignment for the user "recip" in the collection "exchange_collection" + When I start to fulfill my assignment + And I fill in "Gift this work to" with "recip" + And I press "Post" + Then I should see "For recip." + When I follow "Edit" + And I uncheck "exchange_collection (recip)" + And I press "Post" + Then I should see "For recip." diff --git a/features/gift_exchanges/challenge_giftexchange_tagsets.feature b/features/gift_exchanges/challenge_giftexchange_tagsets.feature new file mode 100755 index 0000000..119686e --- /dev/null +++ b/features/gift_exchanges/challenge_giftexchange_tagsets.feature @@ -0,0 +1,69 @@ +@collections @tag_sets +Feature: Gift Exchange Challenge with Tag Sets + In order to have more fics for my fandom + As a humble user + I want to run a gift exchange with tag sets so I can make it single-fandom + + Scenario: Tagsets show up in Challenge metadata + Given I am logged in as "mod1" + And I have created the gift exchange "Cabbot Cove Remixes" + And I go to the tagsets page + And I follow the add new tagset link + And I fill in "Title" with "Angela Lansbury" + And I submit + And I go to "Cabbot Cove Remixes" collection's page + And I follow "Profile" + And I should see "Tag Set:" + And I should see "Standard Challenge Tags" + When I edit settings for "Cabbot Cove Remixes" challenge + And I fill in "Tag Sets To Use:" with "Angela Lansbury" + And I press "Update" + Then I should see "Tag Sets:" + And I should see "Standard Challenge Tags" + And I should see "Angela Lansbury" + When I edit settings for "Cabbot Cove Remixes" challenge + And I check "Standard Challenge Tags" + And I check "Angela Lansbury" + And I press "Update" + Then I should not see "Tag Sets:" + And I should not see "Tag Set:" + And I should not see "Standard Challenge Tags" + And I should not see "Angela Lansbury" + + @javascript + Scenario: Run a single-fandom exchange + + Given basic tags + And I am logged in as "mod1" + And I have a canonical "Celebrities & Real People" fandom tag named "Hockey RPF" + And I have a canonical "Celebrities & Real People" fandom tag named "Bandom" + And a canonical character "Alexander Ovechkin" in fandom "Hockey RPF" + And a canonical character "Gerard Way" in fandom "Bandom" + And I set up the tag set "HockeyExchangeTags" with the fandom tags "Hockey RPF" + When I go to the "HockeyExchangeTags" tag set page + Then I should see "About HockeyExchangeTags" + And I should see "Celebrities & Real People" within ".index" + When I press "↓" within ".index" + Then I should see "Hockey RPF" + When I have set up the gift exchange "My Hockey Exchange" + And I fill in single-fandom gift exchange challenge options + And I fill in "Tag Sets To Use:" with "HockeyExchangeTags" + And I submit + Then I should see "Challenge was successfully created" + When I follow "Challenge Settings" + Then I should see "HockeyExchangeTags" + When I follow "Sign-up Form" + And I check the 1st checkbox with the value "Hockey RPF" + And I check the 2nd checkbox with the value "Hockey RPF" + And I enter "Gerard Way" in the "Characters" autocomplete field + Then I should see "No suggestions found" in the autocomplete + # "Gerard Way" from a different fandom cannot appear in autocomplete; let's force it anyway. + When I fill in the 1st field with id matching "character_tagnames" with "Gerard Way" + And I submit + Then I should see "Sorry! We couldn't save this challenge signup because" + And I should see "These character tags in your request are not in the selected fandom(s), Hockey RPF: Gerard Way (Your moderator may be able to fix this.)" + And I should not see "Sign-up was successfully created." + When I follow "remove Gerard Way" + And I choose "Alexander Ovechkin" from the "Characters" autocomplete + And I submit + Then I should see "Sign-up was successfully created." diff --git a/features/gift_exchanges/challenge_yuletide.feature b/features/gift_exchanges/challenge_yuletide.feature new file mode 100755 index 0000000..216209a --- /dev/null +++ b/features/gift_exchanges/challenge_yuletide.feature @@ -0,0 +1,636 @@ +@collections +Feature: Collection + I want to test Yuletide, because it has several specific settings that are different from an ordinary gift exchange + + # Basic tag set testing is covered in challenge_giftexchange_tagsets.feature. + # Advanced stuff and nominations are covered in tags_and_wrangling/tag_set.feature. + + # uncomment this and the other 'javascript' lines below when testing on local + # in order to test javascript-based features + #@javascript + Scenario: Create a Yuletide gift exchange, sign up for it, run matching, post, fulfil pinch hits + + Given the following activated users exist + | login | password | + | mod1 | password | + | myname1 | password | + | myname2 | password | + | myname3 | password | + | myname4 | password | + | pinchhitter | password | + And I am logged in as "mod1" + And I have no collections + And I have Yuletide challenge tags setup + And I add the fandom "Stargate Atlantis" to the character "John Sheppard" + And I add the fandom "Starsky & Hutch" to the character "John Sheppard" + And I add the fandom "Tiny fandom" to the character "John Sheppard" + And a character exists with name: "Teyla Emmagan", canonical: true + And I add the fandom "Stargate Atlantis" to the character "Teyla Emmagan" + And I add the fandom "Starsky & Hutch" to the character "Teyla Emmagan" + And a character exists with name: "Foo The Wonder Goat", canonical: true + And I add the fandom "Tiny fandom" to the character "Foo The Wonder Goat" + And I add the fandom "Starsky & Hutch" to the character "Foo The Wonder Goat" + And a character exists with name: "Obscure person", canonical: true + And I add the fandom "Tiny fandom" to the character "Obscure person" + When I go to the collections page + Then I should see "Collections in the " + And I should not see "Yuletide" + When I follow "New Collection" + And I fill in "Display title" with "Yuletide" + And I fill in "Collection name" with "yule2011" + And I fill in "Introduction" with "Welcome to the exchange" + And I fill in "FAQ" with "<dl><dt>What is this thing?</dt><dd>It's a gift exchange-y thing</dd></dl>" + And I fill in "Rules" with "Be even nicer to people" + And I select "Gift Exchange" from "challenge_type" + And I check "This collection is unrevealed" + And I check "This collection is anonymous" + And I submit + Then I should see "Collection was successfully created" + And I should see "Setting Up the Yuletide Gift Exchange" + When I fill in "General Sign-up Instructions" with "Here are some general tips" + And I fill in "Request Instructions" with "Please request easy things" + And I fill in "Offer Instructions" with "Please offer lots of stuff" + # for testing convenience while still exercising the options, we are going with + # 2-3 requests, 2-3 offers + # url allowed in request + # description not allowed in offer + # 1 fandom required in offer and request + # 0-2 characters allowed in request + # 2-3 characters required in offer + # unique fandoms required in offers and requests + # "any" option available in character offers + # restrict character to fandom only + # match on 1 fandom and 1 character + And I check "gift_exchange_request_restriction_attributes_url_allowed" + And I uncheck "gift_exchange_offer_restriction_attributes_description_allowed" + And I fill in "gift_exchange_requests_num_required" with "2" + And I fill in "gift_exchange_requests_num_allowed" with "3" + And I fill in "gift_exchange_offers_num_required" with "2" + And I fill in "gift_exchange_offers_num_allowed" with "3" + And I fill in "Tag Sets To Use:" with "Standard Challenge Tags" + And I fill in "gift_exchange_request_restriction_attributes_fandom_num_required" with "1" + And I fill in "gift_exchange_request_restriction_attributes_fandom_num_allowed" with "1" + And I check "gift_exchange_request_restriction_attributes_require_unique_fandom" + And I fill in "gift_exchange_request_restriction_attributes_character_num_allowed" with "2" + And I fill in "gift_exchange_offer_restriction_attributes_fandom_num_required" with "1" + And I fill in "gift_exchange_offer_restriction_attributes_fandom_num_allowed" with "1" + And I fill in "gift_exchange_offer_restriction_attributes_character_num_required" with "2" + And I fill in "gift_exchange_offer_restriction_attributes_character_num_allowed" with "3" + And I check "gift_exchange_offer_restriction_attributes_require_unique_fandom" + And I check "gift_exchange_offer_restriction_attributes_allow_any_character" + And I select "1" from "gift_exchange_potential_match_settings_attributes_num_required_fandoms" + And I select "1" from "gift_exchange_potential_match_settings_attributes_num_required_characters" + And I check "gift_exchange_offer_restriction_attributes_character_restrict_to_fandom" + And I check "Sign-up open?" + And I set up the challenge dates + And I submit + Then I should see "Challenge was successfully created" + When I log out + And I am logged in as "myname1" + When I go to the collections page + Then I should see "Yuletide" + When I follow "Yuletide" + Then I should see "Sign Up" + When I follow "Profile" + Then I should see "About Yuletide (yule2011)" + And I should see "Sign-up:" within ".collection .meta" + And I should see "Open" within ".collection .meta" + And I should see "Sign-up Closes:" within ".collection .meta" + And I should see "Assignments Due:" within ".collection .meta" + And I should see "Works Revealed:" within ".collection .meta" + And I should see "Creators Revealed:" within ".collection .meta" + And I should see "Signed up:" within ".collection .meta" + And I should see "0" within ".collection .meta" + And I should see "Welcome to the exchange" within "#intro" + And I should see "What is this thing?" within "#faq" + And I should see "It's a gift exchange-y thing" within "#faq" + And I should see "Be even nicer to people" within "#rules" + When I follow "Sign Up" + Then I should see "General Sign Up Instructions" + And I should see "Here are some general tips" + And I should see "Requests (2 - 3)" + And I should see "Please request easy things" + And I should see "Request 1" + And I should see "Fandom (1):" + And I should see "Care Bears" + And I should see "Stargate Atlantis" + And I should see "Starsky & Hutch" + And I should see "Tiny fandom" + And I should see "Yuletide Hippos RPF" + And I should see "Characters (0 - 2):" + And I should see "Prompt URL:" + And I should see "Description:" + And I should see "Request 2" + And I should not see "Request 3" + And I should see "Add another request? (Up to 3 allowed.)" + And I should see "Offers (2 - 3)" + And I should see "Please offer lots of stuff" + And I should see "Offer 1" + And I should see "Characters (2 - 3)" + And I should see "Any Character" within "dd.any.option" + And I should see "Offer 2" + And I should not see "Offer 3" + And I should see "Add another offer? (Up to 3 allowed.)" + # we fill in 1 request with 1 fandom, 1 character; 1 offer with 1 fandom and 1 character + When I check the 1st checkbox with the value "Stargate Atlantis" + And I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_character_tagnames" with "John Sheppard" + And I fill in "Prompt URL" with "http://user.dreamwidth.org/123.html" + And I fill in "Description" with "This is my wordy request" + And I check the 3rd checkbox with the value "Care Bears" + And I fill in "challenge_signup_offers_attributes_0_tag_set_attributes_character_tagnames" with "Obscure person" + And I press "Submit" + Then I should see a save error message + # errors for the empty request + And I should see "Request: Your Request must include exactly 1 fandom tags, but you have included 0 fandom tags in your current Request" + # errors for the not-quite-filled offer + And I should see "Offer: Your Offer must include between 2 and 3 character tags, but you have included 1 character tags in your current Offer" + And I should see a not-in-fandom error message + # errors for the empty offer + And I should see "Offer: Your Offer must include exactly 1 fandom tags, but you have included 0 fandom tags in your current Offer" + And I should see "Offer: Your Offer must include between 2 and 3 character tags, but you have included 0 character tags in your current Offer" + # Over-fill the remaining missing fields and duplicate fandoms + When I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_character_tagnames" with "John Sheppard, Teyla Emmagan, Obscure person" + And I check the 2nd checkbox with the value "Tiny fandom" + And I check the 2nd checkbox with the value "Starsky & Hutch" + And I fill in "challenge_signup_requests_attributes_1_tag_set_attributes_character_tagnames" with "Teyla Emmagan" + And I fill in "challenge_signup_offers_attributes_0_tag_set_attributes_character_tagnames" with "Obscure person, John Sheppard" + And I check the 4th checkbox with the value "Care Bears" + And I fill in "challenge_signup_offers_attributes_1_tag_set_attributes_character_tagnames" with "Obscure person, John Sheppard, Teyla Emmagan, Foo The Wonder Goat" + And I press "Submit" + Then I should see a save error message + And I should see "Request: Your Request must include between 0 and 2 character tags, but you have included 3 character tags in your current Request" + And I should see a not-in-fandom error message for "Obscure person" in "Stargate Atlantis" + And I should see "Request: Your Request must include exactly 1 fandom tags, but you have included 2 fandom tags in your current Request" + And I should see a not-in-fandom error message for "Obscure person, John Sheppard" in "Care Bears" + And I should see "Offer: Your Offer must include between 2 and 3 character tags, but you have included 4 character tags in your current Offer" + And I should see a not-in-fandom error message for "Obscure person, John Sheppard, Teyla Emmagan, Foo The Wonder Goat" in "Care Bears" + And I should see "You have submitted more than one offer with the same fandom tags. This challenge requires them all to be unique." + + + # now fill in correctly + # We have six participants who sign up as follows: + + # myname1 requests: SGA (JS, TE), Tiny fandom (Obscure person) + # offers: Tiny fandom (Obscure person, JS), Hippos (Any) + # (is the only person who can write for myname2 and should therefore be assigned to them) + When I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_character_tagnames" with "John Sheppard, Teyla Emmagan" + And I uncheck the 2nd checkbox with the value "Starsky & Hutch" + And I fill in "challenge_signup_requests_attributes_1_tag_set_attributes_character_tagnames" with "Obscure person" + And I uncheck the 3rd checkbox with the value "Care Bears" + And I check the 3rd checkbox with the value "Tiny fandom" + And I uncheck the 4th checkbox with the value "Care Bears" + And I check the 4th checkbox with the value "Yuletide Hippos RPF" + And I fill in "challenge_signup_offers_attributes_1_tag_set_attributes_character_tagnames" with "" + And I check "challenge_signup_offers_attributes_1_any_character" + And I press "Submit" + Then I should see "Sign-up was successfully created" + And I should see "Sign-up for myname1" + And I should see "Requests" + And I should see "This is my wordy request" + And I should see "Offers" + And I should see "Edit" + And I should see "Delete" + + # another person signs up + When I log out + And I am logged in as "myname2" + When I go to the collections page + And I follow "Yuletide" + And I follow "Profile" + # before signing up, you can check who else has already signed up + Then I should see "Signed up:" within ".collection .meta" + And I should see "1" within ".collection .meta" + + # myname2 requests: Unoffered (no chars), Hippos (no chars) + # offers: S&H (JS, TE), SGA (JS, TE) + # can only get from myname1 + When I follow "Sign Up" + And I check the 1st checkbox with value "Unoffered" + And I check the 2nd checkbox with value "Yuletide Hippos RPF" + And I check the 3rd checkbox with value "Starsky & Hutch" + And I check the 4th checkbox with value "Stargate Atlantis" + And I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_character_tagnames" with "Any" + And I fill in "challenge_signup_offers_attributes_0_tag_set_attributes_character_tagnames" with "Teyla Emmagan, John Sheppard" + And I fill in "challenge_signup_offers_attributes_1_tag_set_attributes_character_tagnames" with "Teyla Emmagan, John Sheppard" + And I press "Submit" + Then I should see a save error message + And I should see a not-in-fandom error message for "Any" in "Unoffered" + When I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_character_tagnames" with "" + And I press "Submit" + Then I should see "Sign-up was successfully created" + + # and a third person signs up + # myname3 requests: S&H (JS), Tiny fandom; + # offers: SGA (JS, TE), S&H (JS, TE, Foo) + When I log out + And I am logged in as "myname3" + When I go to the collections page + And I follow "Yuletide" + And I follow "Sign Up" + When I check the 1st checkbox with the value "Starsky & Hutch" + And I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_character_tagnames" with "John Sheppard" + And I check the 2nd checkbox with the value "Tiny fandom" + And I check the 3rd checkbox with the value "Stargate Atlantis" + And I fill in "challenge_signup_offers_attributes_0_tag_set_attributes_character_tagnames" with "John Sheppard, Teyla Emmagan" + And I check the 4th checkbox with the value "Starsky & Hutch" + And I fill in "challenge_signup_offers_attributes_1_tag_set_attributes_character_tagnames" with "John Sheppard, Teyla Emmagan, Foo The Wonder Goat" + # TRICKY note here! the index value for the javascript-added request 3 is actually 3; this is + # a workaround because otherwise it would display a duplicate number + # These three commented out so it can run on the command-line + #And I follow "Add another request? (Up to 3 allowed.)" + #Then I should see "Request 3" + #And I check "challenge_signup_requests_attributes_3_fandom_30" + And I press "Submit" + Then I should see "Sign-up was successfully created" + + # fourth person signs up + # myname4 requests SGA, S&H (JS, TE) + # offers Tiny (Obscure, JS), S&H (Foo, JS) + When I log out + And I am logged in as "myname4" + When I go to the collections page + And I follow "Yuletide" + And I follow "Sign Up" + And I check the 1st checkbox with value "Stargate Atlantis" + And I check the 2nd checkbox with value "Starsky & Hutch" + And I fill in "challenge_signup_requests_attributes_1_tag_set_attributes_character_tagnames" with "John Sheppard, Teyla Emmagan" + And I check the 3rd checkbox with value "Tiny fandom" + And I fill in "challenge_signup_offers_attributes_0_tag_set_attributes_character_tagnames" with "Obscure person, John Sheppard" + And I check the 4th checkbox with value "Starsky & Hutch" + And I fill in "challenge_signup_offers_attributes_1_tag_set_attributes_character_tagnames" with "Foo The Wonder Goat, John Sheppard" + And I press "Submit" + Then I should see "Sign-up was successfully created" + + # ordinary users can't see signups until 5 people have signed up + When I go to the collections page + And I follow "Yuletide" + Then I should not see "Sign-ups" within "#dashboard" + And I should see "Sign-up Summary" + When I follow "Sign-up Summary" + Then I should see "Summary does not appear until at least 5 sign-ups have been made!" + And I should not see "Stargate Atlantis" + + # fifth person signs up + # myname5 requests SGA, S&H + # offers Tiny (Foo, Obscure), SGA (JS, TE) + When I log out + And I am logged in as "myname5" + When I go to the collections page + And I follow "Yuletide" + And I follow "Sign Up" + And I check the 1st checkbox with value "Stargate Atlantis" + And I check the 2nd checkbox with value "Starsky & Hutch" + And I check the 3rd checkbox with value "Tiny fandom" + And I fill in "challenge_signup_offers_attributes_0_tag_set_attributes_character_tagnames" with "Foo The Wonder Goat, Obscure Person" + And I check the 4th checkbox with value "Stargate Atlantis" + And I fill in "challenge_signup_offers_attributes_1_tag_set_attributes_character_tagnames" with "Teyla Emmagan, John Sheppard" + And I press "Submit" + Then I should see "Sign-up was successfully created" + + # ordinary users can't see signups but can see summary + When I go to the collections page + And I follow "Yuletide" + Then I should not see "Sign-ups" within "#dashboard" + And I should see "Sign-up Summary" + When I follow "Sign-up Summary" + Then I should see "Sign-up Summary for Yuletide" + And I should see "Requested Fandoms" + And I should see "Starsky & Hutch 3 3" + And I should see "Stargate Atlantis 3 3" + And I should see "Tiny fandom 2 3" + + # signup summary changes when another person signs up + # myname6 requests: SGA, S&H + # offers: Tiny (Foo, Obscure), SGA (JS, TE) + When I log out + And I am logged in as "myname6" + When I go to the collections page + And I follow "Yuletide" + And I follow "Sign Up" + And I check the 1st checkbox with value "Stargate Atlantis" + And I check the 2nd checkbox with value "Starsky & Hutch" + And I check the 3rd checkbox with value "Tiny fandom" + And I fill in "challenge_signup_offers_attributes_0_tag_set_attributes_character_tagnames" with "Foo The Wonder Goat, Obscure Person" + And I check the 4th checkbox with value "Stargate Atlantis" + And I fill in "challenge_signup_offers_attributes_1_tag_set_attributes_character_tagnames" with "Teyla Emmagan, John Sheppard" + And I press "Submit" + Then I should see "Sign-up was successfully created" + When I go to the collections page + And I follow "Yuletide" + And I follow "Sign-up Summary" + Then I should see "Sign-up Summary for Yuletide" + And I should see "Requested Fandoms" + And I should see "Starsky & Hutch 4 3" + And I should see "Stargate Atlantis 4 4" + And I should see "Tiny fandom 2 4" + + # mod can view signups + When I log out + And I am logged in as "mod1" + And I go to the collections page + And I follow "Yuletide" + And I follow "Sign-ups" + Then I should see "myname4" within "#main" + And I should see "myname3" within "#main" + And I should see "myname2" within "#main" + And I should see "myname1" within "#main" + And I should see "myname5" within "#main" + And I should see "myname6" within "#main" + And I should see "John Sheppard" + And I should see "Obscure person" + And I should see "http://user.dreamwidth.org/123.html" + + # mod runs matching + When I follow "Matching" + Then I should see "You can't generate matches while sign-up is still open." + And I should not see "Generate Potential Matches" + When I follow "Challenge Settings" + And I uncheck "Sign-up open?" + And I press "Update" + Then I should see "Challenge was successfully updated" + When I follow "Matching" + Then I should see "Matching for Yuletide" + And I should see "Generate Potential Matches" + And I should see "No potential matches yet" + When all emails have been delivered + When I press "Generate Potential Matches" + Then I should see "Beginning generation of potential matches. This may take some time, especially if your challenge is large." + When I reload the page + Then I should see "Reviewing Assignments" + And I should see "Complete" + And I should not see "No Recipient" + And I should not see "No Giver" + And I should see "Regenerate Assignments" + And I should see "Regenerate All Potential Matches" + And I should see "Send Assignments" + And 1 email should be delivered + + # mod regenerates the assignments + When all emails have been delivered + When I press "Regenerate Assignments" + Then I should see "Beginning regeneration of assignments. This may take some time, especially if your challenge is large." + When I reload the page + Then I should see "Complete" + And I should not see "No Recipient" + And I should not see "No Giver" + And 1 email should be delivered + + # mod sends assignments out + When all emails have been delivered + And I press "Send Assignments" + Then I should see "Assignments are now being sent out" + And I should see "No assignments to review" + And I should see "Defaulted" + And I should see "Pinch Hits" + And I should see "Open" + And I should see "Complete" + And I should see "Purge Assignments" + And I should see "Default All Incomplete" + When I reload the page + Then I should not see "Assignments are now being sent out" + # 6 users and the mod should get emails :) + And 7 emails should be delivered + + + # Notes for understanding the matching here: + # + # myname1 requests: SGA (JS, TE), Tiny fandom (Obscure person) + # offers: Tiny fandom (Obscure person, JS), Hippos (Any) + # myname2 requests: Unoffered (no chars), Hippos (no chars) + # offers: S&H (JS, TE), SGA (JS, TE) + # myname3 requests: S&H (JS), Tiny fandom; + # offers: SGA (JS, TE), S&H (JS, TE, Foo) + # myname4 requests SGA, S&H (JS, TE) + # offers Tiny (Obscure, JS), S&H (Foo, JS) + # myname5 requests SGA, S&H + # offers Tiny (Foo, Obscure), SGA (JS, TE) + # myname6 requests: SGA, S&H + # offers: Tiny (Foo, Obscure), SGA (JS, TE) + # + # so myname1 is the only person who can write for myname2 and therefore myname2 should be their assignment + # + + # first user starts posting + When I log out + And I am logged in as "myname1" + And I go to myname1's user page + And all emails have been delivered + #' stop annoying syntax highlighting after apostrophe + Then I should see "Assignments (1)" + When I follow "Assignments" + Then I should see "Yuletide for myname2" within "dl" + And I should see "Fulfill" + When I follow "Fulfill" + Then I should see "Post New Work" + When I fill in "Work Title" with "Fulfilling Story 1" + And I fill in "Fandoms" with "Stargate Atlantis" + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "content" with "This is an exciting story about Atlantis" + When I press "Preview" + Then I should see "Preview" + And 0 emails should be delivered + + # someone looks while it's still a draft + When I log out + And I am logged in as "myname2" + And I go to myname2's user page + #' stop annoying syntax highlighting after apostrophe + Then I should see "Gifts (0)" + And I should not see "Gifts (1)" + When I follow "Gifts" + Then I should not see "Stargate Atlantis" + And I should not see "myname" within "ul.gift" + When I go to the collections page + And I follow "Yuletide" + Then I should see "Works (0)" + And I should see "Fandoms (0)" + When I follow "Works (0)" + Then I should not see "Stargate" + And I should not see "myname" within "#main" + When I follow "Fandoms (0)" + Then I should not see "Stargate" + And I should not see "myname" within "#main" + When I follow "Random Items" + Then I should not see "Stargate" + And I should not see "myname" within "#main" + + # first user posts the work + When I log out + And I am logged in as "myname1" + And I go to myname1's user page + #' stop annoying syntax highlighting after apostrophe + And I follow "Drafts" + Then I should see "Fulfilling Story 1" + When I follow "Edit" + And I fill in "Fandoms" with "Stargate Atlantis" + And I press "Preview" + Then I should see "Preview" + And I should see "Fulfilling Story" + And I should see "myname" within "#main" + And I should see "Anonymous" + And 0 emails should be delivered + When I press "Post" + And all indexing jobs have been run + Then I should see "Work was successfully posted" + And I should see "For myname" + And I should see "Collections:" + And I should see "Yuletide" within ".meta" + And I should see "Anonymous" + # notification is still not sent, because it's unrevealed + And 0 emails should be delivered + + # someone tries to view it + When I log out + And I go to myname1's user page + #' stop annoying syntax highlighting after apostrophe + Then I should not see "Mystery Work" + And I should not see "Yuletide" + And I should not see "Fulfilling Story 1" + And I should not see "Stargate Atlantis" + When I follow "Works (0)" + Then I should not see "Stargate Atlantis" + + # user edits it to undo fulfilling the assignment + # When I am logged in as "myname1" + # And I go to myname1's user page + # #' stop highlighting + # Then I should see "Fulfilling Story" + # When I follow "Edit" + # When I uncheck "Yuletide (myname3)" + # And I fill in "work_collection_names" with "" + # And I fill in "work_recipients" with "" + # When I press "Preview" + # Then show me the html + # Then I should see "Work was successfully updated" + + # post works for all the assignments + When "myname2" posts the fulfilling story "Fulfilling Story 2" in "Stargate Atlantis" + And "myname3" posts the fulfilling story "Fulfilling Story 3" in "Tiny Fandom" + And "myname4" posts the fulfilling story "Fulfilling Story 4" in "Starsky & Hutch, Tiny Fandom" + And "myname5" posts the fulfilling draft "Fulfilling Story 5" in "Starsky & Hutch" + And I log out + Then I should see "Sorry, you don't have permission to access the page you were trying to reach. Please log in." + + # Mod checks for unfulfilled assignments, and gets pinch-hitters to do them. + When I am logged in as "mod1" + And I go to the collections page + And I follow "Yuletide" + And I follow "Assignments" + Then I should see "No assignments to review!" + When I follow "Open" + Then I should see "myname5" within "dl.index.group" + And I should see "myname6" within "dl.index.group" + When I follow "Complete" + Then I should see "myname1" within "dl.index.group" + And I should see "myname2" within "dl.index.group" + And I should see "myname3" within "dl.index.group" + And I should see "myname4" within "dl.index.group" + And I should see "Fulfilling Story" + When I press "Default All Incomplete" + Then I should see "All unfulfilled assignments marked as defaulting." + And I should not see "No assignments to review!" + When I fill in the 1st field with id matching "cover" with "pinchhitter" + And I submit + Then 1 email should be delivered + And the email should contain "You have been assigned the following request" + And I should see "Assignment updates complete!" + And all emails have been delivered + When I follow "Pinch Hits" + Then I should see "pinchhitter" + + # pinch hitter writes story + When "pinchhitter" posts the fulfilling story "Fulfilling Story pinch" in "Starsky & Hutch" + And I am logged in as "mod1" + And I go to "Yuletide" collection's page + And I follow "Assignments" + And I follow "Pinch Hits" + Then I should not see "pinchhitter" + When I follow "Complete" + Then I should see "pinchhitter" + And I should see "Fulfilling Story pinch" + + # mod reveals challenge on Dec 25th + When I am logged in as "mod1" + And 0 emails should be delivered + And all emails have been delivered + And I go to "Yuletide" collection's page + And I follow "Collection Settings" + And I uncheck "This collection is unrevealed" + And I press "Update" + Then I should see "Collection was successfully updated" + When I reload the page + # 5 gift notification emails are delivered for the 5 stories that have been posted so far (4 standard, 1 pinch-hit, 1 still a draft) + Then 5 emails should be delivered + And the email should contain "A gift work has been posted for you in the" + And the email should contain "Yuletide" + And the email should contain "at the Archive of Our Own" + And the email should contain "by Anonymous" + And the email should not contain "by myname1" + And the email should not contain "by myname2" + And the email should not contain "by myname3" + And the email should not contain "by myname4" + And the email should not contain "by myname5" + And the email should not contain "by myname6" + + # someone views their gift and it is anonymous + # Needs everyone to have fulfilled their assignments to be sure of finding a gift + When I am logged in as "myname2" + And I go to myname2's user page + #' + And I follow "Gifts" + Then I should see "Anonymous" + And I should not see "myname1" + And I should not see "myname3" + And I should not see "myname4" + And I should not see "myname5" + And I should not see "myname6" + And I should not see "pinchhitter" + When I follow "Fulfilling Story 1" + Then I should see the page title "Fulfilling Story 1 - Anonymous - Stargate Atlantis [Example Archive]" + Then I should see "Anonymous" + And I should not see "myname1" + And I should not see "myname3" + And I should not see "myname4" + And I should not see "myname5" + And I should not see "myname6" + And I should not see "pinchhitter" within ".byline" + # TODO: Check downloads more thoroughly + # When I follow "MOBI" + # Then I should see "Anonymous" + When I log out + Then I should see "Successfully logged out" + + # mod reveals authors on Jan 1st + When I am logged in as "mod1" + And I go to the collections page + And I follow "Yuletide" + And I follow "Collection Settings" + And I uncheck "This collection is anonymous" + And I press "Update" + Then I should see "Collection was successfully updated" + + # someone can now see their writer + When I log out + And I am logged in as "myname1" + And I go to myname1's user page + #' + Then I should see "Fulfilling Story 1" + And I should not see "Anonymous" + When I follow "Fulfilling Story 1" + Then I should not see "Anonymous" + And I should see "myname" within ".byline" + + When I follow "New Work" + Then I should not see "Does this fulfill a challenge assignment" + When I log out + And I am logged in as "pinchhitter" + And I follow "New Work" + Then I should not see "Does this fulfill a challenge assignment" + When I log out + And I am logged in as "myname6" + And I follow "New Work" + Then I should not see "Does this fulfill a challenge assignment" + + diff --git a/features/gift_exchanges/notification_emails.feature b/features/gift_exchanges/notification_emails.feature new file mode 100755 index 0000000..2ab0e78 --- /dev/null +++ b/features/gift_exchanges/notification_emails.feature @@ -0,0 +1,164 @@ +Feature: Gift Exchange Notification Emails + Make sure that gift exchange notification emails are formatted properly + + Scenario: Assignment sent notification emails should be sent to two owners in their respective locales when assignments are generated + Given I have created the tagless gift exchange "Holiday Swap" + And I open signups for "Holiday Swap" + + When I am logged in as "participant1" + And I start signing up for "Holiday Swap" + And I press "Submit" + Then I should see "Sign-up was successfully created." + + When I am logged in as "participant2" + And I start signing up for "Holiday Swap" + And I press "Submit" + Then I should see "Sign-up was successfully created." + + When I have added a co-moderator "mod2" to collection "Holiday Swap" + And a locale with translated emails + And the user "mod1" enables translated emails + And I close signups for "Holiday Swap" + And I have generated matches for "Holiday Swap" + And I have sent assignments for "Holiday Swap" + + Then 4 emails should be delivered + And "mod1" should receive 1 email + And the email to "mod1" should be translated + And the email should contain "You have received a message about your collection" + And "mod2" should receive 1 email + And the email to "mod2" should be non-translated + And the email should contain "You have received a message about your collection" + And "participant1" should receive 1 email + And "participant2" should receive 1 email + + Scenario: If collection email is set, use the collection email instead of moderator emails + Given I have created the tagless gift exchange "Holiday Swap" + And I open signups for "Holiday Swap" + And I am logged in as "participant1" + And I start signing up for "Holiday Swap" + And I press "Submit" + And I am logged in as "participant2" + And I start signing up for "Holiday Swap" + And I press "Submit" + And I have added a co-moderator "mod2" to collection "Holiday Swap" + And I go to "Holiday Swap" collection's page + And I follow "Collection Settings" + And I fill in "Collection email" with "test@archiveofourown.org" + And I press "Update" + And I close signups for "Holiday Swap" + And I have generated matches for "Holiday Swap" + And I have sent assignments for "Holiday Swap" + Then 3 emails should be delivered + And 1 email should be delivered to test@archiveofourown.org + And the email should contain "You have received a message about your collection" + + Scenario: Default notification emails should be sent to two owners in their respective locales when a user defaults on an assignment + + Given everyone has their assignments for "Holiday Swap" + And I have added a co-moderator "mod2" to collection "Holiday Swap" + And a locale with translated emails + And the user "mod1" enables translated emails + + When I am logged in as "myname1" + And I go to the assignments page for "myname1" + And I press "Default" + Then I should see "We have notified the collection maintainers that you had to default on your assignment." + And 7 emails should be delivered + And "mod1" should receive 2 emails + And the last email to "mod1" should be translated + And the last email should contain "defaulted on their assignment" + And "mod2" should receive 1 email + And the email to "mod2" should be non-translated + And the email should contain "defaulted on their assignment" + + Scenario: Assignment notifications with linebreaks. + Given I have created the tagless gift exchange "Holiday Swap" + And I open signups for "Holiday Swap" + And I create an assignment notification message with linebreaks for "Holiday Swap" + + When I am logged in as "participant1" + And I start signing up for "Holiday Swap" + And I press "Submit" + Then I should see "Sign-up was successfully created." + + When I am logged in as "participant2" + And I start signing up for "Holiday Swap" + And I press "Submit" + Then I should see "Sign-up was successfully created." + + When I close signups for "Holiday Swap" + And I have generated matches for "Holiday Swap" + And I have sent assignments for "Holiday Swap" + + Then 3 emails should be delivered + And "mod1" should receive 1 email + And "participant1" should receive 1 email + And "participant2" should receive 1 email + And the notification message to "participant1" should contain linebreaks + And the notification message to "participant2" should contain linebreaks + + Scenario: Assignment notifications with ampersands should escape them. + Given I have created the tagless gift exchange "Holiday Swap" + And I open signups for "Holiday Swap" + And I create an assignment notification message with an ampersand for "Holiday Swap" + + When I am logged in as "participant1" + And I start signing up for "Holiday Swap" + And I press "Submit" + Then I should see "Sign-up was successfully created." + + When I am logged in as "participant2" + And I start signing up for "Holiday Swap" + And I press "Submit" + Then I should see "Sign-up was successfully created." + + When I close signups for "Holiday Swap" + And I have generated matches for "Holiday Swap" + And I have sent assignments for "Holiday Swap" + + Then 3 emails should be delivered + And "mod1" should receive 1 email + And "participant1" should receive 1 email + And "participant2" should receive 1 email + And the notification message to "participant1" should escape the ampersand + And the notification message to "participant2" should escape the ampersand + + Scenario: Assignment notifications with warning tags work. + Given I have set up the gift exchange "Dark Fic Exchange" + And I check "Sign-up open?" + And I allow warnings in my gift exchange + And I submit + + When I am logged in as "participant1" + And I start signing up for "Dark Fic Exchange" + And I check "No Archive Warnings Apply" + And I submit + Then I should see "Sign-up was successfully created." + + When I am logged in as "participant2" + And I start signing up for "Dark Fic Exchange" + And I check "No Archive Warnings Apply" + And I submit + Then I should see "Sign-up was successfully created." + + When I close signups for "Dark Fic Exchange" + And I have generated matches for "Dark Fic Exchange" + And I have sent assignments for "Dark Fic Exchange" + + Then "participant1" should receive 1 email + And the notification message to "participant1" should contain the no archive warnings tag + + Scenario: Assignment notifications should be sent to participants in their respective locales + Given the gift exchange "Holiday Swap" is ready for matching + And a locale with translated emails + And the user "myname1" enables translated emails + When I close signups for "Holiday Swap" + And I have generated matches for "Holiday Swap" + And I have sent assignments for "Holiday Swap" + Then "myname1" should receive 1 email + And the email should have "Your assignment!" in the subject + And the email to "myname1" should be translated + And "myname2" should receive 1 email + And the email should have "Your assignment!" in the subject + And the email to "myname2" should be non-translated diff --git a/features/gift_exchanges/potential_matches.feature b/features/gift_exchanges/potential_matches.feature new file mode 100755 index 0000000..e4e4e27 --- /dev/null +++ b/features/gift_exchanges/potential_matches.feature @@ -0,0 +1,360 @@ +Feature: + Testing potential match generation. + + Scenario: Small multi-fandom exchange, only fandom tags. + + Given I create the gift exchange "multifan3" with the following options + | value | minimum | maximum | match | + | prompts | 2 | 2 | 1 | + | fandoms | 1 | 1 | 1 | + And the user "test1" signs up for "multifan3" with the following prompts + | type | fandoms | + | request | Popular Fandom | + | request | Fandom of One | + | offer | Rare Fandom 1 | + | offer | Fandom of One | + And the user "test2" signs up for "multifan3" with the following prompts + | type | fandoms | + | request | Rare Fandom 1 | + | request | Rare Fandom 2 | + | offer | Popular Fandom | + | offer | Rare Fandom 2 | + And the user "test3" signs up for "multifan3" with the following prompts + | type | fandoms | + | request | Rare Fandom 2 | + | request | Rare Fandom 3 | + | offer | Popular Fandom | + | offer | Rare Fandom 2 | + + When potential matches are generated for "multifan3" + Then the potential matches for "multifan3" should be + | offer | request | + | test1 | test2 | + | test2 | test1 | + | test2 | test3 | + | test3 | test1 | + | test3 | test2 | + + Scenario: Unconstrained exchange. + + Given I create the gift exchange "unconstrained3" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + | characters | 1 | 1 | 0 | + And the user "test1" signs up for "unconstrained3" with the following prompts + | type | characters | + | request | Evil Villain | + | offer | Evil Villain | + And the user "test2" signs up for "unconstrained3" with the following prompts + | type | characters | + | request | Sweet Protagonist | + | offer | Sweet Protagonist | + And the user "test3" signs up for "unconstrained3" with the following prompts + | type | characters | + | request | Morally Grey | + | offer | Morally Grey | + + When potential matches are generated for "unconstrained3" + Then the potential matches for "unconstrained3" should be + | offer | request | + | test1 | test2 | + | test1 | test3 | + | test2 | test1 | + | test2 | test3 | + | test3 | test1 | + | test3 | test2 | + + Scenario: Unconstrained exchange with no tags. + + Given I create the gift exchange "no_tags3" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + And the user "test1" signs up for "no_tags3" with the following prompts + | type | + | request | + | offer | + And the user "test2" signs up for "no_tags3" with the following prompts + | type | + | request | + | offer | + And the user "test3" signs up for "no_tags3" with the following prompts + | type | + | request | + | offer | + + When potential matches are generated for "no_tags3" + Then the potential matches for "no_tags3" should be + | offer | request | + | test1 | test2 | + | test1 | test3 | + | test2 | test1 | + | test2 | test3 | + | test3 | test1 | + | test3 | test2 | + + Scenario: Constrained exchange with no matches. + + Given I create the gift exchange "constrained3" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + | characters | 1 | 1 | 1 | + And the user "test1" signs up for "constrained3" with the following prompts + | type | characters | + | request | Evil Villain | + | offer | Evil Villain | + And the user "test2" signs up for "constrained3" with the following prompts + | type | characters | + | request | Sweet Protagonist | + | offer | Sweet Protagonist | + And the user "test3" signs up for "constrained3" with the following prompts + | type | characters | + | request | Morally Grey | + | offer | Morally Grey | + + When potential matches are generated for "constrained3" + Then there should be no potential matches for "constrained3" + + Scenario: Exchange with someone offering Any. + + Given I create the gift exchange "any_offer3" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + | characters | 1 | 1 | 1 | + And the user "test1" signs up for "any_offer3" with the following prompts + | type | characters | + | request | Evil Villain | + | offer | any | + And the user "test2" signs up for "any_offer3" with the following prompts + | type | characters | + | request | Sweet Protagonist | + | offer | Sweet Protagonist | + And the user "test3" signs up for "any_offer3" with the following prompts + | type | characters | + | request | Morally Grey | + | offer | Morally Grey | + + When potential matches are generated for "any_offer3" + Then the potential matches for "any_offer3" should be + | offer | request | + | test1 | test2 | + | test1 | test3 | + + Scenario: Exchange with someone requesting Any. + + Given I create the gift exchange "any_request3" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + | characters | 1 | 1 | 1 | + And the user "test1" signs up for "any_request3" with the following prompts + | type | characters | + | request | any | + | offer | Evil Villain | + And the user "test2" signs up for "any_request3" with the following prompts + | type | characters | + | request | Sweet Protagonist | + | offer | Sweet Protagonist | + And the user "test3" signs up for "any_request3" with the following prompts + | type | characters | + | request | Morally Grey | + | offer | Morally Grey | + + When potential matches are generated for "any_request3" + Then the potential matches for "any_request3" should be + | offer | request | + | test2 | test1 | + | test3 | test1 | + + Scenario: Exchange with offers and requests for Any. + + Given I create the gift exchange "any_both3" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + | characters | 1 | 1 | 1 | + And the user "test1" signs up for "any_both3" with the following prompts + | type | characters | + | request | any | + | offer | Evil Villain | + And the user "test2" signs up for "any_both3" with the following prompts + | type | characters | + | request | Sweet Protagonist | + | offer | any | + And the user "test3" signs up for "any_both3" with the following prompts + | type | characters | + | request | Morally Grey | + | offer | Morally Grey | + + When potential matches are generated for "any_both3" + Then the potential matches for "any_both3" should be + | offer | request | + | test2 | test1 | + | test2 | test3 | + | test3 | test1 | + + Scenario: Exchange with ALL matching. + + Given I create the gift exchange "all_matching3" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + | characters | 1 | 4 | -1 | + And the user "test1" signs up for "all_matching3" with the following prompts + | type | characters | + | request | Evil Villain, Shy Friend | + | offer | Evil Villain, Shy Friend, Anti-Villain, Sweet Protagonist | + And the user "test2" signs up for "all_matching3" with the following prompts + | type | characters | + | request | Evil Villain, Comic Relief, Sweet Protagonist | + | offer | Evil Villain, Comic Relief, Sweet Protagonist | + And the user "test3" signs up for "all_matching3" with the following prompts + | type | characters | + | request | Comic Relief | + | offer | Shy Friend, Sweet Protagonist, Comic Relief | + + When potential matches are generated for "all_matching3" + Then the potential matches for "all_matching3" should be + | offer | request | + | test2 | test3 | + + Scenario: Exchange with ALL and Any. + + Given I create the gift exchange "all_and_any4" with the following options + | value | minimum | maximum | match | + | prompts | 1 | 1 | 1 | + | characters | 1 | 4 | -1 | + And the user "test1" signs up for "all_and_any4" with the following prompts + | type | characters | + | request | Evil Villain, Shy Friend | + | offer | any | + And the user "test2" signs up for "all_and_any4" with the following prompts + | type | characters | + | request | Evil Villain, Comic Relief, Sweet Protagonist | + | offer | Evil Villain, Comic Relief, Sweet Protagonist | + And the user "test3" signs up for "all_and_any4" with the following prompts + | type | characters | + | request | Comic Relief | + | offer | Shy Friend, Sweet Protagonist, Comic Relief | + And the user "test4" signs up for "all_and_any4" with the following prompts + | type | characters | + | request | any | + | offer | Shy Friend, Sweet Protagonist, Comic Relief | + + When potential matches are generated for "all_and_any4" + Then the potential matches for "all_and_any4" should be + | offer | request | + | test1 | test2 | + | test1 | test3 | + | test2 | test3 | + | test1 | test4 | + | test2 | test4 | + | test3 | test4 | + | test4 | test3 | + + Scenario: Exchange with freeform restrictions. + + Given I create the gift exchange "freeform4" with the following options + | value | minimum | maximum | match | unique | + | prompts | 1 | 2 | 1 | n/a | + | characters | 1 | 2 | -1 | no | + | freeforms | 1 | 2 | 1 | no | + And the user "test1" signs up for "freeform4" with the following prompts + | type | characters | freeforms | + | request | Evil Villain | Fic | + | request | Evil Villain, Sweet Protagonist | Fic, Art | + | offer | Evil Villain, Sweet Protagonist | Fic | + And the user "test2" signs up for "freeform4" with the following prompts + | type | characters | freeforms | + | request | Comic Relief | Fic | + | request | Woobie of Choice | Art | + | offer | any | Art | + And the user "test3" signs up for "freeform4" with the following prompts + | type | characters | freeforms | + | request | Sweet Protagonist | Art, Fic | + | request | Evil Villain, Anti-Villain | Art | + | offer | Evil Villain, Anti-Villain | Fic | + And the user "test4" signs up for "freeform4" with the following prompts + | type | characters | freeforms | + | request | Sweet Protagonist | Fic | + | offer | Comic Relief, Sweet Protagonist | Fic | + + When potential matches are generated for "freeform4" + Then the potential matches for "freeform4" should be + | offer | request | + | test1 | test3 | + | test1 | test4 | + | test2 | test1 | + | test2 | test3 | + | test3 | test1 | + | test4 | test2 | + | test4 | test3 | + + Scenario: Multi-fandom exchange with optional tags. + + Given I create the gift exchange "optional3" with the following options + | value | minimum | maximum | match | optional | any | + | prompts | 2 | 2 | 1 | n/a | n/a | + | fandoms | 1 | 1 | 1 | yes | no | + | characters | 1 | 1 | 1 | yes | yes | + And the user "bookfan" signs up for "optional3" with the following prompts + | type | fandoms | characters | optional fandoms | + | request | Out-of-Print Book | Rare Woobie | | + | request | Rare Book | Obscure Character | | + | offer | Out-of-Print Book | any | Rare Book | + | offer | Popular Book | any | | + And the user "showfan" signs up for "optional3" with the following prompts + | type | fandoms | characters | optional fandoms | + | request | 80s Cop Show | Badass Partner | | + | request | 90s Fantasy Show | Witty Protagonist | | + | offer | 80s Cop Show | Badass Partner | | + | offer | 90s Fantasy Show | any | 00s SciFi Show | + And the user "mixed" signs up for "optional3" with the following prompts + | type | fandoms | characters | optional fandoms | + | request | Rare Book | Fandom Darling | | + | request | 00s SciFi Show | Bounty Hunter | | + | offer | Popular Book | any | Rare Book | + | offer | 10s Drama Show | any | 90s Fantasy Show | + + When potential matches are generated for "optional3" + Then the potential matches for "optional3" should be + | offer | request | + | mixed | bookfan | + | mixed | showfan | + | bookfan | mixed | + | showfan | mixed | + + Scenario: Exchange with optional tags and restrictions on a different type. + + Given I create the gift exchange "optional4" with the following options + | value | minimum | maximum | match | optional | any | unique | + | prompts | 1 | 3 | 1 | n/a | n/a | n/a | + | characters | 1 | 1 | 1 | yes | no | no | + | freeforms | 1 | 1 | 1 | no | no | yes | + And the user "test1" signs up for "optional4" with the following prompts + | type | character | optional characters | freeform | + | request | Warlock | | Fic | + | request | Warlock | | Art | + | offer | Warlock | Witch, Magician | Fic | + And the user "test2" signs up for "optional4" with the following prompts + | type | character | optional characters | freeform | + | request | Magician | Headologist | Art | + | offer | Magician | Headologist, Warlock | Art | + And the user "test3" signs up for "optional4" with the following prompts + | type | character | optional characters | freeform | + | request | Magician | | Fic | + | request | Magician | | Art | + | request | Magician | | Vid | + | offer | Magician | | Fic | + | offer | Magician | | Art | + | offer | Magician | | Vid | + And the user "test4" signs up for "optional4" with the following prompts + | type | character | optional characters | freeform | + | request | Headologist | Summoner, Witch | Vid | + | offer | Headologist | Summoner, Witch | Art | + | offer | Headologist | Summoner, Witch | Vid | + + When potential matches are generated for "optional4" + Then the potential matches for "optional4" should be + | offer | request | + | test2 | test1 | + | test3 | test2 | + | test1 | test3 | + | test2 | test3 | + | test4 | test2 | diff --git a/features/gift_exchanges/signup_summary.feature b/features/gift_exchanges/signup_summary.feature new file mode 100755 index 0000000..d436d76 --- /dev/null +++ b/features/gift_exchanges/signup_summary.feature @@ -0,0 +1,41 @@ +Feature: Gift Exchange Signup Summary + + Scenario: Updating a live summary + Given signup summaries are always visible + And all signup summaries are live + And I have created the gift exchange "Exchange" + And I open signups for "Exchange" + + When I am logged in as "testuser1" + And I sign up for "Exchange" with combination C + And I view the sign-up summary for "Exchange" + Then I should see "Stargate SG-1 1 1" + + When I am logged in as "testuser2" + And I sign up for "Exchange" with combination D + And I view the sign-up summary for "Exchange" + Then I should see "Stargate SG-1 1 1" + And I should see "Stargate Atlantis 1 1" + + Scenario: Updating a delayed summary + Given signup summaries are always visible + And all signup summaries are delayed + And I have created the gift exchange "Exchange" + And I open signups for "Exchange" + + When I am logged in as "testuser1" + And I sign up for "Exchange" with combination C + And I view the sign-up summary for "Exchange" + Then I should see "Stargate SG-1 1 1" + + When I am logged in as "testuser2" + And I sign up for "Exchange" with combination D + And I view the sign-up summary for "Exchange" + Then I should see "Stargate SG-1 1 1" + But I should not see "Stargate Atlantis" + + When it is currently 61 minutes from now + And I view the sign-up summary for "Exchange" + Then I should see "Stargate SG-1 1 1" + And I should see "Stargate Atlantis 1 1" + And I jump in our Delorean and return to the present diff --git a/features/importing/archivist.feature b/features/importing/archivist.feature new file mode 100755 index 0000000..4879bd6 --- /dev/null +++ b/features/importing/archivist.feature @@ -0,0 +1,392 @@ +@archivist_import +Feature: Archivist bulk imports + + Background: + Given I have an archivist "archivist" + And the default ratings exist + And all warnings exist + And I am logged in as "archivist" + + Scenario: Non-archivist cannot import for others + Given I am logged in as a random user + When I go to the import page + Then I should not see "Import for others ONLY with permission" + + Scenario: Make a user an archivist + Given I have pre-archivist setup for "not_archivist" + And I am logged in as an "open_doors" admin + When I make "not_archivist" an archivist + Then I should see "User was successfully updated" + + Scenario: Archivist can see link to import for others + When I go to the import page + Then I should see "Import for others ONLY with permission" + + Scenario: Importing for others without an email address should give an error + Given I am logged in as "archivist" + When I start importing "http://import-site-with-tags" with a mock website as an archivist + And I check "Import for others ONLY with permission" + And I fill in "Author Name*" with "Name" + And I press "Import" + Then I should see "We couldn't successfully import that work, sorry: No author email specified" + + Scenario: Importing for others without a name should give an error + Given I am logged in as "archivist" + When I start importing "http://import-site-with-tags" with a mock website as an archivist + And I check "Import for others ONLY with permission" + And I fill in "Author Email Address*" with "foo@example.com" + And I press "Import" + Then I should see "We couldn't successfully import that work, sorry: No author name specified" + + Scenario: Importing for others without a name or email address should give an error + Given I am logged in as "archivist" + When I start importing "http://import-site-with-tags" with a mock website as an archivist + And I check "Import for others ONLY with permission" + And I press "Import" + Then I should see "We couldn't successfully import that work, sorry: No external author name or email specified" + + Scenario: Importing for an author without an account should have the correct byline and email + When I import the work "http://rebecca2525.livejournal.com/3562.html" + Then I should see "We have notified the author(s) you imported works for" + And I should see "rebecca2525 [archived by archivist]" + And 1 email should be delivered to "rebecca2525@livejournal.com" + And the email should contain invitation warnings from "archivist" for work "Importing Test" in fandom "Lewis" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Import a work for multiple authors without accounts should display all in the byline + When I go to the import page + And I import the work "http://ao3testing.dreamwidth.org/593.html" by "name1" with email "a@ao3.org" and by "name2" with email "b@ao3.org" + Then I should see "Story" + And I should see "name1 [archived by archivist]" + And I should see "name2 [archived by archivist]" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Import a work for multiple authors without accounts should send emails to all authors + When I go to the import page + And I import the work "http://ao3testing.dreamwidth.org/593.html" by "name1" with email "a@ao3.org" and by "name2" with email "b@ao3.org" + Then 1 email should be delivered to "a@ao3.org" + And 1 email should be delivered to "b@ao3.org" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Import a work for multiple authors with and without accounts should display all in the byline + Given the following activated users exist + | login | email | + | user1 | a@ao3.org | + When I go to the import page + And I import the work "http://ao3testing.dreamwidth.org/593.html" by "name1" with email "a@ao3.org" and by "name2" with email "b@ao3.org" + Then I should see "Story" + And I should see "user1" + And I should see "name2 [archived by archivist]" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Import a work for multiple authors with and without accounts should send emails to all authors + Given the following activated users exist + | login | email | + | user1 | a@ao3.org | + When I go to the import page + And I import the work "http://ao3testing.dreamwidth.org/593.html" by "name1" with email "a@ao3.org" and by "name2" with email "b@ao3.org" + Then 1 email should be delivered to "a@ao3.org" + And 1 email should be delivered to "b@ao3.org" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Import a work for multiple authors with accounts should not display the archivist + Given the following activated users exist + | login | email | + | user1 | a@ao3.org | + | user2 | b@ao3.org | + When I go to the import page + And I import the work "http://ao3testing.dreamwidth.org/593.html" by "name1" with email "a@ao3.org" and by "name2" with email "b@ao3.org" + Then I should see "Story" + And I should see "user1" + And I should see "user2" + But I should not see "archivist" within ".byline" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Import multiple works as an archivist + When I import the works "http://ao3testing.dreamwidth.org/593.html, http://ao3testing.dreamwidth.org/325.html" + Then I should see multi-story import messages + And I should see "Story" + And I should see "Test entry" + And I should see "We have notified the author(s) you imported works for. If any were missed, you can also add co-authors manually." + + # TODO: Enable after AO3-6353. + @wip + Scenario: Importing only sends one email even if there are many works + When I import the works "http://ao3testing.dreamwidth.org/593.html, http://ao3testing.dreamwidth.org/325.html" + Then 1 email should be delivered to "ao3testing@dreamwidth.org" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Importing for an existing Archive author should have correct byline and email + Given the following activated user exists + | login | email | + | ao3 | ao3testing@dreamwidth.org | + When I import the work "http://ao3testing.dreamwidth.org/593.html" + And all indexing jobs have been run + Then I should see import confirmation + And I should see "ao3" + And I should not see "[archived by archivist]" + And 1 email should be delivered to "ao3testing@dreamwidth.org" + And the email should contain claim information + When I go to ao3's works page + Then I should see "Story" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Importing for an email address that's not associated with an existing Archive account, but that does belong to a user, allows the user to claim the works and add them to their account + Given the user "creator" exists and is activated + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "creator" with email "not_creators_account_email@example.com" + And all indexing jobs have been run + Then 1 email should be delivered to "not_creators_account_email@example.com" + When I am logged in as "creator" + # Use the URL because we get logged out if we follow the link in the email + And I go to the claim page for "not_creators_account_email@example.com" + Then I should see "Claim your works with your logged-in account." + When I press "Add these works to my currently-logged-in account" + And all indexing jobs have been run + Then I should see "Author Identities for creator" + And I should see "We have added the stories imported under not_creators_account_email@example.com to your account." + When I go to creator's works page + Then I should see "Story" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Importing sends an email to a guessed address if it can't find the author + When I import the work "http://ao3testing.dreamwidth.org/593.html" + Then I should see import confirmation + And I should see "Story" + # Importer assumes dreamwidth email for works from there + And 1 email should be delivered to "ao3testing@dreamwidth.org" + And the email should contain invitation warnings from "archivist" for work "Story" in fandom "Testing" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Import a single work as an archivist specifying an external author + When I go to the import page + And I import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + Then I should not see multi-story import messages + And I should see "Story" + And I should see "randomtestname" + And I should see "We have notified the author(s) you imported works for. If any were missed, you can also add co-authors manually." + And 1 email should be delivered to "random@example.com" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Import a single work as an archivist specifying an external author with an invalid name + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "ra_ndo!m-t??est n@me." with email "random@example.com" + Then I should see import confirmation + And I should see "ra_ndom-test n@me." + And 1 email should be delivered to "random@example.com" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Claim a work and create a new account in response to an invite + Given account creation is enabled + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + Then 1 email should be delivered to "random@example.com" + And the email should contain "Claim or remove your works" + When I am logged out + And I follow "Claim or remove your works" in the email + Then I should see "Claiming Your Imported Works" + And I should see "An archive including some of your work(s) has been moved to the Archive of Our Own." + When I press "Sign me up and give me my works!" + Then I should see "Create Account" + When I fill in the sign up form with valid data + And I press "Create Account" + Then I should see "Almost Done!" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Orphan a work in response to an invite, leaving name on it + Given I have an orphan account + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + Then 1 email should be delivered to "random@example.com" + And the email should contain "Claim or remove your works" + When I am logged out + And I follow "Claim or remove your works" in the email + Then I should see "Claiming Your Imported Works" + And I should see "An archive including some of your work(s) has been moved to the Archive of Our Own." + When I choose "Orphan my works and take my email address off them, but keep my name." + And I wait 2 seconds + And I press "Update" + Then I should see "Your imported stories have been orphaned. Thank you for leaving them in the archive! Your preferences have been saved." + When I am logged in + And I view the work "Story" + Then I should see "randomtestname (orphan_account)" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Orphan a work in response to an invite, taking name off it + Given I have an orphan account + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + Then 1 email should be delivered to "random@example.com" + And the email should contain "Claim or remove your works" + When I am logged out + And I follow "Claim or remove your works" in the email + Then I should see "Claiming Your Imported Works" + And I should see "An archive including some of your work(s) has been moved to the Archive of Our Own." + When I choose "Orphan my works and take my email address off them, but keep my name." + And I check "Assign my works to the AO3 orphan_account, removing both my name and email address." + And I wait 2 seconds + And I press "Update" + Then I should see "Your imported stories have been orphaned. Thank you for leaving them in the archive! Your preferences have been saved." + When I am logged in + And I view the work "Story" + Then I should not see "randomtestname" + And I should see "orphan_account" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Delete an imported work and choose not to be notified of future imports of your works + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + Then 1 email should be delivered to "random@example.com" + And the email should contain "Claim or remove your works" + When I am logged out + And I follow "Claim or remove your works" in the email + Then I should see "Claiming Your Imported Works" + And I should see "An archive including some of your work(s) has been moved to the Archive of Our Own. Please let us know what you'd like us to do with them." + When I choose "Please remove my works from the archive entirely." + And I check "Do not email me in the future when works are imported with this email address." + And I press "Update" + Then I should be on the homepage + And I should see "Your imported stories have been deleted. Your preferences have been saved." + When the email queue is clear + And I am logged in as "archivist" + And I import the work "http://ao3testing.dreamwidth.org/325.html" by "randomtestname" with email "random@example.com" + Then 0 emails should be delivered to "random@example.com" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Leave an imported work in the archivist's care + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + Then 1 email should be delivered to "random@example.com" + And the email should contain "Claim or remove your works" + When I am logged out + And I follow "Claim or remove your works" in the email + Then I should see "Claiming Your Imported Works" + And I should see "An archive including some of your work(s) has been moved to the Archive of Our Own. Please let us know what you'd like us to do with them." + When I choose "Leave my works in the care of the archivist." + And I press "Update" + Then I should be on the homepage + And I should see "Okay, we'll leave things the way they are! You can use the email link any time if you change your mind. Your preferences have been saved." + + # TODO: Enable after AO3-6353. + @wip + Scenario: Leave an imported work in the archivist's care and choose not to be notified of future imports of your works + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + Then 1 email should be delivered to "random@example.com" + And the email should contain "Claim or remove your works" + When I am logged out + And I follow "Claim or remove your works" in the email + Then I should see "Claiming Your Imported Works" + And I should see "An archive including some of your work(s) has been moved to the Archive of Our Own. Please let us know what you'd like us to do with them." + When I choose "Leave my works in the care of the archivist." + And I check "Do not email me in the future when works are imported with this email address." + And I press "Update" + Then I should be on the homepage + And I should see "Okay, we'll leave things the way they are! You can use the email link any time if you change your mind. Your preferences have been saved." + When the email queue is clear + And I am logged in as "archivist" + And I import the work "http://ao3testing.dreamwidth.org/325.html" by "randomtestname" with email "random@example.com" + Then 0 emails should be delivered to "random@example.com" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Leave an imported work in the archivist's care and do not allow future imports with your email address + When I import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + Then 1 email should be delivered to "random@example.com" + And the email should contain "Claim or remove your works" + When I am logged out + And I follow "Claim or remove your works" in the email + Then I should see "Claiming Your Imported Works" + And I should see "An archive including some of your work(s) has been moved to the Archive of Our Own. Please let us know what you'd like us to do with them." + When I choose "Leave my works in the care of the archivist." + And I check "From now on, do not import works with this email address." + And I press "Update" + Then I should be on the homepage + And I should see "Okay, we'll leave things the way they are! You can use the email link any time if you change your mind. Your preferences have been saved." + When I am logged in as "archivist" + And I import the work "http://ao3testing.dreamwidth.org/325.html" by "randomtestname" with email "random@example.com" + Then I should see "We couldn't successfully import that work, sorry: Author randomtestname at random@example.com does not allow importing their work to this archive." + + # TODO: Enable after AO3-6353. + @wip + Scenario: Importing straight into a collection + Given I have a collection "Club" + And I am logged in as "archivist" + When I start to import the work "http://ao3testing.dreamwidth.org/593.html" by "randomtestname" with email "random@example.com" + And I press "Import" + Then I should see "We have notified the author(s) you imported works for. If any were missed, you can also add co-authors manually." + When I press "Edit" + And I fill in "work_collection_names" with "Club" + And I press "Post" + Then I should see "Story" + And I should see "randomtestname" + And I should see "Club" + And 1 email should be delivered to "random@example.com" + + # TODO: Enable after AO3-6353. + @wip + Scenario: Should not be able to import for others unless the box is checked + When I go to the import page + And I fill in "URLs*" with "http://ao3testing.dreamwidth.org/593.html" + And I select "English" from "Choose a language" + And I fill in "Author Name*" with "ao3testing" + And I fill in "Author Email Address*" with "ao3testing@example.com" + And I press "Import" + Then I should see /You have entered an external author name or e-mail address but did not select "Import for others."/ + When I check the 1st checkbox with id matching "importing_for_others" + And I press "Import" + Then I should see "We have notified the author(s) you imported works for. If any were missed, you can also add co-authors manually." + + Scenario: Archivist can't see Open Doors tools + When I go to the Open Doors tools page + Then I should see "Sorry, you don't have permission to access the page you were trying to reach." + + Scenario: Open Doors committee members can update the redirect URL of a work + Given the work "My Immortal" + And I have an Open Doors committee member "OpenDoors" + And I am logged in as "OpenDoors" + When I go to the Open Doors tools page + Then I should see "Update Redirect URL" + When I fill in "imported_from_url" with "http://example.com/my-immortal" + And I fill in "work_url" with the path to the "My Immortal" work page + And I submit with the 2nd button + Then I should see "Updated imported-from url for My Immortal to http://example.com/my-immortal" + When I follow "http://example.com/my-immortal" + Then I should be on the "My Immortal" work page + + Scenario: Open Doors committee members can block an email address from having imports + Given I have an Open Doors committee member "OpenDoors" + And I have an archivist "archivist" + And I set up mock websites for importing + And the default ratings exist + And I am logged in as "OpenDoors" + When I go to the Open Doors tools page + And I fill in "external_author_email" with "random@example.com" + And I submit with the 3rd button + Then I should see "We have saved and blocked the email address random@example.com" + When I am logged in as "archivist" + And I import the work "http://example.com/second-import-site-with-tags" by "ao3testing" with email "random@example.com" + Then I should see "Author ao3testing at random@example.com does not allow importing their work to this archive." + + Scenario: Open Doors committee members can supply a new email address for an already imported work. + Given I have an Open Doors committee member "OpenDoors" + And I have an archivist "archivist" + And I set up mock websites for importing + And the default ratings exist + And I am logged in as "archivist" + When I import the work "http://example.com/second-import-site-with-tags" by "randomtestname" with email "random@example.com" + And I am logged in as "OpenDoors" + And I go to the Open Doors external authors page + Then I should see "random@example.com" + When I fill in "email" with "random_person@example.com" + And I submit + Then I should see "Claim invitation for random@example.com has been forwarded to random_person@example.com" + And 1 email should be delivered to "random_person@example.com" diff --git a/features/importing/archivist_creatorships.feature b/features/importing/archivist_creatorships.feature new file mode 100755 index 0000000..a36aca5 --- /dev/null +++ b/features/importing/archivist_creatorships.feature @@ -0,0 +1,83 @@ +Feature: Special co-creator behavior for archivists + + Background: + Given I have an archivist "archivist" + And I am logged in as "archivist" + + Scenario: Archivists can add users who allow co-creators to works + Given the user "allow" exists and is activated + And the user "allow" allows co-creators + When I set up a draft "Imported" + And I try to invite the co-author "allow" + And I press "Post" + Then I should see "allow, archivist" within ".byline" + And 1 email should be delivered to "allow" + And the email should contain "The user archivist has added your pseud allow as a co-creator on the following work:" + And the email should not contain "translation missing" + + Scenario: Archivists can add users who don't allow co-creators to works + Given the user "disallow" exists and is activated + And the user "disallow" disallows co-creators + When I set up a draft "Imported" + And I try to invite the co-author "disallow" + And I press "Post" + Then I should see "archivist, disallow" within ".byline" + And 1 email should be delivered to "disallow" + And the email should contain "The user archivist has added your pseud disallow as a co-creator on the following work:" + And the email should not contain "translation missing" + + Scenario: Archivists can add users who allow co-creators to chapters + Given the user "allow" exists and is activated + And the user "allow" allows co-creators + And I post the work "Imported" + When a chapter is set up for "Imported" + And I try to invite the co-author "allow" + # Expire byline cache + And it is currently 1 second from now + And I press "Post" + Then I should see "allow, archivist" within ".byline" + And 1 email should be delivered to "allow" + And the email should contain "The user archivist has added your pseud allow as a co-creator on the following chapter:" + And the email should not contain "translation missing" + + Scenario: Archivists can add users who don't allow co-creators to chapters + Given the user "disallow" exists and is activated + And the user "disallow" disallows co-creators + And I post the work "Imported" + When a chapter is set up for "Imported" + And I try to invite the co-author "disallow" + # Expire byline cache + And it is currently 1 second from now + And I press "Post" + Then I should see "archivist, disallow" within ".byline" + And 1 email should be delivered to "disallow" + And the email should contain "The user archivist has added your pseud disallow as a co-creator on the following chapter:" + And the email should not contain "translation missing" + + Scenario: Archivists can add users who allow co-creators to series + Given the user "allow" exists and is activated + And the user "allow" allows co-creators + And I post the work "Imported" as part of a series "Imported Series" + When I view the series "Imported Series" + And I follow "Edit Series" + And I try to invite the co-author "allow" + And it is currently 1 second from now + And I press "Update" + Then "allow" should be a co-creator of the series "Imported Series" + And 1 email should be delivered to "allow" + And the email should contain "The user archivist has added your pseud allow as a co-creator on the following series:" + And the email should not contain "translation missing" + + Scenario: Archivists can add users who don't allow co-creators to series + Given the user "disallow" exists and is activated + And the user "disallow" disallows co-creators + And I post the work "Imported" as part of a series "Imported Series" + When I view the series "Imported Series" + And I follow "Edit Series" + And I try to invite the co-author "disallow" + And it is currently 1 second from now + And I press "Update" + Then "disallow" should be a co-creator of the series "Imported Series" + And 1 email should be delivered to "disallow" + And the email should contain "The user archivist has added your pseud disallow as a co-creator on the following series:" + And the email should not contain "translation missing" diff --git a/features/importing/work_import.feature b/features/importing/work_import.feature new file mode 100755 index 0000000..f8b6617 --- /dev/null +++ b/features/importing/work_import.feature @@ -0,0 +1,367 @@ +@import +Feature: Import Works + In order to have an archive full of works + As an author + I want to create new works by importing them + + Scenario: You can't create a work unless you're logged in + When I go to the import page + Then I should see "Please log in" + + Scenario: Creating a new minimally valid work + When I set up importing with a mock website + Then I should see "Import New Work" + When I fill in "urls" with "http://import-site-without-tags" + And I press "Import" + Then I should see "Language cannot be blank." + When I select "Deutsch" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Untitled Imported Work" + And I should see "Language: Deutsch" + And I should not see "A work has already been imported from http://import-site-without-tags" + And I should see "No Fandom" + And I should see "Chose Not To" + And I should see "Not Rated" + When I press "Post" + Then I should see "Work was successfully posted." + When I go to the works page + Then I should see "Untitled Imported Work" + + Scenario: With override disabled and tag detection enabled, tags should be detected + When I start importing "http://import-site-with-tags" with a mock website + And I select "Deutsch" from "Choose a language" + And I select "Explicit" from "Rating" + And I check "No Archive Warnings Apply" + And I fill in "Fandoms" with "Idol RPF" + And I check "M/M" + And I fill in "Relationships" with "Adam/Kris" + And I fill in "Characters" with "Adam Lambert, Kris Allen" + And I fill in "Additional Tags" with "kinkmeme" + And I fill in "Notes at the beginning" with "This is a <i>note</i>" + When I press "Import" + Then I should see "Preview" + And I should see "Detected Title" + And I should see "Language: Deutsch" + And I should see "Explicit" + And I should see "Archive Warning: Underage Sex" + And I should see "Fandom: Detected Fandom" + And I should see "Category: M/M" + And I should see "Relationship: Detected 1/Detected 2" + And I should see "Characters: Detected 1Detected 2" + And I should see "Additional Tags: Detected tag 1Detected tag 2" + And I should see "Notes: This is a content note." + When I press "Post" + Then I should see "Work was successfully posted." + + Scenario: With override and tag detection enabled, provided tags should be used when tags are entered + When I start importing "http://import-site-with-tags" with a mock website + And I select "Deutsch" from "Choose a language" + And I check "override_tags" + And I choose "detect_tags_true" + And I select "Mature" from "Rating" + And I check "No Archive Warnings Apply" + And I fill in "Fandoms" with "Idol RPF" + And I check "F/M" + And I fill in "Relationships" with "Adam/Kris" + And I fill in "Characters" with "Adam Lambert, Kris Allen" + And I fill in "Additional Tags" with "kinkmeme" + And I fill in "Notes at the beginning" with "This is a <i>note</i>" + When I press "Import" + Then I should see "Preview" + And I should see "Detected Title" + And I should see "Language: Deutsch" + And I should see "Rating: Mature" + And I should see "Archive Warning: No Archive Warnings" + And I should see "Fandom: Idol RPF" + And I should see "Category: F/M" + And I should see "Relationship: Adam/Kris" + And I should see "Characters: Adam LambertKris Allen" + And I should see "Additional Tags: kinkmeme" + And I should see "Notes: This is a note" + When I press "Post" + Then I should see "Work was successfully posted." + + Scenario: With override and tag detection enabled, both provided and detected tags should be used when not all tags are entered + When I start importing "http://import-site-with-tags" with a mock website + And I select "Deutsch" from "Choose a language" + And I check "override_tags" + And I choose "detect_tags_true" + And I select "Mature" from "Rating" + And I check "No Archive Warnings Apply" + And I fill in "Characters" with "Adam Lambert, Kris Allen" + And I fill in "Additional Tags" with "kinkmeme" + And I fill in "Notes at the beginning" with "This is a <i>note</i>" + And I press "Import" + Then I should see "Preview" + And I should see "Detected Title" + And I should see "Language: Deutsch" + And I should see "Rating: Mature" + And I should see "Archive Warning: No Archive Warnings" + And I should see "Fandom: Detected Fandom" + And I should see "Relationship: Detected 1/Detected 2" + And I should see "Characters: Adam LambertKris Allen" + And I should see "Additional Tags: kinkmeme" + And I should see "Notes: This is a note" + And I should not see "Category: M/M" + When I press "Post" + Then I should see "Work was successfully posted." + + Scenario: Default tags should be used when no tags are entered, and override is enabled and tag detection is disabled + When I start importing "http://import-site-with-tags" with a mock website + And I check "override_tags" + And I choose "detect_tags_false" + When I press "Import" + Then I should see "Detected Title" + And I should see "Rating: Not Rated" + And I should see "Archive Warning: Creator Chose Not To Use Archive Warnings" + And I should see "Fandom: No Fandom" + And I should not see "Relationship:" + And I should not see "Additional Tags:" + And I should not see "Relationship: Detected 1/Detected 2" + + Scenario Outline: Admins see IP address on imported works + Given I import "http://import-site-with-tags" with a mock website + And I press "Post" + When I am logged in as a "<role>" admin + And I go to the "Detected Title" work page + Then I should see "IP Address: 127.0.0.1" + + Examples: + | role | + | legal | + | policy_and_abuse | + + Scenario Outline: Admins see IP address on works imported without preview + Given I start importing "http://import-site-with-tags" with a mock website + And I check "Post without previewing" + And I press "Import" + When I am logged in as a "<role>" admin + And I go to the "Detected Title" work page + Then I should see "IP Address: 127.0.0.1" + + Examples: + | role | + | legal | + | policy_and_abuse | + + Scenario Outline: Admins see IP address on multi-chapter works imported without preview + Given I import the urls with mock websites as chapters without preview + """ + http://import-site-without-tags + http://second-import-site-without-tags + """ + When I am logged in as a "policy_and_abuse" admin + And I go to the "Untitled Imported Work" work page + Then I should see "Chapters:2/2" + And I should see "IP Address: 127.0.0.1" + + Examples: + | role | + | legal | + | policy_and_abuse | + + Scenario: Imported works can be set to restricted + When I start importing "http://import-site-with-tags" with a mock website + And I check "Only show imported works to registered users" + And I press "Import" + And I press "Post" + When I am logged out + And I go to the "Detected Title" work page + Then I should see "This work is only available to registered users of the Archive." + + Scenario: Imported works can have comments enabled to guests + When I start importing "http://import-site-with-tags" with a mock website + And I choose "comment_permissions_enable_all" + And I press "Import" + And I press "Post" + When I am logged out + And I go to the "Detected Title" work page + And I follow "Yes, Continue" + Then I should see "Guest name" + + Scenario: Imported works can have comments disabled to guests + When I start importing "http://import-site-with-tags" with a mock website + And I choose "comment_permissions_disable_anon" + And I press "Import" + And I press "Post" + When I am logged out + And I go to the "Detected Title" work page + And I follow "Yes, Continue" + Then I should see "Sorry, this work doesn't allow non-Archive users to comment." + + Scenario: Imported works can have comments disabled + When I start importing "http://import-site-with-tags" with a mock website + And I choose "comment_permissions_disable_all" + And I press "Import" + And I press "Post" + When I go to the "Detected Title" work page + Then I should see "Sorry, this work doesn't allow comments." + + Scenario: Imported works can have comment moderation off + When I start importing "http://import-site-with-tags" with a mock website + And I uncheck "moderated_commenting_enabled" + And I press "Import" + And I press "Post" + When I am logged out + And I go to the "Detected Title" work page + And I follow "Yes, Continue" + Then I should not see "This work's creator has chosen to moderate comments on the work." + + Scenario: Imported works can have comment moderation on + When I start importing "http://import-site-with-tags" with a mock website + And I choose "comment_permissions_enable_all" + And I check "moderated_commenting_enabled" + And I press "Import" + And I press "Post" + When I am logged out + And I go to the "Detected Title" work page + And I follow "Yes, Continue" + Then I should see "This work's creator has chosen to moderate comments on the work." + + Scenario: Importing multiple works with backdating + When I import the urls with mock websites + """ + http://example.com/second-import-site-with-tags.html + http://example.com/import-site-with-tags + """ + Then I should see "Imported Works" + And I should see "We were able to successfully upload" + And I should see "Huddling" + And I should see "Detected Title" + When I follow "Huddling" + Then I should see "Preview" + And I should see "2010-01-11" + + Scenario: Importing a new multichapter work with backdating should have correct chapter index dates + Given I set up importing with a mock website + When I fill in "urls" with + """ + http://example.com/import-site-with-tags + http://example.com/second-import-site-with-tags.html + """ + And I choose "Chapters in a single work" + And I select "Deutsch" from "Choose a language" + And I press "Import" + Then I should see "Preview" + When I press "Post" + Then I should see "Language: Deutsch" + And I should see "Published:2002-01-12" + And I should see "Completed:2010-01-11" + When I follow "Chapter Index" + Then I should see "1. Chapter 1 (2002-01-12)" + And I should see "2. Huddling (2010-01-11)" + + Scenario: Imported multichapter work should have the correct word count + Given I import the urls with mock websites as chapters without preview + """ + http://import-site-without-tags + http://second-import-site-without-tags + """ + Then I should see "Words:5" + + Scenario: Editing an imported multichapter work should have the correct word count + Given I import the urls with mock websites as chapters without preview + """ + http://import-site-without-tags + http://second-import-site-without-tags + """ + Then I should see "Words:5" + When I follow "Edit" + And I follow "1" + And I fill in "content" with "some extra content that is longer than before" + And I press "Post" + Then I should see "Words:11" + +# Scenario: Import works for others and have them automatically notified + + @work_import_special_characters_auto_utf + Scenario: Import a work with special characters (UTF-8, autodetect from page encoding) + When I import "http://www.rbreu.de/otwtest/utf8_specified.html" + Then I should see "Preview" + And I should see "Das Maß aller Dinge" within "h2.title" + And I should see "Ä Ö Ü é è È É ü ö ä ß ñ" + + @work_import_special_characters_auto_latin + Scenario: Import a work with special characters (latin-1, autodetect from page encoding) + When I import "http://www.rbreu.de/otwtest/latin1_specified.html" + Then I should see "Preview" + And I should see "Das Maß aller Dinge" within "h2.title" + And I should see "Ä Ö Ü é è È É ü ö ä ß ñ" + + @work_import_special_characters_man_latin + Scenario: Import a work with special characters (latin-1, must set manually) + When I start importing "http://www.rbreu.de/otwtest/latin1_notspecified.html" + And I select "ISO-8859-1" from "encoding" + When I press "Import" + Then I should see "Preview" + And I should see "Das Maß aller Dinge" within "h2.title" + And I should see "Ä Ö Ü é è È É ü ö ä ß ñ" + + @work_import_special_characters_man_cp + Scenario: Import a work with special characters (cp-1252, must set manually) + When I start importing "http://rbreu.de/otwtest/cp1252.txt" + And I select "Windows-1252" from "encoding" + When I press "Import" + Then I should see "Preview" + And I should see "‘He hadn’t known.’" + And I should see "So—what’s up?" + And I should see "“Something witty.”" + + @work_import_special_characters_man_utf + Scenario: Import a work with special characters (utf-8, must overwrite wrong page encoding) + When I start importing "http://www.rbreu.de/otwtest/utf8_notspecified.html" + And I select "UTF-8" from "encoding" + When I press "Import" + Then I should see "Preview" + And I should see "Das Maß aller Dinge" within "h2.title" + And I should see "Ä Ö Ü é è È É ü ö ä ß ñ" + + # TODO: scarvesandcoffee.net is 403. + @wip + Scenario: Import a chaptered work from an efiction site + When I import "http://www.scarvesandcoffee.net/viewstory.php?sid=9570" + Then I should see "Preview" + And I should see "Chapters: 4" + When I press "Post" + And I follow "Next Chapter →" + Then I should see "Chapter 2" + + Scenario: Searching for an imported work by URL will redirect you to the work + When I import "http://import-site-with-tags" with a mock website + And I press "Post" + And I go to the redirect page + And I fill in "Original URL of work" with "http://import-site-with-tags" + And I press "Go" + Then I should see "Detected Title" + + Scenario: Import URLs as chapters of a single work and post from drafts page + Given I import the urls with mock websites as chapters + """ + http://import-site-without-tags + http://second-import-site-without-tags + """ + When I follow "My Dashboard" + And I follow "Drafts (" + And I follow "Post Draft" + Then I should see "Your work was successfully posted." + And I should not see "This chapter is a draft and hasn't been posted yet!" + When I follow "Next Chapter" + Then I should not see "This chapter is a draft and hasn't been posted yet!" + + Scenario: Importing as an archivist for an existing Archive author should send translated claim email + Given a locale with translated emails + And the following activated users exist + | login | email | + | sam | sam@example.com | + | notsam | notsam@example.com | + And the user "sam" enables translated emails + And all emails have been delivered + When I import the mock work "http://import-site-without-tags" by "sam" with email "sam@example.com" and by "notsam" with email "notsam@example.com" + Then I should see import confirmation + And 1 email should be delivered to "sam@example.com" + And the email should contain claim information + And the email to "sam" should be translated + And 1 email should be delivered to "notsam@example.com" + And the email should contain claim information + And the email to "notsam" should be non-translated diff --git a/features/importing/work_import_da.feature b/features/importing/work_import_da.feature new file mode 100755 index 0000000..ebc6343 --- /dev/null +++ b/features/importing/work_import_da.feature @@ -0,0 +1,73 @@ +# TODO: Enable tests after AO3-5716. +@wip +@works @import +Feature: Import Works from deviantart + In order to have an archive full of works + As an author + I want to create new works by importing them from deviantart + + @import_da_title_link + Scenario: Creating a new art work from a deviantart title link with automatic metadata + Given basic tags + And I am logged in as "cosomeone" + When I go to the import page + And I fill in "urls" with "http://bingeling.deviantart.com/art/Flooded-45971613" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + # And I should see the image "src" text "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/intermediary/f/917f216b-24af-41f8-9802-7ab80f56d2f2/drdbx9-adee7105-ed30-4e62-a66d-4f78dfa36879.jpg" + And I should see the image "src" text "https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/917f216b-24af-41f8-9802-7ab80f56d2f2/drdbx9-adee7105-ed30-4e62-a66d-4f78dfa36879.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7InBhdGgiOiJcL2ZcLzkxN2YyMTZiLTI0YWYtNDFmOC05ODAyLTdhYjgwZjU2ZDJmMlwvZHJkYng5LWFkZWU3MTA1LWVkMzAtNGU2Mi1hNjZkLTRmNzhkZmEzNjg3OS5qcGcifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6ZmlsZS5kb3dubG9hZCJdfQ.rcJ-cfuf5xgyl97ztUJVOYQ2PmHgc6P_FWCirRiUKFU" + And I should see "Digital Art" within "dd.freeform" + And I should see "People" within "dd.freeform" + And I should see "Vector" within "dd.freeform" + And I should see "Published:2007-01-04" + # Importer picks up artist name as title instead of actual title + And I should not see "Flooded" within "h2.title" + And I should see "bingeling" within "h2.title" + And I should see "done with Photoshop 7" within "div.notes" + And I should see "but they were definitely helpful" within "div.notes" + And I should not see "deviant" + And I should not see "Visit the Artist" + And I should not see "Download Image" + When I press "Post" + Then I should see "Work was successfully posted." + When I am on cosomeone's user page + Then I should see "bingeling" + + @import_da_gallery_link + Scenario: Creating a new art work from a deviantart gallery link fails - it needs the direct link + Given basic tags + And I am logged in as "cosomeone" + When I go to the import page + And I fill in "urls" with "http://bingeling.deviantart.com/gallery/#/drdbx9" + And I select "English" from "Choose a language" + And I press "Import" + Then I should not see "Preview" + And I should see "Chapter 1 of" + And I should see "is blank." + + @import_da_fic + Scenario: Creating a new fic from deviantart import + Given basic tags + And I am logged in as "cosomeone" + When I go to the import page + And I fill in "urls" with "http://cesy12.deviantart.com/art/AO3-testing-text-196158032" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Scraps" + And I should see "Published:2011-02-04" + # Importer picks up artist name as title instead of actual title + And I should not see "AO3 testing text" within "h2.title" + And I should see "cesy12" within "h2.title" + And I should see "This is the description of the story above." within "div.notes" + And I should see "This is a text, like a story or something." + And I should see "Complete with some paragraphs." + And I should not see "deviant" + And I should not see "AO3 testing text" within "#chapters" + And I should not see "Visit the Artist" + And I should not see "Download File" + When I press "Post" + Then I should see "Work was successfully posted." + When I am on cosomeone's user page + Then I should see "cesy12" diff --git a/features/importing/work_import_dw.feature b/features/importing/work_import_dw.feature new file mode 100755 index 0000000..63dee9e --- /dev/null +++ b/features/importing/work_import_dw.feature @@ -0,0 +1,170 @@ +# TODO: Enable tests after AO3-6353. +@wip +@works +Feature: Import Works from DW + In order to have an archive full of works + As an author + I want to create new works by importing them from DW + + @import_dw + Scenario: Importing a new work from an DW story with automatic metadata + Given basic tags + And a fandom exists with name: "Testing", canonical: true + And the following activated user exists + | login | password | + | cosomeone | something | + And I am logged in as "cosomeone" with password "something" + When I go to the import page + And I fill in "urls" with "https://ao3testing.dreamwidth.org/1726.html" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Testing" within "dd.fandom" + And I should see "General Audiences" within "dd.rating" + And I should see "Character A/Character B" within "dd.relationship" + And I should see "Published:2017-07-03" + And I should see "Importing Test" within "h2.title" + And I should not see "Import Test" within "h2.title" + And I should see "Something I made for testing purposes." within "div.summary" + And I should see "THIS IS USED FOR AUTOMATED TESTS" within "div.notes" + And I should see "This is the body of my single-chapter work." + And I should not see the image "alt" text "Add to memories" + And I should not see the image "alt" text "Next Entry" + And I should not see "location" + And I should not see "music" + And I should not see "mood" + And I should not see "Entry tags" + And I should not see "Crossposts" + When I press "Post" + Then I should see "Work was successfully posted." + When I am on cosomeone's user page + Then I should see "Importing Test" + + @import_dw_tables + Scenario: Creating a new work from an DW story that has tables + # This is to make sure that we don't accidentally strip other tables than + # DW metadata tables esp. when there's no DW metadata table + + Given basic tags + And the following activated user exists + | login | password | + | cosomeone | something | + And I am logged in as "cosomeone" with password "something" + When I go to the import page + And I fill in "urls" with "https://ao3testing.dreamwidth.org/1836.html" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Testing" within "dd.fandom" + And I should see "Teen And Up Audiences" within "dd.rating" + And I should see "Character A/Character B" within "dd.relationship" + And I should see "Published:2017-07-03" + And I should see "Single Chapter Fic from DW" within "h2.title" + And I should see "THIS IS USED FOR AUTOMATED TESTS" within "div.notes" + And I should see "This is the body of my single-chapter work." + And I should not see the image "alt" text "Add to memories" + And I should not see the image "alt" text "Next Entry" + And I should see "My location" + And I should see "My music" + When I press "Post" + Then I should see "Work was successfully posted." + When I am on cosomeone's user page + Then I should see "Single Chapter Fic from DW" + + @import_dw_tables_no_backdate + Scenario: Creating a new work from an DW story without backdating it + Given basic tags + And the following activated user exists + | login | password | + | cosomeone | something | + And I am logged in as a random user + When I go to the import page + And I fill in "urls" with "https://ao3testing.dreamwidth.org/1726.html" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Importing Test" + When I press "Edit" + Then I should see "* Required information" + And I should see "Importing Test" + When I set the publication date to today + And I check "No Archive Warnings Apply" + When I press "Preview" + Then I should see "Importing Test" + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "Importing Test" within "h2.title" + And I should not see "Created:2017-08-29" + And I should not see the image "alt" text "Add to memories!" + And I should not see the image "alt" text "Next Entry" + + @import_dw_comm + Scenario: Creating a new work from an DW story that is posted to a community + Given basic tags + And I am logged in as "cosomeone" + When I go to the import page + And I fill in "urls" with "https://ao3testingcomm.dreamwidth.org/702.html" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Testing" within "dd.fandom" + And I should see "Explicit" within "dd.rating" + And I should see "Published:2017-08-29" + And I should see "Rails 5.1 Single Chapter from Comm (DW)" within "h2.title" + And I should see "This is an imported work" within "div.summary" + And I should see "This is a Rails 5.1 importing test." + And I should see the image "src" text "https://ao3testing.dreamwidth.org/file/495.jpg" + And I should not see "ao3testingcomm" + And I should not see "ao3testing" + And I should not see the image "alt" text "Add to memories" + And I should not see the image "alt" text "Next Entry" + And I should not see "mood" + And I should not see "Entry tags" + When I press "Post" + Then I should see "Work was successfully posted." + When I follow "Edit" + Then the "content" field should contain "class" + And the "content" field should contain "entry-content" + When I go to cosomeone's user page + Then I should see "Rails 5.1 Single Chapter from Comm (DW)" + + @import_dw_multi_chapter + Scenario: Creating a new multichapter work from a DW story + Given basic tags + And the following activated user exists + | login | password | + | cosomeone | something | + And I am logged in as "cosomeone" with password "something" + And the user "cosomeone" sets the time zone to "UTC" + When I go to the import page + And I fill in "urls" with + """ + https://ao3testing.dreamwidth.org/2460.html + https://ao3testing.dreamwidth.org/2664.html + https://ao3testing.dreamwidth.org/2968.html + """ + And I select "English" from "Choose a language" + And I choose "import_multiple_chapters" + And I press "Import" + Then I should see "Preview" + And I should see "Testing" within "dd.fandom" + And I should see "General Audiences" within "dd.rating" + And I should see "Rails 5.1 Chaptered (DW)" within "h2.title" + And I should not see "[FIC]" within "h2.title" + And I should see "Something I made for testing purposes." within "div.summary" + And I should see "THIS IS USED FOR AUTOMATED TESTS" within "div.notes" + And I should see "This is a Rails 5.1 importing test, chapter 1." + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "Chapters:3/3" + And I should see "Published:2017-08-29" + And I should see "Completed:2017-08-29" + And I should see "This is a Rails 5.1 importing test, chapter 1." + When I follow "Next Chapter" + Then I should see "This is a Rails 5.1 importing test, chapter 2." + And I should see "This is the summary for chapter 2." within "div.summary" + And I should see "THIS IS USED FOR AUTOMATED TESTS" within "div.notes" + And I should see "My note on chapter 2." within "div.notes" + And I should see "Rails 5.1 Chaptered (DW)" within "h3.title" + When I am on cosomeone's user page + Then I should see "Rails 5.1 Chaptered (DW)" diff --git a/features/importing/work_import_errors.feature b/features/importing/work_import_errors.feature new file mode 100755 index 0000000..036821b --- /dev/null +++ b/features/importing/work_import_errors.feature @@ -0,0 +1,26 @@ +@works +Feature: Import Works + In order to have an archive full of works + As an author + I want to create new works by importing them + + Scenario: Entering a bogus URL + Given basic tags + And I set up importing with a mock website + And I am logged in as a random user + When I go to the import page + And I fill in "urls" with "http://no-content" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "We couldn't successfully import that work, sorry: We couldn't download anything from http://no-content. Please make sure that the URL is correct and complete, and try again." + When I follow "My Dashboard" + Then I should see "Drafts (0)" + + Scenario: Cannot import works from the current archive + Given I set up importing + And I fill in "urls" with "https://archiveofourown.org/works/54711364" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "We couldn't successfully import that work, sorry: URL is for a work on the Archive. Please bookmark it directly instead." + When I follow "My Dashboard" + Then I should see "Drafts (0)" diff --git a/features/importing/work_import_ffn.feature b/features/importing/work_import_ffn.feature new file mode 100755 index 0000000..6a68173 --- /dev/null +++ b/features/importing/work_import_ffn.feature @@ -0,0 +1,25 @@ +@works +Feature: Import Works from fanfiction.net + In order to have an archive full of works + As an author + I want to create new works by importing them from fanfiction.net + + @import_ffn + Scenario: Importing a new work from an FFN story + Given I am logged in as "cosomeone" with password "something" + And the default ratings exist + When I go to the import page + And I fill in "urls" with "http://www.fanfiction.net/s/3129674/1/What_More_Than_Usual_Light" + And I select "English" from "Choose a language" + When I press "Import" + Then I should see "Sorry, Fanfiction.net does not allow imports from their site." + + @import_ffn_multi_chapter + Scenario: Importing a new multichapter work from an FFN story + Given I am logged in as "cosomeone" with password "something" + And the default ratings exist + When I go to the import page + And I fill in "urls" with "http://www.fanfiction.net/s/6646765/1/IChing" + And I select "English" from "Choose a language" + When I press "Import" + Then I should see "Sorry, Fanfiction.net does not allow imports from their site." diff --git a/features/importing/work_import_lj.feature b/features/importing/work_import_lj.feature new file mode 100755 index 0000000..3b766e9 --- /dev/null +++ b/features/importing/work_import_lj.feature @@ -0,0 +1,172 @@ +@works +Feature: Import Works from LJ + In order to have an archive full of works + As an author + I want to create new works by importing them from LJ + @import_lj + Scenario: Creating a new work from an LJ story with automatic metadata + Given basic tags + And a fandom exists with name: "Lewis", canonical: true + And I am logged in as "cosomeone" + When I go to the import page + And I fill in "urls" with "http://rebecca2525.livejournal.com/3562.html" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Lewis" within "dd.fandom" + And I should see "General Audiences" within "dd.rating" + And I should see "Lewis/Hathaway" within "dd.relationship" + And I should see "Published:2000-01-10" + And I should see "Importing Test" within "h2.title" + And I should not see "[FIC]" within "h2.title" + And I should see "Something I made for testing purposes." within "div.summary" + And I should see "Yes, this is really only for testing. :)" within "div.notes" + And I should see "My first paragraph." + And I should see "My second paragraph." + And I should not see the image "alt" text "Add to memories!" + And I should not see the image "alt" text "Next Entry" + And I should not see "location" + And I should not see "music" + And I should not see "mood" + And I should not see "Entry tags" + When I press "Post" + Then I should see "Work was successfully posted." + When I am on cosomeone's user page + Then I should see "Importing Test" + + @import_lj_tables + Scenario: Creating a new work from an LJ story that has tables + # This is to make sure that we don't accidentally strip other tables than + # LJ metadata tables esp. when there's no LJ metadata table + + Given basic tags + And a fandom exists with name: "Lewis", canonical: true + And I am logged in as "cosomeone" + When I go to the import page + And I fill in "urls" with "http://rebecca2525.livejournal.com/3591.html" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Lewis" within "dd.fandom" + And I should see "General Audiences" within "dd.rating" + And I should see "Lewis/Hathaway" within "dd.relationship" + And I should see "Published:2000-01-10" + And I should see "Importing Test" within "h2.title" + And I should not see "[FIC]" within "h2.title" + And I should see "Something I made for testing purposes." within "div.summary" + And I should see "Yes, this is really only for testing. :)" within "div.notes" + And I should see "My first paragraph." + And I should see "My second paragraph." + And I should not see the image "alt" text "Add to memories!" + And I should not see the image "alt" text "Next Entry" + And I should see "My location" + And I should see "My music" + And I should see "My mood" + And I should see "My tags" + When I press "Post" + Then I should see "Work was successfully posted." + When I am on cosomeone's user page + Then I should see "Importing Test" + + @import_lj_no_backdate + Scenario: Creating a new work from an LJ story without backdating it + Given basic tags + And I am logged in as a random user + When I go to the import page + And I fill in "urls" with "http://rebecca2525.livejournal.com/3562.html" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + And I should see "Importing Test" + When I press "Edit" + Then I should see "* Required information" + And I should see "Importing Test" + When I set the publication date to today + And I check "No Archive Warnings Apply" + And I press "Preview" + Then I should see "Importing Test" + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "Importing Test" within "h2.title" + And I should not see the image "alt" text "Add to memories!" + And I should not see the image "alt" text "Next Entry" + + @import_lj_comm + Scenario: Creating a new work from an LJ story that is posted to a community + Given basic tags + And I am logged in as "cosomeone" + When "AO3-4179" is fixed + #When I go to the import page + # And I fill in "urls" with "http://community.livejournal.com/rarelitslash/271960.html" + # And I select "English" from "Choose a language" + # And I press "Import" + #Then I should see "Preview" + # And I should see "Poirot - Agatha Christie" within "dd.fandom" + # And I should see "General Audiences" within "dd.rating" + # And I should see "Published:2010-10-23" + # And I should see "Mrs Stanwood's Birthday Party" within "h2.title" + # And I should not see "[Poirot]" within "h2.title" + # And I should see "Mrs Stanwood, famous medical researcher" within "div.summary" + # And I should see "more to their friendship than he'd thought." within "div.summary" + # And I should see "Thanks to Tevildo and phantomphan1990 for beta-reading!" + # And I should see the image "src" text "http://www.rbreu.de/fan/stanwood_title_400.png" + # And I should see "Follow me to AO3" + # And I should not see "rarelitslash" + # And I should not see "rebecca2525" + # And I should not see the image "alt" text "Add to memories!" + # And I should not see the image "alt" text "Next Entry" + # And I should not see "mood" + # And I should not see "Entry tags" + #When I press "Post" + #Then I should see "Work was successfully posted." + #When I am on cosomeone's user page + #Then I should see "Mrs Stanwood's Birthday Party" + + @import_lj_underscores + Scenario: Importing from a journal with underscores in the name + Given basic tags + And I am logged in as "cosomeone" + When I go to the import page + And I fill in "urls" with "http://ao3_testing.livejournal.com/557.html" + And I select "English" from "Choose a language" + And I press "Import" + Then I should see "Preview" + + @import_lj_multi_chapter + Scenario: Creating a new multichapter work from an LJ story + Given basic tags + And I am logged in as "cosomeone" + And the user "cosomeone" sets the time zone to "UTC" + When I go to the import page + And I fill in "urls" with + """ + http://rebecca2525.livejournal.com/3562.html + http://rebecca2525.livejournal.com/4024.html + """ + And I select "English" from "Choose a language" + And I choose "import_multiple_chapters" + And I press "Import" + Then I should see "Preview" + And I should see "Lewis" within "dd.fandom" + And I should see "General Audiences" within "dd.rating" + And I should see "Importing Test" within "h2.title" + And I should not see "[FIC]" within "h2.title" + And I should see "Something I made for testing purposes." within "div.summary" + And I should see "Yes, this is really only for testing. :)" within "div.notes" + And I should see "My first paragraph." + And I should see "My second paragraph." + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "Chapters:2/2" + And I should see "Published:2000-01-10" + And I should see "Completed:2000-01-22" + And I should see "My first paragraph." + And I should see "My second paragraph." + When I follow "Next Chapter" + Then I should see "The long awaited second part." + And I should see "And another paragraph." + And I should see "The plot thickens." within "div.summary" + And I should see "MOAR TESTING! :)" within "div.notes" + And I should see "Importing Test Part 2" within "h3.title" + When I am on cosomeone's user page + Then I should see "Importing Test" diff --git a/features/other_a/abuse_report.feature b/features/other_a/abuse_report.feature new file mode 100755 index 0000000..cdd83ad --- /dev/null +++ b/features/other_a/abuse_report.feature @@ -0,0 +1,77 @@ +Feature: Filing an abuse report + In order to report something + As an annoyed user + I want to file an abuse ticket + + Scenario: File an abuse request with default options + + Given basic languages + When I am logged in as "otheruser" + And I am on the home page + And I follow "Policy Questions & Abuse Reports" + And I should see the text with tags 'value="http://www.example.com/' + When I fill in "Description of the content you are reporting (required)" with "This is wrong" + And I fill in "Brief summary of Terms of Service violation (required)" with "This is a summary of bad things" + And I fill in "Link to the page you are reporting (required)" with "http://www.archiveofourown.org/works" + And I press "Submit" + Then I should see "Your report was submitted to the Policy & Abuse team. A confirmation message has been sent to the email address you provided." + # Receiving a copy of the abuse report is no longer a choice for the user. + # The email is sent automatically. + And 1 email should be delivered + + Scenario: URL is auto-filled on abuse report + + Given I have a work "Illegal thing" + And basic languages + When I am logged in as "otheruser" + And I view the work "Illegal thing" + And I follow "Policy Questions & Abuse Reports" + Then I should see the text with tags 'value="http://www.example.com/works/' + + Scenario: File an abuse request while logged out + + Given basic languages + When I am on the home page + And I follow "Policy Questions & Abuse Reports" + When I fill in "Brief summary of Terms of Service violation (required)" with "This is a summary of bad things" + And I fill in "Description of the content you are reporting (required)" with "This is wrong" + And I fill in "Link to the page you are reporting (required)" with "http://www.archiveofourown.org/works" + And I fill in "Your email (required)" with "otheruser@example.org" + And I press "Submit" + Then I should see "Your report was submitted to the Policy & Abuse team. A confirmation message has been sent to the email address you provided." + And 1 email should be delivered + + Scenario: File a request and enter blank email + + When I am logged in as "otheruser" + And basic languages + And I am on the home page + And I follow "Policy Questions & Abuse Reports" + And I fill in "Brief summary of Terms of Service violation (required)" with "This is a summary of bad things" + And I fill in "Description of the content you are reporting (required)" with "This is wrong" + And I fill in "Link to the page you are reporting (required)" with "http://www.archiveofourown.org/works" + And I fill in "Your email (required)" with "" + And I select "Deutsch" from "abuse_report_language" + And I press "Submit" + And I should see "Email should look like an email address." + And "Deutsch" should be selected within "Select language (required)" + Then I fill in "Your email (required)" with "valid@archiveofourown.org" + And I press "Submit" + And I should see "Your report was submitted to the Policy & Abuse team. A confirmation message has been sent to the email address you provided." + And 1 email should be delivered + + Scenario: File a report containing images + + Given I am logged in as "otheruser" + And basic languages + When I follow "Policy Questions & Abuse Reports" + And I fill in "Brief summary of Terms of Service violation (required)" with '<img src="foo.jpg" />Gross' + And I fill in "Description of the content you are reporting (required)" with "This is wrong <img src='bar.jpeg' />" + And I fill in "Link to the page you are reporting (required)" with "http://www.archiveofourown.org/works" + And I press "Submit" + Then 1 email should be delivered + # The sanitizer adds the domain in front of relative image URLs as of AO3-6571 + And the email should not contain "<img src="http://www.example.org/foo.jpg" />" + And the email should not contain "<img src="http://www.example.org/bar.jpeg" />" + But the email should contain "Gross" + And the email should contain "This is wrong img src="http://www.example.org/bar.jpeg"" diff --git a/features/other_a/accept_header.feature b/features/other_a/accept_header.feature new file mode 100755 index 0000000..4ac4f87 --- /dev/null +++ b/features/other_a/accept_header.feature @@ -0,0 +1,10 @@ +Feature: Browsing from a non-standard user agent +As a Playstation user +In order to browse the AO3 +I want to be able to browse from my PSP + +Scenario: user agent requests a weird header + + Given I use a PSP browser + When I make a request for "/works" + Then the response should be "200" diff --git a/features/other_a/autocomplete.feature b/features/other_a/autocomplete.feature new file mode 100755 index 0000000..596ddd6 --- /dev/null +++ b/features/other_a/autocomplete.feature @@ -0,0 +1,262 @@ +Feature: Display autocomplete for tags + In order to facilitate posting + I should be getting autocompletes for my tags + + @javascript + Scenario: Only matching canonical tags should appear in autocomplete, + and searching for the same data twice should produce same results + Given I am logged in + And a set of tags for testing autocomplete + And I go to the new work page + Then the tag autocomplete fields should list only matching canonical tags + + @javascript + Scenario: If a fandom is entered, only characters/relationships in the fandom + should appear in autocomplete + Given I am logged in + And a set of tags for testing autocomplete + And I go to the new work page + Then the fandom-specific tag autocomplete fields should list only fandom-specific canonical tags + + @javascript + Scenario: Bookmark archive work form autocomplete should work + Given I am logged in + And a set of tags for testing autocomplete + When I start a new bookmark + And I enter text in the "Your tags" autocomplete field + Then I should only see matching canonical tags in the autocomplete + + @javascript + Scenario: Bookmark external work form autocomplete should work + Given I am logged in + And a set of tags for testing autocomplete + And an external work + When I go to the new external work page + Then the tag autocomplete fields should list only matching canonical tags + And the fandom-specific tag autocomplete fields should list only fandom-specific canonical tags + And the external url autocomplete field should list the urls of existing external works + + @javascript + Scenario: Work co-author and association autocompletes should work + Given I am logged in + And a set of collections for testing autocomplete + And a set of users for testing autocomplete + And basic tags + And I go to the new work page + Then the coauthor autocomplete field should list matching users + And the gift recipient autocomplete field should list matching users + And the collection item autocomplete field should list matching collections + + @javascript + Scenario: Work co-author and association autocompletes should work with pseuds containing diacrictics + Given basic tags + And a set of users for testing autocomplete + And "coauthor" has the pseud "çola" + And I am logged in + And I go to the new work page + Then the coauthor autocomplete field should list matching users + When I enter "c" in the "pseud_byline_autocomplete" autocomplete field + Then the pseud autocomplete should contain "çola (coauthor)" + And the pseud autocomplete should contain "coauthor" + When I enter "ç" in the "pseud_byline_autocomplete" autocomplete field + Then the pseud autocomplete should contain "çola (coauthor)" + And the pseud autocomplete should contain "coauthor" + + + @javascript + Scenario: Collection autocomplete shows collection title and name + Given I am logged in as "Scott" with password "password" + And I post the work "All The Nice Things" + And I set my preferences to allow collection invitations + And I have the collection "Issue" with name "jb_fletcher" + And I have the collection "Ïssue" with name "robert_stack" + And I am logged in as "moderator" + When I view the work "All The Nice Things" + And I follow "Invite To Collections" + And I enter "Issue" in the "Collection name(s)" autocomplete field + Then I should see "jb_fletcher" in the autocomplete + And I should see "robert_stack" in the autocomplete + + Scenario: Pseuds should be added and removed from autocomplete as they are changed + Given I am logged in as "new_user" + Then the pseud autocomplete should contain "new_user" + When "new_user" creates the pseud "extra" + Then the pseud autocomplete should contain "extra (new_user)" + When "new_user" changes the pseud "extra" to "funny" + And I go to new_user's pseuds page + Then I should not see "extra" + And I should see "funny" + And the pseud autocomplete should not contain "extra (new_user)" + And the pseud autocomplete should contain "funny (new_user)" + When "new_user" deletes the pseud "funny" + Then the pseud autocomplete should not contain "funny (new_user)" + And the pseud autocomplete should contain "new_user" + + Scenario: Pseuds should be added and removed from autocomplete as usernames change + Given I am logged in as "new_user" + And "new_user" creates the pseud "funny" + When I change my username to "different_user" + Then the pseud autocomplete should not contain "funny (new_user)" + And the pseud autocomplete should not contain "new_user" + And the pseud autocomplete should contain "different_user" + And the pseud autocomplete should contain "funny (different_user)" + When I try to delete my account as different_user + Then a user account should not exist for "funny" + And the pseud autocomplete should not contain "funny" + And the pseud autocomplete should not contain "different_user (funny)" + + @javascript + Scenario: People search autocomplete shows no results when searching for space + Given I go to the search people page + When I enter " " in the "Name" autocomplete field + Then I should see "Searching..." in the autocomplete + When I am logged in as "basic" + And "basic" creates the pseud "one" + And I go to the search people page + When I enter " " in the "Name" autocomplete field + Then I should see "Searching..." in the autocomplete + And I should not see "one (basic)" in the autocomplete + And I should not see "basic" in the autocomplete + + @javascript + Scenario: Characters in a fandom with non-ASCII uppercase letters should appear in the autocomplete. + + Given basic tags + And I am logged in + And a canonical character "Bear" in fandom "Østenfor sol og vestenfor måne" + And a canonical character "Beatrice" in fandom "Much Ado About Nothing" + And I go to the new work page + + When I choose "Østenfor sol og vestenfor måne" from the "Fandoms" autocomplete + And I enter "Bea" in the "Characters" autocomplete field + Then I should see "Bear" in the autocomplete + But I should not see "Beatrice" in the autocomplete + + @javascript + Scenario: Accented uppercase letters should appear in the autocomplete. + + Given basic tags + And I am logged in + And a canonical character "Éowyn (Tolkien)" + And a canonical character "Tybalt (Rómeó és Júlia)" + And I go to the new work page + + When I enter "é" in the "Characters" autocomplete field + Then I should see "Éowyn (Tolkien)" in the autocomplete + And I should see "Tybalt (Rómeó és Júlia)" in the autocomplete + When I enter "e" in the "Characters" autocomplete field + Then I should see "Éowyn (Tolkien)" in the autocomplete + And I should see "Tybalt (Rómeó és Júlia)" in the autocomplete + + + @javascript + Scenario: Other non-ASCII uppercase letters should appear in the autocomplete. + + Given basic tags + And I am logged in + And a canonical fandom "Østenfor sol og vestenfor måne" + And I go to the new work page + + When I enter "ø" in the "Fandoms" autocomplete field + Then I should see "Østenfor sol og vestenfor måne" in the autocomplete + When I enter "ostenfor" in the "Fandoms" autocomplete field + Then I should see "Østenfor sol og vestenfor måne" in the autocomplete + + @javascript + Scenario: Characters with a non-ASCII uppercase letter will appear in fandom-specific autocompletes. + + Given basic tags + And I am logged in + And a canonical character "Éowyn" in fandom "Lord of the Rings" + And I go to the new work page + + When I choose "Lord of the Rings" from the "Fandoms" autocomplete + And I enter "É" in the "Characters" autocomplete field + Then I should see "Éowyn" in the autocomplete + When I enter "e" in the "Characters" autocomplete field + Then I should see "Éowyn" in the autocomplete + + @javascript + Scenario: Search terms are highlighted in autocomplete results + Given I am logged in + And basic tags + And a canonical relationship "Cassian Andor & Jyn Erso" + And a canonical character "Éowyn" + And I go to the new work page + + When I enter "Jyn" in the "Relationships" autocomplete field + Then I should see HTML "Cassian Andor & <b>Jyn</b> Erso" in the autocomplete + + When I enter "Cass" in the "Relationships" autocomplete field + Then I should see HTML "<b>Cass</b>ian Andor & Jyn Erso" in the autocomplete + + When I enter "erso and" in the "Relationships" autocomplete field + Then I should see HTML "Cassian <b>And</b>or & Jyn <b>Erso</b>" in the autocomplete + + When I enter "Cassian Andor & Jyn Erso" in the "Relationships" autocomplete field + Then I should see HTML "<b>Cassian</b> <b>Andor</b> & <b>Jyn</b> <b>Erso</b>" in the autocomplete + + When I enter "é" in the "Characters" autocomplete field + Then I should see HTML "<b>É</b>owyn" in the autocomplete + + # AO3-4976 There should not be stray semicolons if the query has... + # ...trailing spaces + When I enter "Jyn " in the "Relationships" autocomplete field + Then I should see HTML "Cassian Andor & <b>Jyn</b> Erso" in the autocomplete + # ...leading spaces + When I enter " Jyn" in the "Relationships" autocomplete field + Then I should see HTML "Cassian Andor & <b>Jyn</b> Erso" in the autocomplete + # ...consecutive spaces + When I enter "Jyn Erso" in the "Relationships" autocomplete field + Then I should see HTML "Cassian Andor & <b>Jyn</b> <b>Erso</b>" in the autocomplete + + @javascript + Scenario: Tags with symbols shouldn't match all other tags with symbols. + + Given basic tags + And I am logged in + And a canonical freeform "AU - Canon" + And a canonical freeform "AU - Cats" + And a canonical freeform "Science Fiction & Fantasy" + And a canonical freeform "日月" + And a canonical freeform "大小" + And I go to the new work page + + When I enter "AU - Ca" in the "Additional Tags" autocomplete field + Then I should see "AU - Canon" in the autocomplete + And I should see "AU - Cats" in the autocomplete + But I should not see "Science Fiction & Fantasy" in the autocomplete + When I enter "日" in the "Additional Tags" autocomplete field + Then I should see "日月" in the autocomplete + But I should not see "大小" in the autocomplete + + @javascript + Scenario: Zero width space tag doesn't appear in the autocomplete for space + Given a canonical character "Gold" + And a zero width space tag exists + And I am logged in as a tag wrangler + When I go to the "Gold" tag edit page + Then I should see "This is the official name for the Character" + When I enter " " in the "tag_merger_string_autocomplete" autocomplete field + Then I should see "No suggestions found" in the autocomplete + + @javascript + Scenario: Zero width space tag appears in the autocomplete for zero width space + Given a canonical character "Gold" + And a zero width space tag exists + And I am logged in as a tag wrangler + When I go to the "Gold" tag edit page + Then I should see "This is the official name for the Character" + # Zero width space tag + When I enter "​" in the "tag_merger_string_autocomplete" autocomplete field + Then I should not see "No suggestions found" in the autocomplete + + @javascript + Scenario: Vertical bar is treated as a word separator + Given I am logged in + And a canonical character "Taylor Hebert | Skitter | Weaver" + And I go to the new work page + When I enter "|" in the "Characters" autocomplete field + Then I should see "No suggestions found" in the autocomplete + When I enter "Taylor|Skitter" in the "Characters" autocomplete field + Then I should see "Taylor Hebert | Skitter | Weaver" in the autocomplete diff --git a/features/other_a/banner_general.feature b/features/other_a/banner_general.feature new file mode 100755 index 0000000..3aa2228 --- /dev/null +++ b/features/other_a/banner_general.feature @@ -0,0 +1,142 @@ +@users +Feature: General notice banner + +Scenario: Banner is blank until admin sets it + Given there are no banners + Then a logged-in user should not see a banner + And a logged-out user should not see a banner + +Scenario: Admin can set a banner + Given there are no banners + When an admin creates an active banner + Then a logged-in user should see the banner + And a logged-out user should see the banner + +Scenario: Admin can set an alert banner + Given there are no banners + And an admin creates an active "alert" banner + When I am logged in as "whatever" + Then a logged-in user should see the "alert" banner + And a logged-out user should see the "alert" banner + +Scenario: Admin can set an event banner + Given there are no banners + When an admin creates an active "event" banner + Then a logged-in user should see the "event" banner + And a logged-out user should see the "event" banner + +Scenario: Admin can edit an active banner + Given there are no banners + And an admin creates an active banner + When an admin edits the active banner + Then a logged-in user should see the edited active banner + And a logged-out user should see the edited active banner + +Scenario: Admin can deactivate a banner + Given there are no banners + And an admin creates an active banner + When an admin deactivates the banner + Then a logged-in user should not see a banner + And a logged-out user should not see a banner + +Scenario: User can turn off banner using "×" button + Given there are no banners + And an admin creates an active banner + When I turn off the banner + Then the page should not have a banner + +Scenario: Banner stays off when logging out and in again + Given there are no banners + And an admin creates an active banner + And I turn off the banner + When I am logged out + And I am logged in as "newname" + Then the page should not have a banner + +Scenario: Logged out user can turn off banner + Given there are no banners + And an admin creates an active banner + And I am logged out + When I follow "×" + Then the page should not have a banner + +Scenario: User can turn off banner in preferences + Given there are no banners + And an admin creates an active banner + And I am logged in as "banner_tester" + And I set my preferences to turn off the banner showing on every page + When I go to banner_tester's user page + Then the page should not have a banner + +Scenario: User can turn off banner in preferences, but will still see a banner when an admin deactivates the existing banner and sets a new banner + Given there are no banners + And an admin creates an active banner + And I am logged in as "banner_tester_2" + When I set my preferences to turn off the banner showing on every page + And I go to banner_tester_2's user page + Then the page should not have a banner + When an admin deactivates the banner + And an admin creates a different active banner + When I am logged in as "banner_tester_2" + Then the page should have the different banner + +Scenario: Admin can delete a banner and it will no longer be shown to users + Given there are no banners + And an admin creates an active banner + When I am logged in as a "communications" admin + And I am on the admin_banners page + And I follow "Delete" + And I press "Yes, Delete Banner" + Then I should see "Banner successfully deleted." + And a logged-in user should not see a banner + And a logged-out user should not see a banner + +Scenario: Admin should not have option to make minor updates on a new banner + Given there are no banners + And I am logged in as a "communications" admin + When I am on the new_admin_banner page + Then I should not see "This is a minor update (Do not turn the banner back on for users who have dismissed it)" + +Scenario: Admin should not have option to make minor updates on banner that is not active + Given there are no banners + And an admin creates a banner + When I am logged in as a "communications" admin + And I am on the admin_banners page + And I follow "Edit" + Then I should not see "This is a minor update (Do not turn the banner back on for users who have dismissed it)" + +Scenario: Admin can make minor changes to the text of an active banner without turning it back on for users who have already dismissed it + Given there are no banners + And an admin creates an active banner + And I am logged in as "banner_tester_3" + And I set my preferences to turn off the banner showing on every page + And an admin makes a minor edit to the active banner + When I am logged in as "banner_tester_3" + Then I should not see the banner with minor edits + And the page should not have a banner + When I am logged out + Then I should see the banner with minor edits + When I am logged in as "banner_tester_4" + Then I should see the banner with minor edits + +Scenario: Development & Membership admin can see edit options but not delete or create + Given an admin creates a banner + When I am logged in as a "development_and_membership" admin + And I go to the admin_banners page + Then I should see "Banners" within "#header .admin.navigation" + And I should see "Banners" within "#main .navigation.actions" + And I should see "Edit" within "#main ul.banners.index.group" + But I should not see "Delete" within "#main ul.banners.index.group" + And I should not see "New Banner" within "#main .navigation.actions" + When I follow "Edit" + Then I should not see "New Banner" within "#main .navigation.actions" + And I should not see "Delete Banner" within "#main .navigation.actions" + But I should see "Edit Banner" within "#main h2" + And I should see "Edit Banner" within "#main .navigation.actions" + When I fill in "Banner text" with "Some fun new text" + And I press "Update Banner" + Then I should see "Banner successfully updated." + And I should see "Banners" within "#main .navigation.actions" + And I should see "Edit Banner" within "#main .navigation.actions" + But I should not see "Delete Banner" within "#main .navigation.actions" + And I should not see "New Banner" within "#main .navigation.actions" diff --git a/features/other_a/banner_login.feature b/features/other_a/banner_login.feature new file mode 100755 index 0000000..4f431f2 --- /dev/null +++ b/features/other_a/banner_login.feature @@ -0,0 +1,70 @@ +@users +Feature: First login help banner + + Scenario: New user sees the banner + + Given I am logged in as "newname" + When I am on newname's user page + Then I should see the first login banner + And I should see "For help getting started on AO3, check out some useful tips for new users or browse through our FAQs." + And I should see "If you need technical support, contact our Support team. If you experience harassment or have questions about our Terms of Service (including the Content Policy and Privacy Policy), contact our Policy & Abuse team." + When I follow "our FAQs" + Then I should be on the faq page + When I am on newname's user page + And I follow "contact our Support team" + Then I should be on the support page + When I am on newname's user page + And I follow "Terms of Service" + Then I should be on the tos page + When I am on newname's user page + And I follow "Content Policy" + Then I should be on the content page + When I am on newname's user page + And I follow "Privacy Policy" + Then I should be on the privacy page + When I am on newname's user page + And I follow "contact our Policy & Abuse team" + Then I should see "Policy Questions & Abuse Reports" + + Scenario: Popup details can be viewed + + Given I am logged in as "newname" + When I am on newname's user page + When I follow "useful tips for new users" + Then I should see the first login popup + + Scenario: Turn off first login help banner directly + + Given I am logged in as "newname2" + When I am on newname2's user page + When I press "Dismiss permanently" + Then I should not see the first login banner + + Scenario: Banner stays off after logout and login if turned off directly + + Given I am logged in as "newname2" + When I am on newname2's user page + When I press "Dismiss permanently" + When I am logged out + And I am logged in as "newname2" + Then I should not see the first login banner + When I am on newname2's user page + Then I should not see the first login banner + + Scenario: Hide banner using X + + Given I am logged in as "newname2" + When I am on newname2's user page + # Note this is "×" and not a letter "x" + When I follow "×" within "div#main" + + Scenario: Banner comes back if turned off using X + + Given I am logged in as "newname2" + When I go to newname2's user page + # Note this is "×" and not a letter "x" + When I follow "×" within "div#main" + When I am logged out + And I am logged in as "newname2" + And I go to newname2's user page + Then I should see the first login banner diff --git a/features/other_a/gift.feature b/features/other_a/gift.feature new file mode 100755 index 0000000..ca1baa8 --- /dev/null +++ b/features/other_a/gift.feature @@ -0,0 +1,458 @@ +Feature: Create Gifts + In order to make friends and influence people + As an author + I want to create works for other people + + + Background: + Given the following activated users exist + | login | password | email | + | gifter | something | gifter@example.com | + | gifter2 | something | gifter2@example.com | + | giftee1 | something | giftee1@example.com | + | giftee2 | something | giftee2@example.com | + | associate | something | associate@example.com | + And "giftee1" has the pseud "g1" + And the user "giftee1" allows gifts + And the user "giftee2" allows gifts + And the user "associate" allows gifts + And I am logged in as "gifter" with password "something" + And I set up the draft "GiftStory1" + + Scenario: Gifts page for recipient should show recipient's gifts + When I give the work to "giftee1" + And I press "Post" + And I go to the gifts page for the recipient giftee1 + Then I should see "GiftStory1 by gifter for giftee1" + + Scenario: Work blurb includes an HTML comment containing the unix epoch of the updated time + + Given time is frozen at 2025-04-12 17:00 UTC + When I give the work to "giftee1" + And I press "Post" + And I go to the gifts page for the recipient giftee1 + Then I should see an HTML comment containing the number 1744477200 within "li.work.blurb" + + Scenario: Gifts page for recipient when logged out should show recipient's gifts if visible to all + When I give the work to "giftee1" + And I press "Post" + And I set up the draft "GiftStory2" as a gift to "giftee1" + And I lock the work + And I press "Post" + And I log out + And I go to the gifts page for the recipient giftee1 + Then I should see "GiftStory1 by gifter for giftee1" + And I should not see "GiftStory2 by gifter for giftee1" + + Scenario: Gifts page for user should show gifts given to their pseud + Given I give the work to "g1 (giftee1)" + And I press "Post" + When I go to giftee1's gifts page + Then I should see "GiftStory1 by gifter for g1 (giftee1)" + + Scenario: Gifts page for recipient without account should show their gifts + Given I give the work to "g1" + And I press "Post" + When I go to the gifts page for the recipient g1 + Then I should see "GiftStory1 by gifter for g1" + + Scenario: When logged out, gifts page for recipient without account should show gifts visible to all + When I give the work to "g1" + And I press "Post" + And I set up the draft "GiftStory2" as a gift to "g1" + And I lock the work + And I press "Post" + And I log out + When I go to the gifts page for the recipient g1 + Then I should see "GiftStory1 by gifter for g1" + And I should not see "GiftStory2 by gifter for g1" + + Scenario: Giving a work as a gift when posting directly + Given I give the work to "giftee1" + When I press "Post" + Then I should see "For giftee1" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: Giving a work as a gift when posting after previewing + Given I give the work to "giftee1" + And I press "Preview" + And I should see "For giftee1" + And 0 emails should be delivered + When I press "Post" + Then I should see "For giftee1" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: Edit a draft to add a recipient, then post after previewing + Given I press "Preview" + And I press "Edit" + And I give the work to "giftee1" + And I press "Preview" + And 0 emails should be delivered + When I press "Post" + Then I should see "For giftee1" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: Edit an existing work to add a recipient, then post directly + Given I press "Post" + And I follow "Edit" + And I give the work to "giftee1" + When I press "Post" + Then I should see "For giftee1" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: Edit an existing work to add a recipient, then post after previewing + Given I press "Post" + And I follow "Edit" + And I give the work to "giftee1" + When I press "Preview" + # this next thing is broken on beta currently, will settle for not breaking it worse + Then 0 emails should be delivered + When I press "Edit" + Then "giftee1" should be listed as a recipient in the form + When I press "Preview" + Then 0 emails should be delivered + When I press "Update" + Then I should see "For giftee1" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: Give two gifts to the same recipient + Given I give the work to "giftee1" + And I press "Post" + And I set up the draft "GiftStory2" + And I give the work to "giftee1" + When I press "Post" + And I follow "giftee1" + Then I should see "Gifts for giftee1" + And I should see "GiftStory1" + And I should see "GiftStory2" + + Scenario: Add another recipient to a posted gift + Given I give the work to "giftee1" + And I press "Post" + And I should see "For giftee1" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + And all emails have been delivered + And I follow "Edit" + And I give the work to "giftee1, giftee2" + When I press "Post" + Then I should see "For giftee1, giftee2" + And 0 emails should be delivered to "giftee1@example.com" + And "giftee2@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: Add another recipient to a draft gift + Given I give the work to "giftee1" + And I press "Preview" + And I should see "For giftee1" + And 0 emails should be delivered to "giftee1@example.com" + And I press "Edit" + And I give the work to "giftee1, giftee2" + When I press "Post" + Then I should see "For giftee1, giftee2" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + And "giftee2@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: Add two recipients, post, then remove one + Given I give the work to "giftee1, giftee2" + And I press "Post" + And I should see "For giftee1, giftee2" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + And "giftee2@example.com" should be notified by email about their gift "GiftStory1" + And all emails have been delivered + And I follow "Edit" + And I give the work to "giftee1" + When I press "Post" + Then I should see "For giftee1" + And I should not see "giftee2" + And 0 emails should be delivered to "giftee1@example.com" + And 0 emails should be delivered to "giftee2@example.com" + + Scenario: Add two recipients, preview, then remove one + Given I give the work to "giftee1, giftee2" + And I press "Preview" + And I should see "For giftee1, giftee2" + And 0 emails should be delivered + And I press "Edit" + And I give the work to "giftee1" + When I press "Post" + Then I should see "For giftee1" + And I should not see "giftee2" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + And 0 emails should be delivered to "giftee2@example.com" + + Scenario: Edit a posted work to replace one recipient with another + Given I give the work to "giftee1" + And I press "Post" + And I should see "For giftee1" + And "giftee1@example.com" should be notified by email about their gift "GiftStory1" + And all emails have been delivered + And I follow "Edit" + And I give the work to "giftee2" + When I press "Post" + Then I should see "For giftee2" + And I should not see "giftee1" + And 0 emails should be delivered to "giftee1@example.com" + And "giftee2@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: Edit a draft to replace one recipient with another + Given I give the work to "giftee1" + And I press "Preview" + And I should see "For giftee1" + And 0 emails should be delivered + And I press "Edit" + And I give the work to "giftee2" + When I press "Post" + Then I should see "For giftee2" + And I should not see "giftee1" + And 0 emails should be delivered to "giftee1@example.com" + And "giftee2@example.com" should be notified by email about their gift "GiftStory1" + + Scenario: When a user is notified that a co-authored work has been given to them as a gift, the e-mail should link to each author's URL instead of showing escaped HTML + Given I invite the co-author "gifter2" + And I give the work to "giftee1" + And I preview the work + Then 1 email should be delivered to "gifter2" + And the email should contain "The user gifter has invited your pseud gifter2 to be listed as a co-creator on the following work" + And the email should not contain "translation missing" + When all emails have been delivered + And the user "gifter2" accepts all co-creator requests + And I press "Post" + Then 1 email should be delivered to "giftee1" + And the email should link to gifter's user url + And the email should not contain "<a href="http://archiveofourown.org/users/gifter/pseuds/gifter"" + And the email should link to gifter2's user url + And the email should not contain "<a href="http://archiveofourown.org/users/gifter2/pseuds/gifter2"" + + Scenario: A gift work should have an associations list + Given I give the work to "associate" + When I press "Post" + Then I should find a list for associations + And I should see "For associate" + + Scenario: A user should not be able to gift a work twice to the same person + Given "associate" has the pseud "associate2" + And I am logged in as "troll" + And I set up the draft "Yuck" + And I have given the work to "associate, associate2 (associate)" + Then I should not see "For associate, associate2" + And I should see "For associate" + And 1 email should be delivered to "associate@example.com" + When all emails have been delivered + And I edit the work "Yuck" + And I give the work to "associate, associate2 (associate)" + And I post the work without preview + Then I should see "You seem to already have given this work to that user." + And I should not see "For associate, associate2" + And 0 emails should be delivered to "associate@example.com" + + Scenario: A user should be able to refuse a gift + Given I have given the work to "associate" + And I am logged in as "someone_else" + And I am on associate's gifts page + Then I should not see "Refuse Gift" + And I should not see "Refused Gifts" + When I am logged in as "associate" with password "something" + And I go to associate's gifts page + Then I should see "GiftStory1" + And I should see "Refuse Gift" + And I should see "Refused Gifts" + When I follow "Refuse Gift" + Then I should see "This work will no longer be listed among your gifts." + And I should not see "GiftStory1" + When I follow "Refused Gifts" + Then I should see "GiftStory1" + And I should not see "by gifter for associate" + When I view the work "GiftStory1" + Then I should not see "For associate" + And I should not see "For ." + + Scenario: A user should be able to re-accept a gift + Given I have refused the work + And I am on giftee1's gifts page + And I follow "Refused Gifts" + Then I should see "Accept Gift" + And I should not see "by gifter for giftee1" + # Delay to make sure the cache is expired when re-accepting the gift: + When it is currently 1 second from now + And I follow "Accept Gift" + Then I should see "This work will now be listed among your gifts." + And I should see "GiftStory1" + And I should see "by gifter for giftee1" + When I view the work "GiftStory1" + Then I should see "For giftee1" + + Scenario: An admin should see that a gift has been refused + Given I have refused the work + And I am logged in as an admin + And I view the work "GiftStory1" + Then I should see "Refused As Gift: giftee1" + + Scenario: Can't remove a recipient who has refused the gift + Given I have refused the work + And I am logged in as "gifter" + When I edit the work "GiftStory1" + Then "giftee1" should not be listed as a recipient in the form + And the gift for "giftee1" should still exist on "GiftStory1" + When I have removed the recipients + Then the gift for "giftee1" should still exist on "GiftStory1" + + Scenario: Opt to disable notifications, then receive a gift (with no collection) + Given I am logged in as "giftee1" with password "something" + And I set my preferences to turn off notification emails for gifts + When I am logged in as "gifter" with password "something" + And I post the work "QuietGift" as a gift for "giftee1, giftee2" + Then 0 emails should be delivered to "giftee1@example.com" + And "giftee2@example.com" should be notified by email about their gift "QuietGift" + + Scenario: Opt to disable notifications, then receive a gift posted to a non-hidden collection + Given I am logged in as "giftee1" with password "something" + And I set my preferences to turn off notification emails for gifts + And I have the collection "Open Skies" + When I am logged in as "gifter" with password "something" + And I post the work "QuietGift" in the collection "Open Skies" as a gift for "giftee1, giftee2" + Then 0 emails should be delivered to "giftee1@example.com" + And "giftee2@example.com" should be notified by email about their gift "QuietGift" + + Scenario: Opt to disable notifications, then receive a gift posted to a hidden collection and later revealed + Given I am logged in as "giftee1" with password "something" + And I set my preferences to turn off notification emails for gifts + And I have the hidden collection "Hidden Treasures" + When I am logged in as "gifter" with password "something" + And I post the work "QuietGift" in the collection "Hidden Treasures" as a gift for "giftee1, giftee2" + And I reveal works for "Hidden Treasures" + Then 0 emails should be delivered to "giftee1@example.com" + And "giftee2@example.com" should be notified by email about their gift "QuietGift" + + Scenario: Can't give a gift to a user who disallows them + Given the user "giftee1" disallows gifts + When I am logged in as "gifter" + And I post the work "Rude Gift" as a gift for "giftee1" + Then I should see "Sorry! We couldn't save this work because: giftee1 does not accept gifts." + And 0 emails should be delivered to "giftee1@example.com" + + Scenario: A user who disallows gifts can refuse existing ones + Given I am logged in as "gifter" + And I post the work "Rude Gift" as a gift for "giftee1" + And the user "giftee1" disallows gifts + When I am logged in as "giftee1" + And I go to giftee1's gifts page + # Delay to make sure the cache is expired when the gift is refused: + And it is currently 1 second from now + And I follow "Refuse Gift" + Then I should see "This work will no longer be listed among your gifts." + And I should not see "Rude Gift" + When I follow "Refused Gifts" + Then I should see "Rude Gift" + And I should not see "by gifter for giftee1" + When I view the work "Rude Gift" + Then I should not see "For giftee1." + + Scenario: Can't give a gift to a user who has blocked you + Given the user "giftee1" has blocked the user "gifter" + When I am logged in as "gifter" + And I post the work "Rude Gift" as a gift for "giftee1" + Then I should see "Sorry! We couldn't save this work because: giftee1 does not accept gifts from you." + And 0 emails should be delivered to "giftee1@example.com" + + Scenario: Can't gift an existing work to a user who has blocked you + Given the user "giftee1" has blocked the user "gifter" + And I press "Post" + And I follow "Edit" + And I give the work to "giftee1" + When I press "Post" + Then I should see "Sorry! We couldn't save this work because: giftee1 does not accept gifts from you." + + Scenario: Can't gift a work whose co-creator is blocked by recipient + Given I coauthored the work "Collateral" as "gifter" with "gifter2" + And the user "giftee1" has blocked the user "gifter2" + And I edit the work "Collateral" + And I give the work to "giftee1" + When I press "Post" + Then I should see "Sorry! We couldn't save this work because: giftee1 does not accept gifts." + + Scenario: Only see one error message is shown if gifts are disabled and user is blocked* + Given the user "giftee1" disallows gifts + And the user "giftee1" has blocked the user "gifter" + When I am logged in as "gifter" + And I post the work "Rude Gift" as a gift for "giftee1" + Then I should see "Sorry! We couldn't save this work because:" + And I should see "giftee1 does not accept gifts." + And I should not see "giftee1 does not accept gifts from you." + + Scenario: A user can refuse previous gifts from user after blocking them + Given I am logged in as "gifter" + And I post the work "Rude Gift" as a gift for "giftee1" + When I am logged in as "giftee1" + And I go to giftee1's gifts page + Then I should see "Rude Gift" + When I go to the blocked users page for "giftee1" + And I fill in "blocked_id" with "gifter" + And I press "Block" + And I press "Yes, Block User" + Then I should see "You have blocked the user gifter." + When I go to giftee1's gifts page + And it is currently 1 second from now + And I follow "Refuse Gift" + Then I should see "This work will no longer be listed among your gifts." + And I should not see "Rude Gift" + When I follow "Refused Gifts" + Then I should see "Rude Gift" + And I should not see "by gifter for giftee1" + When I view the work "Rude Gift" + Then I should not see "For giftee1." + + Scenario: Translated email is sent when a regular work is gifted + Given a locale with translated emails + And the user "giftee1" enables translated emails + And all emails have been delivered + When I give the work to "giftee1" + And I press "Post" + And I set up the draft "GiftStory2" as a gift to "giftee2" + And I press "Post" + Then "giftee1" should be emailed + And the email should have "A gift work for you" in the subject + And the email to "giftee1" should be translated + Then "giftee2" should be emailed + And the email should have "A gift work for you" in the subject + And the email to "giftee2" should be non-translated + + Scenario: Translated email is sent when a work in a collection is gifted + Given a locale with translated emails + And the user "giftee1" enables translated emails + And all emails have been delivered + When I have the collection "SomeCollection" + And I am logged in as "gifter" + And I set up the draft "GiftStory2" in the collection "SomeCollection" + And I give the work to "giftee1" + And I press "Post" + And I set up the draft "GiftStory3" in the collection "SomeCollection" + And I give the work to "giftee2" + And I press "Post" + Then "giftee1" should be emailed + And the email should have "\[SomeCollection\] A gift work for you from SomeCollection" in the subject + And the email to "giftee1" should be translated + Then "giftee2" should be emailed + And the email should have "\[SomeCollection\] A gift work for you from SomeCollection" in the subject + And the email to "giftee2" should be non-translated + + Scenario: Translated email is sent when a gift work in a hidden collection is revealed + Given a locale with translated emails + And the user "giftee1" enables translated emails + And all emails have been delivered + When I have the hidden collection "Hidden Treasury" + And I am logged in as "gifter" + And I set up the draft "GiftStory2" in the collection "Hidden Treasury" + And I give the work to "giftee1" + And I press "Post" + And I set up the draft "GiftStory3" in the collection "Hidden Treasury" + And I give the work to "giftee2" + And I press "Post" + Then "giftee1" should not be emailed + And "giftee2" should not be emailed + When I am logged in as "moderator" + And I reveal works for "Hidden Treasury" + Then "giftee1" should be emailed + And the email should have "\[Hidden Treasury\] A gift work for you from Hidden Treasury" in the subject + And the email to "giftee1" should be translated + Then "giftee2" should be emailed + And the email should have "\[Hidden Treasury\] A gift work for you from Hidden Treasury" in the subject + And the email to "giftee2" should be non-translated diff --git a/features/other_a/help.feature b/features/other_a/help.feature new file mode 100755 index 0000000..da05dc6 --- /dev/null +++ b/features/other_a/help.feature @@ -0,0 +1,42 @@ +@help +Feature: Help + In order to get help + As a humble user + I want to read help links + + Scenario: clicking the help popup for moderated collection + + Given I am logged in as "first_user" + When I go to the collections page + When I follow "New Collection" + And I follow "Collection moderated" + Then I should see "By default, collections are not moderated" + + Scenario: view the help popup for chapter title + + Given the following activated user exists + | login | password | + | epicauthor | password | + And basic tags + When I am logged in as "epicauthor" + And I go to epicauthor's user page + And I follow "New Work" + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I fill in "Fandoms" with "New Fandom" + And I fill in "Work Title" with "New Epic Work" + And I select "English" from "Choose a language" + And I fill in "content" with "Well, maybe not so epic." + And I press "Post" + And I follow "Add Chapter" + And I follow "Chapter title" + Then I should see "You can add a chapter title" + + Scenario: Asked to log in if trying to access the first login page as guest + + When I go to the first login help page + Then I should be on the login page + + Given I am logged in + When I go to the first login help page + Then I should see "Here are some tips to help you get started" diff --git a/features/other_a/hit_counts.feature b/features/other_a/hit_counts.feature new file mode 100755 index 0000000..be99a5e --- /dev/null +++ b/features/other_a/hit_counts.feature @@ -0,0 +1,112 @@ +@javascript +Feature: Hit Counts + # Throughout these tests, we use the "all hit count information is reset" + # step because logging in/logging out may result in the user being redirected + # to the page that the user was just on, i.e. the work whose hit count we're + # trying to test. + + Scenario: When the owner views their own work, it doesn't increment the hit count + Given the work "Hit Count Test" + And I am logged in as the author of "Hit Count Test" + And all hit count information is reset + When I go to the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 0" + + Scenario: Viewing a work logged-in increments the hit count + Given the work "Hit Count Test" + And I am logged in as "viewer" + And all hit count information is reset + When I go to the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 1" + + Scenario: Viewing a work logged-out increments the hit count + Given the work "Hit Count Test" + And all hit count information is reset + When I go to the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 1" + + Scenario: Viewing an unrevealed work doesn't increment the hit count + Given there is a work "Hit Count Test" in an unrevealed collection "Unrevealed" + And I am logged in as the owner of "Unrevealed" + And all hit count information is reset + When I go to the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 0" + + Scenario: Viewing a work hidden by an admin doesn't increment the hit count + Given the hidden work "Hit Count Test" + And I am logged in as an admin + And all hit count information is reset + When I go to the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 0" + + Scenario: When an admin views a draft, it doesn't increment the hit count + Given I am logged in as a random user + And the draft "Hit Count Test" + And I am logged in as an admin + And all hit count information is reset + When I go to the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 0" + + Scenario: Viewing the first chapter logged-in increments the hit count + Given the chaptered work "Hit Count Test" + And all hit count information is reset + And I am logged in as "viewer" + When I go to the 1st chapter of the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 1" + + Scenario: Viewing the first chapter logged-out increments the hit count + Given the chaptered work "Hit Count Test" + And all hit count information is reset + When I go to the 1st chapter of the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 1" + + Scenario: Viewing the second chapter logged-in increments the hit count + Given the chaptered work "Hit Count Test" + And I am logged in as "viewer" + And all hit count information is reset + When I go to the 2nd chapter of the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 1" + + Scenario: Viewing the second chapter logged-out increments the hit count + Given the chaptered work "Hit Count Test" + And all hit count information is reset + When I go to the 2nd chapter of the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 1" + + Scenario: Viewing multiple chapters in sequence only increments the hit count once + Given the chaptered work "Hit Count Test" + And all hit count information is reset + When I go to the 1st chapter of the work "Hit Count Test" + And all AJAX requests are complete + And I go to the 2nd chapter of the work "Hit Count Test" + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 1" + + Scenario: Viewing a full multi-chapter work increments the hit count + Given the chaptered work "Hit Count Test" + And all hit count information is reset + When I go to the work "Hit Count Test" in full mode + And the hit counts for all works are updated + And I go to the work "Hit Count Test" + Then I should see "Hits: 1" diff --git a/features/other_a/homepage.feature b/features/other_a/homepage.feature new file mode 100755 index 0000000..15de4da --- /dev/null +++ b/features/other_a/homepage.feature @@ -0,0 +1,34 @@ +Feature: Various things on the homepage + + Scenario: Logged out + + When I am on the homepage + Then I should see "The Archive of Our Own is a project of the Organization for Transformative Works." + + Scenario: Diversity statement + + Given I am on the homepage + When I follow "Diversity Statement" + Then I should see "You are welcome at the Archive of Our Own." + + Scenario: DMCA + + Given I am on the homepage + When I follow "DMCA Policy" + Then I should see "Filing a DMCA counternotice" + + Scenario: Donate + + Given I am on the homepage + When I follow "Site Map" + And I follow "Donations" + Then I should see "There are two main ways to support the AO3 - donating your time or money" + And I should see the page title "Donate or Volunteer" + And I should see a link "donation to the OTW" to "https://donate.transformativeworks.org/otwgive" + + Scenario: About + + Given I am on the about page + Then I should see the page title "About the OTW" + And I should see a link "GitHub repository" to "https://github.com/otwcode/otwarchive" + And I should see a link "Jira project" to "https://otwarchive.atlassian.net/browse/AO3" diff --git a/features/other_a/invite_queue.feature b/features/other_a/invite_queue.feature new file mode 100755 index 0000000..308b0cd --- /dev/null +++ b/features/other_a/invite_queue.feature @@ -0,0 +1,183 @@ +@admin +Feature: Invite queue management + + Background: + Given I have no users + And the following users exist + | login | password | + | user1 | password | + + Scenario: Can turn queue off in Admin Settings and it displays as off + + Given I am logged in as a "policy_and_abuse" admin + And I go to the admin-settings page + And I uncheck "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + When I log out + And I am on the homepage + Then I should not see "Get an Invite" + And I should see "Archive of Our Own" + + Scenario: Can turn queue on in Admin Settings and it displays as on + + Given I am logged in as a "policy_and_abuse" admin + And account creation requires an invitation + And I go to the admin-settings page + And I check "Invite from queue enabled (People can add themselves to the queue and invitations are sent out automatically)" + And I press "Update" + When I log out + And I am on the homepage + Then I should see "Get an Invitation" + When I follow "Get an Invitation" + Then I should see "Request an invitation" + + Scenario: An admin can delete people from the queue + + Given an invitation request for "invitee@example.org" + And I am logged in as a "policy_and_abuse" admin + When I go to the manage invite queue page + And I press "Delete" + Then I should see "Request for invitee@example.org was removed from the queue." + And I should be on the manage invite queue page + + Scenario: Visitors can join the queue and check status when invitations are required and the queue is enabled + + # join queue + Given I am a visitor + And account creation requires an invitation + And the invitation queue is enabled + When I am on the homepage + And all emails have been delivered + And I follow "Get an Invitation" + Then I should see "We are sending out 10 invitations every 12 hours." + When I fill in "invite_request_email" with "test@archiveofourown.org" + And I press "Add me to the list" + Then I should see "You've been added to our queue" + + # check your place in the queue - invalid address + When I check how long "testttt@archiveofourown.org" will have to wait in the invite request queue + Then I should see "Invitation Request Status" + And I should see "Sorry, we can't find the email address you entered." + And I should not see "You are currently number" + + # check your place in the queue - correct address + When I check how long "test@archiveofourown.org" will have to wait in the invite request queue + Then I should see "Invitation Status for test@archiveofourown.org" + And I should see "You are currently number 1 on our waiting list! At our current rate, you should receive an invitation on or around" + + Scenario: Can't add yourself to the queue when queue is off + + Given the invitation queue is disabled + When I go to the invite_requests page + Then I should not see "Request an invitation" + And I should not see "invite_request_email" + And I should see "New invitation requests are currently closed." + And I should see "There are 0 people remaining on the waiting list." + And I should not see "Add me to the list" + + Scenario: Can still check status when queue is off + + Given the invitation queue is disabled + When I go to the invite_requests page + And I follow "check your position on the waiting list" + Then I should see the page title "Invitation Request Status" + And I should see "There are currently 0 people on the waiting list." + And I should not see "We are currently sending out" + + Scenario: The queue sends out invites and user can create and activate an account + + Given account creation is enabled + And the invitation queue is enabled + And account creation requires an invitation + And the invite_from_queue_at is yesterday + When I am on the homepage + And all emails have been delivered + And I follow "Get an Invitation" + When I fill in "invite_request_email" with "test@archiveofourown.org" + And I press "Add me to the list" + And the scheduled check_invite_queue job is run + Then 1 email should be delivered to test@archiveofourown.org + When I check how long "test@archiveofourown.org" will have to wait in the invite request queue + Then I should see "Invitation Request Status" + And I should see "If you can't find it, please check your email spam folder as your spam filters may have placed it there." + + # invite can be used + When I am logged in as an admin + And I follow "Invitations" + And I fill in "track_invitation_invitee_email" with "test@archiveofourown.org" + And I press "Search" within "form.invitation.simple.search" + And I follow "Copy and use" + Then I should see "You are already logged in!" + + # user uses email invite + Given I am a visitor + # "You've" removed from test due to escaping on apostrophes + Then the email should contain "been invited to join the Archive of Our Own" + And the email should contain "fanart" + And the email should contain "podfic" + And the email should contain "If you do not receive this email after 48 hours" + And the email should contain "With an account, you can post fanworks" + + When I follow "follow this link to sign up" in the email + And I fill in the sign up form with valid data + And I fill in the following: + | user_registration_login | newuser | + | user_registration_email | test@archiveofourown.org | + | user_registration_password | password1 | + | user_registration_password_confirmation | password1 | + And all emails have been delivered + When I press "Create Account" + Then I should see "Almost Done!" + Then 1 email should be delivered + And the email should contain "Welcome to the Archive of Our Own," + And the email should contain "newuser" + And the email should contain "activate your account" + And the email should not contain "translation missing" + + # user activates account + When all emails have been delivered + And I click the first link in the email + Then I should be on the login page + And I should see "Account activation complete! Please log in." + + When I am logged in as "newuser" with password "password1" + Then I should see "Successfully logged in." + + Scenario: You can't request an invitation with an email address that is + already attached to an account + Given account creation requires an invitation + And the invitation queue is enabled + And the following activated users exist + | login | password | email | + | fred | yabadabadoo | fred@bedrock.com | + When I am on the homepage + And I follow "Get an Invitation" + And I fill in "invite_request_email" with "fred@bedrock.com" + And I press "Add me to the list" + Then I should see "Email is already being used by an account holder." + + Scenario: Users can resend their invitation after enough time has passed + Given account creation is enabled + And the invitation queue is enabled + And account creation requires an invitation + And the invite_from_queue_at is yesterday + And an invitation request for "invitee@example.org" + When the scheduled check_invite_queue job is run + Then 1 email should be delivered to invitee@example.org + + When I check how long "invitee@example.org" will have to wait in the invite request queue + Then I should see "Invitation Request Status" + And I should see "If you can't find it, please check your email spam folder as your spam filters may have placed it there." + And I should not see "Because your invitation was sent more than 24 hours ago, you can have your invitation resent." + And I should not see "Resend Invitation" + + When all emails have been delivered + And it is currently 25 hours from now + And I check how long "invitee@example.org" will have to wait in the invite request queue + Then I should see "Invitation Request Status" + And I should see "If you can't find it, please check your email spam folder as your spam filters may have placed it there." + And I should see "Because your invitation was sent more than 24 hours ago, you can have your invitation resent." + And I should see "Resend Invitation" + + When I press "Resend Invitation" + Then 1 email should be delivered to invitee@example.org diff --git a/features/other_a/invite_request.feature b/features/other_a/invite_request.feature new file mode 100755 index 0000000..e4d5b75 --- /dev/null +++ b/features/other_a/invite_request.feature @@ -0,0 +1,189 @@ +@admin +Feature: Invite requests + + Scenario: Request an invite for a friend + + Given invitations are required + And I am logged in as "user1" + When I try to invite a friend from my user page + And I follow "Request invitations" + When I fill in "How many invitations would you like? (max 10)" with "3" + And I fill in "Please specify why you'd like them:" with "I want them for a friend" + And I press "Send Request" + Then I should see a create confirmation message + + Scenario: Requests are not instantly granted + + Given invitations are required + And I am logged in as "user1" + And I request some invites + When I follow "Invitations" + Then I should see "Sorry, you have no unsent invitations right now." + + Scenario: Admin sees the request + + Given invitations are required + And I am logged in as "user1" + And I request some invites + When I view requests as an admin + Then I should see "user1" + And the "requests[user1]" field should contain "3" + And I should see "I want them for a friend" + + Scenario: Admin can refuse request + + Given invitations are required + And I am logged in as "user1" + And I request some invites + When I view requests as an admin + And I fill in "requests[user1]" with "0" + And I press "Update" + Then I should see "Requests were successfully updated." + And I should not see "user1" + + Scenario: Admin can grant request + + Given invitations are required + And I am logged in as "user1" + And I request some invites + When I view requests as an admin + And I fill in "requests[user1]" with "2" + And I press "Update" + Then I should see "Requests were successfully updated." + + Scenario: User is granted invites + + Given invitations are required + And I am logged in as "user1" + And I request some invites + And an admin grants the request + When I try to invite a friend from my user page + Then I should see "Invite a friend" + And I should not see "Sorry, you have no unsent invitations right now." + And I should see "You have 2 open invitations and 0 that have been sent but not yet used." + + Scenario: User can see an error after trying to invite an invalid email address + + Given I am logged in as "user1" + And "user1" has "1" invitation + And I am on user1's manage invitations page + When I follow the link for "user1" first invite + And I fill in "Enter an email address" with "test@" + And I press "Update Invitation" + Then I should see "Invitee email should look like an email address" + + Scenario: User can send out invites they have been granted, and the recipient can sign up + + Given invitations are required + And I am logged in as "user1" + And I request some invites + And an admin grants the request + And I try to invite a friend from my user page + When all emails have been delivered + And I fill in "Email address" with "test@archiveofourown.org" + And I press "Send Invitation" + Then 1 email should be delivered to test@archiveofourown.org + And the email should contain "has invited you to join the Archive of Our Own!" + And the email should contain "If you do not receive this email after 48 hours" + And the email should contain "With an account, you can post fanworks" + + Given I am a visitor + When I follow "follow this link to sign up" in the email + And I fill in the sign up form with valid data + And I fill in the following: + | user_registration_login | user2 | + | user_registration_password | password1 | + | user_registration_password_confirmation | password1 | + And I press "Create Account" + Then I should see "You should soon receive an activation email at the address you gave us" + And I should see how long I have to activate my account + And I should see "If you haven't received this email within 24 hours" + + Scenario: Banned users cannot access their invitations page + + Given the user "bad_user" is banned + And I am logged in as "bad_user" + When I go to bad_user's invitations page + Then I should be on bad_user's user page + And I should see "Your account has been banned." + + Scenario: A user can manage their invitations + + Given I am logged in as "user1" + And "user1" has "5" invitations + When I go to user1's user page + And I follow "Invitations" + And I follow "Manage Invitations" + Then I should see "Unsent (5)" + When I follow "Unsent (5)" + Then I should see "Unsent (5)" + When I follow the link for "user1" first invite + Then I should see "Enter an email address" + When I fill in "invitation[invitee_email]" with "user6@example.org" + And I press "Update Invitation" + Then I should see "Invitation was successfully sent." + + Scenario: An admin can get to a user's invitations page + Given I am logged in as a "support" admin + And the user "steven" exists and is activated + When I go to the user administration page for "steven" + And I follow "Add Invitations" + Then I should be on steven's invitations page + + Scenario: An admin can get to a user's manage invitations page + Given I am logged in as a "support" admin + And the user "steven" exists and is activated + When I go to the user administration page for "steven" + And I follow "Manage Invitations" + Then I should be on steven's manage invitations page + + Scenario: An admin can create a user's invitations + Given I am logged in as a "support" admin + And the user "steven" exists and is activated + When I go to steven's invitations page + Then I should see "Create more invitations for this user" + When I fill in "invitation[number_of_invites]" with "4" + And press "Create" + Then I should see "Invitations were successfully created." + + Scenario: An admin can delete a user's invitations + Given the user "user1" exists and is activated + And "user1" has "5" invitations + And I am logged in as a "support" admin + When I follow "Invite New Users" + And I fill in "invitation[user_name]" with "user1" + And I press "Search" within "form.invitation.simple.search" + Then I should see "Invite token" + When I follow "Delete" + Then I should see "Invitation successfully destroyed" + And "user1" should have "4" invitations + + Scenario: Translated email is sent when invitation request is declined by admin + Given a locale with translated emails + And invitations are required + And the user "user1" exists and is activated + And the user "notuser1" exists and is activated + And the user "user1" enables translated emails + And all emails have been delivered + When as "user1" I request some invites + And as "notuser1" I request some invites + And I view requests as an admin + And I press "Decline All" + Then "user1" should be emailed + And the email should have "Additional invitation request declined" in the subject + And the email to "user1" should be translated + Then "notuser1" should be emailed + And the email should have "Additional invitation request declined" in the subject + And the email to "notuser1" should be non-translated + + Scenario: Translated email is sent when new invitation is given to registered user + Given a locale with translated emails + And invitations are required + And the user "user1" exists and is activated + And the user "user1" enables translated emails + And all emails have been delivered + When as "user1" I request some invites + And an admin grants the request + Then "user1" should be emailed + And the email should have "New invitations" in the subject + And the email to "user1" should be translated \ No newline at end of file diff --git a/features/other_a/invite_use.feature b/features/other_a/invite_use.feature new file mode 100755 index 0000000..54054d8 --- /dev/null +++ b/features/other_a/invite_use.feature @@ -0,0 +1,50 @@ +Feature: invitations +In order to join the archive +As an unregistered user +I want to use an invitation to create an account + + Scenario: user attempts to use an invitation + + Given account creation is enabled + And account creation requires an invitation + And I am a visitor + When I use an invitation to sign up + Then I should see "Create Account" + + Scenario: user attempts to use an already redeemed invitation + + Given account creation is enabled + And account creation requires an invitation + And I am a visitor + When I use an already used invitation to sign up + Then I should see "This invitation has already been used to create an account" + + Scenario: I visit the invitations page for a non-existent user + + Given I am a visitor + And I go to SOME_USER's invitations page + Then I should be on the login page + And I should see "Sorry, you don't have permission to access the page you were trying to reach. Please log in." + When I am logged in as "Scott" with password "password" + And I go to SOME_USER2's invitations page + Then I should be on Scott's user page + And I should see "Sorry, you don't have permission to access the page you were trying to reach." + + Scenario: Viewing invitation details when the invitee has deleted their account + Given the user "creator" exists and is activated + And the user "invitee" exists and is activated + And an invitation created by "creator" and used by "invitee" + And I am logged in as "creator" + When I go to creator's manage invitations page + Then I should see "invitee" + When I view the most recent invitation for "creator" + Then I should see "invitee" + When I am logged in as "invitee" + And "invitee" deletes their account + And I am logged in as "creator" + And I go to creator's manage invitations page + Then I should see "Deleted User" + But I should not see "invitee" + When I view the most recent invitation for "creator" + Then I should see "Deleted User" + But I should not see "invitee" diff --git a/features/other_a/languages.feature b/features/other_a/languages.feature new file mode 100755 index 0000000..8df8d39 --- /dev/null +++ b/features/other_a/languages.feature @@ -0,0 +1,53 @@ +@works +Feature: Languages + + # Scenario: Browse works by language + + # Admin set up the language + + # Given I am logged in as an admin + # And I go to the admin-settings page + # TODO: Then I should be able to add a language in the front end + + Scenario: post a work in another language + + Given the following activated users exist + | login | password | + | englishuser | password | + | germanuser1 | password | + | germanuser2 | password | + | frenchuser | password | + And basic tags + And basic languages + When I am logged in as "germanuser2" with password "password" + And I post the work "Die Rache der Sith" + And I follow "Edit" + And I select "Deutsch" from "Choose a language" + And I press "Preview" + And I press "Update" + Then I should see "Die Rache der Sith" + + # TODO: French including sedilla, other characters not in the ascii set. + + When I log out + And I am logged in as "englishuser" with password "password" + And I post the work "Revenge of the Sith" + Then I should see "Revenge of the Sith" + + # Browse works in a language + + When I am on the languages page + And all indexing jobs have been run + Then I should see "Deutsch" + When I follow "Deutsch" + Then I should see "1 Work in Deutsch" + And I should see "Die Rache der Sith" + And I should not see "Revenge of the Sith" + + # cross-check in English + + When I am on the languages page + Then I should see "English" + And I should see "English" within "dl.language" + # And I should see the text with tags "<a href=\"/works\">1</a>" + # And I should see the text with tags '<a href="/works">1</a>' diff --git a/features/other_a/media.feature b/features/other_a/media.feature new file mode 100755 index 0000000..db64635 --- /dev/null +++ b/features/other_a/media.feature @@ -0,0 +1,131 @@ +Feature: The All Fandoms page. + Users should be able to see a list of the most popular canonical fandoms for + each category, with correct filter counts. + + Scenario: Fandoms with more works should appear before fandoms with fewer. + Given a media exists with name: "Movies", canonical: true + And a canonical "Movies" fandom "Marvel Cinematic Universe" with 3 works + And a canonical "Movies" fandom "Star Wars" with 2 works + + When I go to the media page + Then I should see "Marvel Cinematic Universe (3)" + And I should see "Star Wars (2)" + And "Marvel Cinematic Universe" should appear before "Star Wars" + + Scenario: Only the top 5 fandoms of each type should appear. + Given a media exists with name: "TV Shows", canonical: true + And a canonical "TV Shows" fandom "Doctor Who" with 2 works + And a canonical "TV Shows" fandom "Sherlock" with 2 works + And a canonical "TV Shows" fandom "Star Trek" with 2 works + And a canonical "TV Shows" fandom "Supernatural" with 2 works + And a canonical "TV Shows" fandom "Teen Wolf" with 2 works + And a canonical "TV Shows" fandom "The Forgotten" with 1 works + + When I go to the media page + Then I should see "Doctor Who (2)" + And I should see "Sherlock (2)" + And I should see "Star Trek (2)" + And I should see "Supernatural (2)" + And I should see "Teen Wolf (2)" + But I should not see "The Forgotten" + + When I follow "TV Shows" + Then I should see "The Forgotten (1)" + + Scenario: Adding or removing works in a fandom should change the count. + Given I have a canonical "Books" fandom tag named "Lord of the Rings" + And I am logged in as "Tolkien" + And I post a work "Fellowship of the Ring" with fandom "Lord of the Rings" + And I post a work "The Two Towers" with fandom "Lord of the Rings" + And I post a work "Return of the King" with fandom "Lord of the Rings" + + When I go to the media page + Then I should see "Lord of the Rings (3)" + + When I delete the work "Return of the King" + And the periodic filter count task is run + And I go to the media page + Then I should see "Lord of the Rings (2)" + + When I lock the work "The Two Towers" + And the periodic filter count task is run + And I go to the media page + Then I should see "Lord of the Rings (2)" + + When I am logged out + And I go to the media page + Then I should see "Lord of the Rings (1)" + + When I am logged in as a "policy_and_abuse" admin + And I go to the media page + Then I should see "Lord of the Rings (2)" + + When I view the work "The Two Towers" + And I follow "Hide Work" + And the periodic filter count task is run + And I go to the media page + Then I should see "Lord of the Rings (1)" + + Scenario: Adding or removing a metatag changes the metatag's count. + Given I have a canonical "Books" fandom tag named "Harry Potter" + And I have a canonical "Books" fandom tag named "Wizarding World" + And I am logged in as "Rowling" + And I post a work "Philosopher's Stone" with fandom "Harry Potter" + And I post a work "Fantastic Beasts" with fandom "Wizarding World" + + When I go to the media page + Then I should see "Harry Potter (1)" + And I should see "Wizarding World (1)" + + # Adding a metatag. + When I am logged in as a tag wrangler + And I subtag the tag "Harry Potter" to "Wizarding World" + And the periodic filter count task is run + And I go to the media page + Then I should see "Harry Potter (1)" + And I should see "Wizarding World (2)" + + # Removing the metatag. + When I remove the metatag "Wizarding World" from "Harry Potter" + And the periodic filter count task is run + And I go to the media page + Then I should see "Harry Potter (1)" + And I should see "Wizarding World (1)" + + Scenario: Making a tag canonical and adding synonyms adjusts the counts. + Given a media exists with name: "Books", canonical: true + And I am logged in as "Asimov" + And I post a work "I, Robot" with fandom "Robots" + And I post a work "Caves of Steel" with fandom "R. Daneel Olivaw" + + # Make the tag canonical + When I am logged in as a tag wrangler + And I edit the tag "Robots" + And I fill in "tag_media_string" with "Books" + And I check "Canonical" + And I press "Save changes" + Then I should see "Tag was updated." + + When the periodic filter count task is run + And I go to the media page + Then I should see "Robots (1)" + + # Add the synonym + When I edit the tag "R. Daneel Olivaw" + And I fill in "Synonym" with "Robots" + And I press "Save changes" + Then I should see "Tag was updated." + + When the periodic filter count task is run + And I go to the media page + Then I should see "Robots (2)" + + # Remove the synonym + When I edit the tag "R. Daneel Olivaw" + And I fill in "Synonym" with "" + And I press "Save changes" + Then I should see "Tag was updated." + + When the periodic filter count task is run + And I go to the media page + Then I should see "Robots (1)" diff --git a/features/other_a/orphan_account.feature b/features/other_a/orphan_account.feature new file mode 100755 index 0000000..f1bc794 --- /dev/null +++ b/features/other_a/orphan_account.feature @@ -0,0 +1,69 @@ +@works, @users +Feature: Orphan account + In order to have an archive full of works + As an author + I want to orphan all works in my account + +Scenario: Orphan all works belonging to a user + Given I have an orphan account + And the following activated user exists + | login | password | + | orphaneer | password | + And I am logged in as "orphaneer" with password "password" + When I post the work "Shenanigans" + And I post the work "Shenanigans 2" + And I post the work "Shenanigans - the early years" + When I go to orphaneer's user page + Then I should see "Recent works" + And I should see "Shenanigans" + And I should see "Shenanigans 2" + And I should see "Shenanigans - the early years" + When I go to the orphan all works page + Then I should see "Orphan All Works" + And I should see "Are you really sure you want to" + When I choose "Take my pseud off as well" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + And I press "Yes, I'm sure" + Then I should see "Orphaning was successful." + When I view the work "Shenanigans" + Then I should see "orphan_account" + And I should not see "orphaneer" within ".userstuff" + When I view the work "Shenanigans 2" + Then I should see "orphan_account" + And I should not see "orphaneer" within ".userstuff" + When I view the work "Shenanigans - the early years" + Then I should see "orphan_account" + And I should not see "orphaneer" within ".userstuff" + +Scenario: Orphan all works belonging to a user, add a copy of the pseud to the orphan_account +Given I have an orphan account + And the following activated user exists + | login | password | + | orphaneer | password | + And I am logged in as "orphaneer" with password "password" + When I post the work "Shenanigans" + When I post the work "Shenanigans 2" + When I post the work "Shenanigans - the early years" + When I go to orphaneer's user page + Then I should see "Recent works" + And I should see "Shenanigans" + And I should see "Shenanigans 2" + And I should see "Shenanigans - the early years" + When I go to the orphan all works page + Then I should see "Orphan All Works" + And I should see "Are you really sure you want to" + When I choose "Leave a copy of my pseud on" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + And I press "Yes, I'm sure" + Then I should see "Orphaning was successful." + When I view the work "Shenanigans" + Then I should see "orphaneer (orphan_account)" + And I should not see "orphaneer" within ".userstuff" + When I view the work "Shenanigans 2" + Then I should see "orphaneer (orphan_account)" + And I should not see "orphaneer" within ".userstuff" + When I view the work "Shenanigans - the early years" + Then I should see "orphaneer (orphan_account)" + And I should not see "orphaneer" within ".userstuff" diff --git a/features/other_a/orphan_pseud.feature b/features/other_a/orphan_pseud.feature new file mode 100755 index 0000000..5781bdb --- /dev/null +++ b/features/other_a/orphan_pseud.feature @@ -0,0 +1,104 @@ +@works +Feature: Orphan pseud + In order to have an archive full of works + As an author + I want to orphan all works under one pseud + # TODO: Expand this to cover a user who has more than one pseud, and check that works on the other pseud don't get orphaned + + Scenario: Orphan all works belonging to one pseud + Given I have an orphan account + And the following activated user exists + | login | password | + | orphanpseud | password | + And I am logged in as "orphanpseud" with password "password" + When I post the work "Shenanigans" + And I post the work "Shenanigans 2" + When I follow "orphanpseud" within ".byline" + Then I should see "Shenanigans 2 by orphanpseud" + When I follow "Back To Pseuds" + Then I should see "orphanpseud" + And I should see "2 works" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + When I follow "Orphan Works" + Then I should see "Orphan All Works by orphanpseud" + When I choose "Take my pseud off as well" + And I press "Yes, I'm sure" + Then I should see "Orphaning was successful." + When I view the work "Shenanigans" + Then I should see "orphan_account" + And I should not see "orphanpseud" within ".userstuff" + When I view the work "Shenanigans 2" + Then I should see "orphan_account" + And I should not see "orphanpseud" within ".userstuff" + + Scenario: Orphan all works belonging to one pseud, add a copy of the pseud to the orphan_account + Given I have an orphan account + And the following activated user exists + | login | password | + | orphanpseud | password | + And I am logged in as "orphanpseud" with password "password" + When I post the work "Shenanigans" + When I post the work "Shenanigans 2" + When I follow "orphanpseud" within ".byline" + Then I should see "Shenanigans by orphanpseud" + And I should see "Shenanigans 2 by orphanpseud" + When I follow "Back To Pseuds" + Then I should see "orphanpseud" + And I should see "2 works" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + When I follow "Orphan Works" + Then I should see "Orphan All Works by orphanpseud" + When I choose "Leave a copy of my pseud on" + And I press "Yes, I'm sure" + Then I should see "Orphaning was successful." + When I view the work "Shenanigans" + Then I should see "orphanpseud (orphan_account)" + And I should not see "orphanpseud" within ".userstuff" + When I view the work "Shenanigans 2" + Then I should see "orphanpseud (orphan_account)" + And I should not see "orphanpseud" within ".userstuff" + + Scenario: Orphan a pseud with works co-created by another pseud + Given I have an orphan account + And I am logged in as "halfandhalf" + And "halfandhalf" creates the pseud "To Be Kept" + And "halfandhalf" creates the pseud "To Be Orphaned" + + When I set up the draft "Treasure" + And I unselect "halfandhalf" from "Creator/Pseud(s)" + And I select "To Be Kept" from "Creator/Pseud(s)" + And I press "Post" + Then I should see "To Be Kept" within ".byline" + When I set up the draft "Trash" + And I unselect "halfandhalf" from "Creator/Pseud(s)" + And I select "To Be Orphaned" from "Creator/Pseud(s)" + And I press "Post" + Then I should see "To Be Orphaned" within ".byline" + When I set up the draft "Half and Half" + And I unselect "halfandhalf" from "Creator/Pseud(s)" + And I select "To Be Kept" from "Creator/Pseud(s)" + And I select "To Be Orphaned" from "Creator/Pseud(s)" + And I press "Post" + Then I should see "To Be Kept" within ".byline" + And I should see "To Be Orphaned" within ".byline" + + When I go to halfandhalf's pseuds page + And I follow "Orphan Works by To Be Orphaned" + Then I should see "Orphan All Works by To Be Orphaned" + When I choose "Take my pseud off as well" + And I wait 2 seconds + And I press "Yes, I'm sure" + Then I should see "Orphaning was successful." + + When I view the work "Trash" + Then I should see "orphan_account" within ".byline" + But I should not see "halfandhalf" within ".byline" + When I view the work "Treasure" + Then I should see "To Be Kept (halfandhalf)" within ".byline" + But I should not see "orphan_account" within ".byline" + When I view the work "Half and Half" + Then I should see "To Be Kept (halfandhalf)" within ".byline" + And I should see "orphan_account" within ".byline" + But I should not see "To Be Orphaned (halfandhalf)" within ".byline" diff --git a/features/other_a/orphan_series.feature b/features/other_a/orphan_series.feature new file mode 100755 index 0000000..eddcf06 --- /dev/null +++ b/features/other_a/orphan_series.feature @@ -0,0 +1,81 @@ +@series +Feature: Orphan series + As an author + I want to orphan a series full of works + + Background: + Given I have an orphan account + And I am logged in as "orphaneer" + + Scenario: Orphaning a series (remove pseud) should remove all references to the user from the series + + Given I add the work "Work to be Rued" to the series "My Biggest Mistakes" + And I add the work "Regrettable Work" to the series "My Biggest Mistakes" + + When I orphan and take my pseud off the series "My Biggest Mistakes" + And I am logged out + And I view the series "My Biggest Mistakes" + + Then I should not see "orphaneer" + + Scenario: Orphaning a series (leave pseud) should change the authorship to the correct pseudonym of orphan_account + + Given I add the work "Work to be Rued" to the series "My Biggest Mistakes" + And I add the work "Regrettable Work" to the series "My Biggest Mistakes" + + When I orphan and leave my pseud on the series "My Biggest Mistakes" + And I view the series "My Biggest Mistakes" + + Then I should see "orphaneer (orphan_account)" within ".series.meta" + And I should not see "Edit" + + Scenario: Orphaning a series should remove it from the user's series page + + Given I add the work "Work to be Rued" to the series "My Biggest Mistakes" + And I add the work "Regrettable Work" to the series "My Biggest Mistakes" + + When I orphan and take my pseud off the series "My Biggest Mistakes" + And I am on orphaneer's series page + + Then I should not see "My Biggest Mistakes" + + Scenario: Orphaning a work in a series with only one work should cause the series to be orphaned + + Given I add the work "Work to be Rued" to the series "My Biggest Mistakes" + + When I orphan the work "Work to be Rued" + And I am logged out + And I view the series "My Biggest Mistakes" + + Then I should see "orphan_account" + And I should not see "orphaneer" + + Scenario: Orphaning one but not all of the works in a series should make the series co-created by orphan_account + + Given I add the work "Work to be Rued" to the series "My Biggest Mistakes" + And I add the work "Work to be Kept" to the series "My Biggest Mistakes" + + When I orphan the work "Work to be Rued" + + Then "orphaneer" should be a co-creator of the series "My Biggest Mistakes" + And "orphan_account" should be a co-creator of the series "My Biggest Mistakes" + + Scenario: When a user orphans a shared series, it should not change the byline for works that they didn't co-create + + # Set up a shared series where orphaneer is not listed as a creator on the second work + Given I am logged in as "keeper" + And I add the work "Shared Beginnings" to the series "Shared Series" + And I add the co-author "orphaneer" to the work "Shared Beginnings" + And I add the work "Keeper's Solo" to the series "Shared Series" + + # Double-check to make sure that we've set up the authorships correctly. + Then "orphaneer" should be a co-creator of the series "Shared Series" + And "orphaneer" should be a co-creator of the work "Shared Beginnings" + But "orphaneer" should not be a co-creator of the work "Keeper's Solo" + + When I am logged in as "orphaneer" + And I orphan the series "Shared Series" + + Then "orphan_account" should be a co-creator of the series "Shared Series" + And "orphan_account" should be a co-creator of the work "Shared Beginnings" + But "orphan_account" should not be a co-creator of the work "Keeper's Solo" diff --git a/features/other_a/orphan_work.feature b/features/other_a/orphan_work.feature new file mode 100755 index 0000000..d9758f5 --- /dev/null +++ b/features/other_a/orphan_work.feature @@ -0,0 +1,162 @@ +@works +Feature: Orphan work + In order to have an archive full of works + As an author + I want to orphan works + + + Background: + Given I have an orphan account + And the following activated users exists + | login | password | email | + | orphaneer | password | orphaneer@foo.com | + | author_subscriber | password | author_subscriber@foo.com | + And "author_subscriber" subscribes to author "orphaneer" + And all emails have been delivered + And I am logged in as "orphaneer" + + + Scenario: Orphan a single work, using the default orphan_account + + Given I post the work "Shenanigans" + And I view the work "Shenanigans" + Then I should see "Edit" + When I follow "Edit" + Then I should see "Edit Work" + And I should see "Orphan Work" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + When I follow "Orphan Work" + Then I should see "Read More About The Orphaning Process" + When I choose "Take my pseud off as well" + And I press "Yes, I'm sure" + And all indexing jobs have been run + Then I should see "Orphaning was successful." + And I should see "Bookmarks (0)" + When I follow "Works (0)" + Then I should not see "Shenanigans" + When I view the work "Shenanigans" + Then I should see "orphan_account" + And I should not see "Delete" + + + Scenario: Orphan a single work and add a copy of the pseud to the orphan_account + + Given I post the work "Shenanigans2" + When I view the work "Shenanigans2" + Then I should see "Edit" + When I follow "Edit" + Then I should see "Edit Work" + And I should see "Orphan Work" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + When I follow "Orphan Work" + Then I should see "Read More About The Orphaning Process" + When I choose "Leave a copy of my pseud on" + And I press "Yes, I'm sure" + Then I should see "Orphaning was successful." + When I go to orphaneer's works page + Then I should not see "Shenanigans2" + When I view the work "Shenanigans2" + Then I should see "orphaneer (orphan_account)" + And I should not see "Delete" + + + Scenario: Orphan a work (remove pseud) and don't notify subscribers to my account + + Given I post the work "Doomed Story" + And I follow "Edit" + And I follow "Orphan Work" + And I choose "Take my pseud off as well" + And I press "Yes, I'm sure" + When subscription notifications are sent + Then 0 emails should be delivered + + + Scenario: Orphan a work (leave pseud) and don't notify subscribers to my account + + Given I post the work "Awful Concoction" + And I follow "Edit" + And I follow "Orphan Work" + And I choose "Leave a copy of my pseud on" + And I press "Yes, I'm sure" + When subscription notifications are sent + Then 0 emails should be delivered + + + Scenario: Orphan a work (leave pseud) and don't notify subscribers to the work + + Given the following activated user exists + | login | password | email | + | work_subscriber | password | work_subscriber@foo.com | + And I post the work "Torrid Idfic" + And I am logged in as "work_subscriber" + And I view the work "Torrid Idfic" + And I press "Subscribe" + And a chapter is added to "Torrid Idfic" + And I follow "Edit" + And I follow "Orphan Work" + And I choose "Leave a copy of my pseud on" + And I press "Yes, I'm sure" + When subscription notifications are sent + Then 0 emails should be delivered + + + Scenario: Orphan a work (leave pseud) and don't notify subscribers to the work's series + + Given the following activated user exists + | login | password | email | + | series_subscriber | password | series_subscriber@foo.com | + And I add the work "Lazy Purple Sausage" to series "Shame Series" + And I am logged in as "series_subscriber" + And I view the series "Shame Series" + And I press "Subscribe" + And I am logged in as "orphaneer" + And I view the work "Lazy Purple Sausage" + And I follow "Edit" + And I follow "Orphan Work" + And I choose "Leave a copy of my pseud on" + And I press "Yes, I'm sure" + When subscription notifications are sent + Then 0 emails should be delivered + + Scenario: I can orphan multiple works at once + Given I am logged in as "author" + And I post the work "Glorious" with fandom "SGA" + And I post the work "Excellent" with fandom "Star Trek" + And I post the work "Lovely" with fandom "Steven Universe" + And I go to author's works page + When I follow "Edit Works" + Then I should see "Edit Multiple Works" + When I select "Glorious" for editing + And I select "Excellent" for editing + And I press "Delete" + Then I should see "Are you sure you want to delete these works PERMANENTLY?" + And I should see "Glorious" + And I should see "Excellent" + And I should not see "Lovely" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + When I follow "Orphan Works Instead" + Then I should see "Orphaning a work removes it from your account and re-attaches it to the specially created orphan_account." + When I press "Yes, I'm sure" + And all indexing jobs have been run + Then I should see "Orphaning was successful." + When I go to author's works page + Then I should not see "Glorious" + And I should not see "Excellent" + And I should see "Lovely" + + Scenario: Orphaning a shared work should not affect chapters created solely by the other creator + + Given I am logged in as "keeper" + And I post the work "Half-Orphaned" + And I add the co-author "orphaneer" to the work "Half-Orphaned" + And I post a chapter for the work "Half-Orphaned" + # Verify that the authorship has been set up properly + Then "orphaneer" should be a co-creator of Chapter 1 of "Half-Orphaned" + But "orphaneer" should not be a co-creator of Chapter 2 of "Half-Orphaned" + When I am logged in as "orphaneer" + And I orphan the work "Half-Orphaned" + Then "orphan_account" should be a co-creator of Chapter 1 of "Half-Orphaned" + But "orphan_account" should not be a co-creator of Chapter 2 of "Half-Orphaned" diff --git a/features/other_a/page_title.feature b/features/other_a/page_title.feature new file mode 100755 index 0000000..dfbd456 --- /dev/null +++ b/features/other_a/page_title.feature @@ -0,0 +1,73 @@ +Feature: Page titles +When I browse the AO3 +I want page titles to be readable + +Background: + + Given the app name is "Example Archive" + +Scenario: An index page uses only the controller name in the default browser page title + + Given a fandom exists with name: "No Fandom", canonical: true + When I go to the tags page + Then I should see the page title "Tags | Example Archive" + +Scenario: A non-index page uses the action and controller names in the default browser page title + + When I am logged in as "user" + And I go to the new work page + Then I should see the page title "New Work | Example Archive" + +Scenario: user reads a TOS or FAQ page + + When I go to the TOS page + Then the page title should include "Terms of Service | Example Archive" + When I go to the FAQ page + Then the page title should include "Archive FAQs | Example Archive" + +Scenario: Work page title should respect user preference + + Given I am logged in as "author" + And I follow "My Preferences" + And I fill in "Browser page title format" with "FANDOM - AUTHOR - TITLE" + And I press "Update" + And I post the work "New Story" with fandom "Stargate" + When I view the work "New Story" + Then the page title should include "Stargate - author - New Story [Example Archive]" + +Scenario: Work page title should change when tags are edited + + Given I am logged in as "author" + And I post the work "New Story" with fandom "Stargate" + When I view the work "New Story" + Then the page title should include "Stargate" + When I edit the work "New Story" + And I fill in "Fandoms" with "Harry Potter" + And I press "Post" + When I view the work "New Story" + Then the page title should include "Harry Potter" + And the page title should not include "Stargate" + +Scenario: Work page title should be informative on the adult content notice page + + Given I am logged in as "author" + And I post the 2 chapter work "New Story" with fandom "Stargate" with rating "Mature" + When I am logged out + And I view the work "New Story" + Then I should see "This work could have adult content" + And the page title should include "New Story - author - Stargate [Example Archive]" + When I follow the recent chapter link for the work "New Story" + Then I should see "This work could have adult content" + And the page title should include "New Story - Chapter 2 - author - Stargate [Example Archive]" + +Scenario: Inbox has the expected browser page title + + When I am logged in as "boxer" + And I go to boxer's inbox page + Then I should see the page title "boxer - Inbox | Example Archive" + +Scenario: New tag set page has the expected browser page title + + When I am logged in as "user" + When I go to the new tag set page + Then I should see the page title "New Owned Tag Set | Example Archive" diff --git a/features/other_a/parser.feature b/features/other_a/parser.feature new file mode 100755 index 0000000..6761f73 --- /dev/null +++ b/features/other_a/parser.feature @@ -0,0 +1,126 @@ +@works +Feature: Parsing HTML + + # tests for parsing only are in spec/lib/html_cleaner_spec.rb + + Scenario: Editing a work and saving it twice without changes should preserve the same content + When I am logged in as "newbie" + And I set up the draft "My Awesome Story" + And I fill in "content" with + """ + This is paragraph 1. + + This is paragraph 2. + + + + This is paragraph 3. + """ + And I press "Preview" + Then I should see "Preview" + # testing the HTML here + And I should see the text with tags + """ + <p>This is paragraph 1.</p> + <p>This is paragraph 2.</p> + <p> </p> + <p>This is paragraph 3.</p> + """ + When I press "Post" + And I follow "Edit" + # testing the textarea content here + Then I should see in the "content" input + """ + <p>This is paragraph 1.</p> + + <p>This is paragraph 2.</p> + + <p> </p> + + <p>This is paragraph 3.</p> + """ + When I press "Post" + And I follow "Edit" + Then I should see in the "content" input + """ + <p>This is paragraph 1.</p> + + <p>This is paragraph 2.</p> + + <p> </p> + + <p>This is paragraph 3.</p> + """ + + Scenario: HTML Parser should kick in + When I am logged in as "newbie" + And I set up the draft "My Awesome Story" + And I fill in "content" with + """ + A paragraph + + Another paragraph. + """ + And I press "Preview" + Then I should see "Preview" + And I should see the text with tags + """ + <p>A paragraph</p> + <p>Another paragraph.</p> + """ + + Scenario: Work notes and content HTML can have classes and they are kept when editing after previewing + Given I am logged in as a random user + And I set up the draft "Classy Work" + When I fill in "Summary" with "<p class='myclass'>Text</p>" + And I fill in "Notes" with "<p class='note'>Text</p>" + And I fill in "End Notes" with "<span class='keep-me'>Text</span>" + And I fill in "content" with "<p class='size-10'><img src='britney.gif' alt='Britney Spears' />You better work</p>" + And I press "Preview" + Then I should see "Draft was successfully created." + And I should see the image "src" text "http://www.example.org/britney.gif" + And I should see the image "alt" text "Britney Spears" + When I press "Edit" + Then the "Summary" field should not contain "myclass" + And the "Notes" field should contain "note" + And the "End Notes" field should contain "keep-me" + And the "content" field should contain "size-10" + When I press "Post" + Then I should see "Work was successfully posted." + And I should see the image "src" text "http://www.example.org/britney.gif" + + Scenario: Chapter notes and content HTML keep classes when previewing before posting + Given I am logged in as a random user + And I post the work "Classy Multichapter Work" + And a chapter is set up for "Classy Multichapter Work" + When I fill in "Chapter Summary" with "<p class='summary classes'>Text</p>" + And I fill in "Notes" with "<p class='note'>Text</p>" + And I fill in "End Notes" with "<span class='keep-me'>Text</span>" + And I fill in "content" with "<div class='elaborate formatting'><p>The continuation of my <a href='works/123'>masterpiece</a></p></div>" + And I press "Preview" + Then I should see "This is a draft chapter in a posted work." + When I press "Post" + Then I should see "Chapter was successfully posted." + And I should see the text with tags '<p>The continuation of my <a href="works/123" rel="nofollow">masterpiece</a></p>' + When I follow "Edit Chapter" + Then the "Chapter Summary" field should not contain "summary classes" + And the "Notes" field should contain "note" + And the "End Notes" field should contain "keep-me" + And the "content" field should contain "elaborate formatting" + + Scenario: Can't use classes in comment content + Given the work "Generic Work" + And I am logged in as "commenter" + And I view the work "Generic Work" + When I fill in "Comment" with "<p class='strip me'>Hi there!</p>" + And I press "Comment" + Then I should see "Comment created!" + When I follow "Edit" + Then the "Comment" field should not contain "strip me" + +Scenario: Can't use classes in a bookmark note + Given the work "Really Good Thing" + And I am logged in as "bookmarker" + When I bookmark the work "Really Good Thing" with the note "My <span='remove-me'>best yet</span>" + And I edit the bookmark for "Really Good Thing" + Then the "Notes" field should not contain "remove-me" diff --git a/features/other_a/preferences_edit.feature b/features/other_a/preferences_edit.feature new file mode 100755 index 0000000..5624444 --- /dev/null +++ b/features/other_a/preferences_edit.feature @@ -0,0 +1,337 @@ +@users +Feature: Edit preferences + In order to have an archive full of users + As a humble user + I want to fill out my preferences + + + Scenario: Ensure all Preference options are available + + Given the following activated user exists + | login | password | + | scott | password | + + When I am logged in as "scott" with password "password" + And I go to scott's user page + And I follow "Preferences" + Then I should see "Set My Preferences" + And I should see "Hide my work from search engines when possible." + And I should see "Hide the share buttons on my work." + And I should see "Show me adult content without checking." + And I should see "Show the whole work by default." + And I should see "Hide warnings (you can still choose to show them)." + And I should see "Hide additional tags (you can still choose to show them)." + And I should see "Hide work skins (you can still choose to show them)." + And I should see "Your site skin" + And I should see "Your time zone" + And I should see "Browser page title format" + And I should see "Turn off emails about comments." + And I should see "Turn off messages to your inbox about comments." + And I should see "Turn off copies of your own comments." + And I should see "Turn off emails about kudos." + And I should see "Do not allow guests to reply to my comments on news posts or other users' works (you can still control the comment settings for your works separately)." + And I should see "Allow others to invite my works to collections." + And I should see "Turn off emails from collections." + And I should see "Turn off inbox messages from collections." + And I should see "Turn off emails about gift works." + And I should see "Turn on History." + And I should see "Turn the new user help banner back on." + And I should see "Turn off the banner showing on every page." + + + Scenario: View and edit preferences for history, view entire work + + Given the following activated user exists + | login | password | + | editname | password | + When I go to editname's user page + And I follow "Profile" + Then I should not see "My email address" + And I should not see "My birthday" + When I am logged in as "editname" with password "password" + And I post the 2 chapter work "This has two chapters" + Then I should be on the 2nd chapter of the work "This has two chapters" + And I follow "Previous Chapter" + Then I should be on the 1st chapter of the work "This has two chapters" + When I follow "editname" + Then I should see "Dashboard" within "div#dashboard" + And I should see "History" within "div#dashboard" + And I should see "Preferences" within "div#dashboard" + And I should see "Profile" within "div#dashboard" + When I follow "Preferences" within "div#dashboard" + Then I should see "Set My Preferences" + When I follow "Edit My Profile" + Then I should see "Password" + # TODO: figure out why pseud switcher doesn't show up in cukes + # When I follow "editname" within "#pseud_switcher" + When I follow "Dashboard" + And I follow "Profile" + Then I should see "Set My Preferences" + When I follow "Set My Preferences" + Then I should see "Edit My Profile" + When I uncheck "Turn on History" + And I check "Show the whole work by default." + And I press "Update" + Then I should see "Your preferences were successfully updated" + And I should not see "History" within "div#dashboard" + When I go to the works page + And I follow "This has two chapters" + Then I should not see "Next Chapter" + + @javascript + Scenario: User can hide warning and freeform tags and reveal them on a case- + by-case basis. + + Given a canonical freeform "Scary tag" + And I am logged in as "someone_else" + And I post the work "Someone Else's Work" as part of a series "A Series" + And I am logged in as "tester" + And I post the work "My Work" + And I bookmark the work "Someone Else's Work" + + # Change tester's preferences to hide warnings. + When I set my preferences to hide warnings + Then I should see "Your preferences were successfully updated" + + # Warnings are hidden on work meta, except on user's own works. + # We use a selector so it doesn't pick up the info in the Share box. + When I view the work "Someone Else's Work" + Then I should not see "No Archive Warnings Apply" within "dl.work.meta" + And I should see "Show warnings" + And I should see "Scary tag" within "dl.work.meta" + And I should not see "Show additional tags" + When I follow "Show warnings" + Then I should see "No Archive Warnings Apply" within "dl.work.meta" + When I follow "No Archive Warnings Apply" within "dl.work.meta" + Then I should be on the works tagged "No Archive Warnings Apply" + When I view the work "My Work" + Then I should see "No Archive Warnings Apply" within "dl.work.meta" + And I should not see "Show warnings" + And I should see "Scary tag" within "dl.work.meta" + And I should not see "Show additional tags" + + # Warnings are hidden in work blurbs, except on user's own works. + When I go to someone_else's works page + Then I should see "Someone Else's Work" + And I should not see "No Archive Warnings Apply" within "li.warnings" + And I should see "Show warnings" + And I should see "Scary tag" within "li.freeforms" + And I should not see "Show additional tags" + When I follow "Show warnings" + Then I should see "No Archive Warnings Apply" within "li.warnings" + When I follow "No Archive Warnings Apply" within "li.warnings" + Then I should be on the works tagged "No Archive Warnings Apply" + When I go to tester's works page + Then I should see "My Work" + And I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Show warnings" + And I should see "Scary tag" within "li.freeforms" + And I should not see "Show additional tags" + + # Warnings are hidden in series blurbs. + When I go to someone_else's series page + Then I should see "A Series" + And I should not see "No Archive Warnings Apply" within "li.warnings" + And I should see "Show warnings" + And I should see "Scary tag" within "li.freeforms" + And I should not see "Show additional tags" + When I follow "Show warnings" + Then I should see "No Archive Warnings Apply" within "li.warnings" + When I follow "No Archive Warnings Apply" within "li.warnings" + Then I should be on the works tagged "No Archive Warnings Apply" + + # Warnings are hidden in bookmark blurbs. + # This is slightly excessive -- bookmarks use the work blurb -- but we'll + # check in case that ever changes. + When I go to tester's bookmarks page + Then I should see "Someone Else's Work" + And I should not see "No Archive Warnings Apply" within "li.warnings" + And I should see "Show warnings" + And I should see "Scary tag" within "li.freeforms" + And I should not see "Show additional tags" + When I follow "Show warnings" + Then I should see "No Archive Warnings Apply" within "li.warnings" + When I follow "No Archive Warnings Apply" within "li.warnings" + Then I should be on the works tagged "No Archive Warnings Apply" + + # Change tester's preferences to hide freeforms as well as warnings. + When I follow "My Preferences" + And I check "Hide additional tags" + And I press "Update" + Then I should see "Your preferences were successfully updated" + + # Freeforms and warnings are hidden on work meta, except for user's own works. + When I view the work "Someone Else's Work" + Then I should not see "No Archive Warnings Apply" within "dl.work.meta" + And I should see "Show warnings" + And I should not see "Scary tag" within "dl.work.meta" + And I should see "Show additional tags" + When I follow "Show warnings" + Then I should see "No Archive Warnings Apply" within "dl.work.meta" + And I should not see "Scary tag" within "dl.work.meta" + When I follow "Show additional tags" + Then I should see "Scary tag" within "dl.work.meta" + When I view the work "My Work" + Then I should see "No Archive Warnings Apply" within "dl.work.meta" + And I should not see "Show warnings" + And I should see "Scary tag" within "dl.work.meta" + And I should not see "Show additional tags" + + # Freeforms and warnings are hidden in work blurbs, except on user's own + # works. + When I go to someone_else's works page + Then I should see "Someone Else's Work" + And I should not see "No Archive Warnings Apply" within "li.warnings" + And I should see "Show warnings" + And I should not see "Scary tag" within "li.freeforms" + And I should see "Show additional tags" + When I follow "Show warnings" + Then I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Scary tag" within "li.freeforms" + When I follow "Show additional tags" + Then I should see "Scary tag" within "li.freeforms" + When I go to tester's works page + Then I should see "My Work" + And I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Show warnings" + And I should see "Scary tag" within "li.freeforms" + And I should not see "Show additional tags" + + # Freeforms and warnings are hidden in series blurbs. + When I go to someone_else's series page + Then I should see "A Series" + And I should not see "No Archive Warnings Apply" within "li.warnings" + And I should see "Show warnings" + And I should not see "Scary tag" within "li.freeforms" + And I should see "Show additional tags" + When I follow "Show warnings" + Then I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Scary tag" within "li.freeforms" + When I follow "Show additional tags" + Then I should see "Scary tag" within "li.freeforms" + + # Freeforms and warnings are hidden in bookmark blurbs. + When I go to tester's bookmarks page + Then I should see "Someone Else's Work" + And I should not see "No Archive Warnings Apply" within "li.warnings" + And I should see "Show warnings" + And I should not see "Scary tag" within "li.freeforms" + And I should see "Show additional tags" + When I follow "Show warnings" + Then I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Scary tag" within "li.freeforms" + When I follow "Show additional tags" + Then I should see "Scary tag" within "li.freeforms" + + # Change tester's preferences to show warnings but keep freeforms hidden. + When I follow "My Preferences" + And I uncheck "Hide warnings" + And I press "Update" + Then I should see "Your preferences were successfully updated" + + # Freeforms are hidden on work meta, except on user's own works. + When I view the work "Someone Else's Work" + Then I should see "No Archive Warnings Apply" within "dl.work.meta" + And I should not see "Show warnings" + And I should see "Show additional tags" + And I should not see "Scary tag" within "dl.work.meta" + When I follow "Show additional tags" + Then I should see "Scary tag" within "dl.work.meta" + When I follow "Scary tag" within "dl.work.meta" + Then I should be on the works tagged "Scary tag" + When I view the work "My Work" + Then I should see "No Archive Warnings Apply" within "dl.work.meta" + And I should not see "Show warnings" + And I should see "Scary tag" within "dl.work.meta" + And I should not see "Show additional tags" + + # Freeforms are hidden in work blurbs, except on user's own works. + When I go to someone_else's works page + Then I should see "Someone Else's Work" + And I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Show warnings" + And I should not see "Scary tag" within "li.freeforms" + And I should see "Show additional tags" + When I follow "Show additional tags" + Then I should see "Scary tag" within "li.freeforms" + When I follow "Scary tag" within "li.freeforms" + Then I should be on the works tagged "Scary tag" + When I go to tester's works page + Then I should see "My Work" + And I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Show warnings" + And I should see "Scary tag" within "li.freeforms" + And I should not see "Show additional tags" + + # Freeforms are hidden in series blurbs. + When I go to someone_else's series page + Then I should see "A Series" + And I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Show warnings" + And I should not see "Scary tag" within "li.freeforms" + And I should see "Show additional tags" + When I follow "Show additional tags" + Then I should see "Scary tag" within "li.freeforms" + When I follow "Scary tag" within "li.freeforms" + Then I should be on the works tagged "Scary tag" + + # Freeforms are hidden in bookmark blurbs. + When I go to tester's bookmarks page + Then I should see "Someone Else's Work" + And I should see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Show warnings" + And I should not see "Scary tag" within "li.freeforms" + And I should see "Show additional tags" + When I follow "Show additional tags" + Then I should see "Scary tag" within "li.freeforms" + When I follow "Scary tag" within "li.freeforms" + Then I should be on the works tagged "Scary tag" + + Scenario: User can hide warning and freeform tags on work blurbs and meta with + JavaScript disabled, but gets an error if they attempt to reveal them. + + Given I am logged in as "first_user" + And I post the work "Asteroid Blues" with fandom "Cowboy Bebop" with freeform "Ed is a sweetie" + When I am logged in + And I set my preferences to hide both warnings and freeforms + And I go to first_user's works page + + # Check hidden tags on the blurb + Then I should see "Asteroid Blues" + And I should not see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Ed is a sweetie" + When I follow "Show additional tags" + Then I should see "Sorry, you need to have JavaScript enabled for this." + And I should see "Show additional tags" + When I follow "Show warnings" + Then I should see "Sorry, you need to have JavaScript enabled for this." + And I should see "Show warnings" + + # Check hidden tags in the meta + When I view the work "Asteroid Blues" + And I follow "Show additional tags" + Then I should see "Sorry, you need to have JavaScript enabled for this." + And I should see "Show additional tags" + When I follow "Show warnings" + Then I should see "Sorry, you need to have JavaScript enabled for this." + And I should see "Show warnings" + + Scenario: User can hide warning and freeform tags on series blurbs with + JavaScript disabled, but gets an error if they attempt to reveal them. + + Given I am logged in as "first_user" + And I post the work "Asteroid Blues" with fandom "Cowboy Bebop" with freeform "Ed is a sweetie" as part of a series "Cowboy Bebop Blues" + And I post the work "Wild Horses" with fandom "Cowboy Bebop" with freeform "Faye Valentine is a sweetie" as part of a series "Cowboy Bebop Blues" + When I am logged in + And I set my preferences to hide both warnings and freeforms + And I go to first_user's series page + Then I should see "Cowboy Bebop Blues" + And I should not see "No Archive Warnings Apply" within "li.warnings" + And I should not see "Ed is a sweetie" + And I should not see "Faye Valentine is a sweetie" + When I follow "Show additional tags" + Then I should see "Sorry, you need to have JavaScript enabled for this." + And I should see "Show additional tags" + When I follow "Show warnings" + Then I should see "Sorry, you need to have JavaScript enabled for this." + And I should see "Show warnings" diff --git a/features/other_a/preferences_edit_more.feature b/features/other_a/preferences_edit_more.feature new file mode 100755 index 0000000..31e95ee --- /dev/null +++ b/features/other_a/preferences_edit_more.feature @@ -0,0 +1,73 @@ +@users +Feature: Preferences + + Scenario: View and edit preferences - show/hide mature content warning + + Given I am logged in as "mywarning1" + And I post the work "Adult Work by mywarning1" with rating "Mature" + When I am logged in as "mywarning2" + And I follow "My Preferences" + And I check "Show me adult content without checking." + And I press "Update" + Then I should see "Your preferences were successfully updated" + When I go to the works page + And I follow "Adult Work by mywarning1" + Then I should not see "adult content" + And I should see "Rating: Mature" + When I follow "My Preferences" + And I uncheck "Show me adult content without checking." + And I press "Update" + Then I should see "Your preferences were successfully updated" + When I go to the works page + And I follow "Adult Work by mywarning1" + Then I should see "adult content" + And I should not see "Rating: Mature" + + Scenario: set preference to hide custom css on stories + Given basic tags + And basic skins + And I am logged in as "tasteless" + When I set up the draft "Big and Loud" + And I select "Basic Formatting" from "work_work_skin_id" + And I press "Preview" + And I press "Post" + And I go to the "Big and Loud" work page + Then I should see "#workskin .font-murkyyellow" in the page style + And I should see "Hide Creator's Style" + When I follow "My Preferences" + Then the "Hide work skins (you can still choose to show them)." checkbox should not be checked + When I check "Hide work skins (you can still choose to show them)." + And I press "Update" + When I go to the "Big and Loud" work page + Then I should not see "#workskin .font-murkyyellow" + And I should not see "Hide Creator's Style" + And I should see "Show Creator's Style" + When I follow "Creator's Style" + Then I should see "#workskin .font-murkyyellow" in the page style + And I should see "Hide Creator's Style" + Given I am logged out + And I am logged in as "tasteful" + And I go to the "Big and Loud" work page + + Scenario: Hidden users' user, works, and series pages are disallowed for search engine indexing + Given I am logged in as "hidden" + And the user "hidden" is hidden from search engines + And I post the work "Hidden Work" as part of a series "Hidden Series" + And I am logged out + When I go to hidden's user page + Then the page should be hidden from search engines + When I view the work "Hidden Work" + Then the page should be hidden from search engines + When I view the series "Hidden Series" + Then the page should be hidden from search engines + + Scenario: Unhidden users' user, works, and series pages are allowed for search engine indexing + Given I am logged in as "unhidden" + And I post the work "Unhidden Work" as part of a series "Unhidden Series" + And I am logged out + When I go to unhidden's user page + Then the page should not be hidden from search engines + When I view the work "Unhidden Work" + Then the page should not be hidden from search engines + When I view the series "Unhidden Series" + Then the page should not be hidden from search engines \ No newline at end of file diff --git a/features/other_a/profile_edit.feature b/features/other_a/profile_edit.feature new file mode 100755 index 0000000..a5930a8 --- /dev/null +++ b/features/other_a/profile_edit.feature @@ -0,0 +1,229 @@ +@users +Feature: Edit profile + In order to have a presence on the archive + As a humble user + I want to fill out and edit my profile + +Background: + Given the following activated user exists + | login | password | email | + | editname | password | bar@ao3.org | + And I am logged in as "editname" + And I want to edit my profile + +Scenario: Add details + Then I should see the page title "Edit Profile" + When I fill in the details of my profile + Then I should see "Your profile has been successfully updated" + And 0 emails should be delivered + And I should see "Test title thingy" + And I should see "This is some text about me." + +Scenario: Change details + When I change the details in my profile + Then I should see "Your profile has been successfully updated" + And 0 emails should be delivered + And I should see "Alternative title thingy" + And I should see "This is some different text about me." + +Scenario: Remove details + When I remove details from my profile + Then I should see "Your profile has been successfully updated" + And 0 emails should be delivered + And I should not see "Bio" + +Scenario: Change details as an admin + + Given I am logged in as a "policy_and_abuse" admin + And an abuse ticket ID exists + When I go to editname profile page + And I follow "Edit Profile" + And I fill in "About Me" with "is it merely thy habit, to talk to dolls?" + And I fill in "Ticket ID" with "fine" + And I press "Update" + Then I should see "may begin with an # and otherwise contain only numbers." + And the field labeled "Ticket ID" should contain "fine" + When I fill in "Ticket ID" with "480000" + And I press "Update" + Then I should see "Your profile has been successfully updated" + And I should see "is it merely thy habit, to talk to dolls?" + When I visit the last activities item + Then I should see "edit profile" + And I should see a link "Ticket #480000" + + # Skip logging admin activity if no change was actually made. + When I go to editname profile page + And I follow "Edit Profile" + And I fill in "Ticket ID" with "480000" + And I press "Update" + Then I should see "Your profile has been successfully updated" + When I go to the admin-activities page + Then I should see 1 admin activity log entry + +Scenario: Changing email address shows a confirmation page and sends a confirmation mail + When it is currently 2020-04-10 13:37 + And the email address change confirmation period is set to 4 days + And I follow "Profile" + And I follow "Edit My Profile" + And I follow "Change Email" + And I fill in "New email" with "valid2@archiveofourown.org" + And I fill in "Enter new email again" with "valid2@archiveofourown.org" + And I fill in "Password" with "password" + And I press "Confirm New Email" + Then I should see "Are you sure you want to change your email address to valid2@archiveofourown.org?" + And I should see "If you don't confirm your request within 4 days" + And 0 emails should be delivered + When I press "Yes, Change Email" + Then I should see "You have requested to change your email address to valid2@archiveofourown.org." + And I should see "If you don't confirm your request by Tue, 14 Apr 2020" + And I should see "bar@ao3.org" + And 1 email should be delivered to "bar@ao3.org" + And the email should contain "Someone has made a request to change the email address associated with your AO3 account." + And the email should contain "valid2@archiveofourown.org" + And 1 email should be delivered to "valid2@archiveofourown.org" + And the email should contain "request to change the email address associated with the AO3 account" + And the email should contain "editname" + + When I am a visitor + And I follow "confirm your email change" in the email + Then I should see "Sorry, you don't have permission to access the page you were trying to reach. Please log in." + When I am logged in as "editname" + And I go to editname's profile page + And I follow "Edit My Profile" + And I follow "Change Email" + Then I should see "bar@ao3.org" + + When I am logged in as "editname" + And I follow "confirm your email change" in the email + Then I should see "Your email has been successfully updated." + And I should see "valid2@archiveofourown.org" + But I should not see "bar@ao3.org" + But I should not see "You have requested to change your email address" + When I go to editname's profile page + And I follow "Edit My Profile" + And I follow "Change Email" + Then I should see "valid2@archiveofourown.org" + +Scenario: Changing email address -- canceling in confirmation step + + When I follow "Change Email" + And I start to change my email to "valid2@archiveofourown.org" + Then I should see "Are you sure you want to change your email address" + And 0 emails should be delivered + When I follow "Cancel" + Then I should see "Change Email" within "h2.heading" + And 0 emails should be delivered + And I should not see "You have requested to change your email address" + +Scenario: Changing email address -- request expires + + When it is currently 2020-04-10 13:37 + And the email address change confirmation period is set to 4 days + And I follow "Change Email" + And I request to change my email to "valid2@archiveofourown.org" + Then I should see "If you don't confirm your request by Tue, 14 Apr 2020" + And 1 email should be delivered to "valid2@archiveofourown.org" + And the email should contain "request to change the email address" + And I should see "You have requested to change your email address" + + When it is currently 2020-04-15 14:00 + And I follow "My Preferences" + And I follow "Change Email" + Then I should not see "You have requested to change your email address" + And I should see "bar@ao3.org" + But I should not see "valid2@archiveofourown.org" + When I follow "confirm your email change" in the email + Then I should see "This email confirmation link is invalid or expired. Please check your email for the correct link or submit the email change form again." + And I should see "bar@ao3.org" + But I should not see "valid2@archiveofourown.org" + +Scenario: Changing email address -- resubmitting form changes target email and expiration date + + When it is currently 2020-04-10 13:37 + And the email address change confirmation period is set to 4 days + And I follow "Change Email" + And I request to change my email to "valid2@archiveofourown.org" + Then I should see "If you don't confirm your request by Tue, 14 Apr 2020" + And 1 email should be delivered to "bar@ao3.org" + And 1 email should be delivered to "valid2@archiveofourown.org" + And the email should contain "request to change the email address" + + When it is currently 2020-04-12 14:00 + And I request to change my email to "another@archiveofourown.org" + Then I should see "You have requested to change your email address to another@archiveofourown.org." + And I should see "If you don't confirm your request by Thu, 16 Apr 2020" + # The original email gets another notification + And 2 emails should be delivered to "bar@ao3.org" + # Old link should be invalid + And 1 email should be delivered to "valid2@archiveofourown.org" + When I follow "confirm your email change" in the email + Then I should see "This email confirmation link is invalid or expired. Please check your email for the correct link or submit the email change form again." + And I should see "bar@ao3.org" + And I should see "You have requested to change your email address to another@archiveofourown.org" + But I should not see "valid2@archiveofourown.org" + # Newest email gets new link that should work + And 1 email should be delivered to "another@archiveofourown.org" + And the email should contain "request to change the email address" + When I follow "confirm your email change" in the email + Then I should see "Your email has been successfully updated." + And I should see "another@archiveofourown.org" + But I should not see "valid2@archiveofourown.org" + But I should not see "bar@ao3.org" + +Scenario: Changing email address -- after requesting password reset + + When I am logged out + And I follow "Forgot password?" + And I fill in "Email address or username" with "editname" + And I press "Reset Password" + Then 1 email should be delivered to "bar@ao3.org" + When all emails have been delivered + And I am logged in as "editname" + And I follow "My Preferences" + And I follow "Change Email" + And I request to change my email to "valid2@archiveofourown.org" + Then I should see "You have requested to change your email address to valid2@archiveofourown.org." + And 1 email should be delivered to "bar@ao3.org" + And 1 email should be delivered to "valid2@archiveofourown.org" + When I follow "confirm your email change" in the email + Then I should see "Your email has been successfully updated." + And I should see "valid2@archiveofourown.org" + But I should not see "bar@ao3.org" + +Scenario: Changing email address -- translated emails are sent when user enables locale settings + Given a locale with translated emails + And the user "editname" enables translated emails + And all emails have been delivered + When I am logged in as "editname" + And I follow "My Preferences" + And I follow "Change Email" + And I request to change my email to "valid2@archiveofourown.org" + Then the email address "bar@ao3.org" should be emailed + And the email should have "Email change request" in the subject + And the email to email address "bar@ao3.org" should be translated + And 1 email should be delivered to "valid2@archiveofourown.org" + And the email should have "Confirm your email change" in the subject + And the email to email address "valid2@archiveofourown.org" should be translated + +Scenario: Change password - mistake in typing old password + + When I make a mistake typing my old password + Then I should see "Your old password was incorrect" + +Scenario: Change password - mistake in typing new password confirmation + + When I make a typing mistake confirming my new password + Then I should see "Password confirmation doesn't match new password." + +Scenario: Change password + + When it is currently 2025-04-12 17:00 UTC + And I change my password + Then I should see "Your password has been changed. To protect your account, you have been logged out of all active sessions. Please log in with your new password." + And 1 email should be delivered to "editname" + And the email should have "Your password has been changed" in the subject + And the email should contain "The password for your AO3 account was changed on Sat, 12 Apr 2025 17:00:\d+ \+0000" + When I am logged in as a super admin + And I go to the user administration page for "editname" + Then I should see "Password Changed" within "#user_history" + But I should not see "Password Reset" within "#user_history" diff --git a/features/other_a/pseud_dashboard.feature b/features/other_a/pseud_dashboard.feature new file mode 100755 index 0000000..029df57 --- /dev/null +++ b/features/other_a/pseud_dashboard.feature @@ -0,0 +1,107 @@ +@users +Feature: Pseud dashboard + In order to have an archive full of users + As a humble user + I want to write some works and see my dashboard + + Scenario: Fandoms on pseud dashboard + + Given the following activated user exists + | login | password | + | myself | password | + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + + # set up metatag and synonym + + When I am logged in as "Enigel" with password "wrangulate!" + And a fandom exists with name: "Stargate SG-1", canonical: true + And a fandom exists with name: "Stargatte SG-oops", canonical: false + And a fandom exists with name: "Stargate Franchise", canonical: true + And I edit the tag "Stargate SG-1" + Then I should see "Edit Stargate SG-1 Tag" + And I should see "MetaTags" + When I fill in "MetaTags" with "Stargate Franchise" + And I press "Save changes" + Then I should see "Tag was updated" + When I edit the tag "Stargatte SG-oops" + And I fill in "Synonym" with "Stargate SG-1" + And I press "Save changes" + Then I should see "Tag was updated" + + When I log out + Then I should see "Sorry, you don't have permission to access the page you were trying to reach. Please log in." + + # set up pseuds + + When I am logged in as "myself" with password "password" + And I go to myself's pseuds page + Then I should see "Default Pseud" within "div#main.pseuds-index" + When I follow "New Pseud" + And I fill in "Name" with "Me" + And I check "pseud_is_default" + And I fill in "Description" with "Something's cute" + And I press "Create" + Then I should see "Pseud was successfully created." + + # view main dashboard - when posting a work with the canonical, metatag and synonym should not be seen + + When I follow "myself" + Then I should see "Dashboard" + And I should see "You don't have anything posted under this name yet" + And I should not see "Revenge of the Sith" + And I should not see "Stargate" + When I post the work "Revenge of the Sith" + And I follow "myself" + Then I should see "Stargate" + And I should see "SG-1" within "#user-fandoms" + And I should not see "Stargate Franchise" + And I should not see "Stargatte SG-oops" + + # check on pseud that posted the work + + When I follow "Me" within ".pseud .expandable li" + Then I should see "Stargate" + And I should see "SG-1" within "#user-fandoms" + And I should not see "Stargate Franchise" + And I should not see "Stargatte SG-oops" + + # check on pseud that didn't post the work + When I follow "myself" within "div#dashboard ul.expandable.secondary" + Then I should not see "Stargate" + And I should not see "SG-1" + And I should not see "Stargate Franchise" + And I should not see "Stargatte SG-oops" + + # now using the synonym - canonical should be seen, but metatag still not seen + + When I edit the work "Revenge of the Sith" + And I fill in "Fandoms" with "Stargatte SG-oops" + And I press "Preview" + And I press "Update" + Then I should see "Work was successfully updated" + When I follow "myself" + Then I should see "Stargate" + And I should see "SG-1" within "#user-fandoms" + And I should not see "Stargate Franchise" + And I should not see "Stargatte SG-oops" within "#user-fandoms" + And I should see "Stargatte SG-oops" + + # check on pseud that posted the work + + When I follow "Me" within ".pseud .expandable li" + Then I should see "Stargate" + And I should see "SG-1" within "#user-fandoms" + And I should not see "Stargate Franchise" + And I should not see "Stargatte SG-oops" within "#user-fandoms" + And I should see "Stargatte SG-oops" + + # check on pseud that didn't post the work + + When I follow "myself" within "div#dashboard ul.expandable.secondary" + Then I should not see "Stargate" + And I should not see "SG-1" + And I should not see "Stargate Franchise" + And I should not see "Stargatte SG-oops" + diff --git a/features/other_a/pseud_delete.feature b/features/other_a/pseud_delete.feature new file mode 100755 index 0000000..225ad6f --- /dev/null +++ b/features/other_a/pseud_delete.feature @@ -0,0 +1,209 @@ +@users +Feature: Delete pseud. + In order to tidy some mess + As a humble user + I want to delete a pseud + + Scenario: Delete pseud, have option to move works, delete works, or orphan works. Test if those choices work. + Given the user "testuser" exists and is activated + And "testuser" has the pseud "tester_pseud" + And "testuser" has the pseud "testy" + And "testuser" has the pseud "testymctesty" + And pseud "tester_pseud" has a bookmark of a work titled "one" by "testuser2" + And pseud "testy" has a bookmark of a work titled "two" by "testuser2" + And pseud "testymctesty" has a bookmark of a work titled "three" by "testuser2" + When I am logged in as "sad_user_with_no_pseuds" + And I am on sad_user_with_no_pseuds's pseuds page + Then I should not see "Delete" + + When I am logged in as "testuser" + And I am on testuser's pseuds page + And I follow "delete_tester_pseud" + And I press "Cancel" + Then I should see "The pseud was not deleted." + When I am on testuser's pseuds page + And I follow "tester_pseud" + Then I should see "one by testuser2" + + When I am on testuser's pseuds page + And I follow "delete_tester_pseud" + And I choose "Delete this bookmark" + And I press "Submit" + Then I should see "The pseud was successfully deleted." + When I am on testuser's pseuds page + Then I should not see "tester_pseud" + + When I follow "delete_testy" + And I choose "Transfer this bookmark to the default pseud" + And I press "Submit" + Then I should see "The pseud was successfully deleted." + When I am on testuser's pseuds page + And I follow "testymctesty" + Then I should see "three by testuser2" + + Scenario: Deleting a pseud shouldn't break gift exchange signups. + Given I am logged in as "moderator" + And I set up the collection "Exchange1" + And I select "Gift Exchange" from "Type of challenge" + And I press "Submit" + And I check "Sign-up open?" + And I press "Submit" + And I am logged in as "test" + And "test" creates the pseud "testpseud" + + When I start signing up for "Exchange1" + And I select "testpseud" from "challenge_signup_pseud_id" + And I fill in "Description:" with "Antidisestablishmentarianism." + And I press "Submit" + Then I should see "Sign-up was successfully created." + + When I view the collection "Exchange1" + And I follow "My Sign-up" + Then I should see "Antidisestablishmentarianism." + + When I am on test's pseuds page + And I follow "Delete" + Then I should see "The pseud was successfully deleted." + + When I view the collection "Exchange1" + And I follow "My Sign-up" + Then I should see "Antidisestablishmentarianism." + + Scenario: Deleting a pseud shouldn't break prompt meme signups. + Given I am logged in as "moderator" + And I set up the collection "PromptsGalore" + And I select "Prompt Meme" from "challenge_type" + And I press "Submit" + And I press "Submit" + And I am logged in as "test" + And "test" creates the pseud "testpseud" + + When I start signing up for "PromptsGalore" + And I select "testpseud" from "challenge_signup_pseud_id" + And I fill in "Description:" with "Antidisestablishmentarianism." + And I press "Submit" + Then I should see "Sign-up was successfully created." + + When I view the collection "PromptsGalore" + And I follow "My Prompts" + Then I should see "Antidisestablishmentarianism." + + When I am on test's pseuds page + And I follow "Delete" + Then I should see "The pseud was successfully deleted." + + When I view the collection "PromptsGalore" + And I follow "My Prompts" + Then I should see "Antidisestablishmentarianism." + + Scenario: Deleting a pseud should preserve approved creatorships even if the default pseud has a request for the same work. + Given I am logged in as "original_pseud" + And "original_pseud" creates the pseud "other_pseud" + And I am logged in as "coauthor" + And the user "original_pseud" allows co-creators + + When I set up the draft "Original Invited" + And I try to invite the co-authors "original_pseud, other_pseud" + And I press "Post" + Then I should see "Work was successfully posted." + + When I am logged in as "original_pseud" + And I go to original_pseud's co-creator requests page + Then I should see "Co-Creator Requests (2)" + + When I check the 1st checkbox with id matching "selected" + And I press "Accept" + Then I should see "You are now listed as a co-creator on Original Invited." + And I should see "original_pseud" within ".creatorships" + And I should see "Original Invited" within ".creatorships" + And I should see "Co-Creator Requests (1)" + + When I view the work "Original Invited" + Then I should see "Edit" + And I should see "You've been invited to become a co-creator of this work." + + When I go to original_pseud's pseuds page + And I follow "Delete" + Then I should see "The pseud was successfully deleted." + + When I view the work "Original Invited" + Then I should see "Edit" + But I should not see "You've been invited to become a co-creator of this work." + + Scenario: Deleting a pseud should preserve co-creator requests. + Given I am logged in as "original_pseud" + And "original_pseud" creates the pseud "other_pseud" + And I am logged in as "coauthor" + And the user "original_pseud" allows co-creators + + When I set up the draft "Other Invited" + And I try to invite the co-author "other_pseud" + And I press "Post" + Then I should see "Work was successfully posted." + + When I am logged in as "original_pseud" + And I go to original_pseud's co-creator requests page + Then I should see "other_pseud" within ".creatorships" + And I should see "Other Invited" within ".creatorships" + And I should see "Co-Creator Requests (1)" + + When I go to original_pseud's pseuds page + And I follow "Delete" + Then I should see "The pseud was successfully deleted." + + # We should still have a request for Other Invited: + When I go to original_pseud's co-creator requests page + Then I should see "Other Invited" within ".creatorships" + And I should see "original_pseud" within ".creatorships" + And I should see "Co-Creator Requests (1)" + And I should not see "other_pseud" within ".creatorships" + + Scenario: Collections reflect pseud deletion of the owner after the cache expires + + When I am logged in as "original_pseud" + And "original_pseud" creates the pseud "other_pseud" + And I set up the collection "My Collection Thing" + And I select "other_pseud" from "Owner pseud(s)" + And I unselect "original_pseud" from "Owner pseud(s)" + And I press "Submit" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "other_pseud (original_pseud)" within "#main" + + When "original_pseud" deletes the pseud "other_pseud" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "other_pseud (original_pseud)" within "#main" + When the collection blurb cache has expired + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "original_pseud" within "#main" + And I should not see "other_pseud" within "#main" + + + Scenario: Collections reflect pseud deletion of moderators after the cache expires + + Given "myself" has the pseud "other_pseud" + When I have the collection "My Collection Thing" + And I am logged in as the owner of "My Collection Thing" + And I am on the "My Collection Thing" participants page + And I fill in "participants_to_invite" with "other_pseud (myself)" + And I press "Submit" + Then I should see "New members invited: other_pseud (myself)" + When I select "Moderator" from "myself_role" + And I submit with the 4th button + Then I should see "Updated other_pseud." + When I go to the collections page + Then I should see "My Collection Thing" + And I should see "other_pseud (myself)" within "#main" + + When I am logged in as "myself" + And "myself" deletes the pseud "other_pseud" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "other_pseud (myself)" within "#main" + When the collection blurb cache has expired + And I go to the collections page + Then I should see "My Collection Thing" + And I should not see "other_pseud (myself)" within "#main" + And I should see "myself" within "#main" diff --git a/features/other_a/pseuds.feature b/features/other_a/pseuds.feature new file mode 100755 index 0000000..1dba626 --- /dev/null +++ b/features/other_a/pseuds.feature @@ -0,0 +1,330 @@ +@users +Feature: Pseuds + +Scenario: pseud creation and playing with the default pseud + + Given I am logged in as "myself" + And I go to myself's pseuds page + + # Check that you can't edit your default pseud. + Then I should see "Default Pseud" + When I follow "Edit" + Then I should see "You cannot change the pseud that matches your username." + And the "Make this name default" checkbox should be checked and disabled + + # Make a new default pseud called "Me." + When I follow "Back To Pseuds" + And I follow "New Pseud" + And I fill in "Name" with "Me" + And I check "Make this name default" + And I fill in "Description" with "Something's cute" + And I press "Create" + Then I should see "Pseud was successfully created." + And I should be on the dashboard page for user "myself" with pseud "Me" + + # Make sure the new "Me" pseud is the default. + When I follow "Edit Pseud" + Then I should see "Me" + And the "Make this name default" checkbox should not be disabled + And the "Make this name default" checkbox should be checked + + # Make sure the old "myself" pseud is no longer the default. + When I follow "Back To Pseuds" + And I follow "edit_myself" + Then the "Make this name default" checkbox should not be checked + And the "Make this name default" checkbox should not be disabled + + # Edit "Me" to remove it as your default pseud. + When I follow "Back To Pseuds" + And I follow "Me" + Then I should be on the dashboard page for user "myself" with pseud "Me" + When I follow "Edit Pseud" + And I uncheck "Make this name default" + And I press "Update" + Then I should see "Pseud was successfully updated." + And I should be on the dashboard page for user "myself" with pseud "Me" + + # Make sure "Me" is no longer the default pseud, but "myself" is. + When I follow "Edit Pseud" + Then the "Make this name default" checkbox should not be checked + When I follow "Back To Pseuds" + And I follow "edit_myself" + Then the "Make this name default" checkbox should be checked and disabled + + # Test the pseud update path by making Me the default pseud once again. + When I follow "Back To Pseuds" + And I follow "Me" + And I follow "Edit Pseud" + And I check "Make this name default" + And I press "Update" + Then I should see "Pseud was successfully updated." + And I should be on the dashboard page for user "myself" with pseud "Me" + When I follow "Edit Pseud" + Then the "Make this name default" checkbox should be checked + +Scenario: Manage pseuds - add, edit + + Given I am logged in as "editpseuds" + + # Check the Manage My Pseuds link in the profile works. + When I go to editpseuds's user page + And I follow "Profile" + And I follow "Manage My Pseuds" + Then I should see "Pseuds for editpseuds" + + # Make a new pseud. + When I follow "New Pseud" + And I fill in "Name" with "My new name" + And I fill in "Description" with "I wanted to add another name" + And I press "Create" + Then I should be on the dashboard page for user "editpseuds" with pseud "My new name" + And I should see "Pseud was successfully created." + And I should see "My new name" + And I should see "You don't have anything posted under this name yet." + + # Check that all pseuds are listed on user's pseuds page. + When I follow "Back To Pseuds" + Then I should see "editpseuds (editpseuds)" + And I should see "My new name (editpseuds)" + And I should see "I wanted to add another name" + And I should see "Default Pseud" + + # Try to create another pseud with the same name you already used. + When I follow "New Pseud" + Then I should see "New pseud" + When I fill in "Name" with "My new name" + And I press "Create" + Then I should see "You already have a pseud with that name." + + # Recheck various links. + When I follow "Back To Pseuds" + And I follow "editpseuds" + And I follow "Profile" + And I follow "Manage My Pseuds" + Then I should see "Edit My new name" + + # Edit your new pseud's name and description. + When I follow "edit_my_new_name" + And I fill in "Description" with "I wanted to add another fancy name" + And I fill in "Name" with "My new fancy name" + And I press "Update" + Then I should see "Pseud was successfully updated." + And I should be on the dashboard page for user "editpseuds" with pseud "My new fancy name" + + # Check that the changes to your pseud show up on your pseuds page. + When I follow "Back To Pseuds" + Then I should see "editpseuds (editpseuds)" + And I should see "My new fancy name (editpseuds)" + And I should see "I wanted to add another fancy name" + And I should not see "My new name (editpseuds)" + +Scenario: Pseud descriptions do not display images + + Given I am logged in as "myself" + And I go to myself's pseuds page + When I follow "Edit" + And I fill in "Description" with "Fantastic!<img src='http://example.com/icon.svg'>" + And I press "Update" + Then I should see "Pseud was successfully updated." + When I follow "Back To Pseuds" + Then I should not see the image "src" text "http://example.com/icon.svg" + And I should see "Fantastic!" + +Scenario: Comments reflect pseud changes immediately + + Given the work "Interesting" + And I am logged in as "myself" + And "myself" creates the pseud "before" + When I set up the comment "Wow!" on the work "Interesting" + And I select "before" from "comment[pseud_id]" + And I press "Comment" + And I view the work "Interesting" with comments + Then I should see "before (myself)" within ".comment h4.byline" + + When it is currently 1 second from now + And "myself" changes the pseud "before" to "after" + And I view the work "Interesting" with comments + Then I should see "after (myself)" within ".comment h4.byline" + And I should not see "before (myself)" + +Scenario: Collections reflect pseud changes of the owner after the cache expires + + When I am logged in as "myself" + And "myself" creates the pseud "before" + And I set up the collection "My Collection Thing" + And I select "before" from "Owner pseud(s)" + And I unselect "myself" from "Owner pseud(s)" + And I press "Submit" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "before (myself)" within "#main" + + When "myself" changes the pseud "before" to "after" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "before (myself)" within "#main" + When the collection blurb cache has expired + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "after (myself)" within "#main" + And I should not see "before (myself)" within "#main" + +Scenario: Collections reflect pseud changes of moderators after the cache expires + + Given "myself" has the pseud "before" + When I have the collection "My Collection Thing" + And I am logged in as the owner of "My Collection Thing" + And I am on the "My Collection Thing" participants page + And I fill in "participants_to_invite" with "before (myself)" + And I press "Submit" + Then I should see "New members invited: before (myself)" + When I select "Moderator" from "myself_role" + And I submit with the 3rd button + Then I should see "Updated before." + When I go to the collections page + Then I should see "My Collection Thing" + And I should see "before (myself)" within "#main" + + When I am logged in as "myself" + And "myself" changes the pseud "before" to "after" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "before (myself)" within "#main" + When the collection blurb cache has expired + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "after (myself)" within "#main" + And I should not see "before (myself)" within "#main" + +Scenario: Many pseuds + + Given there are 3 pseuds per page + And "Zaphod" has the pseud "Slartibartfast" + And "Zaphod" has the pseud "Agrajag" + And "Zaphod" has the pseud "Betelgeuse" + And I am logged in as "Zaphod" + + When I view my profile + Then I should see "Zaphod" within "dl.meta" + And I should see "Agrajag" within "dl.meta" + And I should see "Betelgeuse" within "dl.meta" + And I should not see "Slartibartfast" within "dl.meta" + And I should see "1 more pseud" within "dl.meta" + + When I go to Zaphod's user page + Then I should see "Zaphod" within "ul.expandable" + And I should see "Agrajag" within "ul.expandable" + And I should see "Betelgeuse" within "ul.expandable" + And I should not see "Slartibartfast" within "ul.expandable" + And I should see "All Pseuds (4)" within "ul.expandable" + + When I go to the dashboard page for user "Zaphod" with pseud "Slartibartfast" + Then I should see "Pseuds" within "li.pseud > a" + And I should see "Slartibartfast" within "ul.expandable" + + When I go to Zaphod's pseuds page + Then I should not see "Zaphod (Zaphod)" within "ul.pseud.index" + But I should see "Agrajag (Zaphod)" within "ul.pseud.index" + And I should see "Betelgeuse (Zaphod)" within "ul.pseud.index" + And I should see "Slartibartfast (Zaphod)" within "ul.pseud.index" + And I should see "Next" within ".pagination" + When I follow "Next" within ".pagination" + Then I should see "Zaphod (Zaphod)" within "ul.pseud.index" + + When there are 10 pseuds per page + And I view my profile + Then I should see "Zaphod, Agrajag, Betelgeuse, and Slartibartfast" within "dl.meta" + +Scenario: Edit pseud updates series blurbs + + Given I am logged in as "Myself" + And "Myself" creates the pseud "Me2" + And I add the work "Great Work" to series "Best Series" as "Me2" + When I go to the dashboard page for user "Myself" with pseud "Me2" + And I follow "Series" + Then I should see "Best Series by Me2 (Myself)" + + When I view my profile + And I follow "Manage My Pseuds" + And I follow "Edit Me2" + And I fill in "Name" with "Me3" + And I press "Update" + Then I should see "Pseud was successfully updated." + + When I follow "Series" + Then I should see "Best Series by Me3 (Myself)" + +Scenario: Change details as an admin + + Given "someone" has the pseud "alt" + And I am logged in as a "policy_and_abuse" admin + And an abuse ticket ID exists + When I go to someone's pseuds page + And I follow "Edit alt" + And I fill in "Description" with "I'd probably be removing text." + And I fill in "Ticket ID" with "no 💜" + And I press "Update" + Then I should see "may begin with an # and otherwise contain only numbers" + And the field labeled "Ticket ID" should contain "no 💜" + When I fill in "Ticket ID" with "#4798454#331" + And I press "Update" + Then I should see "may begin with an # and otherwise contain only numbers" + And the field labeled "Ticket ID" should contain "4798454#331" + When I fill in "Ticket ID" with "47" + And I press "Update" + Then I should see "Pseud was successfully updated." + When I go to someone's pseuds page + And I follow "Edit alt" + When I fill in "Ticket ID" with "#47" + And I press "Update" + Then I should see "Pseud was successfully updated." + When I go to someone's pseuds page + Then I should see "I'd probably be removing text." + When I follow "Activities" within ".admin.primary.navigation" + Then I should see "Pseud alt (someone)" + When I follow "Pseud alt (someone)" + Then I should be on someone's pseuds page + When I visit the last activities item + Then I should see "Pseud alt (someone)" + And I should see "edit pseud" + And I should see a link "Ticket #47" + + # Skip logging admin activity if no change was actually made. + When I go to someone's pseuds page + And I follow "Edit alt" + And I fill in "Ticket ID" with "47" + And I press "Update" + Then I should see "Pseud was successfully updated." + When I go to the admin-activities page + Then I should see 1 admin activity log entry + +Scenario: Bookmarks reflect pseud changes immediately + + Given the work "Interesting" + And I am logged in as "myself" + And "myself" has the pseud "before" + And I bookmark the work "Interesting" as "before" + And I go to myself's bookmarks page + Then I should see "Bookmarked by before (myself)" + + When it is currently 1 second from now + And "myself" changes the pseud "before" to "after" + And I go to myself's bookmarks page + Then I should see "Bookmarked by after (myself)" + And I should not see "Bookmarked by before (myself)" + +Scenario: Chapter byline reflects pseud changes immediately + + Given I am logged in as "myself" + And "myself" creates the pseud "before" + And I post the work "Title" using the pseud "before" + And I add the co-author "pikachu" to the work "Title" + And I post a chapter for the work "Title" as "before" + When I view the work "Title" + And I view the 2nd chapter + Then I should see "Chapter by before (myself)" + When it is currently 1 second from now + And "myself" changes the pseud "before" to "after" + And I view the work "Title" + And I view the 2nd chapter + Then I should see "Chapter by after (myself)" diff --git a/features/other_a/pseuds_special_characters.feature b/features/other_a/pseuds_special_characters.feature new file mode 100755 index 0000000..a2a3f25 --- /dev/null +++ b/features/other_a/pseuds_special_characters.feature @@ -0,0 +1,162 @@ +@users +Feature: Pseuds + +Scenario: creating pseud with unicode characters + + Given I am logged in as "myself" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Àlice and Bôb" + And I fill in "Description" with "special character name" + And I fill in "Icon alt text" with "special Alice" + And I press "Create" + Then I should see "Pseud was successfully created." + When I follow "Edit Pseud" + Then I should see "Àlice and Bôb" + And I should not see "Alice" + +Scenario: creating pseud with chinese characters + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "爱丽丝" + And I press "Create" + Then I should see "Pseud was successfully created." + When I follow "Edit Pseud" + Then I should see "爱丽丝" + +Scenario: creating pseud with pinyin characters + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Aì lì sī" + And I press "Create" + Then I should see "Pseud was successfully created." + When I follow "Edit Pseud" + Then I should see "Aì lì sī" + +Scenario: creating pseud with japanese characters + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "アリス" + And I press "Create" + Then I should see "Pseud was successfully created." + When I follow "Edit Pseud" + Then I should see "アリス" + +Scenario: creating pseud with russian characters + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Алиса" + And I press "Create" + Then I should see "Pseud was successfully created." + When I follow "Edit Pseud" + Then I should see "Алиса" + + +Scenario: not creating pseuds with characters which break urls + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Alice/Bob" + And I press "Create" + Then I should not see "Pseud was successfully created." + And I should see "can contain letters, numbers, spaces, underscores, and dashes" + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Alice & Bob" + And I press "Create" + Then I should not see "Pseud was successfully created." + And I should see "can contain letters, numbers, spaces, underscores, and dashes" + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Alice." + And I press "Create" + Then I should not see "Pseud was successfully created." + And I should see "can contain letters, numbers, spaces, underscores, and dashes" + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Alice?" + And I press "Create" + Then I should not see "Pseud was successfully created." + And I should see "can contain letters, numbers, spaces, underscores, and dashes" + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Alice#" + And I press "Create" + Then I should not see "Pseud was successfully created." + And I should see "can contain letters, numbers, spaces, underscores, and dashes" + +Scenario: not creating pseuds with other characters we don't allow + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Alice + Bob" + And I press "Create" + Then I should not see "Pseud was successfully created." + And I should see "can contain letters, numbers, spaces, underscores, and dashes" + +Scenario: not creating pseuds with more characters we don't allow + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Alice 'Bob'" + And I press "Create" + Then I should not see "Pseud was successfully created." + And I should see "can contain letters, numbers, spaces, underscores, and dashes" + +Scenario: not creating pseuds with even more characters we don't allow + + Given I am logged in as "myself" with password "password" + And I go to myself's user page + And I follow "Profile" within "div#dashboard ul.navigation.actions" + And I follow "Manage My Pseuds" within "div.user" + And I follow "New Pseud" within "div#main.pseuds-index" + And I fill in "Name" with "Alice (Bob)" + And I press "Create" + Then I should not see "Pseud was successfully created." + And I should see "can contain letters, numbers, spaces, underscores, and dashes" + + + diff --git a/features/other_a/reading.feature b/features/other_a/reading.feature new file mode 100755 index 0000000..18db0d3 --- /dev/null +++ b/features/other_a/reading.feature @@ -0,0 +1,303 @@ +@users +Feature: Reading count + + Scenario: A user can only see their own reading history + + Given the following activated user exists + | login | + | first_reader | + When I am logged in as "second_reader" + And I go to first_reader's reading page + Then I should see "Sorry, you don't have permission" + And I should not see "History" within "div#dashboard" + When I go to second_reader's reading page + Then I should see the page title "History" + And I should see "History" within "h2.heading" + And I should see "History" within "div#dashboard" + + Scenario: A user can read a work several times, updating the count and date in their history + + Given I am logged in as "writer" + And I post the work "some work" + And all indexing jobs have been run + And I am logged out + When I am logged in as "fandomer" + And fandomer first read "some work" on "2010-05-25" + And I go to fandomer's reading page + Then I should see "some work" + And I should see "Visited once" + And I should see "Last visited: 25 May 2010" + + When time is frozen at 20/4/2020 + And I go to the work "some work" + And the readings are saved to the database + And I go to fandomer's reading page + Then I should see "Visited 2 times" + And I should see "Last visited: 20 Apr 2020" + + Scenario: A user's reading history is updated only when enabled + + Given I am logged in as "writer" + And I post the work "some work" + And I am logged out + When I am logged in as "fandomer" + And fandomer first read "some work" on "2010-05-25" + And I go to fandomer's reading page + Then I should see "some work" + And I should see "Visited once" + And I should see "Last visited: 25 May 2010" + + When I follow "Preferences" + And I uncheck "Turn on History" + And I press "Update" + And all indexing jobs have been run + Then I should not see "My History" + + When I go to the work "some work" + And the readings are saved to the database + And I go to fandomer's reading page + Then I should see "You have reading history disabled" + And I should not see "some work" + + When I check "Turn on History" + And I press "Update" + Then I should see "Your preferences were successfully updated." + + When I go to fandomer's reading page + Then I should see "Visited once" + And I should see "Last visited: 25 May 2010" + When time is frozen at 20/4/2020 + And I go to the work "some work" + And the readings are saved to the database + And I go to fandomer's reading page + Then I should see "Visited 2 times" + And I should see "Last visited: 20 Apr 2020" + + Scenario: Clear entire reading history + + Given the work "First work" by "testuser" + And the work "second work" by "testuser" + And the work "fourth" by "testuser2" + And I am logged in as "testuser2" + And I post the work "fifth" with rating "Mature" + When I am logged in as "fandomer" + And I am on testuser's works page + And I follow "First work" + And I am on testuser's works page + And I follow "second work" + And I am on testuser2 works page + And I follow "fifth" + And I should see "fifth by testuser2" + And I follow "Yes, Continue" + And the readings are saved to the database + When I go to fandomer's reading page + Then I should see "History" within "div#dashboard" + And I should see "First work" + And I should see "second work" + And I should see "fifth" + But I should not see "fourth" + When I follow "Clear History" + Then I should see "Your history is now cleared" + And I should see "History" within "div#dashboard" + But I should not see "First work" + And I should not see "second work" + And I should not see "fifth" + + Scenario: Mark a story to read later + + Given I am logged in as "writer" + When I post the work "Testy" + Then I should see "Work was successfully posted" + When I am logged out + And I am logged in as "reader" + And I view the work "Testy" + Then I should see "Mark for Later" + When I press "Mark for Later" + Then I should see "This work was added to your Marked for Later list." + When I go to reader's reading page + And I follow "Marked for Later" + Then I should see the page title "Marked for Later" + And I should see "Marked for Later" within "h2.heading" + And I should see "Testy" + And I should see "(Marked for Later.)" + When I view the work "Testy" + Then I should see "Mark as Read" + When I press "Mark as Read" + Then I should see "This work was removed from your Marked for Later list." + And I go to reader's reading page + Then I should see "Testy" + And I should not see "(Marked for Later.)" + + Scenario: You can't mark a story to read later if you're not logged in or the author + + Given I am logged in as "writer" + When I post the work "Testy" + Then I should see "Work was successfully posted" + When I view the work "Testy" + Then I should not see "Mark for Later" + And I should not see "Mark as Read" + When I am logged out + And I view the work "Testy" + Then I should not see "Mark for Later" + And I should not see "Mark as Read" + + Scenario: Multi-chapter works are added to history, can be deleted from history, are updated every time the user accesses a chapter, and can be marked for later + + Given I am logged in as "writer" + And I post the work "multichapter work" + And a chapter is added to "multichapter work" + Then I should see "multichapter work" + When I am logged out + And I am logged in as "fandomer" + And I view the work "multichapter work" + When the readings are saved to the database + And I go to fandomer's reading page + Then I should see "multichapter work" + And I should see "Visited once" + When I press "Delete from History" + Then I should see "Work successfully deleted from your history." + When I view the work "multichapter work" + And the readings are saved to the database + When I go to fandomer's reading page + Then I should see "multichapter work" + And I should see "Visited once" + When I view the work "multichapter work" + And I follow "Next Chapter" + And the readings are saved to the database + When I go to fandomer's reading page + Then I should see "multichapter work" + And I should see "Visited 3 times" + When I view the work "multichapter work" + And I follow "Next Chapter" + When I press "Mark for Later" + Then I should see "This work was added to your Marked for Later list." + And the readings are saved to the database + And I go to fandomer's reading page + Then I should see "multichapter work" + And I should see "Visited 6 times" + And I should see "(Marked for Later.)" + + Scenario: A user can see some of their works marked for later on the homepage + + Given the work "Maybe Tomorrow" + And I am logged in as "testy" + When I mark the work "Maybe Tomorrow" for later + And I go to the homepage + Then I should see "Is it later already?" + And I should see "Some works you've marked for later." + And I should see "Maybe Tomorrow" + + Scenario: A user cannot see works marked for later on the homepage if they have their reading history disabled + + Given the work "Maybe Tomorrow" + And I am logged in as "testy" + When I mark the work "Maybe Tomorrow" for later + And I set my preferences to turn off history + When I go to the homepage + Then I should not see "Is it later already?" + And I should not see "Some works you've marked for later." + And I should not see "Maybe Tomorrow" + + Scenario: A user can delete a work marked for later from their history on the homepage + + Given the work "Not Ever" + And I am logged in as "testy" + When I mark the work "Not Ever" for later + And I go to the homepage + Then I should see "Not Ever" + And I should see a "Delete from History" button + When I press "Delete from History" + Then I should see "Work successfully deleted from your history." + And I should be on the homepage + And I should not see "Is it later already?" + And I should not see "Some works you've marked for later." + And I should not see "Not Ever" + + Scenario: When a user marks a work for later and the creator deletes that work, the marked for later blurb on their homepage should be replaced with a "Deleted work" placeholder + + Given I am logged in as "golucky" with password "password" + And I post the work "Gone Gone Gone" + And I am logged out + When I am logged in as "reader" with password "password" + And I mark the work "Gone Gone Gone" for later + And the readings are saved to the database + And I am logged out + When I am logged in as "golucky" with password "password" + And I delete the work "Gone Gone Gone" + And I am logged out + When I am logged in as "reader" with password "password" + And I go to the homepage + Then I should see "Deleted work" + And I should not see "Gone Gone Gone" + When I go to reader's reading page + Then I should see "Deleted work" + And I should not see "Gone Gone Gone" + When I follow "Marked for Later" + Then I should see "Deleted work" + And I should not see "Gone Gone Gone" + + Scenario: When a user marks a work for later and the creator updates that work, the marked for later blurb on their homepage should update + + Given I am logged in as "editor" with password "password" + And I post the work "Some Work V1" + And I am logged out + When I am logged in as "reader" with password "password" + And I mark the work "Some Work V1" for later + And the readings are saved to the database + And I am logged out + When I am logged in as "editor" with password "password" + And I edit the work "Some Work V1" + And I fill in "Work Title" with "Some Work V2" + And I press "Post" + And I am logged out + When I am logged in as "reader" with password "password" + And I go to the homepage + Then I should see "Some Work V2" + And I should not see "Some Work V1" + + Scenario: A user cannot see hidden by admin works in their reading history + + Given I am logged in as "writer" + When I post the work "Testy" + Then I should see "Work was successfully posted" + When I am logged in as "reader" + And I view the work "Testy" + Then I should see "Mark for Later" + When I press "Mark for Later" + Then I should see "This work was added to your Marked for Later list." + When I am logged in as a "policy_and_abuse" admin + And I view the work "Testy" + And I follow "Hide Work" + Then I should see "Item has been hidden." + When I am logged in as "reader" + And I go to reader's reading page + Then I should not see "Testy" + + Scenario: When a chapter is added to a work, "update available" should not appear until it is posted + + Given the work "Some Work" by "writer" + When I am logged in as "reader" + And I mark the work "Some Work" for later + And the readings are saved to the database + And I am logged out + When a draft chapter is added to "Some Work" + And I am logged in as "reader" + And I go to reader's reading page + Then I should not see "(Update available.)" + When I am logged in as "writer" + And I view the work "Some Work" + And I view the 2nd chapter + And I post the draft chapter + When I am logged in as "reader" + And I go to reader's reading page + Then I should see "(Update available.)" + + Scenario: Reading history blurb includes an HTML comment containing the unix epoch of the updated time + + Given time is frozen at 2025-04-12 17:00 UTC + And I am logged in as "ethel" + And the work "Test" + And I view the work "Test" + And the readings are saved to the database + When I go to ethel's reading page + Then I should see an HTML comment containing the number 1744477200 within "li.work.blurb" diff --git a/features/other_b/errors.feature b/features/other_b/errors.feature new file mode 100755 index 0000000..1bc91f4 --- /dev/null +++ b/features/other_b/errors.feature @@ -0,0 +1,11 @@ +@errors +Feature: Error messages + + Scenario: Error messages should be able to display '^' + Given I am logged in as a random user + And I post the work "Work 1" + And I view the work "Work 1" + And I follow "Edit Tags" + When I fill in "Fandoms" with "^" + And I press "Post" + Then I should see "Sorry! We couldn't save this work because: Tag name '^' cannot include the following restricted characters: , ^ * < > { } = ` , 、 \ %" diff --git a/features/other_b/fandoms.feature b/features/other_b/fandoms.feature new file mode 100755 index 0000000..8c4a95f --- /dev/null +++ b/features/other_b/fandoms.feature @@ -0,0 +1,47 @@ +@fandoms +Feature: There is a list of unassigned Fandoms + + Scenario: A user can see the list of fandoms and filter it + + Given I have a canonical "TV Shows" fandom tag named "Steven Universe" + And I have a canonical "Movies" fandom tag named "High School Musical" + And I am logged in as "author" + And I post the work "Stronger than you" with fandom "Steven Universe" + And I post the work "Breaking free" with fandom "High School Musical" + And I am logged in as a tag wrangler + When I go to the unassigned fandoms page + Then I should see "Steven Universe" + And I should see "High School Musical" + When I select "TV Shows" from "media_id" + And I press "Sort and Filter" + Then I should see "Steven Universe" + And I should not see "High School Musical" + When I select "Movies" from "media_id" + And I press "Sort and Filter" + Then I should see "High School Musical" + When I follow "High School Musical" + Then I should see "This tag belongs to the Fandom Category." + + Scenario: A user can see the list of relationships in a fandom + + Given the following typed tags exists + | name | type | canonical | + | Steven Universe | Fandom | true | + | Ruby/Sapphire (Steven Universe) | Relationship | true | + | Ruby (Steven Universe) | Character | true | + | Sapphire (Steven Universe) | Character | true | + And I add the fandom "Steven Universe" to the character "Ruby (Steven Universe)" + And I add the fandom "Steven Universe" to the character "Sapphire (Steven Universe)" + And I am logged in as "author" + And I post the work "Stronger than you" with fandom "Steven Universe" with character "Ruby (Steven Universe)" with second character "Sapphire (Steven Universe)" with relationship "Ruby/Sapphire (Steven Universe)" + When I go to the "Steven Universe" tag page + And I follow "Relationship tags in this fandom" + Then I should see "Ruby (Steven Universe)" + And I should see "Sapphire (Steven Universe)" + + Scenario: Click on "Relationships by Character" on a fandom tag containing periods + Given a canonical fandom "Harry Potter - J. K. Rowling" + When I view the tag "Harry Potter - J. K. Rowling" + And I follow "Relationship tags in this fandom" + Then I should not see "The page you were looking for doesn't exist." + And I should see "Relationships by Character" diff --git a/features/other_b/icon.feature b/features/other_b/icon.feature new file mode 100755 index 0000000..e7e5ab8 --- /dev/null +++ b/features/other_b/icon.feature @@ -0,0 +1,54 @@ +@users +Feature: User icons + + Scenario Outline: Users should be able to upload icons using an allowed image format + + Given I am editing a pseud + When I attach an icon with the extension "<extension>" + And I press "Update" + Then I should see "Pseud was successfully updated" + And I should see the image "alt" text "" + + Examples: + | extension | + | gif | + | jpg | + | png | + + Scenario: Users should not be able to upload icons using the .bmp format + + Given I am editing a pseud + When I attach an icon with the extension "bmp" + And I press "Update" + Then I should see "Sorry! We couldn't save this pseud because:" + And I should see "Icon content type is invalid" + + Scenario: Users can change alt text + + Given I have an icon uploaded + When I follow "Edit Pseud" + And I fill in "pseud_icon_alt_text" with "Some test description" + And I press "Update" + Then I should see the image "alt" text "Some test description" + + Scenario: Add and remove a collection icon + + Given I have a collection "Pretty" + When I add an icon to the collection "Pretty" + Then I should see "Collection was successfully updated" + And the "Pretty" collection should have an icon + When I delete the icon from the collection "Pretty" + Then I should see "Collection was successfully updated." + And the "Pretty" collection should not have an icon + + Scenario: Users can delete icon and alt text + + Given I have an icon uploaded + When I follow "Edit Pseud" + And I fill in "pseud_icon_alt_text" with "Some test description" + And I press "Update" + Then I should see the image "alt" text "Some test description" + When I delete the icon from my pseud + Then I should see "Pseud was successfully updated." + When I follow "Edit Pseud" + Then I should see the icon and alt text boxes are blank diff --git a/features/other_b/sanitizer.feature b/features/other_b/sanitizer.feature new file mode 100755 index 0000000..6ce67b1 --- /dev/null +++ b/features/other_b/sanitizer.feature @@ -0,0 +1,66 @@ +@works +Feature: Sanitizing HTML + + Scenario: Sanitizer should kick in + + When I am logged in as "newbie" with password "password" + And I set up the draft "My Awesome Story" + And I fill in "content" with + """ + The quick brown fox jumps over the lazy dog. + <!-- #exec cmd=\"/bin/echo \" --> + <script src=http://ha.ckers.org/xss.js></script> + """ + And I press "Preview" + Then I should see "Preview" + And I should not see the text with tags '<!-- #exec cmd=' + And I should not see the text with tags '<script src=http://ha.ckers.org/xss.js></script>' + + + Scenario: Sanitizer should leave safe HTML alone + + When I am logged in as "newbie" + And I set up the draft "My Awesome Story" + And I fill in "content" with + """ + 1. Lorem ipsim + + 2. <a href="https://en.wikipedia.org/wiki/The_quick_brown_fox_jumps_over_the_lazy_dog"><em>The quick brown fox jumps over the lazy dog</em></a>. + """ + And I press "Preview" + Then I should see "Preview" + And I should see "The quick brown fox jumps over the lazy dog" within "p a em" + And I should see the text with tags '"https://en.wikipedia.org/wiki/The_quick_brown_fox_jumps_over_the_lazy_dog"' + + + Scenario: XSS hacks in works should be blocked by sanitizing + + # TODO + # + # I moved almost all of these to spec/lib/html_cleaner_spec.rb The + # remaining two below should go there, too, but I'm not quite sure + # what their intention is. The sanitiser doesn't change them, and I + # don't get the reason behind the "should not find XSS" test. -- + # Rebecca + + Given basic tags + And I am logged in as "newbie" with password "password" + When I go to the new work page + Then I should see "Post New Work" + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "Supernatural" + And I fill in "Work Title" with "All Hell Breaks Loose" + And I fill in "content" with 'BODY{-moz-binding:url("http://ha.ckers.org/xssmoz.xml#xss")}' + And I press "Preview" + Then I should see "Preview" + And I should not see "XSS" + And I should see "BODY{-moz-binding:url(" + When I press "Edit" + And I fill in "content" with "behavior: url(xss.htc);" + And I press "Preview" + Then I should see "Preview" + And I should not see "XSS" + And I should see "behavior: url(xss.htc);" + diff --git a/features/other_b/series.feature b/features/other_b/series.feature new file mode 100755 index 0000000..dad4aa2 --- /dev/null +++ b/features/other_b/series.feature @@ -0,0 +1,346 @@ +@series +Feature: Create and Edit Series + In order to view series created by a user + As a reader + The index needs to load properly, even for authors with more than ArchiveConfig.ITEMS_PER_PAGE series + + Scenario: Creator manually enters a series name to add a work to a new series when the work is first posted + Given I am logged in as "author" + And I set up the draft "Sweetie Belle" + When I fill in "Or create and use a new one:" with "Ponies" + When I press "Post" + Then I should see "Part 1 of Ponies" within "div#series" + And I should see "Part 1 of Ponies" within "dd.series" + When I view the series "Ponies" + Then I should see "Sweetie Belle" + + Scenario: Creator selects an existing series name to add a work to an existing series when the work is first posted + Given I am logged in as "author" + And I post the work "Sweetie Belle" as part of a series "Ponies" + And I set up the draft "Starsong" + When I select "Ponies" from "Choose one of your existing series:" + And I press "Post" + Then I should see "Part 2 of Ponies" within "div#series" + And I should see "Part 2 of Ponies" within "dd.series" + When I view the series "Ponies" + Then I should see "Sweetie Belle" + And I should see "Starsong" + + Scenario: Creator adds a work to an existing series by editing the work + Given I am logged in as "author" + And I post the work "Sweetie Belle" as part of a series "Ponies" + And I post the work "Rainbow Dash" + When I view the series "Ponies" + Then I should not see "Rainbow Dash" + When I edit the work "Rainbow Dash" + And I select "Ponies" from "Choose one of your existing series:" + And I press "Post" + Then I should see "Part 2 of Ponies" within "div#series" + And I should see "Part 2 of Ponies" within "dd.series" + When I view the series "Ponies" + Then I should see "Sweetie Belle" + And I should see "Rainbow Dash" + + Scenario: Works in a series have series navigation + Given I am logged in as "author" + And I post the work "Sweetie Belle" as part of a series "Ponies" + And it is currently 1 second from now + And I post the work "Starsong" as part of a series "Ponies" + And it is currently 1 second from now + And I post the work "Rainbow Dash" as part of a series "Ponies" + When I view the series "Ponies" + And I follow "Rainbow Dash" + Then I should see "Part 3 of Ponies" + And I should not see "Next Work →" + When I follow "← Previous Work" + Then I should see "Starsong" + And I should see "Next Work →" within ".work.meta .next" + And I should see "Next Work →" within ".afterword .next" + When I follow "← Previous Work" + And I should see "Next Work →" within ".work.meta .next" + And I should see "Next Work →" within ".afterword .next" + Then I should see "Sweetie Belle" + When I follow "Next Work →" + Then I should see "Starsong" + + Scenario: Creator can add series information + Given I am logged in as "author" + And I post the work "Sweetie Belle" as part of a series "Ponies" + When I view the series "Ponies" + And I follow "Edit Series" + And I fill in "Series Description" with "This is a series about ponies. Of course" + And I fill in "Series Notes" with "I wrote this under the influence of coffee! And pink chocolate." + And I press "Update" + Then I should see "Series was successfully updated." + And I should see "This is a series about ponies. Of course" within "blockquote.userstuff" + And I should see "I wrote this under the influence of coffee! And pink chocolate." within "dl.series" + And I should see "Complete: No" + When I follow "Edit Series" + And I check "This series is complete" + And I press "Update" + Then I should see "Complete: Yes" + + Scenario: A work can be in two series + Given I am logged in as "author" + And I post the work "Sweetie Belle" as part of a series "Ponies" + And I post the work "Rainbow Dash" as part of a series "Ponies" + When I edit the work "Rainbow Dash" + Then the "This work is part of a series" checkbox should be checked + And "Ponies" should be an option within "Choose one of your existing series:" + When I fill in "Or create and use a new one:" with "Black Beauty" + And I press "Preview" + Then I should see "Part 2 of Ponies" within "dd.series" + And I should see "Part 1 of Black Beauty" within "dd.series" + When I press "Update" + And all indexing jobs have been run + Then I should see "Part 1 of Black Beauty" within "dd.series" + And I should see "Part 2 of Ponies" within "dd.series" + And I should see "Part 1 of Black Beauty" within "div#series" + And I should see "Part 2 of Ponies" within "div#series" + + Scenario: Creator with multiple pseuds adds a work to a new series when the work is first posted + Given I am logged in as "author" + And "author" creates the pseud "Pointless Pseud" + And I set up the draft "Sweetie Belle" using the pseud "Pointless Pseud" + When I fill in "Or create and use a new one:" with "Ponies" + And I press "Post" + Then I should see "Pointless Pseud" + And I should see "Part 1 of Ponies" within "div#series" + And I should see "Part 1 of Ponies" within "dd.series" + When I view the series "Ponies" + Then I should see "Sweetie Belle" + + Scenario: Creator with multiple pseuds adds a work to an existing series when the work is first posted + Given I am logged in as "author" + And "author" creates the pseud "Pointless Pseud" + And I post the work "Sweetie Belle" as part of a series "Ponies" using the pseud "Pointless Pseud" + When I set up the draft "Starsong" as part of a series "Ponies" using the pseud "Pointless Pseud" + And I press "Post" + Then I should see "Pointless Pseud" + And I should see "Part 2 of Ponies" + When I view the series "Ponies" + Then I should see "Sweetie Belle" + And I should see "Starsong" + + Scenario: Creator with multiple pseuds adds a work to an existing series by editing the work + Given I am logged in as "author" + And "author" creates the pseud "Pointless Pseud" + And I post the work "Sweetie Belle" as part of a series "Ponies" using the pseud "Pointless Pseud" + And I post the work "Rainbow Dash" using the pseud "Pointless Pseud" + When I view the series "Ponies" + Then I should not see "Rainbow Dash" + When I edit the work "Rainbow Dash" + And I select "Ponies" from "Choose one of your existing series:" + And I press "Post" + Then I should see "Part 2 of Ponies" within "div#series" + And I should see "Part 2 of Ponies" within "dd.series" + When I view the series "Ponies" + Then I should see "Sweetie Belle" + And I should see "Rainbow Dash" + + Scenario: A pseud's series page contains the pseud in the page title + Given I am logged in as "author" + And "author" creates the pseud "Pointless Pseud" + And I post the work "Sweetie Belle" as part of a series "Ponies" using the pseud "Pointless Pseud" + When I follow "Pointless Pseud" + And I follow "Series (1)" + Then the page title should include "Pointless Pseud - Series" + + Scenario: Rename a series + Given I am logged in as a random user + When I add the work "WALL-E" to series "Robots" + Then I should see "Part 1 of Robots" within "div#series" + And I should see "Part 1 of Robots" within "dd.series" + When I view the series "Robots" + And I follow "Edit Series" + And I fill in "Series Title" with "Many a Robot" + And I wait 2 seconds + And I press "Update" + Then I should see "Series was successfully updated." + And I should see "Many a Robot" + # Work blurbs should be updated. + When I follow "My Dashboard" + Then I should see "Part 1 of Many a Robot" within "#user-works" + # Work metas should be updated. + When I view the work "WALL-E" + Then I should see "Part 1 of Many a Robot" within "div#series" + And I should see "Part 1 of Many a Robot" within "dd.series" + + Scenario: Post + Given I am logged in as "whoever" with password "whatever" + And I add the work "public" to series "be_public" + When I follow "be_public" + Then I should not see the image "title" text "Restricted" within "h2" + + Scenario: View user's series index + Given I am logged in as "whoever" with password "whatever" + And I add the work "grumble" to series "polarbears" + When I go to whoever's series page + Then I should see "1 Series by whoever" + And I should see "polarbears" + + Scenario: Series index for maaany series + Given I am logged in as "whoever" with password "whatever" + And I add the work "grumble" to "32" series "penguins" + When I go to whoever's series page + Then I should see "penguins30" + When I follow "Next" + Then I should see "penguins0" + + Scenario: Series show page with many works + Given I am logged in as "author" + And I post the work "Caesar" as part of a series "Salads" + And I post the work "Chicken" as part of a series "Salads" + And I post the work "Pasta" as part of a series "Salads" + And I post the work "Spring" as part of a series "Salads" + And I post the work "Chef" as part of a series "Salads" + And there are 3 works per series page + When I view the series "Salads" + Then I should see "Caesar" + And I should see "Chicken" + And I should see "Pasta" + When I follow "Next" + Then I should see "Spring" + And I should see "Chef" + + Scenario: Removing self as co-creator from co-created series when you are the only creator of a work in the series. + Given I am logged in as "sun" + And the user "moon" allows co-creators + And I post the work "Sweetie Bell" as part of a series "Ponies" + When I view the series "Ponies" + And I follow "Edit Series" + And I try to invite the co-author "moon" + And I press "Update" + Then I should see "Series was successfully updated." + But I should not see "moon" + When the user "moon" accepts all co-creator requests + Then "moon" should be a creator of the series "Ponies" + When I view the series "Ponies" + And I press "Remove Me As Co-Creator" + Then I should see "Sorry, we can't remove all creators of a work." + + Scenario: Removing self as co-creator from co-created series + Given basic tags + And the user "son" allows co-creators + When I am logged in as "moon" with password "testuser" + And I coauthored the work "Sweetie Bell" as "moon" with "son" + And I edit the work "Sweetie Bell" + And I fill in "work_series_attributes_title" with "Ponies" + And I post the work + Then I should see "Work was successfully updated." + And "moon" should be a creator of the series "Ponies" + And "son" should be a creator on the series "Ponies" + # Delay to make sure the cache is expired + And it is currently 1 second from now + When I press "Remove Me As Co-Creator" + Then I should see "You have been removed as a creator from the series and its works." + And "moon" should not be the creator of the series "Ponies" + And "son" should be a creator on the series "Ponies" + When I go to moon's works page + Then I should not see "Sweetie Bell" + + Scenario: Delete a series + Given I am logged in as "cereal" with password "yumyummy" + And I add the work "Snap" to series "Krispies" + When I view the series "Krispies" + And I follow "Delete Series" + And I press "Yes, Delete Series" + Then I should see "Series was successfully deleted." + + Scenario: A work's series information is visible and up to date when previewing the work while posting or editing + Given I am logged in as "author" + And "author" creates the pseud "Pointless Pseud" + And I set up the draft "Sweetie Belle" as part of a series "Ponies" + When I press "Preview" + Then I should see "Part 1 of Ponies" + When I press "Post" + And I set up the draft "Rainbow Dash" as part of a series "Ponies" using the pseud "Pointless Pseud" + And I press "Preview" + Then I should see "Pointless Pseud" + And I should see "Part 2 of Ponies" + When I edit the work "Rainbow Dash" + And I fill in "Or create and use a new one:" with "Black Beauty" + And I wait 2 seconds + And I press "Preview" + Then I should see "Part 2 of Ponies" within "dd.series" + And I should see "Part 1 of Black Beauty" within "dd.series" + + Scenario: A series's metadata is visible when viewing the series + Given I am logged in as a random user + And I post the work "Story" as part of a series "Excellent Series" + And I bookmark the series "Excellent Series" + When I view the series "Excellent Series" + Then I should see "Words: 6" within ".series.meta" + And I should see "Bookmarks: 1" within ".series.meta" + And I should see "Works: 1" within ".series.meta" + + Scenario: When editing a series, the title field should not escape HTML + Given I am logged in as "whoever" + And I post the work "whatever" as part of a series "What a title! :< :& :>" + And I go to whoever's series page + And I follow "What a title! :< :& :>" + And I follow "Edit Series" + Then I should see "What a title! :< :& :>" in the "Series Title" input + + Scenario: You can edit a series to add someone as a co-creator if their preferences are set to permit it. + Given I am logged in as "foobar" + And the user "barbaz" exists and is activated + And the user "barbaz" allows co-creators + And I post the work "Behind her back she’s Gentleman Jack" as part of a series "Gentleman Jack" + When I view the series "Gentleman Jack" + And I follow "Edit Series" + And I try to invite the co-author "barbaz" + And I press "Update" + Then I should see "Series was successfully updated." + But I should not see "barbaz" + And 1 email should be delivered to "barbaz" + And the email should contain "The user foobar has invited your pseud barbaz to be listed as a co-creator on the following series" + When I am logged in as "barbaz" + And I follow "Gentleman Jack" in the email + Then I should not see "Edit Series" + When I follow "Co-Creator Requests page" + And I check "selected[]" + And I wait 2 seconds + And I press "Accept" + Then I should see "You are now listed as a co-creator on Gentleman Jack." + When I follow "Gentleman Jack" + Then I should see "Edit Series" + And "barbaz" should be a co-creator of the series "Gentleman Jack" + + Scenario: You cannot edit a series to add someone as a co-creator if their preferences don't permit it. + Given I am logged in as "foobar" + And the user "barbaz" exists and is activated + And the user "barbaz" disallows co-creators + And I post the work "Behind her back she’s Gentleman Jack" as part of a series "Gentleman Jack" + When I view the series "Gentleman Jack" + And I follow "Edit Series" + And I try to invite the co-author "barbaz" + And I press "Update" + Then I should see "Invalid creator: barbaz does not allow others to invite them to be a co-creator." + When I press "Update" + Then I should see "Series was successfully updated." + And "barbaz" should not be the creator of the series "Gentleman Jack" + + Scenario: If you edit a series to add a co-creator with an ambiguous pseud, you will be prompted to clarify which user you mean. + Given "myself" has the pseud "Me" + And "herself" has the pseud "Me" + And the user "myself" allows co-creators + And the user "herself" allows co-creators + When I am logged in as "testuser" with password "testuser" + And I post the work "Behind her back she’s Gentleman Jack" as part of a series "Gentleman Jack" + And I view the series "Gentleman Jack" + And I follow "Edit Series" + And I try to invite the co-author "Me" + And I press "Update" + Then I should see "There's more than one user with the pseud Me." + When I select "myself" from "Please choose the one you want:" + And I press "Update" + Then I should see "Series was successfully updated." + And I should not see "Me (myself)" + And 1 email should be delivered to "myself" + And the email should contain "The user testuser has invited your pseud Me to be listed as a co-creator on the following series" + When the user "myself" accepts all co-creator requests + And I view the series "Gentleman Jack" + Then "testuser" should be the creator of the series "Gentleman Jack" + And "Me (myself)" should be the creator of the series "Gentleman Jack" + And I should see "Me (myself), testuser" diff --git a/features/other_b/series_lock.feature b/features/other_b/series_lock.feature new file mode 100755 index 0000000..1064ad5 --- /dev/null +++ b/features/other_b/series_lock.feature @@ -0,0 +1,67 @@ +@series +Feature: Locked and partially locked series + In order to keep my works under the radar + As a registered archive user + I should be able to make my serial works visible only to other registered users + + Scenario: Post a series with a restricted work, then add a draft, then make the draft public and post it + Given I am logged in as "fandomer" + And I set up the draft "Humbug" as part of a series "Antiholidays" + And I lock the work + And I press "Post" + Then I should see "Part 1 of Antiholidays" + When I go to fandomer's series page + Then I should see "Antiholidays" + When I am logged out + And I go to fandomer's series page + Then I should not see "Antiholidays" + When I am logged in as "reccer" + And I go to fandomer's series page + Then I should see "Antiholidays" + When I view the series "Antiholidays" + Then I should see "Humbug" + When I am logged in as "fandomer" + And I set up the draft "Antivalentine" as part of a series "Antiholidays" + And I check "work_restricted" + And I press "Preview" + Then I should see "Draft was successfully created." + And I should see "Part 2 of Antiholidays" + When I view the series "Antiholidays" + Then I should see "Works: 1" + And I should not see "Antivalentine" + When I view the work "Humbug" + Then I should not see "Next Work →" within "dd" + When I edit the work "Antivalentine" + And I unlock the work + And I press "Preview" + Then I should see "Part 2 of Antiholidays" + When I press "Post" + Then I should see "Part 2 of Antiholidays" + And I should not see the image "title" text "Restricted" + And I should see "← Previous Work" within "dd.series" + When I am logged out + And I view the series "Antiholidays" + Then I should see "Antivalentine" + But I should not see "Humbug" + When I view the work "Antivalentine" + Then I should see "Part 1 of Antiholidays" + And I should not see "Next Work →" within "dd" + When I am logged in as "reccer" + And I go to fandomer's series page + Then I should see "Antiholidays" + When I view the series "Antiholidays" + Then I should see "Works: 2" + And I should see "Humbug" + And I should see "Antivalentine" + + Scenario: edit a locked work to add it to a series + Given I am logged in as "fandomer" + And I post the locked work "Boohoo" + When I edit the work "Boohoo" + And I uncheck "work_restricted" + And I fill in "work_series_attributes_title" with "Antiholidays" + And I press "Preview" + Then I should see "Preview" + And I should see "Part 1 of Antiholidays" + When I press "Update" + Then I should see "Work was successfully updated" diff --git a/features/other_b/series_order.feature b/features/other_b/series_order.feature new file mode 100755 index 0000000..421c0b3 --- /dev/null +++ b/features/other_b/series_order.feature @@ -0,0 +1,70 @@ +@series +Feature: Rearrange works within a series + In order to manage parts of a series + As a humble series writer + I want to be able to reorder the parts of my series + + Scenario: Rearrange parts of a series. + Given I am logged in as "author" + And I post the work "A Bad, Bad Day" as part of a series "Tale of Woe" + Then I should see "Part 1 of Tale of Woe" + When I view the series "Tale of Woe" + Then I should see "A Bad, Bad Day" + When I post the work "A Bad, Bad Night" as part of a series "Tale of Woe" + Then I should see "Part 2 of Tale of Woe" + When I post the work "Things Get Worse" as part of a series "Tale of Woe" + Then I should see "Part 3 of Tale of Woe" + When I view the series "Tale of Woe" + And I follow "Reorder Series" + Then I should see "Manage Series: Tale of Woe" + And I should see "1. A Bad, Bad Day" + And I should see "2. A Bad, Bad Night" + And I should see "3. Things Get Worse" + When I fill in "serial_0" with "3" + And I fill in "serial_1" with "1" + And I fill in "serial_2" with "2" + And I press "Update Positions" + Then I should see "Series order has been successfully updated" + When I follow "Reorder Series" + And I should see "1. A Bad, Bad Night" + And I should see "2. Things Get Worse" + And I should see "3. A Bad, Bad Day" + + @javascript + Scenario: Reordering series by drag and drop updates work blurbs and meta correctly. + Given I am logged in as "author" + And I post the work "A Bad, Bad Day" as part of a series "Tale of Woe" + And I post the work "A Bad, Bad Night" as part of a series "Tale of Woe" + And I post the work "Things Get Worse" as part of a series "Tale of Woe" + # Blurbs + When I view the series "Tale of Woe" + Then I should see "Part 1 of Tale of Woe" within ".work.blurb:first-child" + Then I should see "Part 2 of Tale of Woe" within ".work.blurb:nth-child(2)" + Then I should see "Part 3 of Tale of Woe" within ".work.blurb:nth-child(3)" + # Meta + When I view the work "A Bad, Bad Day" + Then I should see "Part 1 of Tale of Woe" + When I view the work "A Bad, Bad Night" + Then I should see "Part 2 of Tale of Woe" + When I view the work "Things Get Worse" + When I view the series "Tale of Woe" + And I follow "Reorder Series" + And I reorder the 2nd work to be below the 3rd work in the series + And I press "Update Positions" + Then I should see "Series order has been successfully updated" + # Blurbs + And I should see "Part 1 of Tale of Woe" within ".work.blurb:first-child" + And I should see "Part 2 of Tale of Woe" within ".work.blurb:nth-child(2)" + And I should see "Part 3 of Tale of Woe" within ".work.blurb:nth-child(3)" + When I follow "Reorder Series" + Then I should see "1. A Bad, Bad Day" + And I should see "2. Things Get Worse" + And I should see "3. A Bad, Bad Night" + # Meta + When I view the work "A Bad, Bad Day" + When I view the work "A Bad, Bad Day" + Then I should see "Part 1 of Tale of Woe" + When I view the work "Things Get Worse" + Then I should see "Part 2 of Tale of Woe" + When I view the work "A Bad, Bad Night" + Then I should see "Part 3 of Tale of Woe" diff --git a/features/other_b/skin.feature b/features/other_b/skin.feature new file mode 100755 index 0000000..cc5893a --- /dev/null +++ b/features/other_b/skin.feature @@ -0,0 +1,352 @@ +@set-default-skin +Feature: Non-public site and work skins + + Scenario: A user should be able to create a skin with CSS + Given I am logged in as "skinner" + And the app name is "Example Archive" + When I am on the new skin page + And I fill in "Title" with "my blinking & skin" + And I fill in "CSS" with "#title { text-decoration: blink;}" + And I submit + Then I should see "Skin was successfully created" + And I should see "my blinking & skin skin by skinner" + And I should see "text-decoration: blink;" + And I should see "(No Description Provided)" + And I should see "by skinner" + But I should see a button with text "Use" + And I should see "Delete" + And I should see "Edit" + And I should not see "Stop Using" + And I should not see "(Approved)" + And I should not see "(Not yet reviewed)" + And I should see the page title "my blinking & skin | Example Archive" + + Scenario: A logged-out user should not be able to create skins. + Given I am a visitor + When I go to the new skin page + Then I should see "Sorry, you don't have permission" + + Scenario: A user should be able to select one of their own non-public skins to use in + their preferences + Given I am logged in as "skinner" + And I create the skin "my blinking skin" with css "#title { text-decoration: blink;}" + When I am on skinner's preferences page + And I select "my blinking skin" from "preference_skin_id" + And I submit + Then I should see "Your preferences were successfully updated." + And I should see "#title {" in the page style + And I should see "text-decoration: blink;" in the page style + + Scenario: A user should be able to select one of their own non-public skins to use in + their My Skins page + Given I am logged in as "skinner" + And I create the skin "my blinking skin" with css "#title { text-decoration: blink;}" + Then I should see "my blinking skin" + When I press "Use" + Then I should see "#title {" in the page style + And I should see "text-decoration: blink;" in the page style + + Scenario: Skin titles should be unique + Given I am logged in as "skinner" + When I am on the new skin page + And I fill in "Title" with "Default" + And I submit + Then I should see "must be unique" + + Scenario: The user who creates a skin should be able to edit it + Given I am logged in as "skinner" + And I create the skin "my skin" + When I follow "Edit" + And I fill in "CSS" with "#greeting { text-decoration: blink;}" + And I submit + Then I should see an update confirmation message + + Scenario: Users should be able to create and use a work skin + Given I am logged in as "skinner" + And the default ratings exist + When I am on the new skin page + And I select "Work Skin" from "skin_type" + And I fill in "Title" with "Awesome Work Skin" + And I fill in "Description" with "Great work skin" + And I fill in "CSS" with "p {color: purple;}" + And I submit + Then I should see "Skin was successfully created" + And I should see "#workskin p" + When I go to the new work page + Then I should see "Awesome Work Skin" + When I set up the draft "Story With Awesome Skin" + And I select "Awesome Work Skin" from "work_work_skin_id" + And I press "Preview" + Then I should see "Preview" + And I should see "color: purple" in the page style + When I press "Post" + Then I should see "Story With Awesome Skin" + And I should see "color: purple" in the page style + And I should see "Hide Creator's Style" + When I follow "Hide Creator's Style" + Then I should see "Story With Awesome Skin" + And I should not see "color: purple" + And I should not see "Hide Creator's Style" + And I should see "Show Creator's Style" + Then the cache of the skin on "Awesome Work Skin" should expire after I save the skin + + Scenario: log out from my skins page (Issue 2271) + Given I am logged in as "skinner" + And I am on skinner's user page + When I follow "Skins" + And I log out + Then I should be on the login page + + Scenario: Create a complex replacement skin using Archive skin components + Given I have loaded site skins + And I am logged in as "skinner" + When I set up the skin "Complex" + And I select "replace archive skin entirely" from "What it does:" + And I check "Load Archive Skin Components" + And I submit + Then I should see a create confirmation message + And I should see "We've added all the archive skin components as parents. You probably want to remove some of them now!" + When I check "Load Archive Skin Components" + And I submit + Then I should see errors + + Scenario: Vendor-prefixed properties should be allowed + Given basic skins + And I am logged in as "skinner" + When I am on the new skin page + And I fill in "Title" with "skin with prefixed property" + And I fill in "CSS" with ".myclass { -moz-box-sizing: border-box; -webkit-transition: opacity 2s; }" + And I submit + Then I should see "Skin was successfully created" + Then the cache of the skin on "skin with prefixed property" should expire after I save the skin + + Scenario: #workskin selector prefixing + Given basic skins + And I am logged in as "skinner" + When I am on the new skin page + And I select "Work Skin" from "skin_type" + And I fill in "Title" with "#worksin prefixing" + And I fill in "CSS" with "#workskin, #workskin a, #workskin:hover, #workskin *, .prefixme, .prefixme:hover, * .prefixme { color: red; }" + And I submit + Then I should not see "#workskin #workskin," + And I should not see "#workskin #workskin a" + And I should see ", #workskin a," + And I should not see "#workskin #workskin:hover" + And I should see "#workskin .prefixme," + And I should see "#workskin .prefixme:hover" + And I should see "#workskin * .prefixme" + + Scenario: New skin form should have the correct skin type pre-selected + Given I am logged in as "skinner" + When I am on the skins page + And I follow "Create Site Skin" + Then "Site Skin" should be selected within "skin_type" + When I am on the skins page + And I follow "My Work Skins" + And I follow "Create Work Skin" + Then "Work Skin" should be selected within "skin_type" + + Scenario: Skin type should persist and remain selectable if you encounter errors + during creation + Given I am logged in as "skinner" + When I am on the skins page + And I follow "My Work Skins" + And I follow "Create Work Skin" + And I fill in "Title" with "invalid skin" + And I fill in "CSS" with "this is invalid css" + And I submit + Then I should see errors + And "Work Skin" should be selected within "skin_type" + When I select "Site Skin" from "skin_type" + And I fill in "CSS" with "still invalid css" + And I submit + Then I should see errors + And "Site Skin" should be selected within "skin_type" + + Scenario: View toggle buttons on skins (Issue 3197) + Given basic skins + And I am logged in as "skinner" + When I am on skinner's skins page + Then I should see "My Site Skins" + And I should see "My Work Skins" + And I should see "Public Site Skins" + And I should see "Public Work Skins" + + Scenario: Toggle between user's work skins and site skins + Given basic skins + And I am logged in as "skinner" + And I am on skinner's skins page + When I follow "My Work Skins" + Then I should see "My Work Skins" + When I follow "My Site Skins" + Then I should see "My Site Skins" + + Scenario: The cache should be flushed with a parent and not when unrelated + Given I have loaded site skins + And I am logged in as "skinner" + And I have a skin "Child" with a parent "Parent" + When I am on the new skin page + And I fill in "Title" with "Unrelated" + And I fill in "CSS" with "#title { text-decoration: blink;}" + And I submit + Then I should see "Skin was successfully created" + And the cache of the skin on "Unrelated" should not expire after I save "Child" + And the cache of the skin on "Child" should expire after I save a parent skin + + Scenario: Users should be able to create skins using @media queries + Given I am logged in as "skinner" + And I set up the skin "Media Query Test Skin" + And I check "only screen and (max-width: 42em)" + And I check "only screen and (max-width: 62em)" + When I press "Submit" + Then I should see a create confirmation message + And I should see "only screen and (max-width: 42em), only screen and (max-width: 62em)" + When I press "Use" + Then the page should have a skin with the media query "only screen and (max-width: 42em), only screen and (max-width: 62em)" + + Scenario: A user should be able to delete a skin + Given I am logged in as "skinner" + And I create the skin "Ugly Skin" + When I go to "Ugly Skin" skin page + And I follow "Delete" + And I press "Yes, Delete Skin" + Then I should see "The skin was deleted." + And I should be on skinner's skins page + And I should not see "Ugly Skin" + + Scenario: A user's skin should be reset to the default if they delete the skin they + are using + Given I am logged in as "skinner" + And I create the skin "Ugly Skin" + And I change my skin to "Ugly Skin" + When I go to skinner's skins page + And I follow "Delete" + And I press "Yes, Delete Skin" + Then I should see "The skin was deleted." + When I go to skinner's preferences page + Then "Default" should be selected within "preference_skin_id" + + Scenario: A user can't make a skin with "Archive" in the title + Given I am logged in as "skinner" + And I set up the skin "My Archive Skin" with some css + And I press "Submit" + Then I should see "Sorry, titles including the word 'Archive' are reserved for official skins." + + Scenario: A user can't look at another user's skins + Given the user "scully" exists and is activated + And I am logged in as "skinner" + When I go to scully's skins page + Then I should see "You can only browse your own skins and approved public skins." + And I should be on the public skins page + + Scenario: A user can't use fixed positioning in a work skin + Given I am logged in as "skinner" + When I set up the skin "Work Skin" with css ".selector {position: fixed; top: 0;}" + And I select "Work Skin" from "Type" + And I submit + Then I should see "The position property in .selector cannot have the value fixed in work skins, sorry!" + + Scenario: User should be able to access their site and work skins from an + individual skin's show page + Given I am logged in as "skinner" + And I create the skin "my skin" + When I view the skin "my skin" + Then I should see "My Site Skins" + And I should see "My Work Skins" + + Scenario: User should be able to revert to the default skin from an individual + skin's show page + Given basic skins + And I am logged in as "skinner" + And I create the skin "my skin" + When I view the skin "my skin" + Then I should not see a "Revert to Default Skin" button + When I press "Use" + And I view the skin "my skin" + Then I should see a "Revert to Default Skin" button + And I should see "My Work Skins" + + Scenario: User should be able to access their site and work skins from an + individual skin's edit page + Given I am logged in as "skinner" + And I create the skin "my skin" + When I edit the skin "my skin" + Then I should see "My Site Skins" + And I should see "My Work Skins" + + Scenario: User should be able to revert to the default skin from an individual + skin's edit page + Given basic skins + And I am logged in as "skinner" + And I create the skin "my skin" + When I edit the skin "my skin" + Then I should not see a "Revert to Default Skin" button + When I change my skin to "my skin" + And I edit the skin "my skin" + Then I should see a "Revert to Default Skin" button + + Scenario: When a cached skin is the child of a cached skin, and the parent is updated, the child reflects the changes to the parent + Given I am logged in as "skin_maker" + And I have a skin "Child Skin" with a parent "Parent Skin" + And the skin "Child Skin" is cached + And the skin "Parent Skin" is cached + And I change my skin to "Child Skin" + # Only admins can edit cached skins: + When I am logged in as a "superadmin" admin + And I edit the skin "Parent Skin" + And I fill in "CSS" with "body { background: cyan; }" + And I press "Update" + Then the filesystem cache of the skin "Child Skin" should include "background: cyan;" + When I am logged in as "skin_maker" + Then the page should have the cached skin "Child Skin" + + Scenario: When a cached skin is the child of an uncached skin, and the parent is updated, the child reflects the changes to the parent + Given I am logged in as "skin_maker" + And I have a skin "Child Skin" with a parent "Parent Skin" + And the skin "Child Skin" is cached + And I change my skin to "Child Skin" + When I edit the skin "Parent Skin" + And I fill in "CSS" with "body { background: cyan; }" + And I press "Update" + Then the filesystem cache of the skin "Child Skin" should include "background: cyan;" + And the page should have the cached skin "Child Skin" + + Scenario: When an uncached skin is the child of a cached skin, and the parent is updated, the child reflects the changes to the parent + Given I am logged in as "skin_maker" + And I have a skin "Child Skin" with a parent "Parent Skin" + And the skin "Parent Skin" is cached + And I change my skin to "Child Skin" + # Only admins can edit cached skins: + When I am logged in as a "superadmin" admin + And I edit the skin "Parent Skin" + And I fill in "CSS" with "body { background: cyan; }" + And I press "Update" + Then the filesystem cache of the skin "Parent Skin" should include "background: cyan;" + When I am logged in as "skin_maker" + Then the page should have the cached skin "Parent Skin" + + Scenario: When an uncached skin is the child of an uncached skin, and the parent is updated, the child reflects the changes to the parent + Given I am logged in as "skin_maker" + And I have a skin "Child Skin" with a parent "Parent Skin" + And I change my skin to "Child Skin" + When I edit the skin "Parent Skin" + And I fill in "CSS" with "body { background: cyan; }" + And I press "Update" + Then I should see "background: cyan;" + + @javascript + Scenario: User can add a parent skin using the Custom CSS form + Given the skin "Dad" by "skinner" + And I am logged in as "skinner" + When I go to the new skin page + Then I should see "Advanced" + When I follow "Show ↓" + Then I should see "Parent Skins" + When I fill in "Title" with "Child" + And I follow "Add parent skin" + And it is currently 1 second from now + Then I should see a parent skin text field + When I enter "Dad" in the "skin_skin_parents_attributes_1_parent_skin_title_autocomplete" autocomplete field + And I press "Submit" + Then I should see "Parent Skins" + And I should see "Dad" diff --git a/features/other_b/skin_public.feature b/features/other_b/skin_public.feature new file mode 100755 index 0000000..7680d22 --- /dev/null +++ b/features/other_b/skin_public.feature @@ -0,0 +1,120 @@ +@set-default-skin +Feature: Public skins + + Scenario: A user's initial skin should be set to default + Given basic skins + And I am logged in as "skinner" + When I am on skinner's preferences page + Then "Default" should be selected within "preference_skin_id" + + Scenario: User can set a skin for a session and then unset it + Given basic skins + And the approved public skin "public skin" with css "#title { text-decoration: blink;}" + And the skin "public skin" is cached + And the skin "public skin" is in the chooser + When I am logged in as "skinner" + And I press "public skin" + Then I should see "The skin public skin has been set. This will last for your current session." + And the page should have the cached skin "public skin" + When I press "Default" + Then I should see "You are now using the default Archive skin again!" + And the page should not have the cached skin "public skin" + + Scenario: Only public skins should be on the main skins page + Given basic skins + And I am logged in as "skinner" + And I create the skin "my skin" + When I am on the skins page + Then I should not see "my skin" + And I should see "Default" + + Scenario: Newly created public skins should not appear on the main skins page until + approved and should be marked as not-yet-approved + Given I am logged in as "skinner" + And the unapproved public skin "public skin" + When I am on the skins page + Then I should not see "public skin" + When I am on skinner's skins page + Then I should see "public skin" + And I should see "(Not yet reviewed)" + And I should not see "(Approved)" + + Scenario: Public skins should not be viewable by users until approved + Given the unapproved public skin "public skin" + And I log out + When I go to "public skin" skin page + Then I should see "Sorry, you don't have permission" + When I go to "public skin" edit skin page + Then I should see "Sorry, you don't have permission" + When I go to admin's skins page + Then I should see "I'm sorry, only an admin can" + + Scenario: Users should not be able to edit their public approved skins + Given the approved public skin "public skin" + And I am logged in as "skinner" + When I go to "public skin" edit skin page + Then I should see "Sorry, you don't have permission" + When I am on the skins page + Then I should see "public skin" + When I follow "Site Skins" + Then I should see "public skin" + And I should see "(Approved)" + And I should not see "Edit" + + Scenario: Users should be able to use public approved skins created by others + Given the approved public skin "public skin" with css "#title { text-decoration: blink;}" + And I am logged in as "skinuser" + And I am on skinuser's preferences page + When I select "public skin" from "preference_skin_id" + And I submit + Then I should see "Your preferences were successfully updated." + When I am on skinuser's preferences page + And "public skin" should be selected within "preference_skin_id" + And I should see "#title {" in the page style + And I should see "text-decoration: blink;" in the page style + + Scenario: Toggle between public site skins and public work skins + Given I am logged in as "skinner" + And I am on skinner's skins page + When I follow "Public Work Skins" + Then I should see "Public Work Skins" within "h2" + When I follow "Public Site Skins" + Then I should see "Public Site Skins" within "h2" + + Scenario: Reverting to default skin when a custom skin is selected + Given the approved public skin "public skin" with css "#title { text-decoration: blink;}" + And I am logged in as "skinner" + And I am on skinner's preferences page + And I select "public skin" from "preference_skin_id" + And I submit + When I am on skinner's preferences page + Then "public skin" should be selected within "preference_skin_id" + When I go to skinner's skins page + And I press "Revert to Default Skin" + When I am on skinner's preferences page + Then "Default" should be selected within "preference_skin_id" + + Scenario: A logged out user only sees cached skins on the public skins page + Given the approved public skin "Uncached skin" + And the approved public skin "Cached skin" + And the skin "Cached skin" is cached + When I go to the public skins page + Then I should see "Cached skin" + And I should not see "Uncached skin" + + Scenario: A user can preview a cached public site skin, and it will take the + user to the works page for a canonical tag with between 10 and 20 works + Given the approved public skin "Usable Skin" + And the skin "Usable Skin" is cached + And the canonical fandom "Dallas" with 2 works + And the canonical fandom "Major Crimes" with 11 works + And the canonical fandom "Rizzoli and Isles" with 21 works + And I am logged in as "skinner" + When I go to the public skins page + And I follow "Preview" + Then I should be on the works tagged "Major Crimes" + And I should see "You are previewing the skin Usable Skin. This is a randomly chosen page." + And I should see "Go back or click any link to remove the skin" + And I should see "Tip: You can preview any archive page you want by tacking on '?site_skin=[skin_id]' like you can see in the url above." + When I follow "Return To Skin To Use" + Then I should be on "Usable Skin" skin page diff --git a/features/other_b/skin_wizard.feature b/features/other_b/skin_wizard.feature new file mode 100755 index 0000000..d6ce926 --- /dev/null +++ b/features/other_b/skin_wizard.feature @@ -0,0 +1,105 @@ +@set-default-skin +Feature: Skin wizard + + Scenario: User should be able to toggle between the wizard and the form + Given I am logged in + When I go to the new skin page + Then I should see "CSS" within "form#new_skin" + When I follow "Use Wizard" + Then I should see "Site Skin Wizard" + And I should not see "CSS" within "form" + When I follow "Write Custom CSS" + Then I should see "Create New Skin" + And I should see "CSS" + + @javascript + Scenario: User can add a parent skin using the wizard + Given the skin "Dad" by "mage" + And I am logged in as "mage" + When I go to the new skin page + And I follow "Use Wizard" + Then I should see "Site Skin Wizard" + And I should see "Parent Skins" + When I fill in "Title" with "Child" + And I follow "Add parent skin" + And it is currently 1 second from now + Then I should see a parent skin text field + When I enter "Dad" in the "skin_skin_parents_attributes_1_parent_skin_title_autocomplete" autocomplete field + And I press "Submit" + Then I should see "Parent Skins" + And I should see "Dad" + + Scenario: Users should be able to create and use a wizard skin to adjust work margins, + and they should be able to edit the skin while they are using it + Given I am logged in as "skinner" + And I am on the new wizard skin page + When I fill in "Title" with "Wide margins" + And I fill in "Description" with "Layout skin" + And I fill in "Work margin width" with "text" + And I submit + Then I should see a save error message + And I should see "Margin is not a number" + When I fill in "Work margin width" with "5" + And I submit + Then I should see "Skin was successfully created" + And I should see "Work margin width: 5%" + When I am on skinner's preferences page + And I select "Wide margins" from "preference_skin_id" + And I submit + Then I should see "Your preferences were successfully updated." + And I should see "margin: auto 5%; max-width: 100%" in the page style + # Make sure that the creation/update cache keys are different: + And I wait 1 second + When I edit the skin "Wide margins" with the wizard + And I fill in "Work margin width" with "4.5" + And I submit + # TODO: Think about whether rounding to 4 is actually the right behaviour or not + Then I should see an update confirmation message + And I should see "Work margin width: 4%" + And I should not see "Work margin width: 4.5%" + And I should see "margin: auto 4%;" in the page style + When I am on skinner's preferences page + Then "Wide margins" should be selected within "preference_skin_id" + + Scenario: Users should be able to create and use a wizard skin with multiple wizard + settings + Given I am logged in as "skinner" + And I am on the new wizard skin page + When I fill in "Title" with "Many changes" + And I fill in "Description" with "Layout skin" + And I fill in "Font" with "'Times New Roman', Garamond, serif" + And I fill in "Background color" with "#ccccff" + And I fill in "Text color" with "red" + And I fill in "Percent of browser font size" with "120" + And I fill in "Vertical gap between paragraphs" with "5" + And I submit + Then I should see "Skin was successfully created" + And I should see "Font: 'Times New Roman', Garamond, serif" + And I should see "Background color: #ccccff" + And I should see "Text color: red" + And I should see "Percent of browser font size: 120%" + And I should see "Vertical gap between paragraphs: 5.0em" + When I press "Use" + Then I should see "Your preferences were successfully updated." + And I should see "background: #ccccff;" in the page style + And I should see "color: red;" in the page style + And I should see "font-family: 'Times New Roman', Garamond, serif;" in the page style + And I should see "font-size: 120%;" in the page style + And I should see "margin: 5.0em auto;" in the page style + When I am on skinner's preferences page + Then "Many changes" should be selected within "preference_skin_id" + + Scenario: Users should be able to adjust their wizard skin by adding custom CSS + Given I am logged in as "skinner" + And I create and use a skin to make the header pink + # Make sure that the creation/update cache keys are different: + And I wait 1 second + When I edit my pink header skin to have a purple logo + Then I should see an update confirmation message + And I should see a pink header + And I should see a purple logo + + Scenario: Change the accent color + Given I am logged in as "skinner" + When I create and use a skin to change the accent color + Then I should see a different accent color diff --git a/features/other_b/stats.feature b/features/other_b/stats.feature new file mode 100755 index 0000000..579783c --- /dev/null +++ b/features/other_b/stats.feature @@ -0,0 +1,89 @@ +@stats +Feature: User statistics + In order to know more about my works + As a user + The statistics page needs to show me information about my works + + Scenario: A user with no works should see a message + Given I am logged in as "lurker" + When I go to lurker's stats page + Then I should see "You currently have no works posted to the Archive. If you add some, you'll find information on this page about hits, kudos, comments, and bookmarks of your works." + And I should see "Users can also see how many subscribers they have, but not the names of their subscribers or identifying information about other users who have viewed or downloaded their works." + + Scenario: Show only posted works on stats page + + Given I am logged in as "NUMB3RSfan" + And I post the work "Don Solves Crime" + And I post the work "Don Solves More Crime" + And I set up the draft "Charlie Helps" + When I am logged in as "reader" + And I view the work "Don Solves Crime" + And I am logged in as "NUMB3RSfan" + And I go to NUMB3RSfan's stats page + Then "Don Solves Crime" should appear before "Don Solves More Crime" + And I should not see "Charlie Helps" + When I follow "Date" + Then "Don Solves More Crime" should appear before "Don Solves Crime" + When I follow "Date" + Then "Don Solves Crime" should appear before "Don Solves More Crime" + + Scenario: Calculate word counts from chapter publication date + + Given I am logged in as "statistician" + And I set up the draft "Multiyear Fic" + And I fill in "content" with "Three words long." + And I set the publication date to 3 March 2023 + And I press "Post" + And I follow "Add Chapter" + And I fill in "content" with "Oh look, four words!" + And I set the publication date to 4 April 2024 + And I press "Post" + When I go to statistician's stats page + Then I should see a link "2023" + And I should see a link "2024" + And I should see "Multiyear Fic (7 words)" + And I should see "Word Count: 7" + When I follow "2023" + Then I should see "Multiyear Fic (3 words)" + And I should see "Word Count: 3" + When I follow "2024" + Then I should see "Multiyear Fic (4 words)" + And I should see "Word Count: 4" + + Scenario: Sort works by chapter publication within year + + Given I am logged in as "statistician" + And I set up the draft "New-Year Celebration" + And I set the publication date to 1 January 2023 + And I press "Post" + And I follow "Add Chapter" + And I set the publication date to 1 January 2024 + And I press "Post" + And I set up the draft "Year-End Party" + And I set the publication date to 9 December 2023 + And I press "Post" + And I set up the draft "Midyear Madness" + And I set the publication date to 2 July 2023 + And I press "Post" + When I go to statistician's stats page + And I follow "2023" + And I follow "Flat View" + And I follow "Date" + Then "New-Year Celebration" should appear before "Midyear Madness" + And "Midyear Madness" should appear before "Year-End Party" + + Scenario: Multifandom works once per fandom in Fandoms View + + Given I am logged in as "statistician" + And I set up the draft "Fandom Alphabet" + And I fill in "Fandoms" with "Fandom A, Fandom B, Fandom C" + And I set the publication date to 1 May 2025 + And I press "Post" + When I go to statistician's stats page + Then I should see "Fandom A" within ".fandom.listbox.group[1]" + And I should see "Fandom B" within ".fandom.listbox.group[2]" + And I should see "Fandom C" within ".fandom.listbox.group[3]" + When I follow "2025" + Then I should see "Fandom A" within ".fandom.listbox.group[1]" + And I should see "Fandom B" within ".fandom.listbox.group[2]" + And I should see "Fandom C" within ".fandom.listbox.group[3]" diff --git a/features/other_b/subscriptions.feature b/features/other_b/subscriptions.feature new file mode 100755 index 0000000..89bfb3c --- /dev/null +++ b/features/other_b/subscriptions.feature @@ -0,0 +1,370 @@ + Feature: Subscriptions + In order to follow an author I like + As a reader + I want to subscribe to them + + Background: + Given the following activated users exist + | login | password | email | + | first_user | password | first_user@foo.com | + | second_user | password | second_user@foo.com | + | third_user | password | third_user@foo.com | + And all emails have been delivered + + Scenario: subscribe to an author + + When "second_user" subscribes to author "first_user" + And I am logged in as "first_user" + And I post the work "Awesome Story" + # make sure no emails go out until notifications are sent + Then 0 emails should be delivered + When subscription notifications are sent + Then 1 email should be delivered to "second_user@foo.com" + And the email should contain "first_user" + And the email should contain "Awesome" + When all emails have been delivered + And I post the work "Yet Another Awesome Story" without preview + And subscription notifications are sent + Then 1 email should be delivered to "second_user@foo.com" + When all emails have been delivered + And a draft chapter is added to "Yet Another Awesome Story" + Then 0 emails should be delivered + When I post the draft chapter + Then 0 emails should be delivered + When subscription notifications are sent + Then 1 email should be delivered to "second_user@foo.com" + # This feels hackish to me (scott s), but I'm going with it for now. I'll investigate reworking our email steps for multipart emails once all our gems are up to date. + And the email should contain "first_user" + And the email should contain "posted" + And the email should contain "Chapter 2" + + Scenario: unsubscribe from an author + + When I am logged in as "second_user" + And I go to first_user's user page + And I press "Subscribe" + And I press "Unsubscribe" + Then I should see "successfully unsubscribed" + And I should be on first_user's user page + When I log out + And I am logged in as "first_user" + And I post the work "Awesome Story 2: The Sequel" + And subscription notifications are sent + Then 0 emails should be delivered + + Scenario: unsubscribe from the subscriptions page + + When I am logged in as "second_user" + And I go to first_user's user page + And I press "Subscribe" + When I go to the subscriptions page for "second_user" + And I press "Unsubscribe from first_user" + Then I should see "successfully unsubscribed" + And I should be on the subscriptions page for "second_user" + + Scenario: subscribe button on profile page + + When I am logged in as "second_user" + And I go to first_user's profile page + And I press "Subscribe" + Then I should see "You are now following first_user. If you'd like to stop receiving email updates, you can unsubscribe from your Subscriptions page." + When I press "Unsubscribe" + Then I should see "successfully unsubscribed" + + Scenario: subscribe to individual work + + When "second_user" subscribes to work "Awesome Story" + And a draft chapter is added to "Awesome Story" + Then 0 emails should be delivered + When I post the draft chapter + Then 0 emails should be delivered + When subscription notifications are sent + Then 1 email should be delivered to "second_user@foo.com" + And the email should contain "wip_author" + And the email should contain "posted" + And the email should contain "Chapter 2" + + Scenario: receive notification of a titled chapter + + When "second_user" subscribes to work "Cake Story" + And I am logged in as "wip_author" + And I view the work "Cake Story" + And I follow "Add Chapter" + And I fill in "Chapter Title" with "ICE CREAM CAKE" + And I fill in "content" with "meltiiiinnngg" + And I press "Post" + And subscription notifications are sent + Then 1 email should be delivered to "second_user@foo.com" + And the email should contain "wip_author" + And the email should contain "posted" + And the email should not contain "Chapter ICE CREAM CAKE" + And the email should contain "Chapter 2: ICE CREAM CAKE" + + Scenario: subscribe to series + + When "second_user" subscribes to series "Awesome Series" + And I am logged in as "series_author" + And I set up the draft "Second Work" + And I check "series-options-show" + And I select "Awesome Series" from "work_series_attributes_id" + And I press "Post" + Then 0 emails should be delivered + When subscription notifications are sent + Then 1 email should be delivered to "second_user@foo.com" + And the email should contain "posted a" + And the email should contain "new work" + + Scenario: batched subscription notifications + + When "second_user" subscribes to author "first_user" + And I am logged in as "first_user" + And I post the work "The First Awesome Story" + # make sure no emails go out until notifications are sent + Then 0 emails should be delivered + When I post the work "Another Awesome Story" + And I post the work "A Third Awesome Story" + And I post the work "A FOURTH Awesome Story" + Then 0 emails should be delivered + When subscription notifications are sent + Then 1 email should be delivered to "second_user@foo.com" + And the email should contain "The First" + And the email should contain "Another" + And the email should contain "A Third" + And the email should contain "A FOURTH" + + Scenario: different types of subscriptions are listed separately on a user's subscription page + + When I am logged in as "second_user" + And "second_user" subscribes to author "third_user" + And "second_user" subscribes to work "Awesome Story" + And "second_user" subscribes to series "Awesome Series" + When I go to the subscriptions page for "second_user" + Then I should see "My Subscriptions" + And I should see "Awesome Series (Series)" + And I should see a link "series_author" + And I should see "third_user" + And I should see "Awesome Story (Work)" + And I should see a link "wip_author" + When I follow "Series Subscriptions" + Then I should see "My Series Subscriptions" + And I should see "Awesome Series" + And I should not see "(Series)" + And I should not see "third_user" + And I should not see "Awesome Story" + When I follow "User Subscriptions" + Then I should see "My User Subscriptions" + And I should see "third_user" + And I should not see "Awesome Series" + And I should not see "Awesome Story" + When I follow "Work Subscriptions" + Then I should see "My Work Subscriptions" + And I should see "Awesome Story" + And I should not see "(Work)" + And I should not see "Awesome Series" + And I should not see "third_user" + + Scenario: Subscribe to a multi-chapter work should redirect you back to the chapter you were viewing + + When I am logged in as "first_user" + And I post the work "Multi Chapter Work" + And a chapter is added to "Multi Chapter Work" + When I am logged in as "second_user" + And I view the work "Multi Chapter Work" + And I view the 2nd chapter + When I press "Subscribe" + Then the page title should include "Chapter 2" + + # There are tests in collections/collection_anonymity.feature that ensure + # a creator's subscribers are not notified when the creator posts a new + # anonymous work. + Scenario: When a chapter is added to an anonymous work, subscription emails + are sent to users who have subscribed to the work, but not to users who have + subscribed to the creator. + + Given the anonymous collection "anonymous_collection" + And I am logged in as "creator" + And I post the work "Multi Chapter Work" to the collection "anonymous_collection" + And "author_subscriber" subscribes to author "creator" + And "work_subscriber" subscribes to work "Multi Chapter Work" + When a chapter is added to "Multi Chapter Work" + And subscription notifications are sent + Then "author_subscriber" should not be emailed + But "work_subscriber" should be emailed + And the email should have "Anonymous posted Chapter 2 of Multi Chapter Work" in the subject + And the email should contain "Multi Chapter Work" + And the email should contain "Anonymous" + And the email should not contain "creator" + + Scenario: When a chapter is added to an anonymous work in an anonymous series, + subscription emails are sent to users who have subscribed to the work or + series, but not to users who have subscribed to the creator. + + Given the anonymous collection "anonymous_collection" + And I am logged in as "creator" + And I post the work "Multi Chapter Work" to the collection "anonymous_collection" as part of a series "Multi Work Series" + And "author_subscriber" subscribes to author "creator" + And "work_subscriber" subscribes to work "Multi Chapter Work" + And "series_subscriber" subscribes to series "Multi Work Series" + When a chapter is added to "Multi Chapter Work" + And subscription notifications are sent + Then "author_subscriber" should not be emailed + But "work_subscriber" should be emailed + And the email should have "Anonymous posted Chapter 2 of Multi Chapter Work" in the subject + And the email should contain "Multi Chapter Work" + And the email should contain "Anonymous" + And the email should not contain "creator" + And "series_subscriber" should be emailed + And the email should have "Anonymous posted Chapter 2 of Multi Chapter Work in the Multi Work Series series" in the subject + And the email should contain "Multi Chapter Work" + And the email should contain "Anonymous" + And the email should not contain "creator" + + Scenario: When a new work is added to an anonymous series, subscription emails + are sent to users who are subscribed to the series, but not users who have + subscribed to the creator. + + Given the anonymous collection "anonymous_collection" + And I am logged in as "creator" + And I post the work "Multi Chapter Work" to the collection "anonymous_collection" as part of a series "Multi Work Series" + And "author_subscriber" subscribes to author "creator" + And "series_subscriber" subscribes to series "Multi Work Series" + When I am logged in as "creator" + And I post the work "Second Work" to the collection "anonymous_collection" as part of a series "Multi Work Series" + And subscription notifications are sent + Then "author_subscriber" should not be emailed + But "series_subscriber" should be emailed + And the email should have "Anonymous posted Second Work in the Multi Work Series series" in the subject + And the email should contain "Multi Work Series" + And the email should contain "Second Work" + And the email should contain "Anonymous" + And the email should not contain "creator" + + Scenario: When new chapter for a hidden work is posted, no subscription notifications are sent + + Given I am logged in as "violator" + And I post the work "TOS Violation" as part of a series "Dont Be So Series" + And "author_subscriber" subscribes to author "violator" + And "work_subscriber" subscribes to work "TOS Violation" + And "series_subscriber" subscribes to series "Dont Be So Series" + When I am logged in as a "policy_and_abuse" admin + And I hide the work "TOS Violation" + And a chapter is added to "TOS Violation" + And subscription notifications are sent + Then "author_subscriber" should not be emailed + And "work_subscriber" should not be emailed + And "series_subscriber" should not be emailed + When I am logged in as a "policy_and_abuse" admin + And I unhide the work "TOS Violation" + And subscription notifications are sent + Then "author_subscriber" should not be emailed + And "work_subscriber" should not be emailed + And "series_subscriber" should not be emailed + When a chapter is added to "TOS Violation" + And subscription notifications are sent + Then "author_subscriber" should be emailed + And "work_subscriber" should be emailed + And "series_subscriber" should be emailed + + Scenario: When a hidden work is unrevealed, no subscription notifications are sent + + Given I am logged in as "violator" + And I post the work "TOS Violation" as part of a series "Dont Be So Series" + And "author_subscriber" subscribes to author "violator" + And "work_subscriber" subscribes to work "TOS Violation" + And "series_subscriber" subscribes to series "Dont Be So Series" + And I have the hidden collection "Secret" + And I am logged in as "violator" + And I edit the work "TOS Violation" to be in the collection "Secret" + And I am logged in as a "policy_and_abuse" admin + And I hide the work "TOS Violation" + When I am logged in as "moderator" + And I go to "Secret" collection's page + And I follow "Collection Settings" + And I uncheck "This collection is unrevealed" + And I press "Update" + And subscription notifications are sent + Then "author_subscriber" should not be emailed + And "work_subscriber" should not be emailed + And "series_subscriber" should not be emailed + When I am logged in as a "policy_and_abuse" admin + And I unhide the work "TOS Violation" + And subscription notifications are sent + Then "author_subscriber" should not be emailed + And "work_subscriber" should not be emailed + And "series_subscriber" should not be emailed + + Scenario: subscribe to an individual work with an the & and < and > characters in the title + + Given the work "I am <strong>er Than Yesterday & Other Lies" by "testuser2" + When I am logged in as "subscriber" with password "password" + And I view the work "I am <strong>er Than Yesterday & Other Lies" + When I press "Subscribe" + Then I should see "You are now following I am <strong>er Than Yesterday & Other Lies. If you'd like to stop receiving email updates, you can unsubscribe from your Subscriptions page." + When I am logged in as "testuser2" with password "testuser2" + And a chapter is added to "I am <strong>er Than Yesterday & Other Lies" + When I view the work "I am <strong>er Than Yesterday & Other Lies" + When subscription notifications are sent + Then 1 email should be delivered to "subscriber" + When "The problem with ampersands and angle brackets in email bodies and subjects" is fixed + #And the email should have "I am <strong>er Than Yesterday & Other Lies" in the subject + #And the email should contain "I am <strong>er Than Yesterday & Other Lies" + When I am logged in as "subscriber" with password "password" + And I go to the subscriptions page for "subscriber" + And I press "Unsubscribe from I am <strong>er Than Yesterday & Other Lies" + Then I should see "You have successfully unsubscribed from I am <strong>er Than Yesterday & Other Lies" + +Scenario: delete all subscriptions + + When I am logged in as "second_user" + And "second_user" subscribes to author "third_user" + And "second_user" subscribes to work "Awesome Story" + And "second_user" subscribes to series "Awesome Series" + When I go to the subscriptions page for "second_user" + Then I should see "My Subscriptions" + And I should see "Awesome Series (Series)" + And I should see "third_user" + And I should see "Awesome Story (Work)" + When I follow "Delete All Subscriptions" + Then I should see "Are you sure you want to delete" + When I press "Yes, Delete All Subscriptions" + Then I should see "My Subscriptions" + And I should see "Your subscriptions have been deleted" + And I should not see "Awesome Series (Series)" + And I should not see "third_user" + And I should not see "Awesome Story (Work)" + +Scenario: delete all subscriptions of a specific type + + When I am logged in as "second_user" + And "second_user" subscribes to author "third_user" + And "second_user" subscribes to work "Awesome Story" + And "second_user" subscribes to series "Awesome Series" + When I go to the subscriptions page for "second_user" + Then I should see "My Subscriptions" + And I should see "Awesome Series (Series)" + And I should see "third_user" + And I should see "Awesome Story (Work)" + When I follow "Work Subscriptions" + Then I should see "My Work Subscriptions" + When I follow "Delete All Work Subscriptions" + Then I should see "Delete All Work Subscriptions" + And I should see "Are you sure you want to delete" + When I press "Yes, Delete All Work Subscriptions" + Then I should see "Your subscriptions have been deleted" + When I go to the subscriptions page for "second_user" + Then I should see "Awesome Series (Series)" + And I should see "third_user" + But I should not see "Awesome Story (Work)" + +Scenario: subscriptions are not deleted without confirmation + + When I am logged in as "second_user" + And "second_user" subscribes to work "Awesome Story" + When I go to the subscriptions page for "second_user" + Then I should see "My Subscriptions" + And I should see "Awesome Story (Work)" + When I follow "Delete All Subscriptions" + Then I should see "Are you sure you want to delete" + When I go to the subscriptions page for "second_user" + Then I should see "My Subscriptions" + And I should see "Awesome Story (Work)" diff --git a/features/other_b/subscriptions_fandoms.feature b/features/other_b/subscriptions_fandoms.feature new file mode 100755 index 0000000..a05479f --- /dev/null +++ b/features/other_b/subscriptions_fandoms.feature @@ -0,0 +1,83 @@ +Feature: Subscriptions + In order to follow a fandom I like + As a reader + I want to subscribe to it + + Scenario: Subscribe to a test fandom when there are no works in it + + When I am logged in as "author" + And I post a work "My Work Title" with category "F/M" + When I am logged in as "reader" + And I view the "F/F" works index + Then I should see "RSS Feed" + When I follow "RSS Feed" + Then I should not see "My Work Title" + And I should not see "Stargate SG-1" + + Scenario: Subscribe to a test fandom when there are works in it + + When I am logged in as "author" + And I post a work "My Work Title" with category "F/F" + When I am logged in as "reader" + And I view the "F/F" works index + Then I should see "RSS Feed" + When I follow "RSS Feed" + Then I should see "My Work Title" + And I should see "Stargate SG-1" + + Scenario: Subscribe to a non-test fandom + + When I am logged in as "author" + And I post a work "My Work Title" with category "Multi" + When I am logged in as "reader" + And I view the "Multi" works index + Then I should not see "RSS Feed" + + Scenario: Mystery work is not shown in feed + + Given basic tags + And I am logged in as "myname2" + Given I have a hidden collection "Hidden Treasury" with name "hidden_treasury" + When I am logged in as "myname1" + And I post the work "Old Snippet" + And I edit the work "Old Snippet" + And I fill in "Post to Collections / Challenges" with "hidden_treasury" + And I check "F/F" + And I press "Post" + Then I should see "This work is part of an ongoing challenge and will be revealed soon! You can find details here: Hidden Treasury" + When I am logged in as "author" + And I post a work "My Work Title" with category "F/F" + When I view the "F/F" works index + When I follow "RSS Feed" + Then I should not see "Old Snippet" + And I should not see "myname1" + And I should see "author" + + Scenario: Author of anonymous work is not shown in feed + + Given basic tags + And I am logged in as "myname2" + Given I have an anonymous collection "Hidden Treasury" with name "hidden_treasury" + When I am logged in as "myname1" + And I post the work "Old Snippet" + And I edit the work "Old Snippet" + And I fill in "Post to Collections / Challenges" with "hidden_treasury" + And I check "F/F" + And I press "Post" + And all indexing jobs have been run + Then I should see "Anonymous" + And I should see "Collections: Hidden Treasury" + When I am logged in as "author" + And I post a work "My Work Title" with category "F/F" + When I view the "F/F" works index + When I follow "RSS Feed" + Then I should see "Old Snippet" + And I should not see "myname1" + And I should see "author" + + Scenario: A user can see a feed for non canonical tags + + Given I am logged in as "author" + And I post the work "Glorious" with fandom "SGA" + When I view the "SGA" works feed + Then I should see "Glorious" diff --git a/features/other_b/support.feature b/features/other_b/support.feature new file mode 100755 index 0000000..4f03c15 --- /dev/null +++ b/features/other_b/support.feature @@ -0,0 +1,87 @@ +Feature: Filing a support request + In order to get help + As a confused user + I want to file a support request + + Scenario: Filing a support request + + Given I am logged in as "puzzled" + And basic languages + When time is frozen at 14/3/2022 + When I follow "Support & Feedback" + When I select "Deutsch" from "feedback_language" + And I fill in "Brief summary" with "Just a brief note" + And I fill in "Your question or problem" with "Men have their old boys' network, but we have the OTW. You guys rock!" + And all emails have been delivered + And I press "Send" + Then I should see "Your message was sent to the Archive team - thank you!" + And 1 email should be delivered + And the email should contain "working hard to reply to everyone" + And the email should contain "respond to you as soon as we can." + And the email should contain "If you have additional questions or information" + And the email should contain "Sent at Mon, 14 Mar 2022 12:00:00 \+0000" + When I follow "Support & Feedback" + And I fill in "Brief summary" with "you suck" + And I fill in "Your question or problem" with "blah blah blah" + And I fill in "Your email (required)" with "test@archiveofourown.org" + And I select "Deutsch" from "feedback_language" + And all emails have been delivered + And I press "Send" + Then I should see "Your message was sent to the Archive team - thank you!" + And 1 email should be delivered + + Scenario: Not logged in, with and without email + + When I am on the home page + And basic languages + And I follow "Support & Feedback" + When I select "Deutsch" from "feedback_language" + And I fill in "Brief summary" with "Just a brief note" + And I fill in "Your question or problem" with "Men have their old boys' network, but we have the OTW. You guys rock!" + And I fill in "Your email (required)" with "" + And all emails have been delivered + And I press "Send" + Then I should see "Email should look like an email address." + And "Deutsch" should be selected within "Select language (required)" + And I fill in "Your email (required)" with "test@archiveofourown.org" + And I press "Send" + Then I should see "Your message was sent to the Archive team - thank you!" + And 1 email should be delivered + + Scenario: Submit a request containing an image + + Given I am logged in as "puzzled" + And basic languages + When I follow "Support & Feedback" + And I fill in "Brief summary" with "Just a brief note" + And I fill in "Your question or problem" with '<img src="foo.jpg" />Hi' + And I press "Send" + Then 1 email should be delivered + # The sanitizer adds the domain in front of relative image URLs as of AO3-6571 + And the email should not contain "<img src="http://www.example.org/foo.jpg" />" + But the email should contain "img src="http://www.example.org/foo.jpg"Hi" + + Scenario: Submit a request with an on-Archive referer + + Given I am logged in as "puzzled" + And basic languages + And Zoho ticket creation is enabled + And "www.example.com" is a permitted Archive host + When I go to the works page + And I follow "Support & Feedback" + And I fill in "Brief summary" with "Just a brief note" + And I fill in "Your question or problem" with "Hi, I came from the Archive" + And I press "Send" + Then a Zoho ticket should be created with referer "http://www.example.com/works" + + Scenario: Submit a request with a referer that is not on-Archive + + Given I am logged in as "puzzled" + And basic languages + And Zoho ticket creation is enabled + When I go to the works page + And I follow "Support & Feedback" + And I fill in "Brief summary" with "Just a brief note" + And I fill in "Your question or problem" with "Hi, I didn't come from the Archive" + And I press "Send" + Then a Zoho ticket should be created with referer "" diff --git a/features/prompt_memes_a/challenge_promptmeme_setup.feature b/features/prompt_memes_a/challenge_promptmeme_setup.feature new file mode 100755 index 0000000..822778b --- /dev/null +++ b/features/prompt_memes_a/challenge_promptmeme_setup.feature @@ -0,0 +1,490 @@ +@collections @challenges @promptmemes +Feature: Prompt Meme Challenge + In order to have an archive full of works + As a humble user + I want to create a prompt meme and post to it + + Scenario: Can create a collection to house a prompt meme + + Given I have standard challenge tags setup + When I set up Battle 12 promptmeme collection + Then I should be editing the challenge settings + + Scenario: Creating a prompt meme has different instructions from a gift exchange + + Given I have standard challenge tags setup + When I set up Battle 12 promptmeme collection + Then I should see prompt meme options + + Scenario: Create a prompt meme + + Given I have standard challenge tags setup + When I create Battle 12 promptmeme + Then Battle 12 prompt meme should be correctly created + + Scenario: User can see a prompt meme + + Given I have Battle 12 prompt meme fully set up + And I am logged in as a random user + When I go to the collections page + Then I should see "Battle 12" + + Scenario: Prompt meme is in list of open challenges + + Given I have Battle 12 prompt meme fully set up + And I am logged in as a random user + When I view open challenges + Then I should see "Battle 12" + + Scenario: Prompt meme is also in list of open prompt meme challenges + + Given I have Battle 12 prompt meme fully set up + And I am logged in as a random user + When I view open challenges + And I follow "Prompt Meme Challenges" + Then I should see "Battle 12" + + Scenario: Past challenge is not in list of open challenges + + Given I am logged in as "mod1" + And I have standard challenge tags setup + When I set up Battle 12 promptmeme collection + And I fill in past challenge options + And I am logged in as "myname1" + When I view open challenges + Then I should not see "Battle 12" + + Scenario: Future challenge is not in list of open challenges + + Given I am logged in as "mod1" + And I have standard challenge tags setup + When I set up Battle 12 promptmeme collection + And I fill in future challenge options + And I am logged in as "myname1" + When I view open challenges + Then I should not see "Battle 12" + + Scenario: Can access settings from profile navigation + + Given I have Battle 12 prompt meme fully set up + When I go to "Battle 12" collection's page + And I follow "Profile" + Then I should see "Challenge Settings" within "div#dashboard" + When I follow "Challenge Settings" within "div#dashboard" + Then I should be editing the challenge settings + + Scenario: Can edit settings for a prompt meme + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "mod1" + When I edit settings for "Battle 12" challenge + Then I should be editing the challenge settings + + Scenario: Entering a greater number for required prompts than allowed prompts + automatically increases the number of allowed promps + + Given I set up Battle 12 promptmeme collection + When I require 3 prompts + And I allow 2 prompts + And I press "Submit" + Then I should see a success message + When I edit settings for "Battle 12" challenge + Then 3 prompts should be required + And 3 prompts should be allowed + + Scenario: Sign-up being open is shown on profile + + Given I have Battle 12 prompt meme fully set up + And I am logged in as a random user + When I go to "Battle 12" collection's page + And I follow "Profile" + Then I should see "Sign-up: Open" + + Scenario: User can see profile descriptions + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I go to "Battle 12" collection's page + When I follow "Profile" + Then I should see Battle 12 descriptions + + Scenario: Sign up for a prompt meme + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I go to "Battle 12" collection's page + Then I should see "Sign Up" + When I sign up for Battle 12 with combination A + Then I should see "Sign-up was successfully created" + And I should see "Prompts (2)" + And I should see the whole signup + + Scenario: Sign up for a prompt meme and miss out some fields + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for "Battle 12" with missing prompts + Then I should see "Request: Your Request must include exactly 1 fandom tags, but you have included 0 fandom tags in your current Request" + When I fill in the missing prompt + Then I should see "Sign-up was successfully created" + + Scenario: Correct number of signups is shown in user sidebar + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for Battle 12 with combination A + When I am on myname1's user page + Then I should see "Sign-ups (1)" + + Scenario: View signups in the dashboard + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for Battle 12 with combination A + When I am on myname1's signups page + Then I should see "Battle 12" + + Scenario: Prompt count shows on profile + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for Battle 12 with combination A + When I go to "Battle 12" collection's page + And I follow "Profile" + Then I should see "Prompts: 2" + # TODO: Was the claimed prompts count intentionally removed from profile? + # And I should see "Claimed prompts: 0" + + Scenario: Prompt count shows on collections index + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for Battle 12 with combination A + When I go to the collections page + Then I should see "Prompts: 2" + + Scenario: Sign-ups in the dashboard have correct controls + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for Battle 12 with combination A + When I am on myname1's signups page + Then I should see "Edit" + And I should see "Delete" + + Scenario: Edit individual prompt + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for Battle 12 with combination A + When I view my signup for "Battle 12" + When I follow "Edit Prompt" + Then I should see single prompt editing + And I should see "Edit Sign-up" + When I uncheck "Stargate Atlantis" + And I press "Update" + Then I should see "Sorry! We couldn't save this request because:" + And I should see "Your Request must include exactly 1 fandom tags" + + Scenario: Add one new prompt to existing signup + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for Battle 12 with combination A + And I add a new prompt to my signup + Then I should see "Prompt was successfully added" + And I should see "Request 3" + And I should see "My extra tag" + + Scenario: Sort prompts by date + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination A + And I am logged in as "myname2" + When I sign up for Battle 12 with combination B + When I view prompts for "Battle 12" + And I follow "Date" + Then I should see "Something else weird" + + Scenario: Sort prompts by fandom doesn't give error page + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination A + And I am logged in as "myname2" + When I sign up for Battle 12 with combination B + When I view prompts for "Battle 12" + And I follow "Fandom 1" + Then I should see "Something else weird" + + Scenario: Sign up for a prompt meme with no tags + + Given I have no-column prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination E + Then I should see "Sign-up was successfully created" + + Scenario: If there are no fandoms, prompt info on claims should show description or URL + + Given I have no-column prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination E + When I claim a prompt from "Battle 12" + # TODO: check design: regular user doesn't get link to unposted claims anymore + # When I view unposted claims for "Battle 12" + Then I should see "Weird description" + + Scenario: Sort by fandom shouldn't show when there aren't any fandoms + + Given I have no-column prompt meme fully set up + When I am logged in as "myname1" + And I sign up for Battle 12 with combination E + And I view prompts for "Battle 12" + # TODO: We need to check the display for fandomless memes + Then I should not see "Fandom 1" + + Scenario: Claim a prompt and view claims on main page and user page + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + Then I should see a prompt is claimed + + Scenario: Claim count shows on profile? + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + When I sign up for Battle 12 with combination A + And I claim a prompt from "Battle 12" + When I go to "Battle 12" collection's page + And I follow "Profile" + Then I should see "Prompts: 2" + # TODO: have these been removed by design or by accident? + # And I should see "Claimed prompts: 1" + + Scenario: Mod can view signups + + Given I have Battle 12 prompt meme fully set up + And everyone has signed up for Battle 12 + When I am logged in as "mod1" + And I go to "Battle 12" collection's page + And I follow "Prompts (8)" + Then I should see correct signups for Battle 12 + + Scenario: Mod can delete signups + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + And I sign up for Battle 12 with combination B + When I am logged in as "mod1" + And I go to "Battle 12" collection's page + And I follow "Prompts (" + And I should see "Prompts for Battle 12" + When I follow "Delete Sign-up" + Then I should see "Challenge sign-up was deleted." + And I should see "Prompts (0)" + + Scenario: Sign up with both prompts anon + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + Then I should see "Sign-up was successfully created" + + Scenario: Sign up with neither prompt anon + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination A + Then I should see "Sign-up was successfully created" + + Scenario: Sign up with one anon prompt and one not + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination C + Then I should see "Sign-up was successfully created" + + Scenario: User has more than one pseud on signup form + + Given "myname1" has the pseud "othername" + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I start to sign up for "Battle 12" + Then I should see "othername" + + Scenario: User changes pseud on a challenge signup + + Given "myname1" has the pseud "othername" + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination A + Then I should see "Sign-up was successfully created" + And I should see "Sign-up for myname1" + When I edit my signup for "Battle 12" + Then I should see "othername" + When I select "othername" from "challenge_signup_pseud_id" + # two forms in this page, must specify which button to press + And I press "Update" + Then I should see "Sign-up was successfully updated" + Then I should see "Sign-up for othername (myname1)" + + Scenario: Add more requests button disappears correctly from signup show page + + Given I am logged in as "mod1" + And I have standard challenge tags setup + When I set up a basic promptmeme "Battle 12" + And I follow "Challenge Settings" + When I fill in multi-prompt challenge options + When I sign up for Battle 12 with combination D + And I add prompt 3 + Then I should see "Add Prompt" + When I add prompt 4 + Then I should not see "Add Prompt" + + Scenario: Remove prompt button shouldn't show on Sign-ups + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination A + When I am on myname1's user page + When I follow "Sign-ups" + Then I should not see "Remove prompt" + + Scenario: Mod can't edit signups + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination A + When I am logged in as "mod1" + And I view prompts for "Battle 12" + Then I should not see "Edit Sign-up" + + Scenario: Mod cannot edit someone else's prompt + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination C + When I am logged in as "mod1" + # The next step just takes you to the 'Prompts' page + When I edit the first prompt + Then I should not see "Edit Prompt" + + Scenario: Claim an anon prompt + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname4" + When I sign up for Battle 12 with combination B + When I go to "Battle 12" collection's page + And I follow "Prompts (" + When I press "Claim" + Then I should see "New claim made." + And I should see "by Anonymous" + And I should not see "myname" within "#main" + + Scenario: Prompts are counted up correctly + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination A + Then I should see "Prompts (2)" + When I am logged in as "myname2" + When I sign up for Battle 12 with combination B + Then I should see "Prompts (4)" + + Scenario: Claims are shown to mod + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + Then claims are shown + + Scenario: Claims are hidden from ordinary user + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "myname4" + Then I should not see "Unposted Claims" + # TODO: they got really hidden, since ordinary user can't get to that page at all + # Then claims are hidden + + Scenario: User cannot see unposted claims to delete + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I claim a prompt from "Battle 12" + When I am logged in as "myname1" + Then I should not see "Unposted Claims" + + Scenario: User can delete their own claim + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I claim a prompt from "Battle 12" + And I go to "Battle 12" collection's page + And I follow "My Claims" + And I follow "Drop Claim" + Then I should see "Your claim was deleted." + When I go to "Battle 12" collection's page + Then I should not see "My Claims" + + Scenario: User can drop a claim from the prompts page + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I claim a prompt from "Battle 12" + And I go to "Battle 12" collection's page + And I follow "Prompts" + Then I should see "Drop Claim" + + Scenario: User can't delete another user's claim + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I claim a prompt from "Battle 12" + When I am logged in as "otheruser" + And I go to "Battle 12" collection's page + And I follow "Prompts" + Then I should not see "Drop Claim" + + Scenario: User can delete their own claim from the user claims list + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I claim a prompt from "Battle 12" + When I follow "My Dashboard" + And I follow "Claims" + Then I should see "Drop Claim" + When I follow "Drop Claim" + Then I should see "Your claim was deleted." + # confirm claim no longer exists + When I go to "Battle 12" collection's page + Then I should not see "My Claims" + + Scenario: Mod or owner can delete a claim from the user claims list + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I claim a prompt from "Battle 12" + When I am logged in as "mod1" + And I view unposted claims for "Battle 12" + Then I should see "Delete" + When I follow "Delete" + Then I should see "The claim was deleted." + + Scenario: User can't claim the same prompt twice + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim two prompts from "Battle 12" + And I view prompts for "Battle 12" + # TODO: Refactor this test once we have a new Capybara version so that we look for .exact(Claim) + Then I should see "Drop Claim" diff --git a/features/prompt_memes_b/challenge_promptmeme_posting_fills.feature b/features/prompt_memes_b/challenge_promptmeme_posting_fills.feature new file mode 100755 index 0000000..2216892 --- /dev/null +++ b/features/prompt_memes_b/challenge_promptmeme_posting_fills.feature @@ -0,0 +1,561 @@ +@collections @challenges @promptmemes +Feature: Prompt Meme Challenge + In order to participate without inhibitions + As a humble user + I want to prompt, post and receive fills anonymously + + Scenario: Prompt anonymously and be notified of the fills without the writer knowing who I am + Given basic tags + And the following activated user exists + | login | password | email | + | myname1 | password | my1@e.org | + And a fandom exists with name: "GhostSoup", canonical: true + And I am logged in as "mod1" + And I set up a basic promptmeme "The Kissing Game" + And I log out + When I am logged in as "myname1" + And I go to "The Kissing Game" collection's page + # And the apostrophe stops getting in the way of highlighting in notepad++ ' + And I follow "Sign Up" + And I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_fandom_tagnames" with "GhostSoup" + And I check "challenge_signup_requests_attributes_0_anonymous" + # there are two forms in this page, can't use I submit + And I press "Submit" + Then I should see "Sign-up was successfully created" + When I log out + And I am logged in as "myname2" + And I go to "The Kissing Game" collection's page + And I follow "Prompts (1)" + And I press "Claim" + Then I should see "New claim made" + And I follow "Fulfill" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "GhostSoup" + And I should see "promptcollection" in the "work_collection_names" input + And the "Untitled Prompt in The Kissing Game (Anonymous)" checkbox should be checked + And the "work_recipients" field should not contain "myname1" + And I fill in "Work Title" with "Kinky Story" + And I fill in "content" with "Story written for your kinks, oh mystery reader!" + Given all emails have been delivered + And I press "Post" + Then I should see "Kinky Story" + And I should find a list for associations + And I should see "In response to a prompt by Anonymous in the The Kissing Game collection" + And I should see a link "prompt" + And 1 email should be delivered to "my1@e.org" +# TODO: when work_anonymous is implemented, test that the prompt filler can be anon too + + Scenario: Fulfilling a claim ticks the right boxes automatically + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I start to fulfill my claim + Then the "Battle 12" checkbox should be checked + And the "Battle 12" checkbox should not be disabled + + Scenario: User can fulfill a claim + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I fulfill my claim + Then my claim should be fulfilled + + Scenario: User can fulfill a claim to their own prompt + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + And I sign up for Battle 12 with combination B + And I claim a prompt from "Battle 12" + And I fulfill my claim + Then my claim should be fulfilled + + Scenario: Fulfilled claim shows correctly on my claims + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I fulfill my claim + When I am on myname4's user page + And I follow "Claims" + And I follow "Fulfilled Claims" + Then I should see "Fulfilled Story" + # TODO: should I? It's not there at all + And I should not see "Not yet posted" + + Scenario: Claims count should be correct, shows fulfilled claims as well + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I fulfill my claim + When I am on myname4's user page + # Then show me the sidebar # TODO: it has Claims (0) but why? + Then I should see "Claims (0)" + When I follow "Claims" + And I follow "Fulfilled Claims" + Then I should see "Fulfilled Story" + + Scenario: Claim shows as fulfilled to another user + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I fulfill my claim + When I am logged in as "myname1" + When I go to "Battle 12" collection's page + And I follow "Prompts (" + Then I should see "Fulfilled By" + And I should see "Mystery Work" + + # Scenario: Fulfilled claims are shown to mod + # TODO: We need to figure out if we want to hide claims from mods in 100% anonymous prompt memes +# Given I have Battle 12 prompt meme fully set up +# Given everyone has signed up for Battle 12 +# When I am logged in as "myname4" +# When I claim a prompt from "Battle 12" +# When I close signups for "Battle 12" +# When I am logged in as "myname4" +# When I fulfill my claim +# When mod fulfills claim +# When I am on "Battle 12" collection's page +# When I follow "Prompts" +# And I follow "Show Claims" +# Then I should not see "Claimed by: myname4" +# And I should not see "Claimed by: mod1" +# And I should not see "Claimed by: (Anonymous)" +# When I follow "Show Filled" +# Then I should see "Claimed by: myname4" +# And I should see "Claimed by: mod1" +# And I should not see "Claimed by: (Anonymous)" + + Scenario: Fulfilled claims are hidden from user + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "myname4" + When I fulfill my claim + When mod fulfills claim + When I am logged in as "myname4" + When I go to "Battle 12" collection's page + And I follow "Prompts (8)" + Then I should not see "myname4" within "h5" + And I should not see "mod1" within "h5" + And I should see "Fulfilled Story by Anonymous" within "div.work h4" + + Scenario: Sign-up can be deleted after response has been posted + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I fulfill my claim + When I am logged in as "myname1" + And I delete my signup for the prompt meme "Battle 12" + Then I should see "Challenge sign-up was deleted." + # work fulfilling is still fine + When I view the work "Fulfilled Story" + Then I should see "This work is part of an ongoing challenge and will be revealed soon! You can find details here: Battle 12" + And I should not see "Stargate Atlantis" + # work is still fine as another user + When I am logged in as "myname4" + And I view the work "Fulfilled Story" + Then I should see "This work is part of an ongoing challenge and will be revealed soon! You can find details here: Battle 12" + And I should see "Stargate Atlantis" + + Scenario: Prompt can be removed after response has been posted and still show properly on the work which fulfilled it + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I fulfill my claim + When I am logged in as "myname1" + And I delete my signup for the prompt meme "Battle 12" + When I view the work "Fulfilled Story" + Then I should see "This work is part of an ongoing challenge and will be revealed soon! You can find details here: Battle 12" + And I should not see "Stargate Atlantis" + When I am logged in as "myname4" + And I view the work "Fulfilled Story" + Then I should see "This work is part of an ongoing challenge and will be revealed soon! You can find details here: Battle 12" + And I should see "Stargate Atlantis" + + Scenario: User can fulfill the same claim twice + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I fulfill my claim + When I fulfill my claim again + Then I should see "Work was successfully posted" + And I should see "Second Story" + And I should see "In response to a prompt by Anonymous" + And I should see "Collections: Battle 12" + + Scenario: User edits existing work to fulfill claim + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + And I post the work "Existing Story" + And I should not see "Battle 12" + And I edit the work "Existing Story" + And I check "random SGA love in Battle 12 (Anonymous)" + And I press "Post" + Then I should see "Battle 12" + Then I should see "Existing Story" + And I should see "This work is part of an ongoing challenge" + When I reveal works for "Battle 12" + When I view the work "Existing Story" + And I should not see "This work is part of an ongoing challenge" + + Scenario: User edits existing work in another collection to fulfill claim + + Given I have Battle 12 prompt meme fully set up + And I have a collection "Othercoll" + When I am logged in as "myname1" + When I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + And I post the work "Existing Story" in the collection "Othercoll" + And I edit the work "Existing Story" + And I check "random SGA love in Battle 12 (Anonymous)" + And I press "Post" + Then I should see "Battle 12" + And I should see "Othercoll" + + Scenario: Fulfill a claim by editing an existing work + + Given I have Battle 12 prompt meme fully set up + And everyone has signed up for Battle 12 + When I close signups for "Battle 12" + When I reveal the "Battle 12" challenge + When I reveal the authors of the "Battle 12" challenge + When I am logged in as "myname1" + And I go to "Battle 12" collection's page + And I follow "Prompts (" + When I press "Claim" + Then I should see "New claim made" + When I post the work "Here's one I made earlier" + And I edit the work "Here's one I made earlier" + And I check "Battle 12" + And I press "Preview" + Then I should see "In response to a prompt by" + And I should see "Collections:" + And I should see "Battle 12" + When I press "Update" + Then I should see "Work was successfully updated" + And I should not see "draft" + And I should see "In response to a prompt by" + Then I should see "Collections:" + And I should see "Battle 12" + + # claim is fulfilled on collection page + When I go to "Battle 12" collection's page + And I follow "Prompts" + Then I should see "myname1" within ".prompt .work" + And I should see "Fulfilled By" + + Scenario: When draft is posted, claim is fulfilled and posted to collection + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname2" + And I sign up for Battle 12 with combination B + When I am logged in as "myname4" + And I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I reveal the "Battle 12" challenge + When I reveal the authors of the "Battle 12" challenge + When I am logged in as "myname4" + And I go to the "Battle 12" requests page + When I press "Claim" + When I follow "Fulfill" + And I fill in the basic work information for "Existing work" + And I check "random SGA love in Battle 12 (Anonymous)" + And I press "Preview" + When I am on myname4's user page + And I follow "Drafts" + And all emails have been delivered + When I follow "Post Draft" + Then 1 email should be delivered + Then I should see "Your work was successfully posted" + And I should see "In response to a prompt by Anonymous" + When I go to "Battle 12" collection's page + And I follow "Prompts (" + Then I should see "myname4" + And I should see "Fulfilled By" + When I follow "Existing work" + Then I should see "Existing work" + And I should see "Battle 12" + And I should not see "draft" + + Scenario: Make another claim and then fulfill from the post new form (New Work) + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I close signups for "Battle 12" + When I reveal the "Battle 12" challenge + Given all emails have been delivered + When I reveal the authors of the "Battle 12" challenge + When I go to "Battle 12" collection's page + And I follow "Prompts (8)" + When I press "Claim" + Then I should see "New claim made." + When I am logged in as "myname4" + And I go to the collections page + And I follow "Battle 12" + When I follow "Prompts (" + When I press "Claim" + Then I should see "New claim made" + When I follow "New Work" + When I fill in the basic work information for "Existing work" + And I check "Battle 12 (myname4)" + And I press "Preview" + Then I should see "Draft was successfully created" + And I should see "In response to a prompt by myname4" + And 0 emails should be delivered + And I should see "Collections:" + And I should see "Battle 12" + When I view the work "Existing work" + Then I should see "draft" + + Scenario: Fulfilled claims show as fulfilled to another user + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "myname4" + When I fulfill my claim + When mod fulfills claim + When I reveal the "Battle 12" challenge + Given all emails have been delivered + When I reveal the authors of the "Battle 12" challenge + When I go to "Battle 12" collection's page + And I follow "Prompts (8)" + When I press "Claim" + Then I should see "New claim made." + When I am logged in as "myname4" + And I go to the "Battle 12" requests page + Then I should see "mod1" within ".prompt .work" + And I should see "myname4" within ".prompt .work" + + Scenario: When a prompt is filled with a co-authored work, the e-mail should link to each author's URL instead of showing escaped HTML + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname3" + And I go to myname3's user page + And I follow "Preferences" + And I check "Allow others to invite me to be a co-creator" + And I press "Update" + When I am logged in as "myname1" + And I sign up for Battle 12 with combination A + And I log out + When I am logged in as "myname2" + And I claim a prompt from "Battle 12" + And I start to fulfill my claim with "Co-authored Fill" + And I invite the co-author "myname3" + When I press "Post" + Then 1 email should be delivered to "myname3" + And the email should contain "The user myname2 has invited your pseud myname3 to be listed as a co-creator on the following work" + And the email should not contain "translation missing" + When the user "myname3" accepts all co-creator requests + And I am logged in as "mod1" + And I reveal the authors of the "Battle 12" challenge + And I reveal the "Battle 12" challenge + Then 1 email should be delivered to "myname1" + And the email should link to myname2's user url + And the email should not contain "<a href="http://archiveofourown.org/users/myname2/pseuds/myname2"" + And the email should link to myname3's user url + And the email should not contain "<a href="http://archiveofourown.org/users/myname3/pseuds/myname3"" + + Scenario: check that completed ficlet is unrevealed + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When mod fulfills claim + When I am logged in as "myname4" + When I view the work "Fulfilled Story-thing" + Then I should not see "In response to a prompt by myname4" + And I should not see "Fandom: Stargate Atlantis" + And I should not see "Anonymous" + And I should not see "mod1" + And I should see "This work is part of an ongoing challenge and will be revealed soon! You can find details here: Battle 12" + + Scenario: Mod can post a fic + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "mod1" + When I claim a prompt from "Battle 12" + When I am on mod1's user page + Then I should see "Claims (1)" + When I follow "Claims" + Then I should see "My Claims" + And I should see "canon SGA love by myname4 in Battle 12" within "div#main.challenge_claims-index h4" + When I follow "Fulfill" + And I fill in "Fandoms" with "Stargate Atlantis" + And I fill in "Work Title*" with "Fulfilled Story-thing" + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "content" with "This is an exciting story about Atlantis, but in a different universe this time" + When I press "Preview" + And I press "Post" + Then I should see "Work was successfully posted" + + Scenario: Mod can complete a claim + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "mod1" + When I claim a prompt from "Battle 12" + When I start to fulfill my claim + And I fill in "Work Title" with "Fulfilled Story-thing" + And I fill in "content" with "This is an exciting story about Atlantis, but in a different universe this time" + When I press "Preview" + And I press "Post" + When I am on mod1's user page + Then I follow "Claims" + And I should not see "mod" within "h4" + Then I follow "Fulfilled Claims" + # On the users' My Claims page, they see their anon works as Anonymous + And I should see "Anonymous" within "div.work h4" + + Scenario: Fic shows what prompt it is fulfilling when mod views it + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "mod1" + When I claim a prompt from "Battle 12" + When I start to fulfill my claim + And I fill in "Work Title" with "Fulfilled Story-thing" + And I fill in "content" with "This is an exciting story about Atlantis, but in a different universe this time" + When I press "Preview" + And I press "Post" + When I view the work "Fulfilled Story-thing" + Then I should see "In response to a prompt by myname4" + And I should see "Fandom: Stargate Atlantis" + And I should see "Anonymous" within ".byline" + And I should see a link "prompt" + + Scenario: Work links to the prompt it fulfils, for all users + + Given I have Battle 12 prompt meme fully set up + And I am logged in as "myname1" + And I sign up for Battle 12 with combination B + And I am logged in as "myname4" + And I claim a prompt from "Battle 12" + And I fulfill my claim + And I reveal works for "Battle 12" + And I view the work "Fulfilled Story" + Then I should see "Fulfilled Story" + And I should see "In response to a prompt by Anonymous" + And I should see a link "prompt" + When I follow "prompt" + Then I should see "Request by Anonymous" + When I am logged in as "myname2" + And I view the work "Fulfilled Story" + Then I should see "Fulfilled Story" + And I should see "In response to a prompt by Anonymous" + And I should see a link "prompt" + When I follow "prompt" + Then I should see "Request by Anonymous" + When I am logged in as "mod" + And I view the work "Fulfilled Story" + Then I should see "Fulfilled Story" + And I should see "In response to a prompt by Anonymous" + And I should see a link "prompt" + When I follow "prompt" + Then I should see "Request by Anonymous" + When I log out + And I view the work "Fulfilled Story" + Then I should see "Fulfilled Story" + And I should see "In response to a prompt by Anonymous" + And I should see a link "prompt" + When I follow "prompt" + Then I should see "Request by Anonymous" + + Scenario: A creator can give a gift to a user who disallows gifts if the work is connected to a claim of a non-anonymous prompt belonging to the recipient, and the recipient remains attached even if the work is later disconnected from the claim + + Given I have Battle 12 prompt meme fully set up + And the user "prompter" exists and is activated + And the user "prompter" disallows gifts + And "prompter" has signed up for Battle 12 with combination A + When I am logged in as "gifter" + And I claim a prompt from "Battle 12" + And I start to fulfill my claim + And I fill in "Gift this work to" with "prompter" + And I press "Post" + Then I should see "For prompter." + When I follow "Edit" + And I uncheck "Battle 12 (prompter)" + And I press "Post" + Then I should see "For prompter." + + Scenario: A creator cannot give a gift to a user who disallows gifts if the work is connected to a claim of an anonymous prompt belonging to the recipient + + Given I have Battle 12 prompt meme fully set up + And the user "prompter" exists and is activated + And the user "prompter" disallows gifts + And "prompter" has signed up for Battle 12 with combination B + When I am logged in as "gifter" + And I claim a prompt from "Battle 12" + And I start to fulfill my claim + And I fill in "Gift this work to" with "prompter" + And I press "Post" + Then I should see "prompter does not accept gifts." + + Scenario: A creator cannot give a gift to a user who disallows gifts if the work is connected to a claim of a non-anonymous prompt belonging to a different user + + Given I have Battle 12 prompt meme fully set up + And the user "prompter" exists and is activated + And the user "prompter" disallows gifts + And "prompter" has signed up for Battle 12 with combination A + And the user "bystander" exists and is activated + And the user "bystander" disallows gifts + When I am logged in as "gifter" + And I claim a prompt from "Battle 12" + And I start to fulfill my claim + And I fill in "Gift this work to" with "prompter, bystander" + And I press "Post" + Then I should see "bystander does not accept gifts." + + Scenario: A creator can give a gift to a user who has blocked them if the work is connected to a claim of a non-anonymous prompt belonging to the recipient + + Given I have Battle 12 prompt meme fully set up + And the user "prompter" exists and is activated + And the user "prompter" has blocked the user "gifter" + And "prompter" has signed up for Battle 12 with combination A + When I am logged in as "gifter" + And I claim a prompt from "Battle 12" + And I start to fulfill my claim + And I fill in "Gift this work to" with "prompter" + And I press "Post" + Then I should see "For prompter." + When I follow "Edit" + And I uncheck "Battle 12 (prompter)" + And I press "Post" + Then I should see "For prompter." \ No newline at end of file diff --git a/features/prompt_memes_b/challenge_promptmeme_springkink.feature b/features/prompt_memes_b/challenge_promptmeme_springkink.feature new file mode 100755 index 0000000..2ae763d --- /dev/null +++ b/features/prompt_memes_b/challenge_promptmeme_springkink.feature @@ -0,0 +1,81 @@ +@collections @challenges @promptmemes +Feature: Prompt Meme Challenge + In order to have an archive full of works + As a humble user + I want to create a prompt meme and post to it + + Scenario: Create a prompt meme for a challenge like http://community.livejournal.com/springkink/ + + Given I am logged in as "mod1" + And I have standard challenge tags set up + + # set up the challenge + + When I go to the collections page + When I set up an anon promptmeme "Spring Kink" + And I follow "Challenge Settings" + When I fill in "General Sign-up Instructions" with "Here are some general tips" + And I fill in "Tag Sets To Use:" with "Standard Challenge Tags" + And I fill in "prompt_meme_request_restriction_attributes_fandom_num_required" with "1" + And I fill in "prompt_meme_request_restriction_attributes_fandom_num_allowed" with "1" + And I check "prompt_meme_anonymous" + And I fill in "prompt_meme_requests_num_allowed" with "1" + And I fill in "prompt_meme_requests_num_required" with "1" + And I press "Update" + Then I should see "Challenge was successfully updated" + + # sign up as first prompter + + When I log out + And I am logged in as "prompter1" with password "something" + When I go to "Spring Kink" collection's page + And I follow "Sign Up" + And I check "Stargate Atlantis" + And I submit + Then I should see "Sign-up was successfully created" + And I should see "Prompts (1)" + + # writer 1 replies to prompt, which is anon + When I am logged out + And I am logged in as "writer1" with password "something" + And I go to "Spring Kink" collection's page + And I follow "Prompts (" + Then I should see "Stargate Atlantis" + And I should not see "prompter1" + When I press "Claim" + Then I should see "New claim made" + When I fulfill my claim + Then I should see "Work was successfully posted" + And I should see "This work is part of an ongoing challenge and will be revealed soon!" + + # writer 2 replies to prompt + When I am logged in as "writer2" with password "something" + And I go to "Spring Kink" collection's page + And I follow "Prompts (" + And I press "Claim" + Then I should see "New claim made" + When I fulfill my claim + Then I should see "Work was successfully posted" + + # responses are hidden, e.g. from prompter + When I am logged out + And I am logged in as "prompter1" with password "something" + And I go to "Spring Kink" collection's page + And I follow "Works" + Then I should not see "writer1" + And I should not see "Response Story" + # And I should see "Mystery Work" + + # mod checks that word count is at least 100 and only reveals the right ones + When I am logged out + And I am logged in as "mod1" with password "something" + + # prompter prompts for day 2 + + # writer 1 responds for day 2 + + # writer 3 and writer 4 respond for day 2 + + # writer 4 responds belatedly for day 1 + + # mod can see all that and reveal the right things diff --git a/features/prompt_memes_c/challenge_promptmeme_claims.feature b/features/prompt_memes_c/challenge_promptmeme_claims.feature new file mode 100755 index 0000000..7078d18 --- /dev/null +++ b/features/prompt_memes_c/challenge_promptmeme_claims.feature @@ -0,0 +1,456 @@ +@collections @challenges @promptmemes +Feature: Prompt Meme Challenge + In order to have an archive full of works + As a humble user + I want to create a prompt meme and post to it + + Scenario: Claim two prompts by the same person in one challenge + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname2" + When I sign up for Battle 12 with combination B + # 1st prompt SG-1, 2nd prompt SGA, both anon + When I am logged in as "myname1" + And I claim two prompts from "Battle 12" + And I view prompts for "Battle 12" + # all prompts have been claimed - check it worked + # TODO: find a better way to check that it worked, since 'Drop Claim' includes the word 'Claim', and there is no table anymore, so no tbody + # Then I should not see "Claim" within "tbody" + # TODO: check that they are not intermittent anymore + When I start to fulfill my claim + Then I should find a checkbox "High School AU SG1 in Battle 12 (Anonymous)" + And I should find a checkbox "random SGA love in Battle 12 (Anonymous)" + And the "High School AU SG1 in Battle 12 (Anonymous)" checkbox should not be checked + And the "random SGA love in Battle 12 (Anonymous)" checkbox should be checked + + Scenario: Claim two prompts by different people in one challenge + + Given I have single-prompt prompt meme fully set up + When I am logged in as "sgafan" + And I sign up for "Battle 12" with combination SGA + When I am logged in as "sg1fan" + And I sign up for "Battle 12" with combination SG-1 + When I am logged in as "writer" + And I claim two prompts from "Battle 12" + When I start to fulfill my claim + Then I should find a checkbox "SG1 love in Battle 12 (sg1fan)" + And I should find a checkbox "SGA love in Battle 12 (sgafan)" + # TODO: check that they are not intermittent anymore + And the "SGA love in Battle 12 (sgafan)" checkbox should not be checked + And the "SG1 love in Battle 12 (sg1fan)" checkbox should be checked + + Scenario: Claim two prompts by the same person in one challenge, one is anon + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname2" + When I sign up for Battle 12 + # 1st prompt "something else weird" and titled "crack", 2nd prompt anon + When I am logged in as "myname1" + And I claim two prompts from "Battle 12" + And I view prompts for "Battle 12" + # anon as claims are in reverse date order + When I start to fulfill my claim + Then I should find a checkbox "Untitled Prompt in Battle 12 (Anonymous)" + And I should find a checkbox "crack in Battle 12 (myname2)" + And the "Untitled Prompt in Battle 12 (Anonymous)" checkbox should be checked + And the "crack in Battle 12 (myname2)" checkbox should not be checked + + Scenario: User claims two prompts in one challenge and fulfills one of them + # TODO: When SPRs get merged, make this check that 'prompt' is a link + # and that it shows the correct prompt, or whatever + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname2" + When I sign up for Battle 12 with combination B + # 1st prompt SG-1, 2nd prompt SGA, both anon + When I am logged in as "myname1" + And I claim a prompt from "Battle 12" + # SGA as it's in reverse order + And I claim a prompt from "Battle 12" + # SG-1 + # SGA seems to be the first consistently + When I start to fulfill my claim + Then the "High School AU SG1 in Battle 12 (Anonymous)" checkbox should not be checked + And the "random SGA love in Battle 12 (Anonymous)" checkbox should be checked + When I press "Preview" + And I press "Post" + When I view the work "Fulfilled Story" + Then I should see "Stargate Atlantis" + + Scenario: User claims two prompts in one challenge and fufills both of them at once + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname2" + When I sign up for Battle 12 + # 1st prompt anon, 2nd prompt non-anon + When I am logged in as "myname1" + And I claim a prompt from "Battle 12" + And I claim a prompt from "Battle 12" + And I view prompts for "Battle 12" + When I start to fulfill my claim + # the anon prompt will already by checked + And I check "crack in Battle 12 (myname2)" + And I press "Preview" + And I press "Post" + When I view the work "Fulfilled Story" + # fandoms are not filled in automatically anymore, so we check that both prompts are marked as filled by having one anon and one non-anon + Then I should see "In response to a prompt by Anonymous" + And I should see "In response to a prompt by myname2" + + # Scenario: User claims two prompts in different challenges and fulfills both of them at once + # TODO + + Scenario: Sign up for several challenges and see Sign-ups are sorted + + Given I have Battle 12 prompt meme fully set up + When I set up a basic promptmeme "Battle 13" + When I set up an anon promptmeme "Battle 14" with name "anonmeme" + When I am logged in as "prolific_writer" + When I sign up for "Battle 12" fixed-fandom prompt meme + When I sign up for "Battle 13" many-fandom prompt meme + When I sign up for "Battle 14" many-fandom prompt meme + When I am on prolific_writer's user page + And I follow "Sign-ups" + # TODO + + Scenario: User is participating in a prompt meme and a gift exchange at once, clicks "Post to fulfill" on the prompt meme and sees the right boxes ticked + + Given I have created the gift exchange "My Gift Exchange" + And I open signups for "My Gift Exchange" + And everyone has signed up for the gift exchange "My Gift Exchange" + And I have generated matches for "My Gift Exchange" + And I have sent assignments for "My Gift Exchange" + Given I have Battle 12 prompt meme fully set up + And everyone has signed up for Battle 12 + When I am logged in as "myname3" + And I claim a prompt from "Battle 12" + When I start to fulfill my claim + Then the "canon SGA love in Battle 12 (myname4)" checkbox should be checked + And the "My Gift Exchange (myname2)" checkbox should not be checked + And the "canon SGA love in Battle 12 (myname4)" checkbox should not be disabled + And the "My Gift Exchange (myname2)" checkbox should not be disabled + + Scenario: User posts to fulfill direct from Post New (New Work) + + Given I have Battle 12 prompt meme fully set up + And everyone has signed up for Battle 12 + When I am logged in as "myname3" + And I claim a prompt from "Battle 12" + And I follow "New Work" + Then the "canon SGA love in Battle 12 (myname4)" checkbox should not be checked + And the "canon SGA love in Battle 12 (myname4)" checkbox should not be disabled + + Scenario: User is participating in a prompt meme and a gift exchange at once, clicks "Post to fulfill" on the prompt meme and then changes their mind and fulfills the gift exchange instead + + Given I have Battle 12 prompt meme fully set up + And everyone has signed up for Battle 12 + Given I have created the gift exchange "My Gift Exchange" + And I open signups for "My Gift Exchange" + And everyone has signed up for the gift exchange "My Gift Exchange" + And I have generated matches for "My Gift Exchange" + And I have sent assignments for "My Gift Exchange" + When I am logged in as "myname3" + And I claim a prompt from "Battle 12" + When I start to fulfill my claim + When I check "My Gift Exchange (myname2)" + And I uncheck "canon SGA love in Battle 12 (myname4)" + And I fill in "Post to Collections / Challenges" with "" + And I press "Post" + Then I should see "My Gift Exchange" + And I should not see "Battle 12" + And I should not see "This work is part of an ongoing challenge and will be revealed soon! You can find details here: My Gift Exchange" + + Scenario: Mod can claim a prompt like an ordinary user + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "mod1" + When I claim a prompt from "Battle 12" + Then I should see "New claim made." + + Scenario: Mod can still see anonymous claims after signup is closed + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I fulfill my claim + When I am logged in as "mod1" + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "mod1" + When I am on "Battle 12" collection's page + And I follow "Unposted Claims (" + Then I should see "claimed by mod" + And I should see "by myname4" + And I should see "Stargate Atlantis" + + # Scenario: check that claims can't be viewed even after challenge is revealed + # TODO: Find a way to construct the link to a claim show page for someone who shouldn't be able to see it + + Scenario: Mod can reveal challenge + + Given I have Battle 12 prompt meme fully set up + When I close signups for "Battle 12" + When I go to "Battle 12" collection's page + And I follow "Collection Settings" + And I uncheck "This collection is unrevealed" + And I press "Update" + Then I should see "Collection was successfully updated" + + Scenario: Revealing challenge sends out emails + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "myname4" + When I fulfill my claim + When mod fulfills claim + When I reveal the "Battle 12" challenge + Then I should see "Collection was successfully updated" + # 2 stories are now revealed, so notify the prompters + And 2 emails should be delivered + + Scenario: Story is anon when challenge is revealed + + Given I have standard challenge tags setup + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "myname4" + When I fulfill my claim + When mod fulfills claim + When I reveal the "Battle 12" challenge + When I am logged in as "myname4" + When I view the work "Fulfilled Story-thing" + Then I should see "In response to a prompt by myname4" + And I should see "Fandom: Stargate Atlantis" + And I should see "Collections: Battle 12" + And I should see "Anonymous" within ".byline" + And I should not see "mod1" within ".byline" + + Scenario: Authors can be revealed + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "myname4" + When I fulfill my claim + When mod fulfills claim + When I reveal the "Battle 12" challenge + When I reveal the authors of the "Battle 12" challenge + Then I should see "Collection was successfully updated" + + Scenario: Revealing authors doesn't send emails + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "myname4" + When I fulfill my claim + When mod fulfills claim + When I reveal the "Battle 12" challenge + Given all emails have been delivered + When I reveal the authors of the "Battle 12" challenge + Then I should see "Collection was successfully updated" + Then 0 emails should be delivered + + Scenario: When challenge is revealed-authors, user can see claims + + Given I have Battle 12 prompt meme fully set up + Given everyone has signed up for Battle 12 + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I close signups for "Battle 12" + When I am logged in as "myname4" + When I fulfill my claim + When mod fulfills claim + When I reveal the "Battle 12" challenge + When I reveal the authors of the "Battle 12" challenge + When I am logged in as "myname4" + When I go to "Battle 12" collection's page + And I follow "Prompts (8)" + Then I should see "Fulfilled By" + And I should see "Fulfilled Story by myname4" within "div.work" + And I should see "Fulfilled Story-thing by mod1" within "div.work" + + Scenario: Anon prompts stay anon on claims index even if challenge is revealed + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname4" + When I sign up for Battle 12 with combination B + When I close signups for "Battle 12" + When I am logged in as "myname2" + When I claim a prompt from "Battle 12" + When I fulfill my claim + When I reveal the "Battle 12" challenge + When I reveal the authors of the "Battle 12" challenge + When I go to "Battle 12" collection's page + And I follow "Prompts (" + Then I should see "by Anonymous" + And I should not see "by myname4" + + Scenario: Check that anon prompts are still anon on the prompts page after challenge is revealed + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname4" + When I sign up for Battle 12 with combination B + When I close signups for "Battle 12" + When I am logged in as "myname2" + When I claim a prompt from "Battle 12" + When I fulfill my claim + When I reveal the "Battle 12" challenge + When I reveal the authors of the "Battle 12" challenge + When I view prompts for "Battle 12" + Then I should see "random SGA love by Anonymous" + Then I should see "Fulfilled Story by myname2" + Then I should see "High School AU SG1 by Anonymous " + + Scenario: Check that anon prompts are still anon on user claims index after challenge is revealed + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname4" + When I sign up for Battle 12 with combination B + When I close signups for "Battle 12" + When I am logged in as "myname2" + When I claim a prompt from "Battle 12" + When I reveal the "Battle 12" challenge + When I reveal the authors of the "Battle 12" challenge + When I am logged in as "myname2" + When I am on myname2's user page + And I follow "Claims" + # note that user Claims page currently only shows unfulfilled claims + Then I should not see "myname4" + And I should see "Anonymous" + + Scenario: Check that anon prompts are still anon on claims show after challenge is revealed + # note that only mod can see claims show now - users don't get linked to it + + Given I have Battle 12 prompt meme fully set up + When I am logged in as "myname4" + When I sign up for Battle 12 with combination B + When I close signups for "Battle 12" + When I am logged in as "myname2" + When I claim a prompt from "Battle 12" + When I reveal the "Battle 12" challenge + When I reveal the authors of the "Battle 12" challenge + When I am logged in as "mod1" + When I am on "Battle 12" collection's page + And I follow "Unposted Claims" + And I follow "Anonymous" + Then I should not see "myname4" + And I should see "Anonymous" + + # Scenario: check that anon prompts are still anon on the fulfilling work + # TODO + + Scenario: work left in draft so claim is not yet totally fulfilled + + Given I have Battle 12 prompt meme fully set up + Given an anon has signed up for Battle 12 + When I close signups for "Battle 12" + When I reveal the "Battle 12" challenge + Given all emails have been delivered + When I reveal the authors of the "Battle 12" challenge + When I am logged in as "myname4" + When I claim a prompt from "Battle 12" + When I start to fulfill my claim + And I press "Preview" + When I go to the "Battle 12" requests page + Then I should see "Claimed By" + And I should not see "Fulfilled By" + When I am logged in as "mod1" + And I go to "Battle 12" collection's page + And I follow "Unposted Claims" + Then I should see "myname4" + When I am logged in as "myname4" + And I go to myname4's claims page + # Draft not shown. Instead we see that there is a 'Fulfill' button which + # we can use. Then use the 'Restore From Last Unposted Draft?' button + When I follow "Fulfill" + And I follow "Restore From Last Unposted Draft?" + When I press "Post" + And I should see "Work was successfully posted." + Then I should see "Fulfilled Story" + + Scenario: Maintainers can download CSV from requests or sign-ups page + + Given I am logged in as "mod1" + And I have standard challenge tags setup + And I create Battle 12 promptmeme + When I go to the "Battle 12" signups page + Then I should see "Download (CSV)" + When I go to the "Battle 12" requests page + And I follow "Download (CSV)" + Then I should download a csv file with the header row "Pseud Sign-up URL Tags Title Description" + + Scenario: Users can't download prompt CSV from requests page + + Given I have Battle 12 prompt meme fully set up + And everyone has signed up for Battle 12 + And I am logged in + When I go to the "Battle 12" requests page + Then I should not see "Download (CSV)" + + Scenario: Validation error doesn't cause semi-anon ticky to lose state (Issue 2617) + Given I set up an anon promptmeme "Scotts Prompt" with name "scotts_prompt" + And I am logged in as "Scott" with password "password" + And I go to "Scotts Prompt" collection's page + And I follow "Prompt Form" + And I check "Semi-anonymous Prompt" + And I press "Submit" + Then I should see "There were some problems with this submission. Please correct the mistakes below." + And I should see "Your Request must include between 1 and 2 fandom tags, but you have included 0 fandom tags in your current Request." + And the "Semi-anonymous Prompt" checkbox should be checked + + Scenario: Dates should be correctly set on PromptMemes + Given it is currently 2015-09-21 12:40 AM + And I am logged in as "mod1" + And I have standard challenge tags set up + And I have no prompts + When I set up Battle 12 promptmeme collection + And I check "Sign-up open?" + And I fill in "Sign-up opens:" with "2010-09-20 12:40AM" + And I fill in "Sign-up closes:" with "2010-09-22 12:40AM" + And I submit + Then I should see "If sign-ups are open, sign-up close date cannot be in the past." + When I fill in "Sign-up opens:" with "2022-09-20 12:40AM" + And I fill in "Sign-up closes:" with "2010-09-22 12:40AM" + And I submit + Then I should see "If sign-ups are open, sign-up open date cannot be in the future." + When I fill in "Sign-up opens:" with "2010-09-22 12:40AM" + And I fill in "Sign-up closes:" with "2010-09-20 12:40AM" + And I submit + Then I should see "Close date cannot be before open date." + When I fill in "Sign-up opens:" with "" + And I use tomorrow as the "Sign-up closes" date + And I submit + Then I should see "Challenge was successfully created." + + Scenario: A user who disallows gift works is cautioned about signing up for + a prompt meme, and a user who allows them is not. + Given I have Battle 12 prompt meme fully set up + And I am logged in as "participant" + And the user "participant" disallows gifts + When I go to "Battle 12" collection's page + And I follow "Prompt Form" + Then I should see "any user who claims your prompt to gift you a work in response to your prompt regardless of your preference settings" + When the user "participant" allows gifts + And I go to "Battle 12" collection's page + And I follow "Prompt Form" + Then I should not see "any user who claims your prompt to gift you a work in response to your prompt regardless of your preference settings" + + Scenario: When a work is posted to fulfill a prompt, the notes should contain the collection title + Given I have Battle 12 prompt meme fully set up + And everyone has signed up for Battle 12 + When I am logged in as "myname1" + And I claim a prompt from "Battle 12" + And I fulfill my claim + Then I should see "In response to a prompt by myname4 in the Battle 12 collection" \ No newline at end of file diff --git a/features/prompt_memes_c/challenge_promptmeme_deletion.feature b/features/prompt_memes_c/challenge_promptmeme_deletion.feature new file mode 100755 index 0000000..d7852db --- /dev/null +++ b/features/prompt_memes_c/challenge_promptmeme_deletion.feature @@ -0,0 +1,215 @@ +@collections @challenges @promptmemes +Feature: Prompt Meme Challenge + In order to have an archive full of works + As a humble user + I want to create a prompt meme and post to it + + Background: + Given I have Battle 12 prompt meme fully set up + + Scenario: Mod can delete whole sign-ups + + Given "myname1" has signed up for Battle 12 with combination A + When I am logged in as "mod1" + And I view prompts for "Battle 12" + And I follow "Delete Sign-up" + Then I should see "Challenge sign-up was deleted." + + Scenario: Mod can delete a prompt provided the user's sign-up has more than + the minimum number required for the meme + + Given "myname1" has signed up for Battle 12 with one more prompt than required + When I am logged in as "mod1" + And I view prompts for "Battle 12" + And I follow "Delete Prompt" + Then I should see "Prompt was deleted." + And I should not see "Delete Prompt" + And I should see "Delete Sign-up" + + Scenario: As a co-moderator I can delete whole sign-ups + + Given I have added a co-moderator "mod2" to collection "Battle 12" + And "myname1" has signed up for Battle 12 with combination A + When I am logged in as "mod2" + And I view prompts for "Battle 12" + And I follow "Delete Sign-up" + Then I should see "Challenge sign-up was deleted." + + Scenario: As a co-moderator I can delete prompts provided the user's sign-up + has more than the minimum number required for the meme + + Given I have added a co-moderator "mod2" to collection "Battle 12" + And "myname1" has signed up for Battle 12 with one more prompt than required + When I am logged in as "mod2" + And I view prompts for "Battle 12" + And I follow "Delete Prompt" + Then I should see "Prompt was deleted." + And I should not see "Delete Prompt" + And I should see "Delete Sign-up" + + Scenario: User can't delete prompt if they don't have more than the minimum + number required by the meme + + Given I am logged in as "myname1" + And I sign up for Battle 12 with combination C + When I view prompts for "Battle 12" + Then I should not see "Delete Prompt" + And I should see "Edit Sign-up" + + Scenario: User can delete one prompt provided their sign-up has more than the + minimum number required for the meme + + Given "myname1" has signed up for Battle 12 with one more prompt than required + When I am logged in as "myname1" + And I view prompts for "Battle 12" + And I follow "Delete Prompt" + Then I should see "Prompt was deleted." + And I should see "Sign-up for myname1" + And I should see "Delete Sign-up" + And I should not see "Delete Prompt" + + Scenario: When user deletes signup, its prompts disappear from the collection + + Given I am logged in as "myname1" + And I sign up for Battle 12 with combination A + When I delete my signup for the prompt meme "Battle 12" + And I view prompts for "Battle 12" + Then I should not see "myname1" within "ul.index" + + Scenario: When user deletes sign-up, the sign-up disappears from their + dashboard + + Given I am logged in as "myname1" + And I sign up for Battle 12 with combination A + When I delete my signup for the prompt meme "Battle 12" + And I go to myname1's signups page + Then I should see "Sign-ups (0)" + And I should not see "Battle 12" + + Scenario: When user deletes signup, the work stays part of the collection, + but no longer has the "In response to a prompt by" note + + Given "myname1" has signed up for Battle 12 with combination A + And "myname2" has fulfilled a claim from Battle 12 + And "myname1" has deleted their sign up for the prompt meme "Battle 12" + # Use the work creator account to avoid having to reveal the collection + When I am logged in as "myname2" + And I go to "Battle 12" collection's page + Then I should see "Fulfilled Story" + When I follow "Fulfilled Story" + Then I should not see "In response to a prompt" + And I should see "Battle 12" + + Scenario: When user deletes signup, the work creator can edit the work + normally + + Given "myname1" has signed up for Battle 12 with combination A + And "myname2" has fulfilled a claim from Battle 12 + And "myname1" has deleted their sign up for the prompt meme "Battle 12" + When I am logged in as "myname2" + And I edit the work "Fulfilled Story" + And I fill in "Additional Tags" with "My New Tag" + And I press "Post" + Then I should see "Work was successfully updated." + And I should see "My New Tag" + + Scenario: A mod can delete a prompt meme without needing Javascript and all the + claims and sign-ups will be deleted with it, but the collection will remain + + Given everyone has signed up for Battle 12 + And "myname4" has claimed a prompt from Battle 12 + When I am logged in as "mod1" + And I delete the challenge "Battle 12" + Then I should see "Are you sure you want to delete the challenge from the collection Battle 12? All sign-ups, assignments, and settings will be lost. (Works and bookmarks will remain in the collection.)" + When I press "Yes, Delete Challenge" + Then I should see "Challenge settings were deleted." + And I should not see the prompt meme dashboard for "Battle 12" + And no one should have a claim in "Battle 12" + And no one should be signed up for "Battle 12" + When I go to the collections page + Then I should see "Battle 12" + + Scenario: A user can still access their Sign-ups page after a prompt meme they + were signed up for has been deleted + + Given everyone has signed up for Battle 12 + And the challenge "Battle 12" is deleted + When I am logged in as "myname1" + And I go to myname1's signups page + Then I should see "Challenge Sign-ups for myname1" + And I should not see "Battle 12" + + Scenario: A user can still access their Claims page after a prompt meme they + had an unfulfilled claim in has been deleted + + Given everyone has signed up for Battle 12 + And "myname1" has claimed a prompt from Battle 12 + And the challenge "Battle 12" is deleted + When I am logged in as "myname1" + And I go to myname1's signups page + Then I should see "Challenge Sign-ups for myname1" + And I should not see "Battle 12" + + Scenario: A user can still access their Claims page after a prompt meme they + had a fulfilled claim in has been deleted + + Given everyone has signed up for Battle 12 + And "myname4" has fulfilled a claim from Battle 12 + And the challenge "Battle 12" is deleted + When I am logged in as "myname4" + And I go to myname4's claims page + Then I should see "My Claims" + When I follow "Fulfilled Claims" + Then I should not see "Battle 12" + + Scenario: The prompt line should not show on claim fills after the prompt meme + has been deleted + + Given everyone has signed up for Battle 12 + And "myname1" has fulfilled a claim from Battle 12 + And the challenge "Battle 12" is deleted + When I am logged out + And I view the work "Fulfilled Story" + Then I should not see "In response to a prompt" + + Scenario: A mod can delete a prompt meme collection and all the claims and + sign-ups will be deleted with it + + Given everyone has signed up for Battle 12 + And "myname1" has fulfilled a claim from Battle 12 + And the challenge "Battle 12" is deleted + When I am logged in as "mod1" + And I go to "Battle 12" collection's page + And I follow "Collection Settings" + And I follow "Delete" + Then I should see "Are you sure you want to delete the collection Battle 12?" + When I press "Yes, Delete Collection" + Then I should see "Collection was successfully deleted." + And no one should have a claim in "Battle 12" + And no one should be signed up for "Battle 12" + When I go to the collections page + Then I should not see "Battle 12" + + Scenario: Claim fills should still be accessible even after the prompt meme + collection has been deleted + + Given "AO3-4693" is fixed + # Given I have Battle 12 prompt meme fully set up + # And everyone has signed up for Battle 12 + # And "myname1" has fulfilled a claim from Battle 12 + # And the collection "Battle 12" is deleted + # When I view the work "Fulfilled Story" + # Then I should see "Fulfilled Story" + # TODO: Make an issue + # And I should not see "In response to a prompt" + # And I should not see "Battle 12" + + Scenario: Delete a signup, claims should also be deleted from the prompt + meme's Claims list + + Given "myname1" has signed up for Battle 12 with combination B + And "myname4" has claimed a prompt from Battle 12 + And "myname1" has deleted their sign up for the prompt meme "Battle 12" + When I am logged in as "myname4" + And I go to myname4's claims page + Then I should see "Claims (0)" diff --git a/features/search/exceeding_maximum.feature b/features/search/exceeding_maximum.feature new file mode 100755 index 0000000..c20f328 --- /dev/null +++ b/features/search/exceeding_maximum.feature @@ -0,0 +1,46 @@ +Feature: Large searches + As a user + I want to see how many results my search returns if it's more than the max + + Scenario: Work search should show the correct number of results + Given a set of Kirk/Spock works for searching + And the max search result count is 2 + And 1 item is displayed per page + When I search for works containing "James T. Kirk" + Then I should see "4 Found" + + Scenario: Bookmark search should show the correct number of results + Given I have bookmarks to search + And the max search result count is 2 + And 1 item is displayed per page + When I am on the search bookmarks page + And I select "Work" from "Type" + And I press "Search Bookmarks" + Then I should see "5 Found" + + Scenario: People search should show the correct number of results + Given the following activated users exist + | login | + | test_alice | + | test_betsy | + | test_carol | + | test_diana | + And the max search result count is 2 + And 1 item is displayed per page + And all indexing jobs have been run + When I go to the search people page + And I fill in "Search all fields" with "test" + And I press "Search People" + Then I should see "4 Found" + + Scenario: Tag search should show the correct number of results + Given a canonical freeform "Fluff" + And a canonical freeform "Angst" + And a canonical freeform "Smut" + And a canonical freeform "Alternate Universe" + And the max search result count is 2 + And 1 tag is displayed per search page + When I go to the search tags page + And I choose "Freeform" + And I press "Search Tags" + Then I should see "4 Found" diff --git a/features/search/filters.feature b/features/search/filters.feature new file mode 100755 index 0000000..c0762dc --- /dev/null +++ b/features/search/filters.feature @@ -0,0 +1,354 @@ +@users +Feature: Filters + In order to ensure filtering works on works and bookmarks + As a humble user + I want to filter on a user's works and bookmarks + + Background: + Given a canonical fandom "The Hobbit" + And a canonical fandom "Harry Potter" + And a canonical fandom "Legend of Korra" + And the work "A Hobbit's Meandering" by "meatloaf" with fandom "The Hobbit" + And the work "Bilbo Does the Thing" by "meatloaf" with fandom "The Hobbit, Legend of Korra" + And the work "Roonal Woozlib and the Ferrets of Nimh" by "meatloaf" with fandom "Harry Potter" + And all indexing jobs have been run + And the dashboard counts have expired + And I am logged in as "meatloaf" + + @javascript + Scenario: You can filter through a user's works using inclusion filters + When I go to meatloaf's user page + And I follow "Works (3)" + Then I should see "A Hobbit's Meandering" + And I should see "Bilbo Does the Thing" + And I should see "Roonal Woozlib and the Ferrets of Nimh" + And I should see "Include" + And I should see "Exclude" + When I press "Fandoms" within "dd.include" + Then I should see "The Hobbit (2)" within "#include_fandom_tags" + And I should see "Harry Potter (1)" within "#include_fandom_tags" + And I should see "Legend of Korra (1)" within "#include_fandom_tags" + When I check "The Hobbit (2)" within "#include_fandom_tags" + And I press "Sort and Filter" + Then I should see "A Hobbit's Meandering" + And I should see "Bilbo Does the Thing" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + When I press "Fandoms" within "dd.include" + Then I should see "The Hobbit (2)" within "#include_fandom_tags" + And I should see "Legend of Korra (1)" within "#include_fandom_tags" + And I should not see "Harry Potter (1)" within "#include_fandom_tags" + When I check "Legend of Korra (1)" within "#include_fandom_tags" + And press "Sort and Filter" + Then I should see "Bilbo Does the Thing" + And I should not see "A Hobbit's Meandering" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + When I follow "Clear Filters" + Then I should see "3 Works by meatloaf" + And I should see "A Hobbit's Meandering" + And I should see "Bilbo Does the Thing" + And I should see "Roonal Woozlib and the Ferrets of Nimh" + When I press "Fandoms" within "dd.include" + Then the "The Hobbit (2)" checkbox within "#include_fandom_tags" should not be checked + And the "Legend of Korra (1)" checkbox within "#include_fandom_tags" should not be checked + + @javascript + Scenario: You can filter through a user's works using exclusion filters + When I go to meatloaf's user page + And I follow "Works (3)" + When I press "Fandoms" within "dd.exclude" + Then I should see "The Hobbit (2)" within "#exclude_fandom_tags" + And I should see "Harry Potter (1)" within "#exclude_fandom_tags" + And I should see "Legend of Korra (1)" within "#exclude_fandom_tags" + When I check "Harry Potter (1)" within "#exclude_fandom_tags" + And I press "Sort and Filter" + Then I should see "Bilbo Does the Thing" + And I should see "A Hobbit's Meandering" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + When I press "Fandoms" within "dd.exclude" + Then I should see "The Hobbit (2)" within "#exclude_fandom_tags" + And I should see "Legend of Korra (1)" within "#exclude_fandom_tags" + And I should see "Harry Potter (0)" within "#exclude_fandom_tags" + When I check "Legend of Korra (1)" within "#exclude_fandom_tags" + And I press "Sort and Filter" + Then I should see "A Hobbit's Meandering" + And I should not see "Bilbo Does the Thing" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + When I follow "Clear Filters" + Then I should see "3 Works by meatloaf" + And I should see "A Hobbit's Meandering" + And I should see "Bilbo Does the Thing" + And I should see "Roonal Woozlib and the Ferrets of Nimh" + When I press "Fandoms" within "dd.exclude" + Then the "Legend of Korra (1)" checkbox within "#exclude_fandom_tags" should not be checked + And the "Harry Potter (1)" checkbox within "#exclude_fandom_tags" should not be checked + + @javascript + Scenario: Filter through a user's works with non-existent tags + Given the tag "legend korra" does not exist + And all indexing jobs have been run + + When I go to meatloaf's works page + And I fill in "Other tags to include" with "legend korra" + And I press "Sort and Filter" + Then I should see "1 Work by meatloaf" + And I should see "Bilbo Does the Thing" + And I should not see "A Hobbit's Meandering" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + + When I go to meatloaf's works page + And I fill in "Other tags to exclude" with "legend korra" + And I press "Sort and Filter" + Then I should see "2 Works by meatloaf" + And I should not see "Bilbo Does the Thing" + And I should see "A Hobbit's Meandering" + And I should see "Roonal Woozlib and the Ferrets of Nimh" + + @javascript + Scenario: You can filter through a user's bookmarks using inclusion filters + Given I am logged in as "recengine" + And I bookmark the work "Bilbo Does the Thing" + And I bookmark the work "A Hobbit's Meandering" + And I bookmark the work "Roonal Woozlib and the Ferrets of Nimh" + And the dashboard counts have expired + When I go to recengine's user page + And I follow "Bookmarks (3)" + Then I should see "Bilbo Does the Thing" + And I should see "A Hobbit's Meandering" + And I should see "Roonal Woozlib and the Ferrets of Nimh" + And I should see "Include" + And I should see "Exclude" + When I press "Fandoms" within "dd.include" + Then I should see "The Hobbit (2)" within "#include_fandom_tags" + And I should see "Harry Potter (1)" within "#include_fandom_tags" + And I should see "Legend of Korra (1)" within "#include_fandom_tags" + When I check "The Hobbit (2)" within "#include_fandom_tags" + And I press "Sort and Filter" + Then I should see "A Hobbit's Meandering" + And I should see "Bilbo Does the Thing" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + When I press "Fandoms" within "dd.include" + Then I should see "The Hobbit (2)" within "#include_fandom_tags" + And I should see "Legend of Korra (1)" within "#include_fandom_tags" + And I should not see "Harry Potter (1)" within "#include_fandom_tags" + When I check "Legend of Korra (1)" within "#include_fandom_tags" + And press "Sort and Filter" + Then I should see "Bilbo Does the Thing" + And I should not see "A Hobbit's Meandering" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + + @javascript + Scenario: You can filter through a user's bookmarks using exclusion filters + Given I am logged in as "recengine" + And I bookmark the work "Bilbo Does the Thing" + And I bookmark the work "A Hobbit's Meandering" + And I bookmark the work "Roonal Woozlib and the Ferrets of Nimh" + And the dashboard counts have expired + When I go to recengine's user page + And I follow "Bookmarks (3)" + When I press "Fandoms" within "dd.exclude" + Then the "The Hobbit (2)" checkbox within "#exclude_fandom_tags" should not be checked + And the "Harry Potter (1)" checkbox within "#exclude_fandom_tags" should not be checked + And the "Legend of Korra (1)" checkbox within "#exclude_fandom_tags" should not be checked + When I check "Harry Potter (1)" within "#exclude_fandom_tags" + And I press "Sort and Filter" + Then I should see "Bilbo Does the Thing" + And I should see "A Hobbit's Meandering" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + When I press "Fandoms" within "dd.exclude" + Then the "The Hobbit (2)" checkbox within "#exclude_fandom_tags" should not be checked + And the "Legend of Korra (1)" checkbox within "#exclude_fandom_tags" should not be checked + And the "Harry Potter (0)" checkbox within "#exclude_fandom_tags" should be checked + When I check "Legend of Korra (1)" within "#exclude_fandom_tags" + And I press "Sort and Filter" + Then I should see "A Hobbit's Meandering" + And I should not see "Bilbo Does the Thing" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + + @javascript + Scenario: Filter a user's bookmarks by "Search within results" and "Search bookmarker's tags and notes" + Given I am logged in as "recengine" + And I bookmark the work "Bilbo Does the Thing" with the tags "hobbit" + And I bookmark the work "A Hobbit's Meandering" with the tags "bilbo" + And all indexing jobs have been run + And the dashboard counts have expired + + When I go to recengine's bookmarks page + And I fill in "Search within results" with "bilbo" + And I press "Sort and Filter" + Then I should see "1 Bookmark found by recengine" + And I should see "Bilbo Does the Thing" + And I should not see "A Hobbit's Meandering" + + When I go to recengine's bookmarks page + And I fill in "Search bookmarker's tags and notes" with "bilbo" + And I press "Sort and Filter" + Then I should see "1 Bookmark found by recengine" + And I should see "A Hobbit's Meandering" + And I should not see "Bilbo Does the Thing" + + @javascript + Scenario: Filter a user's bookmarks by bookmarker's tags + Given I am logged in as "recengine" + And I bookmark the work "Bilbo Does the Thing" with the tags "to read,been here" + And I bookmark the work "A Hobbit's Meandering" with the tags "to read" + And I bookmark the work "Roonal Woozlib and the Ferrets of Nimh" with the tags "been here" + And all indexing jobs have been run + And the dashboard counts have expired + + # Use an include checkbox + When I go to recengine's bookmarks page + And I press "Bookmarker's Tags" within "dd.include" + Then the "to read (2)" checkbox within "#include_tag_tags" should not be checked + And the "been here (2)" checkbox within "#include_tag_tags" should not be checked + When I check "to read (2)" within "#include_tag_tags" + And I press "Sort and Filter" + Then I should see "2 Bookmarks by recengine" + And the "to read (2)" checkbox within "#include_tag_tags" should be checked + And I should see "Bilbo Does the Thing" + And I should see "A Hobbit's Meandering" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + + # Use a second include checkbox for bookmarks with both tags + When I check "been here (1)" within "#include_tag_tags" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should see "Bilbo Does the Thing" + + # Use an exclude checkbox + When I go to recengine's bookmarks page + And I press "Bookmarker's Tags" within "dd.exclude" + Then the "to read (2)" checkbox within "#exclude_tag_tags" should not be checked + And the "been here (2)" checkbox within "#exclude_tag_tags" should not be checked + When I check "to read (2)" within "#exclude_tag_tags" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And the "to read (0)" checkbox within "#exclude_tag_tags" should be checked + And I should not see "Bilbo Does the Thing" + And I should not see "A Hobbit's Meandering" + And I should see "Roonal Woozlib and the Ferrets of Nimh" + + # Use a second exclude checkbox for bookmarks with neither tags + When I check "been here (1)" within "#exclude_tag_tags" + And I press "Sort and Filter" + Then I should see "0 Bookmarks by recengine" + + # Use include field + When I go to recengine's bookmarks page + And I fill in "Other bookmarker's tags to include" with "to read" + And I press "Sort and Filter" + Then I should see "2 Bookmarks by recengine" + And I should see "Bilbo Does the Thing" + And I should see "A Hobbit's Meandering" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + + # Use exclude field + When I go to recengine's bookmarks page + And I fill in "Other bookmarker's tags to exclude" with "to read" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should not see "Bilbo Does the Thing" + And I should not see "A Hobbit's Meandering" + And I should see "Roonal Woozlib and the Ferrets of Nimh" + + Scenario: Filter bookmarks by a tag that appears both on bookmarked works and in bookmarker's tags + Given I am logged in as "recengine" + And I bookmark the work "Bilbo Does the Thing" + And I bookmark the work "Roonal Woozlib and the Ferrets of Nimh" with the tags "The Hobbit" + And the dashboard counts have expired + + # Exclude a tag as a work tag but not as a bookmarker's tag + When I go to recengine's bookmarks page + Then the "The Hobbit (1)" checkbox within "#exclude_fandom_tags" should not be checked + And the "The Hobbit (1)" checkbox within "#exclude_tag_tags" should not be checked + + When I check "The Hobbit (1)" within "#exclude_fandom_tags" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should not see "Bilbo Does the Thing" + And I should see "Roonal Woozlib and the Ferrets of Nimh" + And the "The Hobbit (0)" checkbox within "#exclude_fandom_tags" should be checked + And the "The Hobbit (1)" checkbox within "#exclude_tag_tags" should not be checked + + # Exclude a tag as a bookmarker's tag but not as a work tag + When I go to recengine's bookmarks page + And I check "The Hobbit (1)" within "#exclude_tag_tags" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should see "Bilbo Does the Thing" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + And the "The Hobbit (0)" checkbox within "#exclude_tag_tags" should be checked + And the "The Hobbit (1)" checkbox within "#exclude_fandom_tags" should not be checked + + # Exclude a tag as a bookmarker's tag AND as a work tag + When I go to recengine's bookmarks page + And I check "The Hobbit (1)" within "#exclude_fandom_tags" + And I check "The Hobbit (1)" within "#exclude_tag_tags" + And I press "Sort and Filter" + Then I should see "0 Bookmarks by recengine" + And I should not see "Bilbo Does the Thing" + And I should not see "Roonal Woozlib and the Ferrets of Nimh" + And the "The Hobbit (0)" checkbox within "#exclude_fandom_tags" should be checked + And the "The Hobbit (0)" checkbox within "#exclude_tag_tags" should be checked + + @javascript + Scenario: Filter a user's bookmarks by non-existent tags + Given the tag "legend korra" does not exist + And the tag "fun crossover" does not exist + And I am logged in as "recengine" + And I bookmark the work "A Hobbit's Meandering" with the tags "fun" + And I bookmark the work "Bilbo Does the Thing" with the tags "fun little crossover" + And all indexing jobs have been run + And the dashboard counts have expired + + When I go to recengine's bookmarks page + And I fill in "Other work tags to include" with "legend korra" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should not see "A Hobbit's Meandering" + And I should see "Bilbo Does the Thing" + + When I go to recengine's bookmarks page + And I fill in "Other work tags to exclude" with "legend korra" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should see "A Hobbit's Meandering" + And I should not see "Bilbo Does the Thing" + + When I go to recengine's bookmarks page + And I fill in "Other bookmarker's tags to include" with "fun crossover" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should not see "A Hobbit's Meandering" + And I should see "Bilbo Does the Thing" + + When I go to recengine's bookmarks page + And I fill in "Other bookmarker's tags to exclude" with "fun crossover" + And I press "Sort and Filter" + Then I should see "1 Bookmark by recengine" + And I should see "A Hobbit's Meandering" + And I should not see "Bilbo Does the Thing" + + @javascript + Scenario: Tag bookmark pages should display bookmarked items instead of bookmarks, and the sidebar counts should reflect that. + Given I am logged in as "meatloaf" + And I bookmark the work "Bilbo Does the Thing" + And I bookmark the work "A Hobbit's Meandering" + And I am logged out + And I am logged in as "anothermeatloaf" + And I bookmark the work "Bilbo Does the Thing" + And I bookmark the work "A Hobbit's Meandering" + And all indexing jobs have been run + When I go to the bookmarks tagged "The Hobbit" + Then I should see "2 Bookmarked Items in The Hobbit" + When I follow "Fandoms" + Then I should see "The Hobbit (2)" + + Scenario: Filtering with an invalid query while excluding a tag + When I go to meatloaf's user page + And I follow "Works (3)" + When I check "Harry Potter (1)" within "#exclude_fandom_tags" + And I press "Sort and Filter" + Then I should see "Bilbo Does the Thing" + When I fill in "work_search_query" with "bad~query!!!" + And I press "Sort and Filter" + Then I should see "Your search failed because of a syntax error" diff --git a/features/search/people_search.feature b/features/search/people_search.feature new file mode 100755 index 0000000..cb60954 --- /dev/null +++ b/features/search/people_search.feature @@ -0,0 +1,130 @@ +Feature: Search pseuds + As a user + I want to use search to find other users + + Scenario: Search by name + Given the following activated users exists + | login | + | testuser | + | sad_user_with_no_pseuds | + And "testuser" has the pseud "testy" + And "testuser" has the pseud "tester_pseud" + And "testuser" has the pseud "testymctesty" + And I am logged in as "testuser" + When I go to the search people page + And I fill in "Name" with "testuser" + And I press "Search People" + Then I should see "testy" + And I should not see "sad_user_with_no_pseuds" + + When I fill in "Search all fields" with "test" + And I press "Search People" + Then I should see "0 Found" + + When I fill in "Search all fields" with "test*" + And I press "Search People" + Then I should see "4 Found" + And I should see "testy" + And I should not see "sad_user_with_no_pseuds" + + Scenario: Search by fandom + Given a canonical fandom "Ghost Soup" + And a canonical fandom "Bread" + And the work "soup" by "testuser2" with fandom "Ghost Soup" + And the work "toast" by "testy" with fandom "Bread" + And all indexing jobs have been run + And I am logged in as "testuser" + When I go to the search people page + And I fill in "Fandom" with "Ghost Soup" + And I press "Search People" + Then I should see "testuser2" + And I should not see "testy" + + Scenario: Search by fandom updates when a work is posted. + Given a canonical fandom "Ghost Soup" + And I am logged in as "testuser" + When I post a work "Drabble Collection" with fandom "Ghost Soup" + And all indexing jobs have been run + And I go to the search people page + And I fill in "Fandom" with "Ghost Soup" + And I press "Search People" + Then I should see "testuser" within "ol.pseud.group" + + Scenario: Search by fandom updates when a fandom is added to a work. + Given a canonical fandom "Ghost Soup" + And I am logged in as "testuser" + And I post the work "Drabble Collection" with fandom "MCU" + And all indexing jobs have been run + When I edit the work "Drabble Collection" + And I fill in "Fandom" with "MCU, Ghost Soup" + And I press "Post" + And all indexing jobs have been run + And I go to the search people page + And I fill in "Fandom" with "Ghost Soup" + And I press "Search People" + Then I should see "testuser" within "ol.pseud.group" + + Scenario: Search by fandom updates when a fandom is removed from a work. + Given a canonical fandom "Ghost Soup" + And I am logged in as "testuser" + And I post the work "Drabble Collection" with fandom "MCU, Ghost Soup" + And all indexing jobs have been run + When I edit the work "Drabble Collection" + And I fill in "Fandom" with "MCU" + And I press "Post" + And all indexing jobs have been run + And I go to the search people page + And I fill in "Fandom" with "Ghost Soup" + And I press "Search People" + Then I should not see "testuser" within "ol.pseud.group" + + Scenario: Search by fandom updates when an author is added to a work. + Given a canonical fandom "Ghost Soup" + And I am logged in as "testuser" + And I post the work "Drabble Collection" with fandom "Ghost Soup" + And all indexing jobs have been run + When I edit the work "Drabble Collection" + And I invite the co-author "alice" + And I press "Post" + And all indexing jobs have been run + And I go to the search people page + And I fill in "Fandom" with "Ghost Soup" + And I press "Search People" + Then I should see "testuser" within "ol.pseud.group" + But I should not see "alice" within "ol.pseud.group" + When the user "alice" accepts all co-creator requests + And all indexing jobs have been run + And I go to the search people page + And I fill in "Fandom" with "Ghost Soup" + And I press "Search People" + Then I should see "testuser" within "ol.pseud.group" + And I should see "alice" within "ol.pseud.group" + + Scenario: Search by fandom updates when an author is removed from a work. + Given a canonical fandom "Ghost Soup" + And I am logged in as "testuser" + And I post the work "Drabble Collection" with fandom "Ghost Soup" + And I add the co-author "alice" to the work "Drabble Collection" + And all indexing jobs have been run + When I edit the work "Drabble Collection" + And I press "Remove Me As Co-Creator" + And all indexing jobs have been run + And I go to the search people page + And I fill in "Fandom" with "Ghost Soup" + And I press "Search People" + Then I should see "alice" within "ol.pseud.group" + But I should not see "testuser" within "ol.pseud.group" + + Scenario: Search by fandom updates when a work is orphaned. + Given a canonical fandom "Ghost Soup" + And I have an orphan account + And I am logged in as "testuser" + And I post the work "Drabble Collection" with fandom "Ghost Soup" + And all indexing jobs have been run + When I orphan the work "Drabble Collection" + And all indexing jobs have been run + And I go to the search people page + And I fill in "Fandom" with "Ghost Soup" + And I press "Search People" + Then I should see "orphan_account" within "ol.pseud.group" + But I should not see "testuser" within "ol.pseud.group" diff --git a/features/search/works_anonymous.feature b/features/search/works_anonymous.feature new file mode 100755 index 0000000..2075aa9 --- /dev/null +++ b/features/search/works_anonymous.feature @@ -0,0 +1,59 @@ +@works @search +Feature: Search anonymous works + As a creator of anonymous works + I do not want searching for my name to ruin my anonymity + But I do want my works to appear in searches + + Scenario: Works that are anonymous do not show up in searches for the + creator's name + Given I have the anonymous collection "Battle 12" + And I am logged in as "moderator" + And I post the work "Fulfilled Story-thing" in the collection "Battle 12" + When I search for works containing "moderator" + Then I should see "You searched for: moderator" + And I should see "No results found" + When I search for works by "moderator" + Then I should see "You searched for: creator: moderator" + And I should see "No results found" + + Scenario: Works that are anonymous should show up in searches for the + creator Anonymous + Given I have the anonymous collection "Battle 12" + And I am logged in as "moderator" + And I post the work "Fulfilled Story-thing" in the collection "Battle 12" + When I search for works containing "Anonymous" + Then I should see "You searched for: Anonymous" + And I should see "1 Found" + And I should see "Fulfilled Story-thing" + When I search for works by "Anonymous" + Then I should see "You searched for: creator: Anonymous" + And I should see "1 Found" + And I should see "Fulfilled Story-thing" + When I go to the search works page + And I fill in "Creator" with "Anonymous" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Creator: Anonymous" + And I should see "1 Found" + And I should see "Fulfilled Story-thing" + + Scenario: Works that used to be anonymous show up in searches for the + creator's name once the creator is revealed + Given I have the anonymous collection "Battle 12" + And I am logged in as "moderator" + And I post the work "Fulfilled Story-thing" in the collection "Battle 12" + And I reveal authors for "Battle 12" + And all indexing jobs have been run + When I search for works containing "moderator" + Then I should see "You searched for: moderator" + And I should see "1 Found" + And I should see "Fulfilled Story-thing" + When I search for works by "moderator" + Then I should see "You searched for: creator: moderator" + And I should see "1 Found" + And I should see "Fulfilled Story-thing" + When I go to the search works page + And I fill in "Creator" with "moderator" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Creator: moderator" + And I should see "1 Found" + And I should see "Fulfilled Story-thing" diff --git a/features/search/works_collected.feature b/features/search/works_collected.feature new file mode 100755 index 0000000..3fcd071 --- /dev/null +++ b/features/search/works_collected.feature @@ -0,0 +1,48 @@ +Feature: Search collected works + As a creator of collected works + I want to filter for works across all those collections + + Scenario: Works that are collected show up in the creator's + collected works page + Given I am logged in as "author" + And I create the collection "Author Collection" + And I create the collection "Other Collection" + And I post the work "Old Title" to the collection "Author Collection" + And I wait 1 second + And I post the work "Revised Title" to the collection "Author Collection" + And I wait 1 second + And I post the work "New Title" to the collection "Other Collection" + And I wait 1 second + And I post a chapter for the work "Revised Title" + When I go to author's user page + And I follow "Works (3)" + And I follow "Works in Collections" + Then I should see "Works in Challenges/Collections" + And "Date Updated" should be selected within "Sort by" + And "Revised Title" should appear before "New Title" + And "New Title" should appear before "Old Title" + When I select "Title" from "Sort by" + And I press "Sort and Filter" + Then "Title" should be selected within "Sort by" + And "New Title" should appear before "Old Title" + And "Old Title" should appear before "Revised Title" + When I select "Date Posted" from "Sort by" + And I press "Sort and Filter" + Then "Date Posted" should be selected within "Sort by" + And "New Title" should appear before "Revised Title" + And "Revised Title" should appear before "Old Title" + When I check "Author Collection" + And I check "Other Collection" + And I press "Sort and Filter" + Then the "Author Collection" checkbox should be checked + And the "Other Collection" checkbox should be checked + And I should see "New Title" + And I should see "Revised Title" + And I should see "Old Title" + When I uncheck "Other Collection" + And I press "Sort and Filter" + Then the "Author Collection" checkbox should be checked + And I should not see "Other Collection" + And I should not see "New Title" + And I should see "Revised Title" + And I should see "Old Title" diff --git a/features/search/works_info.feature b/features/search/works_info.feature new file mode 100755 index 0000000..52c9b73 --- /dev/null +++ b/features/search/works_info.feature @@ -0,0 +1,145 @@ +@works @search +Feature: Search works by work info + As a user + I want to search works by work info + + Scenario: Inputting bad queries + When I am on the homepage + When I fill in "site_search" with "bad~query!!!" + And I press "Search" + Then I should see "Your search failed because of a syntax error" + + Scenario: Search by language + Given a set of old multilanguage works for searching + When I am on the search works page + And I select "Deutsch" from "Language" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Language: Deutsch" + And I should see "1 Found" + And I should see "My <strong>er German Work" + And the 1st result should contain "Language: Deutsch" + When I follow "Edit Your Search" + Then "Deutsch" should be selected within "Language" + + Scenario: Search by date and then refine by word count + Given a set of old multilanguage works for searching + When I am on the search works page + And I fill in "Date" with "> 2 years ago" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: revised at: > 2 years ago" + And I should see "2 Found" + And I should see "My <strong>er German Work" + And I should see "unfinished" + When I follow "Edit Your Search" + Then I should be on the search works page + And the field labeled "Date" should contain "> 2 years ago" + When I fill in "Word Count" with ">15000" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: word count: >15000 revised at: > 2 years ago" + And I should see "No results found" + + Scenario: Search with the header search field and then refine by creator + Given a set of old multilanguage works for searching + And I am logged in as "searcher" + When I fill in "site_search" with "testuser2" + And I press "Search" + Then I should see "You searched for: testuser2" + And I should see "1 Found" + And I should see "My <strong>er German Work" + When I follow "Edit Your Search" + Then I should be on the search works page + And the field labeled "Any Field" should contain "testuser2" + When I fill in "Any Field" with "" + And I fill in "Creator" with "testuser2" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Creator: testuser2" + And I should see "1 Found" + And I should see "My <strong>er German Work" + + Scenario: Search by status + Given a set of old multilanguage works for searching + When I am on the search works page + And I choose "Complete works only" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Complete" + And I should see "1 Found" + And I should see "My <strong>er German Work" + When I am on the search works page + And I choose "Works in progress only" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Incomplete" + And I should see "1 Found" + And I should see "unfinished" + + Scenario: Search by crossovers + Given a set of crossover works for searching + When I am on the search works page + And I choose "Exclude crossovers" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: No Crossovers" + And I should see "5 Found" + But I should not see "Work With Multiple Fandoms" + When I am on the search works page + And I choose "Only crossovers" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Only Crossovers" + And I should see "3 Found" + And I should see "First Work With Multiple Fandoms" + And I should see "Second Work With Multiple Fandoms" + And I should see "Third Work With Multiple Fandoms" + + Scenario: Search by single chapter + Given a set of old multilanguage works for searching + When I am on the search works page + And I check "Single Chapter" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Single Chapter" + And I should see "1 Found" + And I should see "My <strong>er German Work" + When I follow "Edit Your Search" + Then the "Single Chapter" checkbox should be checked + + Scenario: Search and sort by title + Given the work "First work" + And the work "second work (2 of 6)" + And the work "third work" + And all indexing jobs have been run + When I am on the search works page + And I fill in "Title" with "work" + And I select "Title" from "Sort by" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Title: work sort by: title descending" + And I should see "3 Found" + And the 1st result should contain "third work" + And the 2nd result should contain "second work" + And the 3rd result should contain "First work" + When I follow "Edit Your Search" + Then the field labeled "Title" should contain "work" + And "Title" should be selected within "Sort by" + When I select "Ascending" from "Sort direction" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Title: work sort by: title ascending" + And I should see "3 Found" + And the 1st result should contain "First work" + And the 2nd result should contain "second work" + And the 3rd result should contain "third work" + When I follow "Edit Your Search" + Then the field labeled "Title" should contain "work" + And "Title" should be selected within "Sort by" + And "Ascending" should be selected within "Sort direction" + + Scenario: Search by number in title + Given the work "First work" + And the work "second work (2 of 6)" + And all indexing jobs have been run + When I am on the search works page + And I fill in "Title" with "work 2 6" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Title: work 2 6" + And I should see "1 Found" + And the 1st result should contain "second work (2 of 6)" + When I am on the search works page + And I fill in "Title" with "work 1" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Title: work 1" + And I should see "No results found" diff --git a/features/search/works_restricted.feature b/features/search/works_restricted.feature new file mode 100755 index 0000000..cdc3b9d --- /dev/null +++ b/features/search/works_restricted.feature @@ -0,0 +1,47 @@ +@works @search +Feature: Search restricted works + As a user + I want search results to only include works I can access + + Scenario: Search results for logged out users should contain only posted works + that are public; they should not contain works that are drafts, restricted to + registered users, or hidden by an admin + Given a set of works with various access levels for searching + And I am a visitor + When I search for works containing "Work" + Then I should see "You searched for: Work" + And I should see "1 Found" + And I should see "Posted Work" + And I should not see "Restricted Work" + And I should not see "Work Hidden by Admin" + And I should not see "Draft Work" + + Scenario: Search results for logged in users should contain only posted works + that are public or restricted to registered users; they should not contain + drafts or works hidden by an admin + Given a set of works with various access levels for searching + And I am logged in as a random user + When I search for works containing "Work" + Then I should see "You searched for: Work" + And I should see "2 Found" + And I should see "Posted Work" + And I should see "Restricted Work" + And I should not see "Work Hidden by Admin" + And I should not see "Draft Work" + + Scenario: Searching for restricted works only returns results for logged in + users or admins + Given a set of works with various access levels for searching + And I am logged in as a random user + When I search for works containing "restricted: true" + Then I should see "You searched for: restricted: true" + And I should see "1 Found" + And the results should contain only the restricted work + When I log out + And I search for works containing "restricted: true" + Then I should see "You searched for: restricted: true" + And I should see "No results found." + When I am logged in as an admin + And I search for works containing "restricted: true" + Then I should see "1 Found" + And the results should contain only the restricted work diff --git a/features/search/works_stats.feature b/features/search/works_stats.feature new file mode 100755 index 0000000..ed5b9ad --- /dev/null +++ b/features/search/works_stats.feature @@ -0,0 +1,233 @@ +@works @search +Feature: Search works by stats + As a user + I want to search works by hits, kudos, comments, and bookmarks + + Scenario: Search by range of hits + Given a set of works with stats for searching + When I am on the search works page + And I fill in "Hits" with "10000-20000" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: hits: 10000-20000" + And I should see "1 Found" + And the 1st result should contain "Hits: 10,000" + And I should see "many" + When I follow "Edit Your Search" + Then the field labeled "Hits" should contain "10000-20000" + + Scenario: Search by > hits + Given a set of works with stats for searching + When I am on the search works page + And I fill in "Hits" with "> 100" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: hits: > 100" + And I should see "2 Found" + And I should see "many" + And I should see "less" + When I follow "Edit Your Search" + Then the field labeled "Hits" should contain "> 100" + + Scenario: Search and sort by kudos + Given a set of works with stats for searching + When I am on the search works page + And I fill in "Kudos" with ">0" + And I select "Kudos" from "Sort by" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: kudos count: >0 sort by: kudos descending" + And I should see "2 Found" + And the 1st result should contain "Kudos: 4" + And the 2nd result should contain "Kudos: 1" + When I follow "Edit Your Search" + Then the field labeled "Kudos" should contain ">0" + And "Kudos" should be selected within "Sort by" + When I fill in "Kudos" with "5" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: kudos count: 5 sort by: kudos descending" + And I should see "No results found" + When I follow "Edit Your Search" + Then the field labeled "Kudos" should contain "5" + When I fill in "Kudos" with "4" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: kudos count: 4 sort by: kudos descending" + And I should see "1 Found" + And the 1st result should contain "Kudos: 4" + And I should see "many" + When I follow "Edit Your Search" + Then the field labeled "Kudos" should contain "4" + When I fill in "Kudos" with "<2" + And I select "Ascending" from "Sort direction" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: kudos count: <2 sort by: kudos ascending" + And I should see "3 Found" + And I should see "unfinished" + And I should see "none" + And I should see "less" + And the 3rd result should contain "Kudos: 1" + When I follow "Edit Your Search" + Then the field labeled "Kudos" should contain "<2" + And "Kudos" should be selected within "Sort by" + And "Ascending" should be selected within "Sort direction" + When I choose "Complete works only" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Complete kudos count: <2 sort by: kudos ascending" + And I should see "2 Found" + And I should see "none" + And I should see "less" + And the 2nd result should contain "Kudos: 1" + When I follow "Edit Your Search" + Then the field labeled "Kudos" should contain "<2" + And the "Complete works only" checkbox should be checked + And "Ascending" should be selected within "Sort direction" + + Scenario: Search by exact number of comments + Given a set of works with comments for searching + When I am on the search works page + And I fill in "Comments" with "1" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: comments count: 1" + And I should see "3 Found" + When I follow "Edit Your Search" + Then the field labeled "Comments" should contain "1" + + Scenario: Search by a range of comments + Given a set of works with comments for searching + When I am on the search works page + And I fill in "Comments" with "1-5" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: comments count: 1-5" + And I should see "5 Found" + When I follow "Edit Your Search" + Then the field labeled "Comments" should contain "1-5" + + Scenario: Search by > a number of comments and sort in ascending order by + comments + Given a set of works with comments for searching + When I am on the search works page + And I fill in "Comments" with "> 0" + And I select "Comments" from "Sort by" + And I select "Ascending" from "Sort direction" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: comments count: > 0 sort by: comments ascending" + And I should see "6 Found" + And the 1st result should contain "Comments: 1" + And the 2nd result should contain "Comments: 1" + And the 3rd result should contain "Comments: 1" + And the 4th result should contain "Comments: 3" + And the 5th result should contain "Comments: 3" + And the 6th result should contain "Comments: 10" + When I follow "Edit Your Search" + Then the field labeled "Comments" should contain "> 0" + And "Comments" should be selected within "Sort by" + And "Ascending" should be selected within "Sort direction" + + Scenario: Search by < a number of comments and sort in descending order by + comments + Given a set of works with comments for searching + When I am on the search works page + And I fill in "Comments" with "<20" + And I select "Comments" from "Sort by" + And I select "Descending" from "Sort direction" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: comments count: <20 sort by: comments descending" + And I should see "7 Found" + And the 1st result should contain "Comments: 10" + And the 2nd result should contain "Comments: 3" + And the 3rd result should contain "Comments: 3" + And the 4th result should contain "Comments: 1" + And the 5th result should contain "Comments: 1" + And the 6th result should contain "Comments: 1" + When I follow "Edit Your Search" + Then the field labeled "Comments" should contain "<20" + And "Comments" should be selected within "Sort by" + And "Descending" should be selected within "Sort direction" + + Scenario: Search by > a number of comments and sort in ascending order by + title using the header search + Given a set of works with comments for searching + When I am on the home page + And I fill in "site_search" with "comments: > 2 sort: title ascending" + And I press "Search" + Then I should see "You searched for: comments count: > 2 sort by: title ascending" + And I should see "3 Found" + And the 1st result should contain "Work 5" + And the 2nd result should contain "Work 6" + And the 3rd result should contain "Work 7" + When I follow "Edit Your Search" + Then the field labeled "Comments" should contain "> 2" + And "Title" should be selected within "Sort by" + And "Ascending" should be selected within "Sort direction" + + Scenario: Search by exact number of bookmarks + Given a set of works with bookmarks for searching + When I am on the search works page + And I fill in "Bookmarks" with "1" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: bookmarks count: 1" + And I should see "2 Found" + When I follow "Edit Your Search" + Then the field labeled "Bookmarks" should contain "1" + + Scenario: Search by a range of bookmarks + Given a set of works with bookmarks for searching + When I am on the search works page + And I fill in "Bookmarks" with "2 - 5" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: bookmarks count: 2 - 5" + And I should see "3 Found" + When I follow "Edit Your Search" + Then the field labeled "Bookmarks" should contain "2 - 5" + + Scenario: Search by > a number of bookmarks and sort in ascending order by + bookmarks + Given a set of works with bookmarks for searching + When I am on the search works page + And I fill in "Bookmarks" with ">1" + And I select "Bookmarks" from "Sort by" + And I select "Ascending" from "Sort direction" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: bookmarks count: >1 sort by: bookmarks ascending" + And I should see "4 Found" + And the 1st result should contain "Bookmarks: 2" + And the 2nd result should contain "Bookmarks: 2" + And the 3rd result should contain "Bookmarks: 4" + And the 4th result should contain "Bookmarks: 10" + When I follow "Edit Your Search" + Then the field labeled "Bookmarks" should contain ">1" + And "Bookmarks" should be selected within "Sort by" + And "Ascending" should be selected within "Sort direction" + + Scenario: Search by < a number of bookmarks and sort in descending order by + bookmarks + Given a set of works with bookmarks for searching + When I am on the search works page + And I fill in "Bookmarks" with "< 20" + And I select "Bookmarks" from "Sort by" + And I select "Descending" from "Sort direction" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: bookmarks count: < 20 sort by: bookmarks descending" + And I should see "7 Found" + And the 1st result should contain "Bookmarks: 10" + And the 2nd result should contain "Bookmarks: 4" + And the 3rd result should contain "Bookmarks: 2" + And the 4th result should contain "Bookmarks: 2" + And the 5th result should contain "Bookmarks: 1" + And the 6th result should contain "Bookmarks: 1" + When I follow "Edit Your Search" + Then the field labeled "Bookmarks" should contain "< 20" + And "Bookmarks" should be selected within "Sort by" + And "Descending" should be selected within "Sort direction" + + Scenario: Search by > a number of bookmarks and sort in ascending order by + title using the header search + Given a set of works with bookmarks for searching + When I am on the home page + And I fill in "site_search" with "bookmarks: > 2 sort by: title ascending" + And I press "Search" + Then I should see "You searched for: bookmarks count: > 2 sort by: title ascending" + And I should see "2 Found" + And the 1st result should contain "Work 6" + And the 2nd result should contain "Work 7" + When I follow "Edit Your Search" + Then the field labeled "Bookmarks" should contain "> 2" + And "Title" should be selected within "Sort by" + And "Ascending" should be selected within "Sort direction" diff --git a/features/search/works_tags.feature b/features/search/works_tags.feature new file mode 100755 index 0000000..fb8d3b5 --- /dev/null +++ b/features/search/works_tags.feature @@ -0,0 +1,304 @@ +@works @search +Feature: Search works by tag + As a user + I want to search works by tags + + Scenario: Searching for a fandom in the header search returns works with (a) + the exact tag, (b) the tag's syns, (c) the tag's subtags and _their_ syns, and + (d) any other tags or text matching the search term; refining the search with + the fandom field returns only works with (a), (b), or (c) + Given a set of Star Trek works for searching + When I search for works containing "Star Trek" + Then I should see "You searched for: Star Trek" + And I should see "6 Found" + And the results should contain the fandom tag "Star Trek" + And the results should contain the subtags of "Star Trek" + # A synonym of one of the Star Trek subtags + And the results should contain the fandom tag "ST: TOS" + And the results should contain a freeform mentioning "Star Trek" + When I follow "Edit Your Search" + Then the field labeled "Any Field" should contain "Star Trek" + When I fill in "Fandoms" with "Star Trek" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Star Trek Tags: Star Trek" + And I should see "5 Found" + And the results should contain the fandom tag "Star Trek" + And the results should contain the subtags of "Star Trek" + # A synonym of one of the Star Trek subtags + And the results should contain the fandom tag "ST: TOS" + And the results should not contain a freeform mentioning "Star Trek" + When I follow "Edit Your Search" + Then the field labeled "Any Field" should contain "Star Trek" + And the field labeled "Fandoms" should contain "Star Trek" + + Scenario: Searching by fandom for a tag that does not exist returns 0 results + Given a set of Star Trek works for searching + When I am on the search works page + And I fill in "Fandoms" with "Star Trek: The Next Generation" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: Star Trek: The Next Generation" + And I should see "No results found." + And I should see "You may want to edit your search to make it less specific." + + # We use JavaScript here because otherwise there is a minor spacing issue with + # "You searched for" on the results page and the coder who wrote this test was + # offended by it + @javascript + Scenario: Searching by fandom for two fandoms returns only works tagged with + both fandoms (or syns or subtags of those fandoms) + Given a set of Star Trek works for searching + When I am on the search works page + And I fill in "Fandoms" with "Star Trek, Battlestar Galactica (2003)" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: Star Trek, Battlestar Galactica (2003)" + And I should see "1 Found" + # A synonym of one of the Star Trek subtags + And the results should contain the fandom tag "ST: TOS" + And the results should contain the fandom tag "Battlestar Galactica (2003)" + When I follow "Edit Your Search" + Then "Star Trek" should already be entered in the work search fandom autocomplete field + And "Battlestar Galactica (2003)" should already be entered in the work search fandom autocomplete field + + Scenario: Searching by rating returns only works using that rating + Given a set of works with various ratings for searching + When I am on the search works page + And I select "Teen And Up Audiences" from "Rating" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: Teen And Up Audiences" + And I should see "1 Found" + And the results should contain the rating tag "Teen And Up Audiences" + When I follow "Edit Your Search" + Then "Teen And Up Audiences" should be selected within "Rating" + + Scenario: Searching for Explicit or Mature in the header returns works with + (a) either rating or (b) other tags or text matching either rating; editing + the search to use the ratings' filter_ids returns only (a) + Given a set of works with various ratings for searching + When I search for works containing "Mature || Explicit" + Then I should see "You searched for: Mature || Explicit" + And I should see "3 Found" + And the results should contain the rating tag "Mature" + And the results should contain the rating tag "Explicit" + And the results should contain a summary mentioning "explicit" + When I follow "Edit Your Search" + Then the field labeled "Any Field" should contain "Mature || Explicit" + When I exclude the tags "Mature" and "Explicit" by filter_id + And I press "Search" within "#new_work_search" + Then the search summary should include the filter_id for "Mature" + And the search summary should include the filter_id for "Explicit" + And the results should not contain the rating tag "Mature" + And the results should not contain the rating tag "Explicit" + + Scenario: Using Any Field to exclude works using (a) one of the two ratings or (b) other tags or text matching either rating + Given a set of works with various ratings for searching + When I am on the search works page + And I fill in "Any Field" with "-Mature -Explicit" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: -Mature -Explicit" + And I should see "3 Found" + And the results should contain the rating tag "General Audiences" + And the results should contain the rating tag "Teen And Up Audiences" + And the results should contain the rating tag "Not Rated" + And the results should not contain a summary mentioning "explicit" + When I follow "Edit Your Search" + Then the field labeled "Any Field" should contain "-Mature -Explicit" + + Scenario: Searching by warning returns all works using that warning tag + Given a set of works with various warnings for searching + When I am on the search works page + And I check "No Archive Warnings Apply" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: No Archive Warnings Apply" + And I should see "2 Found" + And the 1st result should contain "No Archive Warnings Apply" + And the 2nd result should contain "No Archive Warnings Apply" + When I follow "Edit Your Search" + Then the "No Archive Warnings Apply" checkbox should be checked + + Scenario: Using the header search to exclude works with certain warnings using the warnings' filter_ids + Given a set of works with various warnings for searching + When I search for works without the "Rape/Non-Con" and "Underage Sex" filter_ids + Then the search summary should include the filter_id for "Rape/Non-Con" + And the search summary should include the filter_id for "Underage Sex" + And I should see "5 Found" + And the results should not contain the warning tag "Underage Sex" + And the results should not contain the warning tag "Rape/Non-Con" + + Scenario: Searching by category returns all works using that category; search + can be refined using Any Field to return works using only that category + Given a set of works with various categories for searching + When I am on the search works page + And I check "F/F" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: F/F" + And I should see "2 Found" + And the results should contain the category tag "F/F" + And the results should contain the category tag "M/M, F/F" + When I follow "Edit Your Search" + Then the "F/F" checkbox should be checked + When I fill in "Any Field" with "-M/M" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: -M/M Tags: F/F" + And I should see "1 Found" + + Scenario: Searching by category for Multi only returns works tagged with the + Multi category, not works tagged with multiple categories + Given a set of works with various categories for searching + When I am on the search works page + And I check "Multi" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: Multi" + And I should see "1 Found" + And the results should contain the category tag "Multi" + And the results should not contain the category tag "M/M, F/F" + When I follow "Edit Your Search" + Then the "Multi" checkbox should be checked + + Scenario: Searching for a character in the header search returns works with + (a) the exact tag, (b) the tag's syns, or (c) any other tags or text matching + the search term + Given a set of Steve Rogers works for searching + When I search for works containing "Steve Rogers" + Then I should see "You searched for: Steve Rogers" + And I should see "6 Found" + And the results should contain the character tag "Steve Rogers" + And the results should contain a synonym of "Steve Rogers" + And the results should contain a relationship mentioning "Steve Rogers" + And the results should contain a summary mentioning "Steve Rogers" + When I follow "Edit Your Search" + Then the field labeled "Any Field" should contain "Steve Rogers" + + Scenario: Searching by character for a tag with synonyms returns works using + the exact tag or its synonyms + Given a set of Steve Rogers works for searching + When I am on the search works page + And I fill in "Characters" with "Steve Rogers" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: Steve Rogers" + And I should see "4 Found" + And the results should contain the character tag "Steve Rogers" + And the results should contain a synonym of "Steve Rogers" + And the results should not contain a relationship mentioning "Steve Rogers" + And the results should not contain a summary mentioning "Steve Rogers" + When I follow "Edit Your Search" + Then the field labeled "Characters" should contain "Steve Rogers" + + Scenario: Searching for a relationship in the header search returns works + with (a) the exact tag and (b) the tag's syns, and (c) any other tags or text + matching the search term (e.g. a threesome); refining the search with the + relationship field returns only (a) or (b) + Given a set of Spock/Uhura works for searching + When I search for works containing "Spock/Nyota Uhura" + Then I should see "You searched for: Spock/Nyota Uhura" + And I should see "3 Found" + And the results should contain the relationship tag "Spock/Nyota Uhura" + And the results should contain a synonym of "Spock/Nyota Uhura" + And the results should contain the relationship tag "James T. Kirk/Spock/Nyota Uhura" + When I follow "Edit Your Search" + Then the field labeled "Any Field" should contain "Spock/Nyota Uhura" + When I fill in "Relationships" with "Spock/Nyota Uhura" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Spock/Nyota Uhura Tags: Spock/Nyota Uhura" + And I should see "2 Found" + And the results should contain the relationship tag "Spock/Nyota Uhura" + And the results should contain a synonym of "Spock/Nyota Uhura" + And the results should not contain the relationship tag "James T. Kirk/Spock/Nyota Uhura" + + Scenario: Searching by relationship returns works using the exact tag or its + synonyms + Given a set of Kirk/Spock works for searching + When I am on the search works page + And I fill in "Relationships" with "James T. Kirk/Spock" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: James T. Kirk/Spock" + And I should see "4 Found" + And the results should contain the relationship tag "James T. Kirk/Spock" + And the results should contain the synonyms of "James T. Kirk/Spock" + When I follow "Edit Your Search" + Then the field labeled "Relationships" should contain "James T. Kirk/Spock" + + Scenario: Searching by otp: true returns works with one relationship tag or + multiple synonymous relationship tags. + Given a set of Ed Stede works for searching + When I am on the search works page + And I fill in "Any Field" with "otp: true" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: otp: true" + And I should see "3 Found" + But I should not see "The Work Without a Relationship" + And I should not see "The Work With Multiple Ships" + When I follow "Edit Your Search" + Then the field labeled "Any Field" should contain "otp: true" + + Scenario: Searching by relationship and category returns only works using the + category and the exact relationship tag or its synonyms + Given a set of Kirk/Spock works for searching + When I am on the search works page + And I fill in "Relationships" with "James T. Kirk/Spock" + And I check "F/M" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: F/M, James T. Kirk/Spock" + And I should see "1 Found" + And the results should contain the category tag "F/M" + And the results should contain the relationship tag "Spirk" + When I follow "Edit Your Search" + Then the field labeled "Relationships" should contain "James T. Kirk/Spock" + And the "F/M" checkbox should be checked + + Scenario: Searching by additional tags (freeforms) for a metatag with synonyms + and subtags should return works using (a) the exact tag, (b) its synonyms, (c) + its subtags, and (d) its subtags' synonyms + Given a set of alternate universe works for searching + When I am on the search works page + And I fill in "Additional Tags" with "Alternate Universe" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: Alternate Universe" + And I should see "4 Found" + And the results should contain the freeform tag "Alternate Universe" + And the results should contain a synonym of "Alternate Universe" + And the results should contain the freeform tag "High School AU" + And the results should contain the freeform tag "Alternate Universe - Coffee Shops & Cafés" + And the results should not contain the freeform tag "Coffee Shop AU" + When I follow "Edit Your Search" + Then the field labeled "Additional Tags" should contain "Alternate Universe" + + Scenario: Searching by additional tags (freeforms) for a synonym of a metatag + returns only works using the exact tag + Given a set of alternate universe works for searching + When I am on the search works page + And I fill in "Additional Tags" with "AU" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: AU" + And I should see "1 Found" + And the results should contain the freeform tag "AU" + And the results should not contain the freeform tag "High School AU" + And the results should not contain the freeform tag "Coffee Shop AU" + And the results should not contain a character mentioning "AU" + When I follow "Edit Your Search" + Then the field labeled "Additional Tags" should contain "AU" + + Scenario: Searching by additional tags (freeforms) for a tag with no direct + uses returns works using the tag's synonyms + Given a set of alternate universe works for searching + When I am on the search works page + And I fill in "Additional Tags" with "Alternate Universe - High School" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: Alternate Universe - High School" + And I should see "1 Found" + And the results should contain a synonym of "Alternate Universe - High School" + When I follow "Edit Your Search" + Then the field labeled "Additional Tags" should contain "Alternate Universe - High School" + + Scenario: Searching by additional tags (freeforms) for a tag that has not been + wrangled returns only works using tags containing the search term (not + summaries, titles, etc) + Given a set of alternate universe works for searching + When I am on the search works page + And I fill in "Additional Tags" with "Coffee Shop AU" + And I press "Search" within "#new_work_search" + Then I should see "You searched for: Tags: Coffee Shop AU" + And I should see "1 Found" + And the results should contain the freeform tag "Coffee Shop AU" + And the results should not contain a summary mentioning "Coffee Shop AU" + When I follow "Edit Your Search" + Then the field labeled "Additional Tags" should contain "Coffee Shop AU" diff --git a/features/step_definitions/admin_steps.rb b/features/step_definitions/admin_steps.rb new file mode 100755 index 0000000..8a3ec4b --- /dev/null +++ b/features/step_definitions/admin_steps.rb @@ -0,0 +1,579 @@ +### GIVEN + +Given /^the following admin settings are configured:$/ do |table| + admin_settings = AdminSetting.first + admin_settings.assign_attributes(table.rows_hash.symbolize_keys) + # Skip validations which require setting an admin as the last updater. + admin_settings.save!(validate: false) +end + +Given /the following admins? exists?/ do |table| + table.hashes.each do |hash| + FactoryBot.create(:admin, hash) + end +end + +Given "I am logged in as a super admin" do + step %{I am logged in as a "superadmin" admin} +end + +Given "I am logged in as a(n) {string} admin" do |role| + step "I start a new session" + login = "testadmin-#{role}" + email = "#{login}@example.org" + FactoryBot.create(:admin, login: login, email: email, roles: [role], password: "adminpassword") if Admin.find_by(login: login, email: email).nil? + visit new_admin_session_path + fill_in "Admin username", with: login + fill_in "Admin password", with: "adminpassword" + click_button "Log In as Admin" + step %{I should see "Successfully logged in"} +end + +Given "I am logged in as an admin" do + step "I start a new session" + FactoryBot.create(:admin, login: "testadmin", email: "testadmin@example.org", password: "adminpassword") if Admin.find_by(login: "testadmin").nil? + visit new_admin_session_path + fill_in "Admin username", with: "testadmin" + fill_in "Admin password", with: "adminpassword" + click_button "Log In as Admin" + step %{I should see "Successfully logged in"} +end + +Given /^basic languages$/ do + Language.default + german = Language.find_or_create_by(short: "DE", name: "Deutsch", support_available: true, abuse_support_available: true) + Locale.create(iso: "de", name: "Deutsch", language: german) +end + +Given /^Persian language$/ do + Language.default + persian = Language.find_or_create_by(short: "fa", name: "Persian", support_available: true, abuse_support_available: true) + Locale.create(iso: "fa", name: "Persian", language: persian) +end + +Given /^downloads are off$/ do + step("I am logged in as a super admin") + visit(admin_settings_path) + uncheck("Allow downloads") + click_button("Update") +end + +Given /^tag wrangling is off$/ do + step(%{I am logged in as a "tag_wrangling" admin}) + visit(admin_settings_path) + step(%{I check "Turn off tag wrangling for non-admins"}) + step(%{I press "Update"}) + step("I log out") +end + +Given /^tag wrangling is on$/ do + step(%{I am logged in as a "tag_wrangling" admin}) + visit(admin_settings_path) + step(%{I uncheck "Turn off tag wrangling for non-admins"}) + step(%{I press "Update"}) + step("I log out") +end + +Given /^the support form is disabled and its text field set to "Please don't contact us"$/ do + step(%{I am logged in as a "support" admin}) + visit(admin_settings_path) + check("Turn off support form") + fill_in(:admin_setting_disabled_support_form_text, with: "Please don't contact us") + click_button("Update") +end + +Given /^the support form is enabled$/ do + step(%{I am logged in as a "support" admin}) + visit(admin_settings_path) + uncheck("Turn off support form") + click_button("Update") +end + +Given "guest comments are on" do + step("I am logged in as a super admin") + visit(admin_settings_path) + uncheck("Turn off guest comments across the site") + click_button("Update") +end + +Given "guest comments are off" do + step("I am logged in as a super admin") + visit(admin_settings_path) + check("Turn off guest comments across the site") + click_button("Update") +end + +Given "account age threshold for comment spam check is set to {int} days" do |days| + step("I am logged in as a super admin") + visit(admin_settings_path) + fill_in("admin_setting_account_age_threshold_for_comment_spam_check", with: days) + click_button("Update") +end + +Given "I have posted known issues" do + step %{I am logged in as a super admin} + step %{I follow "Admin Posts"} + step %{I follow "Known Issues" within "#header"} + step %{I follow "make a new known issues post"} + step %{I fill in "known_issue_title" with "First known problem"} + step %{I fill in "content" with "This is a bit of a problem"} + step %{I press "Post"} +end + +Given /^I have posted an admin post$/ do + step(%{I am logged in as a "communications" admin}) + step("I make an admin post") + step("I log out") +end + +Given "the admin post {string}" do |title| + FactoryBot.create(:admin_post, title: title, comment_permissions: :enable_all) +end + +Given "the fannish next of kin {string} for the user {string}" do |kin, user| + user = ensure_user(user) + kin = ensure_user(kin) + user.create_fannish_next_of_kin(kin: kin, kin_email: "fnok@example.com") +end + +Given "the user {string} is suspended" do |user| + step %{the user "#{user}" exists and is activated} + step %{I am logged in as a "policy_and_abuse" admin} + step %{I go to the user administration page for "#{user}"} + choose("admin_action_suspend") + fill_in("suspend_days", with: 30) + fill_in("Notes", with: "Why they are suspended") + click_button("Update") +end + +Given /^the user "([^\"]*)" is banned$/ do |user| + step %{the user "#{user}" exists and is activated} + step(%{I am logged in as a "policy_and_abuse" admin}) + step %{I go to the user administration page for "#{user}"} + choose("admin_action_ban") + fill_in("Notes", with: "Why they are banned") + click_button("Update") +end + +Then /^the user "([^\"]*)" should be permanently banned$/ do |user| + u = User.find_by(login: user) + assert u.banned? +end + +Given /^I have posted an admin post without paragraphs$/ do + step(%{I am logged in as a "communications" admin}) + step("I make an admin post without paragraphs") + step("I log out") +end + +Given /^I have posted an admin post with tags "(.*?)"$/ do |tags| + step(%{I am logged in as a "communications" admin}) + visit new_admin_post_path + fill_in("admin_post_title", with: "Default Admin Post") + fill_in("content", with: "Content of the admin post.") + fill_in("admin_post_tag_list", with: tags) + click_button("Post") +end + +Given(/^the following language exists$/) do |table| + table.hashes.each do |hash| + FactoryBot.create(:language, hash) + end +end + +Given /^I have posted an admin post with guest comments disabled$/ do + step %{I am logged in as a "communications" admin} + step %{I start to make an admin post} + choose("Only registered users can comment") + click_button("Post") + step %{I log out} +end + +Given /^I have posted an admin post with comments disabled$/ do + step %{I am logged in as a "communications" admin} + step %{I start to make an admin post} + choose("No one can comment") + click_button("Post") + step %{I log out} +end + +Given "an abuse ticket ID exists" do + ticket = { + "departmentId" => ArchiveConfig.ABUSE_ZOHO_DEPARTMENT_ID, + "status" => "Open", + "webUrl" => Faker::Internet.url + } + allow_any_instance_of(ZohoResourceClient).to receive(:find_ticket).and_return(ticket) +end + +Given "a work {string} with the original creator {string}" do |title, creator| + step %{the work "#{title}" by "#{creator}"} + step %{I have an orphan account} + step %{"#{creator}" orphans and takes their pseud off the work "#{title}"} +end + +Given "the admin {string} is locked" do |login| + admin = Admin.find_by(login: login) || FactoryBot.create(:admin, login: login) + # Same as script/lock_admin.rb + admin.lock_access!({ send_instructions: false }) +end + +Given "the admin {string} is unlocked" do |login| + admin = Admin.find_by(login: login) || FactoryBot.create(:admin, login: login) + # Same as script/unlock_admin.rb + admin.unlock_access! +end + +Given "there is/are {int} user creation(s) per page" do |amount| + allow(Work).to receive(:per_page).and_return(amount) + allow(Comment).to receive(:per_page).and_return(amount) +end + +Given "an archive FAQ category with the title {string} exists" do |title| + FactoryBot.create(:archive_faq, title: title) +end + +Given "the app name is {string}" do |app_name| + allow(ArchiveConfig).to receive(:APP_NAME).and_return(app_name) +end + +### WHEN + +When /^I visit the last activities item$/ do + visit("/admin/activities/#{AdminActivity.last.id}") +end + +When /^I fill in "([^"]*)" with "([^"]*)'s" invite code$/ do |field, login| + user = User.find_by(login: login) + token = user.invitations.first.token + fill_in(field, with: token) +end + +When "I start to make an admin post" do + visit new_admin_post_path + fill_in("admin_post_title", with: "Default Admin Post") + fill_in("content", with: "Content of the admin post.") +end + +When /^I make an admin post$/ do + step %(I start to make an admin post) + click_button("Post") +end + +When /^I make an admin post without paragraphs$/ do + visit new_admin_post_path + fill_in("admin_post_title", with: "Admin Post Without Paragraphs") + fill_in("content", with: "<ul><li>This post</li><li>is just</li><li>a list</li></ul>") + click_button("Post") +end + +When /^I make a multi-question FAQ post$/ do + visit new_archive_faq_path + fill_in("Question*", with: "Number 1 Question.") + fill_in("Answer*", with: "Number 1 posted FAQ, this is.") + fill_in("Category name*", with: "Standard FAQ Category") + fill_in("Anchor name*", with: "Number1anchor") + click_button("Post") + step %{I follow "Edit"} + step %{I fill in "Questions:" with "3"} + step %{I press "Update Form"} + fill_in("archive_faq_questions_attributes_1_question", with: "Number 2 Question.") + fill_in("archive_faq_questions_attributes_1_content", with: "This is an answer to the second question") + fill_in("archive_faq_questions_attributes_1_anchor", with: "whatisao32") + fill_in("archive_faq_questions_attributes_2_question", with: "Number 3 Question.") + fill_in("archive_faq_questions_attributes_2_content", with: "This is an answer to the third question") + fill_in("archive_faq_questions_attributes_2_anchor", with: "whatisao33") + click_button("Post") +end + +When "{int} Archive FAQ(s) exist(s)" do |n| + (1..n).each do |i| + FactoryBot.create(:archive_faq, id: i, title: "The #{i} FAQ") + end +end + +When "{int} Archive FAQ(s) with {int} question(s) exist(s)" do |faqs, questions| + (1..faqs).each do |i| + archive_faq = FactoryBot.create(:archive_faq, id: i) + (1..questions).each do + FactoryBot.create(:question, archive_faq: archive_faq) + end + end +end + +When "the invite_from_queue_at is yesterday" do + AdminSetting.first.update_attribute(:invite_from_queue_at, Time.current - 1.day) +end + +When "the scheduled check_invite_queue job is run" do + Resque.enqueue(AdminSetting, :check_queue) +end + +When "I edit known issues" do + step %{I follow "Admin Posts"} + step %{I follow "Known Issues" within "#header"} + step %{I follow "Edit"} + step %{I fill in "known_issue_title" with "More known problems"} + step %{I fill in "content" with "This is a bit of a problem, and this is too"} + step %{I press "Post"} +end + +When "I delete known issues" do + step %{I follow "Admin Posts"} + step %{I follow "Known Issues" within "#header"} + step %{I follow "Delete"} +end + +When "I check the {string} role checkbox" do |role| + role_id = Role.find_by(name: role).id + check("user_roles_#{role_id}") +end + +When "I uncheck the {string} role checkbox" do |role| + role_id = Role.find_by(name: role).id + uncheck("user_roles_#{role_id}") +end + +When /^I make a translation of an admin post( with tags "(.*?)")?$/ do |tags| + admin_post = AdminPost.find_by(title: "Default Admin Post") + # If post doesn't exist, assume we want to reference a non-existent post + admin_post_id = !admin_post.nil? ? admin_post.id : 0 + visit new_admin_post_path + fill_in("admin_post_title", with: "Deutsch Ankuendigung") + fill_in("content", with: "Deutsch Woerter") + step %{I select "Deutsch" from "Choose a language"} + fill_in("admin_post_translated_post_id", with: admin_post_id) + fill_in("admin_post_tag_list", with: tags) if tags + click_button("Post") +end + +When /^I hide the work "(.*?)"$/ do |title| + work = Work.find_by(title: title) + visit work_path(work) + step %{I follow "Hide Work"} +end + +When "I unhide the work {string}" do |title| + work = Work.find_by(title: title) + visit work_path(work) + step %{I follow "Make Work Visible"} +end + +When "the search criteria contains the ID for {string}" do |login| + user_id = User.find_by(login: login).id + fill_in("user_id", with: user_id) +end + +When "it is past the admin password reset token's expiration date" do + days = ArchiveConfig.DAYS_UNTIL_ADMIN_RESET_PASSWORD_LINK_EXPIRES + 1 + step "it is currently #{days} days from now" +end + +When "I confirm I want to remove the pseud" do + expect(page.accept_alert).to eq("Are you sure you want to remove the creator's pseud from this work?") if @javascript +end + +When "I follow the first invitation token url" do + first('//td/a[href*="/invitations/"]').click +end + +### THEN + +Then (/^the translation information should still be filled in$/) do + step %{the "admin_post_title" field should contain "Deutsch Ankuendigung"} + step %{the "content" field should contain "Deutsch Woerter"} + step %{"Deutsch" should be selected within "Choose a language"} +end + +Then /^I should see a translated admin post( with tags "(.*?)")?$/ do |tags| + tags = tags.split(/, ?/) if tags + step %{I go to the admin-posts page} + step %{I should see "Default Admin Post"} + step %{I should see "Tags: #{tags.join(' ')}"} if tags + step %{I should see "Translations: Deutsch"} + step %{I follow "Default Admin Post"} + step %{I should see "Deutsch" within "dd.translations"} + step %{I follow "Deutsch"} + step %{I should see "Deutsch Woerter"} + tags&.each do |tag| + step %{I should see "#{tag}" within "dd.tags"} + end +end + +Then (/^I should not see a translated admin post$/) do + step %{I go to the admin-posts page} + step %{I should see "Default Admin Post"} + step %{I should see "Deutsch Ankuendigung"} + step %{I follow "Default Admin Post"} + step %{I should not see "Translations: Deutsch"} +end + +Then "the {string} role checkbox should be checked" do |role| + role_id = Role.find_by(name: role).id + assert has_checked_field?("user_roles_#{role_id}") +end + +Then "the {string} role checkbox should not be checked" do |role| + role_id = Role.find_by(name: role).id + assert has_unchecked_field?("user_roles_#{role_id}") +end + +Then /^the work "([^\"]*)" should be hidden$/ do |work| + w = Work.find_by_title(work) + user = w.pseuds.first.user.login + step %{logged out users should not see the hidden work "#{work}" by "#{user}"} + step %{logged in users should not see the hidden work "#{work}" by "#{user}"} +end + +Then /^the work "([^\"]*)" should not be hidden$/ do |work| + w = Work.find_by_title(work) + user = w.pseuds.first.user.login + step %{logged out users should see the unhidden work "#{work}" by "#{user}"} + step %{logged in users should see the unhidden work "#{work}" by "#{user}"} +end + +Then /^logged out users should not see the hidden work "([^\"]*)" by "([^\"]*)"?/ do |work, user| + step "I am a visitor" + step %{I should not see the hidden work "#{work}" by "#{user}"} +end + +Then /^logged in users should not see the hidden work "([^\"]*)" by "([^\"]*)"?/ do |work, user| + step %{I am logged in as a random user} + step %{I should not see the hidden work "#{work}" by "#{user}"} +end + +Then /^I should not see the hidden work "([^\"]*)" by "([^\"]*)"?/ do |work, user| + step %{I am on #{user}'s works page} + step %{I should not see "#{work}"} + step %{I view the work "#{work}"} + step %{I should see "Sorry, you don't have permission to access the page you were trying to reach."} +end + +Then /^"([^\"]*)" should see their work "([^\"]*)" is hidden?/ do |user, work| + step %{I am logged in as "#{user}"} + step %{I am on #{user}'s works page} + step %{I should not see "#{work}"} + step %{I view the work "#{work}"} + step %{I should see the image "title" text "Hidden by Administrator"} +end + +Then /^logged out users should see the unhidden work "([^\"]*)" by "([^\"]*)"?/ do |work, user| + step "I am a visitor" + step %{I should see the unhidden work "#{work}" by "#{user}"} +end + +Then /^logged in users should see the unhidden work "([^\"]*)" by "([^\"]*)"?/ do |work, user| + step %{I am logged in as a random user} + step %{I should see the unhidden work "#{work}" by "#{user}"} +end + +Then /^I should see the unhidden work "([^\"]*)" by "([^\"]*)"?/ do |work, user| + step %{I am on #{user}'s works page} + step %{I should see "#{work}"} + step %{I view the work "#{work}"} + step %{I should see "#{work}"} +end + +Then(/^the work "(.*?)" should not be deleted$/) do |work| + w = Work.find_by(title: work) + assert w && w.posted? +end + +Then(/^there should be no bookmarks on the work "(.*?)"$/) do |work| + w = Work.find_by(title: work) + assert w.bookmarks.count == 0 +end + +Then(/^there should be no comments on the work "(.*?)"$/) do |work| + w = Work.find_by(title: work) + assert w.comments.count == 0 +end + +When(/^the user "(.*?)" is unbanned in the background/) do |user| + u = User.find_by(login: user) + u.update_attribute(:banned, false) +end + +Given "I have banned the address {string}" do |email| + visit admin_blacklisted_emails_url + fill_in("Email to ban", with: email) + click_button("Ban Email") +end + +Given "I have banned the address for user {string}" do |user| + visit admin_blacklisted_emails_url + u = User.find_by(login: user) + fill_in("admin_blacklisted_email_email", with: u.email) + click_button("Ban Email") +end + +Then "the address {string} should be banned" do |email| + visit admin_blacklisted_emails_url + fill_in("Email to find", with: email) + click_button("Search Banned Emails") + assert page.should have_content(email) +end + +Then "the address {string} should not be banned" do |email| + visit admin_blacklisted_emails_url + fill_in("Email to find", with: email) + click_button("Search Banned Emails") + step %{I should see "0 emails found"} +end + +Then "I should not be able to add the email {string} to the invite queue" do |email| + step %{I am on the homepage} + click_link "Get an Invitation" + fill_in "Email", with: email + click_button "Add me to the list" + expect(page).to have_content("Sorry! We couldn't save this invite request because:") + expect(page).to have_content("Email has been blocked at the owner's request. That means it can't be used for invitations. Please check the address to make sure it's yours to use and contact AO3 Support if you have any questions.") +end + +Then(/^I should not be able to comment with the address "([^"]*)"$/) do |email| + step %{the work "New Work"} + step %{I post the comment "I loved this" on the work "New Work" as a guest with email "#{email}"} + step %{I should see "has been blocked at the owner's request"} + step %{I should not see "Comment created!"} +end + +Then(/^I should be able to comment with the address "([^"]*)"$/) do |email| + step %{the work "New Work"} + step %{I post the comment "I loved this" on the work "New Work" as a guest with email "#{email}"} + step %{I should not see "has been blocked at the owner's request"} + step %{I should see "Comment created!"} +end + +Then /^the work "([^\"]*)" should be marked as spam/ do |work| + w = Work.find_by_title(work) + assert w.spam? +end + +Then /^the work "([^\"]*)" should not be marked as spam/ do |work| + w = Work.find_by_title(work) + assert !w.spam? +end + +Then "I should see {int} admin activity log entry/entries" do |count| + expect(page).to have_css("tr[id^=admin_activity_]", count: count) +end + +Then /^the user content should be shown as right-to-left$/ do + page.should have_xpath("//div[contains(@class, 'userstuff') and @dir='rtl']") +end + +Then "I should see the original creator {string}" do |creator| + user = User.find_by(login: creator) + expect(page).to have_selector(".original_creators", + text: "#{user.id} (#{creator})") +end + +Then "the history table should show that {string} was {word} as next of kin" do |username, action| + user_id = User.find_by(login: username).id + step %{I should see "Fannish Next of Kin #{action.capitalize}: #{user_id}" within "#user_history"} +end + +Then "the history table should show they were {word} as next of kin of {string}" do |action, username| + user_id = User.find_by(login: username).id + step %{I should see "#{action.capitalize} as Fannish Next of Kin for: #{user_id}" within "#user_history"} +end diff --git a/features/step_definitions/archivist_steps.rb b/features/step_definitions/archivist_steps.rb new file mode 100755 index 0000000..2f5fc07 --- /dev/null +++ b/features/step_definitions/archivist_steps.rb @@ -0,0 +1,103 @@ +### GIVEN + +Given /^I have an archivist "([^\"]*)"$/ do |name| + step(%{the user "#{name}" exists and has the role "archivist"}) +end + +Given /^I have pre-archivist setup for "([^\"]*)"$/ do |name| + step(%{I am logged in as "#{name}"}) + step(%{the role "archivist"}) +end + +Given /^I have an Open Doors committee member "([^\"]*)"$/ do |name| + step(%{I have pre-archivist setup for "#{name}"}) + step(%{I make "#{name}" an Open Doors committee member}) +end + +### WHEN + +When /^I make "([^\"]*)" an archivist$/ do |name| + step(%{I go to the manage users page}) + step(%{I fill in "Name" with "#{name}"}) + step(%{I press "Find"}) + step(%{I check the "archivist" role checkbox}) + step(%{I press "Update"}) +end + +When /^I make "([^\"]*)" an Open Doors committee member$/ do |name| + @user = User.find_by(login: name) + @role = Role.find_or_create_by(name: "opendoors") + @user.roles = [@role] +end + +When /^(?:|I )fill in "([^"]*)" with the path to (.+)$/ do |field, page_name| + fill_in(field, with: path_to(page_name)) +end + +When /^I start to import the work "([^\"]*)"(?: by "([^\"]*)" with email "([^\"]*)")?$/ do |url, external_author_name, external_author_email| + step(%{I go to the import page}) + step(%{I check "Import for others ONLY with permission"}) + step(%{I fill in "urls" with "#{url}"}) + step %{I select "English" from "Choose a language"} + if external_author_name.present? + step(%{I fill in "external_author_name" with "#{external_author_name}"}) + step(%{I fill in "external_author_email" with "#{external_author_email}"}) + end +end + +When /^I import the work "(.*?)"(?: by "(.*?)" with email "(.*?)")?(?: and by "(.*?)" with email "(.*?)")?$/ do + |url, creator_name, creator_email, cocreator_name, cocreator_email| + step(%{I go to the import page}) + step(%{I check "Import for others ONLY with permission"}) + step(%{I fill in "urls" with "#{url}"}) + step %{I select "English" from "Choose a language"} + if creator_name.present? + step(%{I fill in "external_author_name" with "#{creator_name}"}) + step(%{I fill in "external_author_email" with "#{creator_email}"}) + end + if cocreator_name.present? + step(%{I fill in "external_coauthor_name" with "#{cocreator_name}"}) + step(%{I fill in "external_coauthor_email" with "#{cocreator_email}"}) + end + step(%{I check "Post without previewing"}) + step(%{I press "Import"}) +end + +When /^I import the works "([^\"]*)"$/ do |urls| + urls = urls.split(/, ?/).join("\n") + step(%{I go to the import page}) + step(%{I check "Import for others ONLY with permission"}) + step(%{I fill in "urls" with "#{urls}"}) + step %{I select "English" from "Choose a language"} + step(%{I check "Post without previewing"}) + step(%{I press "Import"}) +end + +### THEN + +Then /^I should not see multi-story import messages$/ do + step %{I should not see "Importing completed successfully for the following works! (But please check the results over carefully!)"} + step %{I should not see "Imported Works"} + step %{I should not see "We were able to successfully upload the following works."} +end + +Then /^I should see multi-story import messages$/ do + step %{I should see "Importing completed successfully for the following works! (But please check the results over carefully!)"} + step %{I should see "Imported Works"} + step %{I should see "We were able to successfully upload the following works."} +end + +Then /^I should see import confirmation$/ do + step %{I should see "We have notified the author(s) you imported works for. If any were missed, you can also add co-authors manually."} +end + +Then /^the email should contain invitation warnings from "([^\"]*)" for work "([^\"]*)" in fandom "([^\"]*)"$/ do |name, work, fandom| + step %{the email should contain "has recently been imported"} + step %{the email should contain "Open Doors"} + step %{the email should contain "#{work}"} + step %{the email should contain "#{fandom}"} +end + +Then /^the email should contain claim information$/ do + step %{the email should contain "automatically added to your AO3 account"} +end diff --git a/features/step_definitions/autocomplete_steps.rb b/features/step_definitions/autocomplete_steps.rb new file mode 100755 index 0000000..d2220ed --- /dev/null +++ b/features/step_definitions/autocomplete_steps.rb @@ -0,0 +1,256 @@ +Given /^a set of tags for testing autocomplete$/ do + step %{basic tags} + step %{a canonical fandom "Supernatural"} + step %{a canonical fandom "Battlestar Galactica"} + step %{a noncanonical fandom "Super Awesome"} + step %{a canonical character "Ellen Harvelle" in fandom "Supernatural"} + step %{a canonical character "Ellen Tigh" in fandom "Battlestar Galactica"} + step %{a noncanonical character "ellen somebody"} + step %{a canonical relationship "Dean/Castiel" in fandom "Supernatural"} + step %{a canonical relationship "Sam/Dean" in fandom "Supernatural"} + step %{a canonical relationship "Ellen Tigh/Lee Adama" in fandom "Battlestar Galactica"} + step %{a noncanonical relationship "Destiel"} + step %{a canonical freeform "Alternate Universe"} + step %{a canonical freeform "Superduper"} + step %{a noncanonical freeform "alternate sundays"} +end + +Then /^I should see HTML "(.*)?" in the autocomplete$/ do |string| + # There should be only one visible autocomplete dropdown. + within("input + .autocomplete") do + # Wait for results to appear, then check their HTML content + expect(current_scope).to have_selector("li") + expect(current_scope["innerHTML"]).to include(string) + end +end + +Then /^I should see "([^\"]+)" in the autocomplete$/ do |string| + # There should be only one visible autocomplete dropdown. + expect(find("input + .autocomplete")).to have_content(string) +end + +Then /^I should not see "([^\"]+)" in the autocomplete$/ do |string| + # There should be only one visible autocomplete dropdown. + expect(find("input + .autocomplete")).to have_no_content(string) +end + +# Define all values to be entered here depending on the fieldname +When /^I enter text in the "([^\"]+)" autocomplete field$/ do |fieldname| + text = case fieldname + when "Fandoms" + "sup" + when "Additional Tags" + "alt" + when "Characters" + "ellen" + when "Relationships" + "cast" + when "Your tags" + "sup" + else + "" + end + step %{I enter "#{text}" in the "#{fieldname}" autocomplete field} +end + +When /^I enter "([^\"]+)" in the "([^\"]+)" autocomplete field$/ do |text, fieldname| + field = find_field(fieldname) + # Clear the field. + field.set("") + # Simulate keystrokes to make the autocomplete dropdown appear (instead of fill_in). + field.send_keys(text) + # Wait for the autocomplete right after the field to appear, + # so in the Then steps we can look for the only active autocomplete + # without caring where it is. + expect(page).to have_selector("##{field[:id]} + .autocomplete") +end + +When /^I choose "([^\"]+)" from the "([^\"]+)" autocomplete$/ do |text, fieldname| + field = find_field(fieldname) + # Clear the field. + field.set("") + # Simulate keystrokes to make the autocomplete dropdown appear (instead of fill_in) + field.send_keys(text) + # In the autocomplete right after the field... + with_scope("##{field[:id]} + .autocomplete") do + # Wait for the expected result to appear and click to select it + find("li", text: text).click + end +end + +# alias for most common fields +When /^I enter text in the (\w+) autocomplete field$/ do |fieldtype| + fieldname = case fieldtype + when "fandom" + "Fandoms" + when "character" + "Characters" + when "relationship" + "Relationships" + when "freeform" + "Additional Tags" + end + step %{I enter text in the "#{fieldname}" autocomplete field} +end + +When "I remove selected values from the autocomplete field within {string}" do |selector| + within(selector) do + find_all(".autocomplete .delete").each(&:click) + end +end + +When /^I specify a fandom and enter text in the character autocomplete field$/ do + step %{I choose "Supernatural" from the "Fandoms" autocomplete} + step %{I enter text in the character autocomplete field} +end + +When /^I specify a fandom and enter text in the relationship autocomplete field$/ do + step %{I choose "Supernatural" from the "Fandoms" autocomplete} + step %{I enter text in the relationship autocomplete field} +end + +When /^I specify two fandoms and enter text in the character autocomplete field$/ do + step %{I choose "Supernatural" from the "Fandoms" autocomplete} + step %{I choose "Battlestar Galactica" from the "Fandoms" autocomplete} + step %{I enter text in the character autocomplete field} +end + +When /^I choose a previously bookmarked URL from the autocomplete$/ do + url = ExternalWork.first.url + step %{I choose "#{url}" from the "URL" autocomplete} + step %{all AJAX requests are complete} +end + +## Here's where we create the steps defining which tags should appear/not appear +## based on the set of tags and the data entered + +Then /^I should only see matching canonical fandom tags in the autocomplete$/ do + step %{I should see "Supernatural" in the autocomplete} + step %{I should not see "Super Awesome" in the autocomplete} + step %{I should not see "Battlestar Galactica" in the autocomplete} + step %{I should not see "Superduper" in the autocomplete} +end + +Then /^I should only see matching canonical freeform tags in the autocomplete$/ do + step %{I should see "Alternate Universe" in the autocomplete} + step %{I should not see "alternate sundays" in the autocomplete} + step %{I should not see "Superduper" in the autocomplete} +end + +Then /^I should only see matching canonical character tags in the autocomplete$/ do + step %{I should see "Ellen Harvelle" in the autocomplete} + step %{I should see "Ellen Tigh" in the autocomplete} + step %{I should not see "Ellen Somebody" in the autocomplete} +end + +Then /^I should only see matching canonical relationship tags in the autocomplete$/ do + step %{I should see "Dean/Castiel" in the autocomplete} + step %{I should not see "Sam/Dean" in the autocomplete} + step %{I should not see "Destiel" in the autocomplete} +end + +Then /^I should only see matching canonical character tags in the specified fandom in the autocomplete$/ do + step %{I should see "Ellen Harvelle" in the autocomplete} + step %{I should not see "Ellen Tigh" in the autocomplete} + step %{I should not see "Ellen Somebody" in the autocomplete} +end + +Then /^I should see matching canonical character tags from both fandoms in the autocomplete$/ do + step %{I should see "Ellen Harvelle" in the autocomplete} + step %{I should see "Ellen Tigh" in the autocomplete} + step %{I should not see "Ellen Somebody" in the autocomplete} +end + +Then /^I should only see matching canonical relationship tags in the specified fandom in the autocomplete$/ do + step %{I should see "Dean/Castiel" in the autocomplete} + step %{I should not see "Destiel" in the autocomplete} +end + +Then /^I should only see matching canonical tags in the autocomplete$/ do + step %{I should see "Supernatural" in the autocomplete} + step %{I should see "Superduper" in the autocomplete} + step %{I should not see "Dean/Castiel" in the autocomplete} +end + +Then /^I should only see matching noncanonical tags in the autocomplete$/ do + step %{I should see "Super Awesome" in the autocomplete} + step %{I should not see "Supernatural" in the autocomplete} +end + +Then /^the tag autocomplete fields should list only matching canonical tags$/ do + step %{I enter text in the fandom autocomplete field} + step %{I should only see matching canonical fandom tags in the autocomplete} + step %{I enter text in the character autocomplete field} + step %{I should only see matching canonical character tags in the autocomplete} + step %{I enter text in the relationship autocomplete field} + step %{I should only see matching canonical relationship tags in the autocomplete} + if page.body =~ /Additional Tags/ + step %{I enter text in the freeform autocomplete field} + step %{I should only see matching canonical freeform tags in the autocomplete} + end +end + +Then /^the fandom-specific tag autocomplete fields should list only fandom-specific canonical tags$/ do + step %{I specify a fandom and enter text in the character autocomplete field} + step %{I should only see matching canonical character tags in the specified fandom in the autocomplete} + step %{I specify a fandom and enter text in the relationship autocomplete field} + step %{I should only see matching canonical relationship tags in the specified fandom in the autocomplete} + step %{I specify two fandoms and enter text in the character autocomplete field} + step %{I should see matching canonical character tags from both fandoms in the autocomplete} +end + +Then /^the external url autocomplete field should list the urls of existing external works$/ do + step %{I enter "exam" in the "URL" autocomplete field} + step %{I should see "http://example.org/200" in the autocomplete} +end + +Given /^a set of users for testing autocomplete$/ do + %w(myname coauthor giftee).each do |username| + user = FactoryBot.create(:user, login: username) + user.pseuds.first.add_to_autocomplete + end +end + +Then /^the coauthor autocomplete field should list matching users$/ do + check("co-authors-options-show") + step %{I enter "coa" in the "pseud_byline_autocomplete" autocomplete field} + step %{I should see "coauthor" in the autocomplete} + step %{I should not see "giftee" in the autocomplete} +end + +Then /^the gift recipient autocomplete field should list matching users$/ do + step %{I enter "gif" in the "Gift this work to" autocomplete field} + step %{I should see "giftee" in the autocomplete} + step %{I should not see "coauthor" in the autocomplete} +end + +Given /^a set of collections for testing autocomplete$/ do + step %{I create the collection "awesome"} + step %{I create the collection "great"} + step %{I create the collection "really great"} +end + +Then /^the collection item autocomplete field should list matching collections$/ do + step %{I enter "gre" in the "Post to Collections / Challenges" autocomplete field} + step %{I should see "great" in the autocomplete} + step %{I should see "really great" in the autocomplete} + step %{I should not see "awesome" in the autocomplete} +end + +Given /^a gift exchange for testing autocomplete$/ do + step %{I have created the gift exchange "autocomplete"} +end + +When /^I edit the gift exchange for testing autocomplete$/ do + visit(edit_collection_gift_exchange_path(Collection.find_by(name: "autocomplete"))) +end + +Then(/^the pseud autocomplete should contain "([^\"]*)"$/) do |pseud| + results = Pseud.autocomplete_lookup(search_param: pseud, autocomplete_prefix: "autocomplete_pseud").map { |res| Pseud.fullname_from_autocomplete(res) } + assert results.include?(pseud) +end + +Then(/^the pseud autocomplete should not contain "([^\"]*)"$/) do |pseud| + results = Pseud.autocomplete_lookup(search_param: pseud, autocomplete_prefix: "autocomplete_pseud").map { |res| Pseud.fullname_from_autocomplete(res) } + assert !results.include?(pseud) +end diff --git a/features/step_definitions/banner_steps.rb b/features/step_definitions/banner_steps.rb new file mode 100755 index 0000000..b8922d0 --- /dev/null +++ b/features/step_definitions/banner_steps.rb @@ -0,0 +1,158 @@ +# encoding: UTF-8 + +### GIVEN + +Given /^there are no banners$/ do + AdminBanner.delete_all +end + +### WHEN + +When /^an admin creates an?( active)?(?: "([^\"]*)")? banner$/ do |active, banner_type| + step %{I am logged in as a "communications" admin} + visit(new_admin_banner_path) + fill_in("admin_banner_content", with: "This is some banner text") + if banner_type.present? + if banner_type == "alert" + choose("admin_banner_banner_type_alert") + elsif banner_type == "event" + choose("admin_banner_banner_type_event") + else + choose("admin_banner_banner_type_") + end + end + check("admin_banner_active") unless active.blank? + click_button("Create Banner") + step %{I should see "Setting banner back on for all users. This may take some time."} unless active.blank? +end + +When /^an admin deactivates the banner$/ do + step %{I am logged in as a "communications" admin} + visit(admin_banners_path) + step %{I follow "Edit"} + uncheck("admin_banner_active") + click_button("Update Banner") + step %{I should see "Banner successfully updated."} +end + +When /^an admin edits the active banner$/ do + step %{I am logged in as a "communications" admin} + visit(admin_banners_path) + step %{I follow "Edit"} + fill_in("admin_banner_content", with: "This is some edited banner text") + click_button("Update Banner") + step %{I should see "Setting banner back on for all users. This may take some time."} +end + +When /^an admin makes a minor edit to the active banner$/ do + step %{I am logged in as a "communications" admin} + visit(admin_banners_path) + step %{I follow "Edit"} + fill_in("admin_banner_content", with: "This is some banner text!") + check("admin_banner_minor_edit") + click_button("Update Banner") + step %{I should see "Updating banner for users who have not already dismissed it. This may take some time."} +end + +When /^an admin creates a different active banner$/ do + step %{I am logged in as a "communications" admin} + visit(new_admin_banner_path) + fill_in("admin_banner_content", with: "This is new banner text") + check("admin_banner_active") + click_button("Create Banner") + step %{I should see "Setting banner back on for all users. This may take some time."} +end + +When /^I turn off the banner$/ do + step %{I am logged in as "newname"} + step %{I am on newname's user page} + click_button("×") +end + +### THEN + +Then /^a logged-in user should see the(?: "([^\"]*)")? banner$/ do |banner_type| + step %{I am logged in as "ordinaryuser"} + visit(works_path) + if banner_type.present? + if banner_type == "alert" + page.should have_xpath("//div[@class=\"alert announcement group\"]") + elsif banner_type == "event" + page.should have_xpath("//div[@class=\"event announcement group\"]") + else + page.should have_xpath("//div[@class=\"announcement group\"]") + page.should_not have_xpath("//div[@class=\"alert announcement group\"]") + page.should_not have_xpath("//div[@class=\"event\"]") + end + end + step %{I should see "This is some banner text"} +end + +Then /^a logged-out user should see the(?: "([^\"]*)")? banner$/ do |banner_type| + step "I am a visitor" + visit(works_path) + if banner_type.present? + if banner_type == "alert" + page.should have_xpath("//div[@class=\"alert announcement group\"]") + elsif banner_type == "event" + page.should have_xpath("//div[@class=\"event announcement group\"]") + else + page.should have_xpath("//div[@class=\"announcement group\"]") + page.should_not have_xpath("//div[@class=\"alert announcement group\"]") + page.should_not have_xpath("//div[@class=\"event announcement group\"]") + end + end + step %{I should see "This is some banner text"} +end + +Then /^a logged-in user should see the edited active banner$/ do + step %{I am logged in as "ordinaryuser"} + visit(works_path) + step %{I should see "This is some edited banner text"} +end + +Then /^a logged-out user should see the edited active banner$/ do + step "I am a visitor" + visit(works_path) + step %{I should see "This is some edited banner text"} +end + +Then /^a logged-in user should not see a banner$/ do + step %{I am logged in as "ordinaryuser"} + page.should_not have_xpath("//div[@class=\"announcement group\"]") +end + +Then /^a logged-out user should not see a banner$/ do + step "I am a visitor" + page.should_not have_xpath("//div[@class=\"announcement group\"]") +end + +Then "I should see the first login banner" do + step %{I should see "It looks like you've just logged in to AO3 for the first time."} +end + +Then "I should not see the first login banner" do + step %{I should not see "It looks like you've just logged in to AO3 for the first time."} +end + +Then /^I should see the first login popup$/ do + step %{I should see "Here are some tips to help you get started."} + step %{I should see "To log in, locate the login link"} +end + +Then /^I should see the banner with minor edits$/ do + step %{I should see "This is some banner text!"} +end + +Then /^I should not see the banner with minor edits$/ do + step %{I should not see "This is some banner text!"} +end + +Then /^the page should have the different banner$/ do + step %{I should see "This is new banner text"} +end + +Then /^the page should not have a banner$/ do + page.should_not have_xpath("//div[@class=\"announcement group\"]") +end + diff --git a/features/step_definitions/block_steps.rb b/features/step_definitions/block_steps.rb new file mode 100755 index 0000000..2dba821 --- /dev/null +++ b/features/step_definitions/block_steps.rb @@ -0,0 +1,41 @@ +Given "the user {string} has blocked the user {string}" do |blocker, blocked| + blocker = ensure_user(blocker) + blocked = ensure_user(blocked) + Block.create!(blocker: blocker, blocked: blocked) +end + +Given "there are {int} blocked users per page" do |amount| + allow(Block).to receive(:per_page).and_return(amount) +end + +Given "the maximum number of accounts users can block is {int}" do |count| + allow(ArchiveConfig).to receive(:MAX_BLOCKED_USERS).and_return(count) +end + +Then "the user {string} should have a block for {string}" do |blocker, blocked| + blocker = User.find_by(login: blocker) + blocked = User.find_by(login: blocked) + expect(Block.find_by(blocker: blocker, blocked: blocked)).to be_present +end + +Then "the user {string} should not have a block for {string}" do |blocker, blocked| + blocker = User.find_by(login: blocker) + blocked = User.find_by(login: blocked) + expect(Block.find_by(blocker: blocker, blocked: blocked)).to be_blank +end + +Then "the blurb should say when {string} blocked {string}" do |blocker, blocked| + blocker = User.find_by(login: blocker) + blocked = User.find_by(login: blocked) + block = Block.where(blocker: blocker, blocked: blocked).first + # Find the blurb for the specified block using the h4 with the blocked user's name, navigate back up to div, and then down to the datetime p + expect(page).to have_xpath("//li/div/h4/a[text()[contains(., '#{blocked.login}')]]/parent::h4/parent::div/p[text()[contains(., '#{block.created_at}')]]") +end + +Then "the blurb should not say when {string} blocked {string}" do |blocker, blocked| + blocker = User.find_by(login: blocker) + blocked = User.find_by(login: blocked) + block = Block.where(blocker: blocker, blocked: blocked).first + # Find the blurb for the specified block using the h4 with the blocked user's name, navigate back up to div, and then down to where the datetime p would be + expect(page).not_to have_xpath("//li/div/h4/a[text()[contains(., '#{blocked.login}')]]/parent::h4/parent::div/p[text()[contains(., '#{block.created_at}')]]") +end diff --git a/features/step_definitions/bookmark_steps.rb b/features/step_definitions/bookmark_steps.rb new file mode 100755 index 0000000..e6e4681 --- /dev/null +++ b/features/step_definitions/bookmark_steps.rb @@ -0,0 +1,457 @@ +Given /^mock websites with no content$/ do + WebMock.disable_net_connect! + WebMock.stub_request(:head, "http://example.org/200") + WebMock.stub_request(:head, "http://example.org/301").to_return(status: 301) + WebMock.stub_request(:head, "http://example.org/404").to_return(status: 404) +end + +Given "all pages on the host {string} return status 200" do |url| + WebMock.disable_net_connect! + parsed_url = Addressable::URI.parse(url) + WebMock.stub_request(:any, %r[https?://#{parsed_url.host}.*]).to_return(status: 200) +end + +Given /^I have a bookmark for "([^\"]*)"$/ do |title| + step %{I start a new bookmark for "#{title}"} + fill_in("Your tags", with: DEFAULT_BOOKMARK_TAGS) + step %{I press "Create"} + step %{all indexing jobs have been run} +end + +Given /^I have a bookmark of a deleted work$/ do + title = "Deleted Work For Bookmarking" + step %{I start a new bookmark for "#{title}"} + fill_in("bookmark_tag_string", with: DEFAULT_BOOKMARK_TAGS) + step %{I press "Create"} + work = Work.find_by(title: title) + work.destroy + step %{all indexing jobs have been run} +end + +Given /^I have bookmarks to search$/ do + # set up a user + user1 = FactoryBot.create(:user, login: "testuser") + + # set up the pseuds + pseud1 = FactoryBot.create(:pseud, name: "testy", user_id: user1.id) + pseud2 = FactoryBot.create(:pseud, name: "tester_pseud", user_id: user1.id) + + # set up a tag + freeform1 = FactoryBot.create(:freeform, name: "classic") + freeform2 = FactoryBot.create(:freeform, name: "rare") + + # set up some works + work1 = FactoryBot.create(:work, title: "First work", freeform_string: freeform2.name) + work2 = FactoryBot.create(:work, title: "second work") + work3 = FactoryBot.create(:work, title: "third work") + work4 = FactoryBot.create(:work, title: "fourth") + work5 = FactoryBot.create(:work, title: "fifth") + + # set up an external work + external1 = FactoryBot.create(:external_work, title: "Skies Grown Darker") + + # set up some series + series1 = FactoryBot.create(:series, title: "First Series") + series2 = FactoryBot.create(:series_with_a_work, title: "Second Series") + + # add work1 to series1 to ensure the series has tags + FactoryBot.create(:serial_work, work_id: work1.id, series_id: series1.id) + + # set up the bookmarks + FactoryBot.create(:bookmark, + bookmarkable_id: work1.id, + pseud_id: user1.default_pseud.id, + rec: true) + + FactoryBot.create(:bookmark, + bookmarkable_id: work2.id, + pseud_id: user1.default_pseud.id, + tag_string: freeform2.name) + + FactoryBot.create(:bookmark, + bookmarkable_id: work3.id, + pseud_id: user1.default_pseud.id, + tag_string: freeform1.name) + + FactoryBot.create(:bookmark, bookmarkable_id: work4.id, pseud_id: pseud1.id) + + FactoryBot.create(:bookmark, + bookmarkable_id: work5.id, + pseud_id: pseud2.id, + bookmarker_notes: "Left me with a broken heart") + + FactoryBot.create(:bookmark, + bookmarkable_id: external1.id, + bookmarkable_type: "ExternalWork", + pseud_id: pseud2.id, + bookmarker_notes: "I enjoyed this") + + FactoryBot.create(:bookmark, + bookmarkable_id: series1.id, + bookmarkable_type: "Series", + pseud_id: user1.default_pseud.id, + tag_string: freeform1.name) + + FactoryBot.create(:bookmark, + bookmarkable_id: series2.id, + bookmarkable_type: "Series", + pseud_id: pseud2.id, + rec: true, + bookmarker_notes: "A new classic") + + step %{all indexing jobs have been run} +end + +Given /^I have bookmarks to search by any field$/ do + work1 = FactoryBot.create(:work, + title: "Comfort", + freeform_string: "hurt a little comfort but only so much") + work2 = FactoryBot.create(:work, title: "Hurt and that's it") + work3 = FactoryBot.create(:work, title: "Fluff") + + external1 = FactoryBot.create(:external_work, + title: "External Whump", + author: "im hurt") + external2 = FactoryBot.create(:external_work, title: "External Fix-It") + + series1 = FactoryBot.create(:series_with_a_work, + title: "H/C Series", + summary: "Hurt & comfort ficlets") + series2 = FactoryBot.create(:series_with_a_work, title: "Ouchless Series") + + FactoryBot.create(:bookmark, bookmarkable_id: work1.id, bookmarker_notes: "whatever") + FactoryBot.create(:bookmark, bookmarkable_id: work2.id, tag_string: "more please") + FactoryBot.create(:bookmark, bookmarkable_id: work3.id, bookmarker_notes: "more please") + FactoryBot.create(:bookmark, + bookmarkable_id: external1.id, + bookmarkable_type: "ExternalWork", + bookmarker_notes: "please rec me more like this") + FactoryBot.create(:bookmark, + bookmarkable_id: external2.id, + bookmarkable_type: "ExternalWork", + tag_string: "please no more pain") + FactoryBot.create(:bookmark, + bookmarkable_id: series1.id, + bookmarkable_type: "Series", + bookmarker_notes: "needs more comfort please") + FactoryBot.create(:bookmark, + bookmarkable_id: series2.id, + bookmarkable_type: "Series", + pseud_id: FactoryBot.create(:pseud, name: "more please").id) + + step %{all indexing jobs have been run} +end + +Given /^I have bookmarks to search by dates$/ do + work1 = nil + series1 = nil + external1 = nil + Timecop.freeze(901.days.ago) do + work1 = FactoryBot.create(:work, title: "Old work") + FactoryBot.create(:bookmark, + bookmarkable_id: work1.id, + bookmarker_notes: "Old bookmark of old work") + + series1 = FactoryBot.create(:series_with_a_work, title: "Old series") + FactoryBot.create(:bookmark, + bookmarkable_id: series1.id, + bookmarkable_type: "Series", + bookmarker_notes: "Old bookmark of old series") + + external1 = FactoryBot.create(:external_work, title: "Old external") + FactoryBot.create(:bookmark, + bookmarkable_id: external1.id, + bookmarkable_type: "ExternalWork", + bookmarker_notes: "Old bookmark of old external work") + end + FactoryBot.create(:bookmark, + bookmarkable_id: work1.id, + bookmarker_notes: "New bookmark of old work") + FactoryBot.create(:bookmark, + bookmarkable_id: series1.id, + bookmarkable_type: "Series", + bookmarker_notes: "New bookmark of old series") + FactoryBot.create(:bookmark, + bookmarkable_id: external1.id, + bookmarkable_type: "ExternalWork", + bookmarker_notes: "New bookmark of old external work") + + work2 = FactoryBot.create(:work, title: "New work") + FactoryBot.create(:bookmark, + bookmarkable_id: work2.id, + bookmarker_notes: "New bookmark of new work") + + series2 = FactoryBot.create(:series_with_a_work, title: "New series") + FactoryBot.create(:bookmark, + bookmarkable_id: series2.id, + bookmarkable_type: "Series", + bookmarker_notes: "New bookmark of new series") + + external2 = FactoryBot.create(:external_work, title: "New external") + FactoryBot.create(:bookmark, + bookmarkable_id: external2.id, + bookmarkable_type: "ExternalWork", + bookmarker_notes: "New bookmark of new external work") + + step %{all indexing jobs have been run} +end + +Given /^I have bookmarks of various completion statuses to search$/ do + complete_work = FactoryBot.create(:work, title: "Finished Work") + incomplete_work = FactoryBot.create(:work, title: "Incomplete Work", complete: false, expected_number_of_chapters: 2) + + complete_series = FactoryBot.create(:series_with_a_work, title: "Complete Series", complete: true) + incomplete_series = FactoryBot.create(:series_with_a_work, title: "Incomplete Series", complete: false) + + external_work = FactoryBot.create(:external_work, title: "External Work") + + FactoryBot.create(:bookmark, bookmarkable_id: complete_work.id) + FactoryBot.create(:bookmark, bookmarkable_id: incomplete_work.id) + FactoryBot.create(:bookmark, bookmarkable_id: complete_series.id, bookmarkable_type: "Series") + FactoryBot.create(:bookmark, bookmarkable_id: incomplete_series.id, bookmarkable_type: "Series") + FactoryBot.create(:bookmark, bookmarkable_id: external_work.id, bookmarkable_type: "ExternalWork") + + step %{all indexing jobs have been run} +end + +Given /^I have bookmarks of old series to search$/ do + step %{basic tags} + step %{the user "creator" exists and is activated} + creator = User.find_by(login: "creator").default_pseud + + Timecop.freeze(30.days.ago) do + older_work = FactoryBot.create(:work, title: "WIP in a Series", authors: [creator]) + older_series = FactoryBot.create(:series, title: "Older WIP Series", works: [older_work]) + FactoryBot.create(:bookmark, + bookmarkable_id: older_series.id, + bookmarkable_type: "Series") + end + + Timecop.freeze(7.days.ago) do + newer_series = FactoryBot.create(:series_with_a_work, title: "Newer Complete Series") + FactoryBot.create(:bookmark, + bookmarkable_id: newer_series.id, + bookmarkable_type: "Series") + end +end + +# Freeform is omitted because there is no freeform option on the bookmark external work form +Given /^bookmarks of all types tagged with the (character|relationship|fandom) tag "(.*?)"$/ do |tag_type, tag| + work = if tag_type == "character" + FactoryBot.create(:work, + title: "BookmarkedWork", + character_string: tag) + elsif tag_type == "relationship" + FactoryBot.create(:work, + title: "BoomarkedWork", + relationship_string: tag) + elsif tag_type == "fandom" + FactoryBot.create(:work, + title: "BookmarkedWork", + fandom_string: tag) + end + + FactoryBot.create(:bookmark, bookmarkable_id: work.id, bookmarkable_type: "Work") + + step %{bookmarks of external works and series tagged with the #{tag_type} tag "#{tag}"} +end + +# Freeform is omitted because there is no freeform option on the bookmark external work form +Given /^bookmarks of external works and series tagged with the (character|relationship|fandom) tag "(.*?)"$/ do |tag_type, tag| + # Series get their tags from works, so we have to create the work first + work = if tag_type == "character" + FactoryBot.create(:work, character_string: tag) + elsif tag_type == "relationship" + FactoryBot.create(:work, relationship_string: tag) + elsif tag_type == "fandom" + FactoryBot.create(:work, fandom_string: tag) + end + + # We're going to need to use the series ID, so make the series + series = FactoryBot.create(:series, title: "BookmarkedSeries") + + # Now add the work to the series + FactoryBot.create(:serial_work, work_id: work.id, series_id: series.id) + + external_work = if tag_type == "character" + FactoryBot.create(:external_work, title: "BookmarkedExternalWork", character_string: tag) + elsif tag_type == "relationship" + FactoryBot.create(:external_work, title: "BookmarkedExternalWork", relationship_string: tag) + elsif tag_type == "fandom" + FactoryBot.create(:external_work, title: "BookmarkedExternalWork", fandom_string: tag) + end + + FactoryBot.create(:bookmark, + bookmarkable_id: series.id, + bookmarkable_type: "Series") + + FactoryBot.create(:bookmark, + bookmarkable_id: external_work.id, + bookmarkable_type: "ExternalWork") + + step %{all indexing jobs have been run} +end + +Given /^"(.*?)" has bookmarks of works in various languages$/ do |user| + step %{the user "#{user}" exists and is activated} + user_pseud = User.find_by(login: user).default_pseud + + lang_en = Language.find_or_create_by!(name: "English", short: "en") + lang_de = Language.find_or_create_by!(name: "Deutsch", short: "de") + + work1 = FactoryBot.create(:work, title: "english work", language_id: lang_en.id) + work2 = FactoryBot.create(:work, title: "german work", language_id: lang_de.id) + + FactoryBot.create(:bookmark, bookmarkable_id: work1.id, pseud_id: user_pseud.id) + FactoryBot.create(:bookmark, bookmarkable_id: work2.id, pseud_id: user_pseud.id) + + step %{all indexing jobs have been run} +end + +Given "{string} has a bookmark of a work titled {string}" do |user, title| + step %{the user "#{user}" exists and is activated} + + user_pseud = User.find_by(login: user).default_pseud + work1 = FactoryBot.create(:work, title: title) + FactoryBot.create(:bookmark, + bookmarkable: work1, + pseud: user_pseud) + + step %{all indexing jobs have been run} +end + +Given "pseud {string} has a bookmark of a work titled {string} by {string}" do |pseud, title, creator| + pseud = Pseud.find_by(name: pseud) + work = FactoryBot.create(:work, title: title, authors: [ensure_user(creator).default_pseud]) + FactoryBot.create(:bookmark, bookmarkable: work, pseud: pseud) + + step %{all indexing jobs have been run} +end + +def submit_bookmark_form(pseud, note, tags) + select(pseud, from: "bookmark_pseud_id") unless pseud.nil? + fill_in("bookmark_notes", with: note) unless note.nil? + fill_in("Your tags", with: tags) unless tags.nil? + click_button("Create") + step %{all indexing jobs have been run} +end + +When /^I bookmark the work "(.*?)"(?: as "(.*?)")?(?: with the note "(.*?)")?(?: with the tags "(.*?)")?$/ do |title, pseud, note, tags| + step %{I start a new bookmark for "#{title}"} + submit_bookmark_form(pseud, note, tags) +end + +When /^I bookmark the work "(.*?)"(?: as "(.*?)")?(?: with the note "(.*?)")?(?: with the tags "(.*?)")? from new bookmark page$/ do |title, pseud, note, tags| + step %{I go to the new bookmark page for work "#{title}"} + submit_bookmark_form(pseud, note, tags) +end + +When /^I bookmark the series "([^\"]*)"$/ do |series_title| + series = Series.find_by(title: series_title) + visit series_path(series) + click_link("Bookmark Series") + click_button("Create") + step %{all indexing jobs have been run} +end + +When /^I start a new bookmark for "([^\"]*)"$/ do |title| + step %{I open the bookmarkable work "#{title}"} + click_link("Bookmark") +end + +When /^I start a new bookmark$/ do + step %{I start a new bookmark for "#{DEFAULT_TITLE}"} +end + +When /^I bookmark the works "([^\"]*)"$/ do |worklist| + worklist.split(/, ?/).each do |work_title| + step %{I bookmark the work "#{work_title}"} + step %{it is currently 1 second from now} + end +end + +When /^I edit the bookmark for "([^\"]*)"$/ do |title| + step %{I open the bookmarkable work "#{title}"} + click_link("Edit Bookmark") +end + +When /^I open a bookmarkable work$/ do + step %{I open the bookmarkable work "#{DEFAULT_TITLE}"} +end + +When /^I open the bookmarkable work "([^\"]*)"$/ do |title| + work = Work.find_by(title: title) + work ||= FactoryBot.create(:work, title: title) + visit work_path(work) +end + +When /^I add my bookmark to the collection "([^\"]*)"$/ do |collection_name| + step %{I follow "Add To Collection"} + fill_in("collection_names", with: collection_name) + click_button("Add") +end + +When /^I rec the current work$/ do + click_link("Bookmark") + check("bookmark_rec") + click_button("Create") + step %{all indexing jobs have been run} +end + +When(/^I attempt to create a bookmark of "([^"]*)" with a pseud that is not mine$/) do |work| + step %{I am logged in as "commenter"} + step %{I start a new bookmark for "#{work}"} + pseud_id = User.first.pseuds.first.id + find("#bookmark_pseud_id", visible: false).set(pseud_id) + click_button "Create" +end + +When(/^I attempt to transfer my bookmark of "([^"]*)" to a pseud that is not mine$/) do |work| + step %{the user "not_the_bookmarker" exists and is activated} + step %{I edit the bookmark for "#{work}"} + pseud_id = User.find_by(login: "not_the_bookmarker").pseuds.first.id + find("#bookmark_pseud_id", visible: false).set(pseud_id) + click_button "Update" +end + +When(/^I use the bookmarklet on a previously bookmarked URL$/) do + url = ExternalWork.first.url + visit new_external_work_path(params: { url_from_external: url }) + step %{all AJAX requests are complete} +end + +Then /^the bookmark on "([^\"]*)" should have tag "([^\"]*)"$$/ do |title, tag| + work = Work.find_by(title: title) + bookmark = work.bookmarks.first + bookmark.reload + bookmark.tags.collect(&:name).include?(tag) +end +Then /^the ([\d]+)(?:st|nd|rd|th) bookmark result should contain "([^"]*)"$/ do |n, text| + selector = "ol.bookmark > li:nth-of-type(#{n})" + with_scope(selector) do + page.should have_content(text) + end +end + +Then /^the cache of the bookmark on "([^\"]*)" should expire after I edit the bookmark tags$/ do |title| + work = Work.find_by(title: title) + bookmark = work.bookmarks.first + orig_cache_key = bookmark.cache_key + Kernel::sleep 1 + visit edit_bookmark_path(bookmark) + fill_in("bookmark_tag_string", with: "New Tag") + click_button("Update") + bookmark.reload + assert orig_cache_key != bookmark.cache_key, "Cache key #{orig_cache_key} matches #{bookmark.cache_key}." +end + +Then /^the cache of the bookmark on "([^\"]*)" should not expire if I have not edited the bookmark$/ do |title| + work = Work.find_by(title: title) + bookmark = work.bookmarks.first + orig_cache_key = bookmark.cache_key + Kernel::sleep 1 + visit edit_bookmark_path(bookmark) + visit bookmark_path(bookmark) + bookmark.reload + assert orig_cache_key == bookmark.cache_key, "Cache key #{orig_cache_key} does not match #{bookmark.cache_key}." +end diff --git a/features/step_definitions/challege_gift_exchange_steps.rb b/features/step_definitions/challege_gift_exchange_steps.rb new file mode 100755 index 0000000..8a5395a --- /dev/null +++ b/features/step_definitions/challege_gift_exchange_steps.rb @@ -0,0 +1,405 @@ +# Set up a new/unsaved gift exchange + +Given /^I have set up the gift exchange "([^\"]*)" with name "([^\"]*)"$/ do |challengename, name| + step %{I am logged in as "mod1"} + step "I have standard challenge tags setup" + step %{I set up the collection "#{challengename}" with name "#{name}"} + step %{I select "Gift Exchange" from "challenge_type"} + click_button("Submit") +end + +Given /^I have set up the gift exchange "([^\"]*)"$/ do |challengename| + step %{I have set up the gift exchange "#{challengename}" with name "#{challengename.gsub(/[^\w]/, '_')}"} +end + +Then /^"([^\"]*)" gift exchange should be correctly created$/ do |title| + step %{I should see "Collection was successfully created"} + step %{I should see "Setting Up the #{title} Gift Exchange"} + step %{I should see "Offer Settings"} + step %{I should see "Request Settings"} + step %{I should see "If you plan to use automated matching"} + step %{I should see "Allow Any"} +end + +Then /^I should see gift exchange options$/ do + step %{I should see "Offer Settings"} + step %{I should see "Request Settings"} + step %{I should see "If you plan to use automated matching"} + step %{I should see "Allow Any"} +end + +# Create and save a gift exchange with some common options + +Given /^I have created the gift exchange "([^\"]*)" with name "([^\"]*)"$/ do |challengename, name| + step %{I have set up the gift exchange "#{challengename}" with name "#{name}"} + step "I fill in gift exchange challenge options" + step "I submit" + step %{I should see "Challenge was successfully created"} +end + +Given /^I have created the gift exchange "([^\"]*)"$/ do |challengename| + step %{I have created the gift exchange "#{challengename}" with name "#{challengename.gsub(/[^\w]/, '_')}"} +end + +Given /^I have created the tagless gift exchange "([^\"]*)" with name "([^\"]*)"$/ do |challengename, name| + step %{I have set up the gift exchange "#{challengename}" with name "#{name}"} + step "I submit" + step %{I should see "Challenge was successfully created"} +end + +Given /^I have created the tagless gift exchange "([^\"]*)"$/ do |challengename| + step %{I have created the tagless gift exchange "#{challengename}" with name "#{challengename.gsub(/[^\w]/, '_')}"} +end + +When /^I fill in gift exchange challenge options$/ do + current_date = DateTime.current + fill_in("Sign-up opens", with: "#{current_date.months_ago(2)}") + fill_in("Sign-up closes", with: "#{current_date.years_since(1)}") + select("(GMT-05:00) Eastern Time (US & Canada)", from: "gift_exchange_time_zone") + fill_in("Tag Sets To Use:", with: "Standard Challenge Tags") + fill_in("gift_exchange_request_restriction_attributes_fandom_num_required", with: "1") + fill_in("gift_exchange_request_restriction_attributes_fandom_num_allowed", with: "1") + fill_in("gift_exchange_request_restriction_attributes_freeform_num_allowed", with: "2") + fill_in("gift_exchange_offer_restriction_attributes_fandom_num_required", with: "1") + fill_in("gift_exchange_offer_restriction_attributes_fandom_num_allowed", with: "1") + fill_in("gift_exchange_offer_restriction_attributes_freeform_num_allowed", with: "2") + select("1", from: "gift_exchange_potential_match_settings_attributes_num_required_fandoms") +end + +When /^I fill in single-fandom gift exchange challenge options$/ do + current_date = DateTime.current + fill_in("Sign-up opens", with: current_date.months_ago(2).to_s) + fill_in("Sign-up closes", with: current_date.years_since(1).to_s) + select("(GMT-05:00) Eastern Time (US & Canada)", from: "gift_exchange_time_zone") + fill_in("gift_exchange_request_restriction_attributes_fandom_num_required", with: "1") + fill_in("gift_exchange_request_restriction_attributes_fandom_num_allowed", with: "1") + fill_in("gift_exchange_request_restriction_attributes_character_num_required", with: "1") + fill_in("gift_exchange_request_restriction_attributes_character_num_allowed", with: "3") + fill_in("gift_exchange_request_restriction_attributes_relationship_num_allowed", with: "3") + fill_in("gift_exchange_request_restriction_attributes_rating_num_allowed", with: "5") + fill_in("gift_exchange_request_restriction_attributes_category_num_allowed", with: "5") + fill_in("gift_exchange_request_restriction_attributes_archive_warning_num_allowed", with: "5") + fill_in("gift_exchange_request_restriction_attributes_freeform_num_allowed", with: "2") + fill_in("gift_exchange_offer_restriction_attributes_fandom_num_required", with: "1") + fill_in("gift_exchange_offer_restriction_attributes_fandom_num_allowed", with: "1") + fill_in("gift_exchange_offer_restriction_attributes_character_num_allowed", with: "3") + fill_in("gift_exchange_offer_restriction_attributes_freeform_num_allowed", with: "2") + select("1", from: "gift_exchange_potential_match_settings_attributes_num_required_characters") + check("gift_exchange_offer_restriction_attributes_allow_any_rating") + check("gift_exchange_offer_restriction_attributes_allow_any_category") + check("gift_exchange_offer_restriction_attributes_allow_any_archive_warning") + check("gift_exchange_offer_restriction_attributes_character_restrict_to_fandom") + check("gift_exchange_offer_restriction_attributes_relationship_restrict_to_fandom") +end + +When /^I allow warnings in my gift exchange$/ do + fill_in("gift_exchange_request_restriction_attributes_archive_warning_num_allowed", with: "1") + check("gift_exchange_request_restriction_attributes_allow_any_archive_warning") + fill_in("gift_exchange_offer_restriction_attributes_archive_warning_num_allowed", with: "1") + check("gift_exchange_offer_restriction_attributes_allow_any_archive_warning") +end + +Then /^"([^\"]*)" gift exchange should be fully created$/ do |title| + step %{I should see a create confirmation message} + step %{"#{title}" collection exists} + step %{I should see "(Open, Unmoderated, Gift Exchange Challenge)"} +end + +Given /^the gift exchange "([^\"]*)" is ready for signups$/ do |title| + step %{I am logged in as "mod1"} + step %{I have created the gift exchange "#{title}"} + step %{I open signups for "#{title}"} +end + +# This is going to make broken assignments a la AO3-5748 +Given /^"(.*?)" has two pinchhit assignments in the gift exchange "(.*?)"$/ do |user, collection_title| + collection = Collection.find_by(title: collection_title) + user = User.find_by(login: user) + assignments = ChallengeAssignment.where(collection_id: collection.id).limit(2) + assignments.each do |a| + a.pinch_hitter_id = user.default_pseud_id + a.save + a.reload + end +end + +## Signing up + +When /^I set up a signup for "([^\"]*)" with combination A$/ do |title| + step %{I start signing up for "#{title}"} + step %{I check the 1st checkbox with the value "Stargate Atlantis"} + step %{I check the 2nd checkbox with value "Stargate SG-1"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Alternate Universe - Historical"} + step %{I fill in the 2nd field with id matching "freeform_tagnames" with "Alternate Universe - High School"} +end + +When /^I sign up for "([^\"]*)" with combination A$/ do |title| + step %{I set up a signup for "#{title}" with combination A} + click_button "Submit" +end + +When "I sign up for {string} with combination A and my pseud {string}" do |title, pseud_name| + step %{I set up a signup for "#{title}" with combination A} + select pseud_name, from: "challenge_signup[pseud_id]" + click_button "Submit" +end + +When /^I attempt to sign up for "([^\"]*)" with a pseud that is not mine$/ do |title| + step %{the user "gooduser" exists and is activated} + step %{I am logged in as "baduser"} + step %{I set up a signup for "#{title}" with combination A} + pseud_id = Pseud.where(name: "gooduser").first.id + find("#challenge_signup_pseud_id", visible: false).set(pseud_id) + click_button "Submit" +end + +When /^I attempt to update my signup for "([^\"]*)" with a pseud that is not mine$/ do |title| + step %{the user "gooduser" exists and is activated} + step %{I am logged in as "baduser"} + step %{I sign up for "#{title}" with combination A} + step %{I follow "Edit Sign-up"} + pseud_id = Pseud.where(name: "gooduser").first.id + find("#challenge_signup_pseud_id", visible: false).set(pseud_id) + click_button "Update" +end + +When /^I sign up for "([^\"]*)" with combination B$/ do |title| + step %{I start signing up for "#{title}"} + step %{I check the 1st checkbox with value "Stargate SG-1"} + step %{I check the 2nd checkbox with the value "Stargate Atlantis"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Alternate Universe - High School, Something else weird"} + step %{I fill in the 2nd field with id matching "freeform_tagnames" with "Alternate Universe - High School"} + click_button "Submit" +end + +When /^I sign up for "([^\"]*)" with combination C$/ do |title| + step %{I start signing up for "#{title}"} + step %{I check the 1st checkbox with the value "Stargate SG-1"} + step %{I check the 2nd checkbox with the value "Stargate SG-1"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Something else weird"} + step %{I fill in the 2nd field with id matching "freeform_tagnames" with "Something else weird"} + click_button "Submit" +end + +When /^I sign up for "([^\"]*)" with combination D$/ do |title| + step %{I start signing up for "#{title}"} + step %{I check the 1st checkbox with the value "Stargate Atlantis"} + step %{I check the 2nd checkbox with the value "Stargate Atlantis"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Something else weird, Alternate Universe - Historical"} + step %{I fill in the 2nd field with id matching "freeform_tagnames" with "Something else weird, Alternate Universe - Historical"} + click_button "Submit" +end + +When /^I sign up for "([^\"]*)" with a mismatched combination$/ do |title| + step %{I start signing up for "#{title}"} + step %{I check the 1st checkbox with the value "Bad Choice"} + step %{I check the 2nd checkbox with the value "Bad Choice"} + click_button "Submit" +end + + +When /^I sign up for "([^\"]*)" with combination SGA$/ do |title| + step %{I start signing up for "#{title}"} + step %{I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_fandom_tagnames" with "Stargate Atlantis"} + fill_in("challenge_signup_requests_attributes_0_title", with: "SGA love") + click_button "Submit" +end + +When /^I sign up for "([^\"]*)" with combination SG-1$/ do |title| + step %{I start signing up for "#{title}"} + step %{I fill in "challenge_signup_requests_attributes_0_tag_set_attributes_fandom_tagnames" with "Stargate SG-1"} + fill_in("challenge_signup_requests_attributes_0_title", with: "SG1 love") + click_button "Submit" +end + +When /^I sign up for "([^\"]*)" with missing prompts$/ do |title| + step %{I start signing up for "#{title}"} + step %{I check the 1st checkbox with the value "Stargate Atlantis"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Something else weird"} + click_button "Submit" +end + +When /^I start to sign up for "([^\"]*)"$/ do |title| + step %{I start signing up for "#{title}"} + step %{I check the 1st checkbox with value "Stargate SG-1"} +end + +When /^I start to sign up for "([^\"]*)" tagless gift exchange$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Sign Up"} + step %{I fill in "Description" with "random text"} + step %{I press "Submit"} + step %{I should see "Sign-up was successfully created"} +end + +Then "I should see participant number {int} with byline {string}" do |num, byline| + within(:xpath, ".//dt[@class=\"participant\"][#{num}]") { expect(page).to have_content(byline) } +end + +Then "I should see all the participants who have signed up" do + step %{I should see participant number 1 with byline "myname1_pseud (myname1)"} + step %{I should see participant number 2 with byline "myname2"} + step %{I should see participant number 3 with byline "myname3"} + step %{I should see participant number 4 with byline "myname4"} +end + +## Matching + +Given /^the gift exchange "([^\"]*)" is ready for matching$/ do |title| + step %{the gift exchange "#{title}" is ready for signups} + step %{everyone has signed up for the gift exchange "#{title}"} +end + +Given /^I create an invalid signup in the gift exchange "([^\"]*)"$/ do |challengename| + collection = Collection.find_by(title: challengename) + # create an invalid signup by deleting the first one's offers, + # bypassing the validation checks + collection.signups.first.offers.delete_all +end + +When /^I remove a recipient$/ do + step %{I fill in the 1st field with id matching "_request_signup_pseud" with ""} +end + +When /^I assign a recipient to herself$/ do + first_recip_field = page.all("input[type='text']").select {|el| el['id'] && el['id'].match(/_request_signup_pseud/)}[0] + recip = first_recip_field['value'] + id = first_recip_field['id'] + if id.match(/assignments_(\d+)_request/) + num = $1 + fill_in "challenge_assignments_#{num}_offer_signup_pseud", with: recip + end +end + +When /^I manually destroy the assignments for "([^\"]*)"$/ do |title| + collection = Collection.find_by(title: title) + collection.assignments.destroy_all +end + +When /^I assign a pinch hitter$/ do + step %{I fill in the 1st field with id matching "pinch_hitter_byline" with "mod1"} +end + +When /^I assign a pinch recipient$/ do + name = page.all("td").select {|el| el['id'] && el['id'].match(/offer_signup_for/)}[0].text + pseud = Pseud.find_by(name: name) + request_pseud = ChallengeSignup.where(pseud_id: pseud.id).first.offer_potential_matches.first.request_signup.pseud.byline + step %{I fill in the 1st field with id matching "request_signup_pseud" with "#{request_pseud}"} +end + +Given /^everyone has signed up for the gift exchange "([^\"]*)"$/ do |challengename| + step %{I am logged in as "myname1"} + pseud = User.find_by(login: "myname1").pseuds.find_or_create_by(name: "myname1_pseud") + step %{I sign up for "#{challengename}" with combination A and my pseud "#{pseud.name}"} + step %{I am logged in as "myname2"} + step %{I sign up for "#{challengename}" with combination B} + step %{I am logged in as "myname3"} + step %{I sign up for "#{challengename}" with combination C} + step %{I am logged in as "myname4"} + step %{I sign up for "#{challengename}" with combination D} +end + +Given /^I have generated matches for "([^\"]*)"$/ do |challengename| + step %{I close signups for "#{challengename}"} + step %{I follow "Matching"} + step %{I press "Generate Potential Matches"} + step %{I reload the page} + step %{all emails have been delivered} +end + +Given /^I have sent assignments for "([^\"]*)"$/ do |challengename| + step %{I press "Send Assignments"} + step %{I reload the page} + step %{I should not see "Assignments are now being sent out"} +end + +Given /^everyone has their assignments for "([^\"]*)"$/ do |challenge_title| + step %{the gift exchange "#{challenge_title}" is ready for matching} + step %{I have generated matches for "#{challenge_title}"} + step %{I have sent assignments for "#{challenge_title}"} +end + +Given "{string} has an assignment for the user {string} in the collection {string}" do |giver_login, recip_login, collection_name| + giver = User.find_by(login: giver_login) + recip = User.find_by(login: recip_login) + collection = FactoryBot.create(:collection, name: collection_name, title: collection_name) + assignment = FactoryBot.create(:challenge_assignment, sent_at: Time.zone.now, collection_id: collection.id) + assignment.offer_signup.update_column(:pseud_id, giver.default_pseud_id) + assignment.request_signup.update_column(:pseud_id, recip.default_pseud_id) + assignment.reload +end + +### Fulfilling assignments + +When /^I start to fulfill my assignment$/ do + step %{I follow "My Dashboard"} + step %{I follow "Assignments ("} + step %{I follow "Fulfill"} + step %{I fill in "Work Title" with "Fulfilled Story"} + step %{I select "Not Rated" from "Rating"} + step %{I check "No Archive Warnings Apply"} + step %{I select "English" from "Choose a language"} + step %{I fill in "Fandom" with "Final Fantasy X"} + step %{I fill in "content" with "This is a really cool story about Final Fantasy X"} +end + +When /^I fulfill my assignment$/ do + step %{I start to fulfill my assignment} + step %{I press "Preview"} + step %{I press "Post"} + step %{I should see "Work was successfully posted"} +end + +When /^an assignment has been fulfilled in a gift exchange$/ do + step %{everyone has their assignments for "Awesome Gift Exchange"} + step %{I am logged in as "myname1"} + step %{I fulfill my assignment} +end + +# we're not testing the process of rejection here, just that +# it doesn't affect the completion status of the challenge assignment +When /^I refuse my gift story "(.*?)"/ do |work| + w = Work.find_by(title: work) + w.gifts.first.toggle!(:rejected) +end + +### WHEN we need the author attribute to be set +When /^I fulfill my assignment and the author is "([^\"]*)"$/ do |new_user| + step %{I start to fulfill my assignment} + step %{I select "#{new_user}" from "Author / Pseud(s)"} + step %{I press "Preview"} + step %{I press "Post"} + step %{I should see "Work was successfully posted"} +end + +When /^I have set up matching for "([^\"]*)" with no required matching$/ do |challengename| + step %{I am logged in as "mod1"} + step %{I have created the gift exchange "Awesome Gift Exchange"} + step %{I open signups for "Awesome Gift Exchange"} + step %{everyone has signed up for the gift exchange "Awesome Gift Exchange"} +end + +### Deleting a gift exchange + +Then /^I should not see the gift exchange dashboard for "([^\"]*)"$/ do |challenge_title| + collection = Collection.find_by(title: challenge_title) + visit collection_path(collection) + step %{I should not see "Gift Exchange" within "#dashboard"} + step %{I should not see "Sign-up Form" within "#dashboard"} + step %{I should not see "My Sign-up" within "#dashboard"} + step %{I should not see "Sign-ups" within "#dashboard"} + step %{I should not see "Challenge Settings" within "#dashboard"} + step %{I should not see "Sign-up Summary" within "#dashboard"} + step %{I should not see "Requests Summary" within "#dashboard"} + step %{I should not see "Matching" within "#dashboard"} + step %{I should not see "Assignments" within "#dashboard"} + step %{I should not see "Challenge Settings" within "#dashboard"} +end + +Then /^no one should have an assignment for "([^\"]*)"$/ do |challenge_title| + collection = Collection.find_by(title: challenge_title) + User.all.each do |user| + user.offer_assignments.in_collection(collection).should be_empty + user.pinch_hit_assignments.in_collection(collection).should be_empty + end +end diff --git a/features/step_definitions/challenge_promptmeme_steps.rb b/features/step_definitions/challenge_promptmeme_steps.rb new file mode 100755 index 0000000..b4582c2 --- /dev/null +++ b/features/step_definitions/challenge_promptmeme_steps.rb @@ -0,0 +1,557 @@ + +Given /^I have Battle 12 prompt meme set up$/ do + step %{I am logged in as "mod1"} + step "I have standard challenge tags setup" + step "I set up Battle 12 promptmeme collection" +end + +Given /^I have Battle 12 prompt meme fully set up$/ do + step %{I am logged in as "mod1"} + step "I have standard challenge tags setup" + step "I set up Battle 12 promptmeme collection" + step "I fill in Battle 12 challenge options" +end + +Given /^I have no-column prompt meme fully set up$/ do + step %{I am logged in as "mod1"} + step "I have standard challenge tags setup" + step "I set up Battle 12 promptmeme collection" + step "I fill in no-column challenge options" +end + +Given /^I have single-prompt prompt meme fully set up$/ do + step %{I am logged in as "mod1"} + step "I have standard challenge tags setup" + step "I set up Battle 12 promptmeme collection" + step "I fill in single-prompt challenge options" +end + +Given /^everyone has signed up for Battle 12$/ do + # no anon + step %{I am logged in as "myname1"} + step %{I sign up for Battle 12 with combination A} + + # both anon + step %{I am logged in as "myname2"} + step %{I sign up for Battle 12 with combination B} + + # one anon + step %{I am logged in as "myname3"} + step %{I sign up for Battle 12} + + # no anon + step %{I am logged in as "myname4"} + step %{I sign up for Battle 12 with combination C} +end + +Given /^an anon has signed up for Battle 12$/ do + # both anon + step %{I am logged in as "myname2"} + step %{I sign up for Battle 12 with combination B} +end + +Given /^"([^\"]*)" has signed up for Battle 12 with combination ([^\"]*)$/ do |username, combo| + step %{I am logged in as "#{username}"} + step %{I sign up for Battle 12 with combination #{combo}} +end + +Given /^"([^\"]*)" has signed up for Battle 12 with one more prompt than required$/ do |username| + step %{I am logged in as "#{username}"} + step %{I sign up for Battle 12 with combination C} + step %{I add a new prompt to my signup for a prompt meme} +end + +Given /^"([^\"]*)" has fulfilled a claim from Battle 12$/ do |username| + step %{"#{username}" has claimed a prompt from Battle 12} + step %{I fulfill my claim} +end + +Given /^"([^\"]*)" has deleted their sign up for the prompt meme "([^\"]*)"$/ do |username, challenge_title| + step %{I am logged in as "#{username}"} + step %{I delete my signup for the prompt meme "#{challenge_title}"} +end + +Given /^"([^\"]*)" has claimed a prompt from Battle 12$/ do |username| + step %{I am logged in as "#{username}"} + step %{I claim a prompt from "Battle 12"} +end + +When /^I set up an?(?: ([^"]*)) promptmeme "([^\"]*)"(?: with name "([^"]*)")?$/ do |type, title, name| + step %{I am logged in as "mod1"} + visit new_collection_path + if name.nil? + fill_in("collection_name", with: "promptcollection") + else + fill_in("collection_name", with: name) + end + fill_in("collection_title", with: title) + if type == "anon" + check("This collection is unrevealed") + check("This collection is anonymous") + end + select("Prompt Meme", from: "challenge_type") + step %{I submit} + step "I should see \"Collection was successfully created\"" + + check("prompt_meme_signup_open") + fill_in("prompt_meme_requests_num_allowed", with: ArchiveConfig.PROMPT_MEME_PROMPTS_MAX) + fill_in("prompt_meme_requests_num_required", with: 1) + fill_in("prompt_meme_request_restriction_attributes_fandom_num_required", with: 1) + fill_in("prompt_meme_request_restriction_attributes_fandom_num_allowed", with: 2) + fill_in("Sign-up opens:", with: Date.yesterday) + fill_in("Sign-up closes:", with: Date.tomorrow) + step %{I submit} + step "I should see \"Challenge was successfully created\"" +end + +When /^I set up Battle 12 promptmeme collection$/ do + step %{I am logged in as "mod1"} + visit new_collection_path + fill_in("collection_name", with: "lotsofprompts") + fill_in("collection_title", with: "Battle 12") + fill_in("Introduction", with: "Welcome to the meme") + fill_in("FAQ", with: "<dl><dt>What is this thing?</dt><dd>It is a comment fic thing</dd></dl>") + fill_in("Rules", with: "Be nicer to people") + check("This collection is unrevealed") + check("This collection is anonymous") + select("Prompt Meme", from: "challenge_type") + step %{I submit} + step "I should see \"Collection was successfully created\"" +end + +When /^I create Battle 12 promptmeme$/ do + step "I set up Battle 12 promptmeme collection" + step "I fill in Battle 12 challenge options" +end + +When /^I fill in Battle 12 challenge options$/ do + step "I fill in prompt meme challenge options" + step %{I fill in "Sign-up Instructions" with "Please request easy things"} + fill_in("Sign-up opens:", with: Date.yesterday) + fill_in("Sign-up closes:", with: Date.tomorrow) + step %{I select "(GMT-05:00) Eastern Time (US & Canada)" from "Time zone"} + step %{I fill in "prompt_meme_requests_num_allowed" with "3"} + check("prompt_meme_request_restriction_attributes_title_allowed") + step %{I submit} +end + +When /^I fill in future challenge options$/ do + step "I fill in prompt meme challenge options" + fill_in("Sign-up opens:", with: Date.yesterday) + fill_in("Sign-up closes:", with: Date.tomorrow) + step %{I fill in "prompt_meme_requests_num_allowed" with "3"} + step %{I uncheck "Sign-up open?"} + step %{I submit} +end + +When /^I fill in past challenge options$/ do + step "I fill in prompt meme challenge options" + step %{I fill in "Sign-up opens" with "2010-09-20 12:40AM"} + step %{I fill in "Sign-up closes" with "2010-09-20 12:40AM"} + step %{I fill in "prompt_meme_requests_num_allowed" with "3"} + step %{I uncheck "Sign-up open?"} + step %{I submit} +end + +When /^I fill in no-column challenge options$/ do + step %{I fill in "prompt_meme_requests_num_required" with "1"} + step %{I fill in "prompt_meme_request_restriction_attributes_fandom_num_allowed" with "0"} + step %{I fill in "prompt_meme_request_restriction_attributes_character_num_allowed" with "0"} + step %{I fill in "prompt_meme_request_restriction_attributes_relationship_num_allowed" with "0"} + step %{I check "Sign-up open?"} + fill_in("Sign-up opens:", with: Date.yesterday) + fill_in("Sign-up closes:", with: Date.tomorrow) + step %{I submit} +end + +When /^I fill in single-prompt challenge options$/ do + step %{I fill in "prompt_meme_requests_num_required" with "1"} + step %{I check "Sign-up open?"} + check("prompt_meme_request_restriction_attributes_title_allowed") + fill_in("Sign-up opens:", with: Date.yesterday) + fill_in("Sign-up closes:", with: Date.tomorrow) + step %{I submit} +end + +When /^I fill in multi-prompt challenge options$/ do + step "I fill in prompt meme challenge options" + step %{I fill in "prompt_meme_requests_num_allowed" with "4"} + step %{I submit} +end + +When /^I fill in prompt meme challenge options$/ do + step %{I fill in "General Sign-up Instructions" with "Here are some general tips"} + fill_in("Tag Sets To Use:", with: "Standard Challenge Tags") + step %{I fill in "prompt_meme_request_restriction_attributes_fandom_num_required" with "1"} + step %{I fill in "prompt_meme_request_restriction_attributes_fandom_num_allowed" with "1"} + step %{I fill in "prompt_meme_request_restriction_attributes_freeform_num_allowed" with "2"} + step %{I fill in "prompt_meme_requests_num_required" with "2"} + step %{I check "Sign-up open?"} + fill_in("Sign-up opens:", with: Date.yesterday) + fill_in("Sign-up closes:", with: Date.tomorrow) +end + +When /^I allow (\d+) prompts$/ do |number| + fill_in("prompt_meme_requests_num_allowed", with: number) +end + +When /^I require (\d+) prompts$/ do |number| + fill_in("prompt_meme_requests_num_required", with: number) +end + +When /^I sign up for Battle 12$/ do + step %{I start signing up for "Battle 12"} + step %{I check the 1st checkbox with the value "Stargate SG-1"} + step %{I check the 2nd checkbox with the value "Stargate SG-1"} + step %{I check the 2nd checkbox with id matching "anonymous"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Something else weird"} + step %{I fill in the 1st field with id matching "title" with "crack"} + # We have to use explicit button names because there are two forms on this page - the form to expand prompts + click_button "Submit" +end + +When /^I sign up for Battle 12 with combination A$/ do + step %{I start signing up for "Battle 12"} + step %{I check the 1st checkbox with the value "Stargate Atlantis"} + step %{I check the 2nd checkbox with the value "Stargate Atlantis"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Alternate Universe - Historical"} + click_button "Submit" +end + +When /^I sign up for Battle 12 with combination B$/ do + step %{I start signing up for "Battle 12"} + step %{I check the 1st checkbox with the value "Stargate SG-1"} + step %{I check the 2nd checkbox with the value "Stargate Atlantis"} + step %{I check the 1st checkbox with id matching "anonymous"} + step %{I check the 2nd checkbox with id matching "anonymous"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Alternate Universe - High School, Something else weird"} + step %{I fill in the 1st field with id matching "title" with "High School AU SG1"} + step %{I fill in the 2nd field with id matching "title" with "random SGA love"} + click_button "Submit" + step %{I should see "Sign-up was successfully created"} +end + +When /^I sign up for Battle 12 with combination C$/ do + step %{I start signing up for "Battle 12"} + step %{I check the 1st checkbox with the value "Stargate Atlantis"} + step %{I check the 2nd checkbox with the value "Stargate Atlantis"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Something else weird, Alternate Universe - Historical"} + step %{I fill in the 1st field with id matching "title" with "weird SGA history AU"} + step %{I fill in the 2nd field with id matching "title" with "canon SGA love"} + click_button "Submit" + step %{I should see "Sign-up was successfully created"} + step %{I should see "Stargate Atlantis"} + step %{I should see "Something else weird"} +end + +When /^I sign up for Battle 12 with combination D$/ do + step %{I start signing up for "Battle 12"} + step %{I check the 1st checkbox with the value "Stargate Atlantis"} + step %{I check the 2nd checkbox with the value "Stargate Atlantis"} + click_button "Submit" +end + +When /^I sign up for Battle 12 with combination E$/ do + step "I go to the collections page" + step "I follow \"Battle 12\"" + step "I follow \"Sign Up\"" + step %{I fill in "Description:" with "Weird description"} + step "I press \"Submit\"" +end + +When /^I sign up for "([^\"]*)" fixed-fandom prompt meme$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Sign Up"} + step %{I check the 1st checkbox with value "Stargate SG-1"} + step %{I check the 2nd checkbox with value "Stargate SG-1"} + step %{I check the 2nd checkbox with id matching "anonymous"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "Something else weird"} + click_button "Submit" +end + +When /^I sign up for "([^\"]*)" many-fandom prompt meme$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Sign Up"} + step %{I fill in the 1st field with id matching "fandom_tagnames" with "Stargate Atlantis"} + step %{I check the 1st checkbox with id matching "anonymous"} + click_button "Submit" +end + +When /^I add prompt (\d+)$/ do |number| + step %{I add prompt #{number} with "Stargate Atlantis"} +end + +When /^I add prompt (\d+) with "([^"]+)"$/ do |number, tag| + step %{I follow "Add Prompt"} + step %{I should see "Request #{number}"} + step %{I check the 1st checkbox with the value "#{tag}"} + # there is only one form on the individual prompt page + step %{I submit} + step %{I should see "Prompt was successfully added"} +end + +When /^I add prompts up to (\d+) starting with (\d+)$/ do |final_number_of_prompts, start| + @index = start + while @index <= final_number_of_prompts + step "I add prompt #{@index}" + @index = @index + 1 + end +end + +When /^I fill in the missing prompt$/ do + step %{I check the 2nd checkbox with the value "Stargate Atlantis"} + click_button "Submit" +end + +When /^I add a new prompt to my signup$/ do + step %{I follow "Add Prompt"} + step %{I check "Stargate Atlantis"} + step %{I fill in the 1st field with id matching "freeform_tagnames" with "My extra tag"} + step %{I press "Submit"} +end + +When /^I add a new prompt to my signup for a prompt meme$/ do + step %{I follow "Add Prompt"} + step %{I check "Stargate Atlantis"} + step %{I press "Submit"} +end + +When /^I edit the signup by "([^\"]*)"$/ do |participant| + visit collection_path(Collection.find_by(title: "Battle 12")) + step %{I follow "Prompts ("} + step %{I follow "Edit Sign-up"} +end + +### WHEN viewing after signups + +When /^I view my signup for "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "My Prompts"} +end + +When /^I view unposted claims for "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + # step %{show me the sidebar} + step %{I follow "Unposted Claims ("} +end + +When /^I view prompts for "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Prompts ("} +end + +### WHEN claiming + +When /^I claim a prompt from "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Prompts ("} + step %{I press "Claim"} +end + +When /^I claim two prompts from "([^\"]*)"$/ do |title| + step %{I claim a prompt from "#{title}"} + step %{I claim a prompt from "#{title}"} +end + +### WHEN fulfilling claims + +When /^I start to fulfill my claim with "([^\"]*)"$/ do |title| + step %{I follow "My Dashboard"} + step %{I follow "Claims ("} + step %{I follow "Fulfill"} + step %{I fill in "Work Title" with "#{title}"} + step %{I select "Not Rated" from "Rating"} + step %{I check "No Archive Warnings Apply"} + step %{I select "English" from "Choose a language"} + step %{I fill in "Fandom" with "Stargate Atlantis"} + step %{I fill in "content" with "This is an exciting story about Atlantis"} +end + +When /^I start to fulfill my claim$/ do + step %{I start to fulfill my claim with "Fulfilled Story"} +end + +When /^I fulfill my claim$/ do + step %{I start to fulfill my claim with "Fulfilled Story"} + step %{I press "Preview"} + step %{I press "Post"} + step %{I should see "Work was successfully posted"} +end + +When /^I fulfill my claim again$/ do + step %{I follow "My Dashboard"} + step %{I follow "Claims ("} + step %{I follow "Fulfilled Claims"} + step %{I follow "Fulfill"} + step %{I fill in "Work Title" with "Second Story"} + step %{I select "Not Rated" from "Rating"} + step %{I check "No Archive Warnings Apply"} + step %{I select "English" from "Choose a language"} + step %{I fill in "Fandom" with "Stargate Atlantis"} + step %{I fill in "content" with "This is an exciting story about Atlantis"} + step %{I press "Preview"} + step %{I press "Post"} + step %{I should see "Work was successfully posted"} +end + +When /^mod fulfills claim$/ do + step %{I am logged in as "mod1"} + step %{I claim a prompt from "Battle 12"} + step %{I start to fulfill my claim} + step %{I fill in "Work Title" with "Fulfilled Story-thing"} + step %{I fill in "content" with "This is an exciting story about Atlantis, but in a different universe this time"} + step %{I press "Preview"} + step %{I press "Post"} +end + +When /^I delete my prompt in "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Prompts ("} + step %{I press "Delete Prompt"} +end + +When /^I delete the prompt by "([^\"]*)"$/ do |participant| + visit collection_path(Collection.find_by(title: "Battle 12")) + step %{I follow "Prompts ("} + step %{I follow "Delete Prompt"} +end + +When /^I edit the first prompt$/ do + visit collection_path(Collection.find_by(title: "Battle 12")) + step %{I follow "Prompts ("} + # The 'Edit Sign-up' and 'Edit Prompt' buttons were removed for mods in + # Prompt Meme challenges + #step %{I follow "Edit Prompt"} +end + +Then /^I should see prompt meme options$/ do + step %{I should not see "Offer Settings"} + step %{I should see "Request Settings"} + step %{I should not see "If you plan to use automated matching"} + step %{I should not see "Allow Any"} +end + +Then /^I should see a prompt is claimed$/ do + # note, prompts are in reverse date order by default + step %{I should see "New claim made."} + step %{I should see "My Claims in Battle 12"} + step %{I should see "Fulfill"} + step %{I should see "Drop Claim"} + + # Claims in the user page are just the prompts that have been claimed + step %{I follow "My Dashboard"} + step %{I follow "Claims"} + step %{I should see "Fulfill"} + step %{I should see "by Anonymous"} + step %{I should not see "myname" within ".index"} +end + +Then /^I should see correct signups for Battle 12$/ do + step %{I should see "myname4"} + step %{I should see "myname3"} + step %{I should not see "myname2"} + step %{I should see "by Anonymous"} + step %{I should see "myname1"} + step %{I should see "Stargate Atlantis"} + step %{I should see "Stargate SG-1"} + step %{I should see "Something else weird"} + step %{I should see "Alternate Universe - Historical"} + step %{I should not see "Matching"} +end + +Then /^claims are hidden$/ do + step %{I go to "Battle 12" collection's page} + step %{I follow "Unposted Claims"} + step %{I should see "Unposted Claims"} + step %{I should see "Fulfilled Claims"} + step %{I should see "myname" within ".claims"} + step %{I should see "Secret!" within ".claims"} + step %{I should see "Stargate Atlantis"} +end + +Then /^claims are shown$/ do + step %{I go to "Battle 12" collection's page} + step %{I follow "Unposted Claims"} + step %{I should see "myname4" within "h5"} + step %{I should not see "Secret!"} + step %{I should see "Stargate Atlantis"} +end + +Then /^Battle 12 prompt meme should be correctly created$/ do + step %{I should see "Challenge was successfully created"} + step "signup should be open" + step %{"Battle 12" collection exists} + step %{I should see "(Open, Unmoderated, Unrevealed, Anonymous, Prompt Meme Challenge)"} +end + +Then /^my claim should be fulfilled$/ do + step %{I should see "Work was successfully posted"} + step %{I should see "Fandom:"} + step %{I should see "Stargate Atlantis"} + step %{I should not see "Alternate Universe - Historical"} + step %{I should see "In response to a prompt by"} +end + +Then /^I should see the whole signup$/ do + page.should have_content("Sign-up for") + page.should have_content("Requests") + page.should have_content("Request 1") + page.should have_content("Request 2") +end + +Then /^I should see single prompt editing$/ do + page.should have_content("Edit Sign-up") + page.should have_content("Additional Tags") + step %{the field labeled "Additional Tags" should contain "Alternate Universe - Historical"} + page.should have_no_content("Just add one new prompt instead") +end + +Then /^I should see Battle 12 descriptions$/ do + step %{I should see "Welcome to the meme" within "#intro"} + step %{I should see "Sign-up: Open"} + step %{I should see "Sign-up Closes:"} + step %{I should see "#{Time.now.year}" within ".collection .meta"} + step %{I should see "What is this thing?" within "#faq"} + step %{I should see "It is a comment fic thing" within "#faq"} + step %{I should see "Be nicer to people" within "#rules"} +end + +Then /^I should be editing the challenge settings$/ do + step %{I should see "Setting Up the Battle 12 Prompt Meme"} +end + +Then "{int} prompt(s) should be required" do |number| + expect(page).to have_field("prompt_meme_requests_num_required", with: number.to_s) +end + +Then "{int} prompt(s) should be allowed" do |number| + expect(page).to have_field("prompt_meme_requests_num_allowed", with: number.to_s) +end + +Then /^I should not see the prompt meme dashboard for "([^\"]*)"$/ do |challenge_title| + collection = Collection.find_by(title: challenge_title) + visit collection_path(collection) + step %{I should not see "Prompt Meme" within "#dashboard"} + step %{I should not see "Prompts" within "#dashboard"} + step %{I should not see "My Prompts" within "#dashboard"} + step %{I should not see "Prompt Form" within "#dashboard"} + step %{I should not see "My Claims" within "#dashboard"} + step %{I should not see "Unposted Claims" within "#dashboard"} + step %{I should not see "Challenge Settings" within "#dashboard"} +end + +Then /^no one should have a claim in "([^\"]*)"$/ do |challenge_title| + collection = Collection.find_by(title: challenge_title) + if collection.present? + User.all.each do |user| + user.request_claims.in_collection(collection).should be_empty + end + # we don't have a collection id because the collection has been deleted + # so let's make sure any remaining claims are for exisiting collections + else + ChallengeClaim.all.each do |claim| + collection_id = claim.collection_id + Collection.find_by(id: collection_id).should_not be_nil + end + end +end diff --git a/features/step_definitions/challenge_steps.rb b/features/step_definitions/challenge_steps.rb new file mode 100755 index 0000000..36e4da0 --- /dev/null +++ b/features/step_definitions/challenge_steps.rb @@ -0,0 +1,298 @@ +###### ERROR MESSAGES +Then /^I should see a not\-in\-fandom error message for "([^"]+)" in "([^"]+)"$/ do |tag, fandom| + step %{I should see "are not in the selected fandom(s), #{fandom}: #{tag}"} +end + +Then /^I should see a not\-in\-fandom error message$/ do + step %{I should see "are not in the selected fandom(s)"} +end + +### Set up dates correctly ### +Then /^I set up the challenge dates$/ do + fill_in("Sign-up opens:", with: Date.yesterday) + fill_in("Sign-up closes:", with: Date.tomorrow) +end + +### Clear out old data + +Given /^I have no prompts$/ do + Prompt.delete_all +end + +### CHALLENGE TAGS + +Given /^signup summaries are always visible$/ do + stub_const("ArchiveConfig", OpenStruct.new(ArchiveConfig)) + ArchiveConfig.ANONYMOUS_THRESHOLD_COUNT = 0 +end + +Given /^all signup summaries are delayed$/ do + stub_const("ArchiveConfig", OpenStruct.new(ArchiveConfig)) + ArchiveConfig.MAX_SIGNUPS_FOR_LIVE_SUMMARY = 0 +end + +Given /^all signup summaries are live$/ do + stub_const("ArchiveConfig", OpenStruct.new(ArchiveConfig)) + ArchiveConfig.MAX_SIGNUPS_FOR_LIVE_SUMMARY = 1_000_000 +end + +Given /^I have standard challenge tags set ?up$/ do + begin + unless UserSession.find + step %{I am logged in as "mod1"} + end + rescue + step %{I am logged in as "mod1"} + end + step "I have no tags" + step "basic tags" + step %{a canonical fandom "Stargate Atlantis"} + step %{a canonical fandom "Stargate SG-1"} + step %{a canonical fandom "Bad Choice"} + step %{a canonical character "John Sheppard"} + step %{a canonical freeform "Alternate Universe - Historical"} + step %{a canonical freeform "Alternate Universe - High School"} + step %{a canonical freeform "Something else weird"} + step %{a canonical freeform "My extra tag"} + step %{I set up the tag set "Standard Challenge Tags" with the fandom tags "Stargate Atlantis, Stargate SG-1, Bad Choice", the character tag "John Sheppard"} +end + +Given /^I have Yuletide challenge tags set ?up$/ do + step "I have standard challenge tags setup" + step %{I add the fandom tags "Starsky & Hutch, Tiny fandom, Care Bears, Yuletide Hippos RPF, Unoffered, Unrequested" to the tag set "Standard Challenge Tags"} + step %{a canonical fandom "Starsky & Hutch"} + step %{a canonical fandom "Tiny fandom"} + step %{a canonical fandom "Care Bears"} + step %{a canonical fandom "Yuletide Hippos RPF"} + step %{a canonical fandom "Unoffered"} + step %{a canonical fandom "Unrequested"} +end + +### General Challenge Settings + +When /^I edit settings for "([^\"]*)" challenge$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Challenge Settings"} +end + +# Timezone + +When /^I change the challenge timezone to Alaska$/ do + step %{I follow "Challenge Settings"} + step %{I select "(GMT-09:00) Alaska" from "prompt_meme_time_zone"} + step %{I submit} + step %{I should see "Challenge was successfully updated"} +end + +Then /^I should see both timezones$/ do + step %{I follow "Profile"} + step %{I should see "EST ("} + step %{I should see "AKST)"} +end + +Then /^I should see just one timezone$/ do + step %{I follow "Profile"} + step %{I should see "Sign-up: Open"} + step %{I should not see "EST" within "#main"} + step %{I should see "AKST" within "#main"} +end + +# Open signup + +When /^I open signups for "([^\"]*)"$/ do |title| + step %{I am logged in as "mod1"} + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Challenge Settings"} + step %{I check "Sign-up open?"} + step %{I submit} + step %{I should see "Challenge was successfully updated"} +end + +Then /^signup should be open$/ do + step %{I should see "Profile" within "div#main .collection .navigation"} + step %{I should see "Sign-up: Open" within ".collection .meta"} + step %{I should see "Sign-up Closes:"} +end + +When /^I view open challenges$/ do + step "I go to the collections page" + step %{I follow "Open Challenges"} +end + +### Signup process + +When /^I start signing up for "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Sign Up"} +end + +When /^I view the sign-up summary for "(.*?)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %(I follow "Sign-up Summary") +end + +### Editing signups + +When /^I edit my signup for "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Edit Sign-up"} +end + +### WHEN other + +When /^I close signups for "([^\"]*)"$/ do |title| + collection = Collection.find_by(title: title) + user_id = collection.all_owners.first.user_id + mod_login = User.find_by(id: user_id).login + step %{I am logged in as "#{mod_login}"} + visit collection_path(collection) + step %{I follow "Challenge Settings"} + step %{I uncheck "Sign-up open?"} + step %{I press "Update"} + step %{I should see an update confirmation message} +end + +When /^I delete my signup for the prompt meme "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "My Prompts"} + step %{I delete the signup} +end + +When /^I delete my signup for the gift exchange "([^\"]*)"$/ do |title| + visit collection_path(Collection.find_by(title: title)) + step %{I follow "My Sign-up"} + step %{I delete the signup} +end + +When /^I delete the signup by "([^\"]*)"$/ do |participant| + click_link("#{participant}") + step %{I delete the signup} +end + +When /^I delete the signup$/ do + step %{I follow "Delete Sign-up"} + step %{I press "Yes, Delete Sign-up"} + step %{I should see "Challenge sign-up was deleted."} +end + +When /^I reveal the "([^\"]*)" challenge$/ do |title| + step %{I am logged in as "mod1"} + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Collection Settings"} + step %{I uncheck "This collection is unrevealed"} + step %{I press "Update"} +end + +When /^I approve the first item in the collection "([^\"]*)"$/ do |collection| + collection = Collection.find_by(title: collection) + collection_item = collection.collection_items.first.id + visit collection_path(collection) + step %{I follow "Manage Items"} + step %{I select "Approved" from "collection_items_#{collection_item}_collection_approval_status"} + step %{I press "Submit"} +end + + +When /^I reveal the authors of the "([^\"]*)" challenge$/ do |title| + step %{I am logged in as "mod1"} + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Collection Settings"} + step %{I uncheck "This collection is anonymous"} + step %{I press "Update"} + step %{all indexing jobs have been run} +end + +When /^I use tomorrow as the "Sign-up closes" date$/ do + fill_in("Sign-up closes:", with: Date.tomorrow) +end + +# Notification messages + +When /^I create an assignment notification message with (an ampersand|linebreaks) for "([^\"]*)"$/ do |message_content, title| + c = Collection.find_by(title: title) + field = "collection_collection_profile_attributes_assignment_notification" + message = if message_content == "an ampersand" + "The first thing & the second thing." + else + "First Line\nSecond Line" + end + + step %{I am logged in as "#{c.owners.first.name}"} + visit collection_path(c) + + # TODO: Once AO3-3376 is fixed, this will need to change. + step %{I follow "Collection Settings"} + + fill_in(field, with: message) + step %{I press "Update"} +end + +Then /^the notification message to "([^\"]*)" should contain linebreaks$/ do |user| + @user = User.find_by(login: user) + email = emails("to: \"#{email_for(@user.email)}\"").first + email.multipart?.should be == true + + text_lines = email.text_part.body.to_s.split("\n") + html_lines = email.html_part.body.to_s.split(%r{<(?:\/?p|br|div)\b[^>]*>}i) + + (text_lines + html_lines).each do |line| + # We shouldn't see "First Line" and "Second Line" on the same line. + line.should_not =~ /Second Line/ if line =~ /First Line/ + end + + email.text_part.body.should =~ /First Line/ + email.text_part.body.should =~ /Second Line/ + email.html_part.body.should =~ /First Line/ + email.html_part.body.should =~ /Second Line/ +end + +Then /^the notification message to "([^\"]*)" should escape the ampersand$/ do |user| + @user = User.find_by(login: user) + email = emails("to: \"#{email_for(@user.email)}\"").first + email.multipart?.should be == true + + email.html_part.body.should =~ /The first thing & the second thing./ + email.html_part.body.should_not =~ /The first thing & the second thing./ +end + +Then /^the notification message to "([^\"]*)" should contain the no archive warnings tag$/ do |user| + @user = User.find_by(login: user) + email = emails("to: \"#{email_for(@user.email)}\"").first + email.multipart?.should be == true + + email.text_part.body.should =~ /Warning:/ + email.text_part.body.should =~ /No Archive Warnings Apply/ + email.text_part.body.should_not =~ /Name with colon/ + + email.html_part.body.should =~ /Warning:/ + email.html_part.body.should =~ /No Archive Warnings Apply/ + email.html_part.body.should_not =~ /Name with colon/ +end + +# Delete challenge + +Given /^the challenge "([^\"]*)" is deleted$/ do |challenge_title| + collection = Collection.find_by(title: challenge_title) + collection.challenge.destroy +end + +When /^I delete the challenge "([^\"]*)"$/ do |challenge_title| + step %{I edit settings for "#{challenge_title}" challenge} + step %{I follow "Delete Challenge"} +end + +Then /^no one should be signed up for "([^\"]*)"$/ do |challenge_title| + collection = Collection.find_by(title: challenge_title) + if collection.present? + User.all.each do |user| + user.challenge_signups.in_collection(collection).should be_empty + end + # we don't have a collection id because the collection has been deleted + # so let's make sure any remaining sign ups are for exisiting collections + else + ChallengeSignup.all.each do |signup| + collection_id = signup.collection_id + Collection.find_by(id: collection_id).should_not be_nil + end + end +end diff --git a/features/step_definitions/challenge_yuletide_steps.rb b/features/step_definitions/challenge_yuletide_steps.rb new file mode 100755 index 0000000..7f84718 --- /dev/null +++ b/features/step_definitions/challenge_yuletide_steps.rb @@ -0,0 +1,24 @@ + +When /^"([^"]*)" posts the fulfilling draft "([^"]*)" in "([^"]*)"$/ do |name, title, fandom| + step %{I am logged in as "#{name}"} + step %{I go to #{name}'s user page} + step %{I follow "Assignments"} + step %{I follow "Fulfill"} + step %{I fill in "Work Title" with "#{title}"} + step %{I fill in "Fandoms" with "#{fandom}"} + step %{I select "Not Rated" from "Rating"} + step %{I check "No Archive Warnings Apply"} + step %{I select "English" from "Choose a language"} + step %{I fill in "content" with "This is an exciting story about #{fandom}"} + step %{I press "Preview"} +end + +When /^"([^"]*)" posts the fulfilling story "([^"]*)" in "([^"]*)"$/ do |name, title, fandom| + step %{"#{name}" posts the fulfilling draft "#{title}" in "#{fandom}"} + step %{I press "Post"} + step %{I should see "Work was successfully posted"} + step %{I should see "For myname"} + step %{I should see "Collections:"} + step %{I should see "Yuletide" within ".meta"} + step %{I should see "Anonymous"} +end \ No newline at end of file diff --git a/features/step_definitions/collection_steps.rb b/features/step_definitions/collection_steps.rb new file mode 100755 index 0000000..ce4b210 --- /dev/null +++ b/features/step_definitions/collection_steps.rb @@ -0,0 +1,306 @@ +### GIVEN + +Given /^I have no collections$/ do + Collection.delete_all +end + +Given /^the collection "([^\"]*)" is deleted$/ do |collection_title| + step %{I am logged in as the owner of "#{collection_title}"} + visit edit_collection_path(Collection.find_by(title: collection_title)) + click_link "Delete Collection" + click_button "Yes, Delete Collection" + page.should have_content("Collection was successfully deleted.") +end + +When /^I am logged in as the owner of "([^\"]*)"$/ do |collection| + c = Collection.find_by(title: collection) + step %{I am logged in as "#{c.owners.first.user.login}"} +end + +When /^I view the collection "([^\"]*)"$/ do |collection| + visit collection_path(Collection.find_by(title: collection)) +end + +When /^I add my work to the collection$/ do + step %{I follow "Add To Collection"} + fill_in("collection_names", with: "Various_Penguins") + click_button("Add") +end + +When "I invite the work {string} to the collection {string}" do |work_title, collection_title| + work = Work.find_by(title: work_title) + collection = Collection.find_by(title: collection_title) + visit work_path(work) + click_link("Invite To Collections") + fill_in("collection_names", with: collection.name) + click_button("Invite") +end + +When "I edit the work {string} to be in the collection(s) {string}" do |work, collection| + step %{I edit the work "#{work}"} + fill_in("Post to Collections / Challenges", with: collection) + step %{I post the work} +end + +When /^I view the ([^"]*) collection items page for "(.*?)"$/ do |item_status, collection| + c = Collection.find_by(title: collection) + if item_status == "approved" + visit collection_items_path(c, status: "approved") + elsif item_status == "rejected by user" + visit collection_items_path(c, status: "rejected_by_user") + elsif item_status == "rejected by collection" + visit collection_items_path(c, status: "rejected_by_collection") + elsif item_status == "awaiting user approval" + visit collection_items_path(c, status: "unreviewed_by_user") + elsif item_status == "awaiting collection approval" + visit collection_items_path(c) + end +end + +When "the collection counts have expired" do + step "all indexing jobs have been run" + step "it is currently #{ArchiveConfig.SECONDS_UNTIL_COLLECTION_COUNTS_EXPIRE} seconds from now" +end + +When "the collection blurb cache has expired" do + step "it is currently #{ArchiveConfig.MINUTES_UNTIL_COLLECTION_BLURBS_EXPIRE} minutes from now" +end + +Given /^mod1 lives in Alaska$/ do + step %{I am logged in as "mod1"} + step %{I go to mod1 preferences page} + step %{I select "(GMT-09:00) Alaska" from "preference_time_zone"} + step %{I press "Update"} +end + +Given /^(?:I have )?(?:a|an|the) (hidden)?(?: )?(anonymous)?(?: )?(moderated)?(?: )?(closed)?(?: )?collection "([^\"]*)"(?: with name "([^\"]*)")?$/ do |hidden, anon, moderated, closed, title, name| + mod = ensure_user("moderator") + collection = FactoryBot.create(:collection, title: title, name: (name.presence || title.gsub(/[^\w]/, "_")), owner: mod.default_pseud) + collection.collection_preference.update_attribute(:anonymous, true) if anon.present? + collection.collection_preference.update_attribute(:unrevealed, true) if hidden.present? + collection.collection_preference.update_attribute(:moderated, true) if moderated.present? + collection.collection_preference.update_attribute(:closed, true) if closed.present? +end + +Given /^I open the collection with the title "([^\"]*)"$/ do |title| + step %{I am logged in as "moderator"} + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Collection Settings"} + step %{I uncheck "This collection is closed"} + step %{I submit} + step %{I am logged out} +end + +Given /^I close the collection with the title "([^\"]*)"$/ do |title| + step %{I am logged in as "moderator"} + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Collection Settings"} + step %{I check "This collection is closed"} + step %{I submit} + step %{I am logged out} +end + +Given /^I have added (?:a|the) co\-moderator "([^\"]*)" to collection "([^\"]*)"$/ do |name, title| + # create the user + step %{I am logged in as "#{name}"} + step %{I am logged in as "mod1"} + visit collection_path(Collection.find_by(title: title)) + click_link("Membership") + step %{I fill in "participants_to_invite" with "#{name}"} + step %{I press "Submit"} + + step %{I select "Moderator" from "#{name}_role"} + # TODO: fix the form, it is malformed right now + click_button("#{name}_submit") + step %{I should see "Updated #{name}"} +end + +Given "I have joined the collection {string} as {string}" do |title, login| + collection = Collection.find_by(title: title) + user = User.find_by(login: login) + FactoryBot.create(:collection_participant, pseud: user.default_pseud, collection: collection, participant_role: "Member") + visit collections_path +end + +Given "a set of collections for searching" do + profile = CollectionProfile.create!(faq: "<dl><dt>What is this test thing?</dt><dd>It's a test collection</dd></dl>", + intro: "Welcome to the test collection", + rules: "Be nice to testers") + FactoryBot.create(:collection, + name: "sometest", + title: "Some Test Collection", + collection_profile: profile) + FactoryBot.create(:collection, + name: "othertest", + title: "Some Other Collection") + FactoryBot.create(:collection, + :closed, + name: "anothertest", + title: "Another Plain Collection") + FactoryBot.create(:collection, + :moderated, + name: "surprisetest", + title: "Surprise Presents", + challenge: FactoryBot.create(:gift_exchange)) + FactoryBot.create(:collection, + name: "swaptest", + title: "Another Gift Swap", + challenge: FactoryBot.create(:gift_exchange)) + FactoryBot.create(:collection, + :closed, + name: "demandtest", + title: "On Demand", + challenge: FactoryBot.create(:prompt_meme)) + + step %{all indexing jobs have been run} +end + +### WHEN + +When /^I set up (?:a|the) collection "([^"]*)"(?: with name "([^"]*)")?$/ do |title, name| + visit new_collection_path + fill_in("collection_name", with: (name.blank? ? title.gsub(/[^\w]/, '_') : name)) + fill_in("collection_title", with: title) +end + +When /^I create (?:a|the) collection "([^"]*)"(?: with name "([^"]*)")?$/ do |title, name| + name = title.gsub(/[^\w]/, '_') if name.blank? + step %{I set up the collection "#{title}" with name "#{name}"} + step %{I submit} +end + +When /^I add (?:a|the) subcollection "([^"]*)"(?: with name "([^"]*)")? to (?:a|the) parent collection named "([^"]*)"$/ do |title, name, parent_name| + if Collection.find_by_name(parent_name).nil? + step %{I create the collection "#{parent_name}" with name "#{parent_name}"} + end + name = title.gsub(/[^\w]/, '_') if name.blank? + step %{I set up the collection "#{title}" with name "#{name}"} + fill_in("collection_parent_name", with: parent_name) + step %{I submit} +end + +When /^I sort by fandom$/ do + within(:xpath, "//li[a[contains(@title,'Sort')]]") do + step %{I follow "Fandom 1"} + end +end + +When /^I reveal works for "([^\"]*)"$/ do |title| + step %{I am logged in as the owner of "#{title}"} + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Collection Settings"} + uncheck "This collection is unrevealed" + click_button "Update" + page.should have_content("Collection was successfully updated") +end + +When /^I reveal authors for "([^\"]*)"$/ do |title| + step %{I am logged in as the owner of "#{title}"} + visit collection_path(Collection.find_by(title: title)) + step %{I follow "Collection Settings"} + uncheck "This collection is anonymous" + click_button "Update" + page.should have_content("Collection was successfully updated") +end + +When /^I check all the collection settings checkboxes$/ do + check("collection_collection_preference_attributes_moderated") + check("collection_collection_preference_attributes_closed") + check("collection_collection_preference_attributes_unrevealed") + check("collection_collection_preference_attributes_anonymous") + check("collection_collection_preference_attributes_show_random") + check("collection_collection_preference_attributes_email_notify") +end + +When "{string} accepts the invitation for their work in the collection {string}" do |username, collection| + the_collection = Collection.find_by(title: collection) + collection_item_id = the_collection.collection_items.first.id + visit user_collection_items_path(User.find_by(login: username)) + step %{I select "Approved" from "collection_items_#{collection_item_id}_user_approval_status"} +end + +When "I approve the work {string} in the collection {string}" do |work, collection| + work = Work.find_by(title: work) + collection = Collection.find_by(title: collection) + item_id = CollectionItem.find_by(item: work, collection: collection).id + visit collection_items_path(collection) + step %{I select "Approved" from "collection_items_#{item_id}_collection_approval_status"} +end + +### THEN + +Then /^"([^"]*)" collection exists$/ do |title| + assert Collection.where(title: title).exists? +end + +Then /^the name of the collection "([^"]*)" should be "([^"]*)"$/ do |title, name| + assert Collection.find_by(title: title).name == name +end + +Then /^I should see a collection not found message for "([^\"]+)"$/ do |collection_name| + step %{I should see /We couldn't find the collection(?:.+and)? #{collection_name}/} +end + +Then /^the collection "(.*)" should be deleted/ do |collection| + assert Collection.where(title: collection).first.nil? +end + +Then /^the work "([^\"]*)" should be hidden from me$/ do |title| + work = Work.find_by(title: title) + visit work_path(work) + expect(page.title).to include("Mystery Work") + expect(page.title).not_to include(title) + expect(page).not_to have_content(title) + expect(page).to have_content("This work is part of an ongoing challenge and will be revealed soon!") + expect(page).not_to have_content(Sanitize.clean(work.chapters.first.content)) + if work.collections.first + step "all indexing jobs have been run" + visit collection_path(work.collections.first) + expect(page).not_to have_content(title) + expect(page).to have_content("Mystery Work") + end + visit user_path(work.users.first) + expect(page).not_to have_content(title) +end + +Then /^the work "([^\"]*)" should be visible to me$/ do |title| + work = Work.find_by(title: title) + visit work_path(work) + page.should have_content(title) + page.should have_content(Sanitize.clean(work.chapters.first.content)) +end + +Then /^the author of "([^\"]*)" should be visible to me on the work page$/ do |title| + work = Work.find_by(title: title) + visit work_path(work) + authors = work.pseuds.uniq.sort.collect(&:byline).join(", ") + page.should have_content("Anonymous [#{authors}]") +end + +Then /^the author of "([^\"]*)" should be publicly visible$/ do |title| + work = Work.find_by(title: title) + byline = work.users.first.pseuds.first.byline + visit work_path(work) + expect(page.title).to include(byline) + step %{I should see "#{byline}" within ".byline"} + if work.collections.first + step "all indexing jobs have been run" + visit collection_path(work.collections.first) + expect(page).to have_content("#{title} by #{byline}") + end +end + +Then /^the author of "([^\"]*)" should be hidden from me$/ do |title| + step "all indexing jobs have been run" + work = Work.find_by(title: title) + byline = work.users.first.pseuds.first.byline + visit work_path(work) + expect(page).not_to have_content(byline) + expect(page.title).to include("Anonymous") + step %{I should see "Anonymous" within ".byline"} + visit collection_path(work.collections.first) + expect(page).not_to have_content("#{title} by #{byline}") + expect(page).to have_content("#{title} by Anonymous") + visit user_path(work.users.first) + expect(page).not_to have_content(title) +end diff --git a/features/step_definitions/comment_steps.rb b/features/step_definitions/comment_steps.rb new file mode 100755 index 0000000..7ce8828 --- /dev/null +++ b/features/step_definitions/comment_steps.rb @@ -0,0 +1,406 @@ +# GIVEN + +Given /^I have the default comment notifications setup$/ do +end + +Given /^I have the receive all comment notifications setup$/ do + step %{I set my preferences to turn on copies of my own comments} +end + +ParameterType( + name: "commentable", + regexp: /the (work|admin post|tag) "([^"]*)"/, + type: ActsAsCommentable::Commentable, + transformer: lambda { |type, title| + case type + when "work" + Work.find_by(title: title) + when "admin post" + AdminPost.find_by(title: title) + when "tag" + Tag.find_by(name: title) + end + } +) + +Given "{commentable} with guest comments enabled" do |commentable| + assert !commentable.is_a?(Tag) + commentable.update_attribute(:comment_permissions, :enable_all) +end + +Given "a guest comment on {commentable}" do |commentable| + commentable = Comment.commentable_object(commentable) + FactoryBot.create(:comment, :by_guest, commentable: commentable) +end + +Given "a comment {string} by {string} on {commentable}" do |text, user, commentable| + user = ensure_user(user) + commentable = Comment.commentable_object(commentable) + FactoryBot.create(:comment, + pseud: user.default_pseud, + commentable: commentable, + comment_content: text) +end + +Given "a reply {string} by {string} on {commentable}" do |text, user, commentable| + user = ensure_user(user) + comment = commentable.comments.first + FactoryBot.create(:comment, + pseud: user.default_pseud, + commentable: comment, + comment_content: text) +end + +Given "image safety mode is enabled for comments on a {string}" do |parent_type| + allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return(parent_type) +end + +Given "image safety mode is disabled for comments" do + allow(ArchiveConfig).to receive(:PARENTS_WITH_IMAGE_SAFETY_MODE).and_return([]) +end + +Given "the setup for testing image safety mode on the admin post {string}" do |title| + step %{the admin post "#{title}"} + step %{a comment "plain text" by "commentrecip" on the admin post "#{title}"} + step %{I am logged in as "commenter"} + visit comment_path(Comment.last) + step %{I follow "Reply"} + with_scope(".odd") do + # Use HTML that will get cleaned up by the sanitizer so we're sure it runs. + fill_in("comment[comment_content]", with: 'OMG! <img src= "https://example.com/image.jpg">') + click_button("Comment") + end + step %{I am logged in as "commentrecip"} +end + +Given "the setup for testing image safety mode on the tag {string}" do |name| + step %{the tag wrangler "commentrecip" with password "password" is wrangler of "#{name}"} + step %{the tag wrangler "commenter" with password "password" is wrangler of "Some Fandom"} + step %{I am logged in as "commenter"} + visit tag_comments_path(Tag.find_by_name(name)) + # Use HTML that will get cleaned up by the sanitizer so we're sure it runs. + fill_in("comment[comment_content]", with: 'OMG! <img src= "https://example.com/image.jpg">') + click_button("Comment") + step %{I am logged in as "commentrecip"} +end + +Given "the setup for testing image safety mode on the work {string}" do |title| + step %{the work "#{title}" by "commentrecip"} + step %{I am logged in as "commenter"} + visit work_path(Work.find_by(title: title)) + # Use HTML that will get cleaned up by the sanitizer so we're sure it runs. + fill_in("comment[comment_content]", with: 'OMG! <img src= "https://example.com/image.jpg">') + click_button("Comment") + step %{I am logged in as "commentrecip"} +end + +# THEN + +Then /^the comment's posted date should be nowish$/ do + nowish = Time.zone.now.strftime('%a %d %b %Y %I:%M%p') + step %{I should see "#{nowish}" within ".posted.datetime"} +end + +Then /^I should see Last Edited nowish$/ do + nowish = Time.zone.now.strftime('%a %d %b %Y %I:%M%p') + step "I should see \"Last Edited #{nowish}\"" +end + +Then /^I should see the comment form$/ do + step %{I should see "New comment on"} +end + +Then /^I should see the reply to comment form$/ do + step %{I should see "Comment as" within ".odd"} +end + +Then /^I should see Last Edited in the right timezone$/ do + zone = Time.current.in_time_zone(Time.zone).zone + step %{I should see "#{zone}" within ".comment .posted"} + step %{I should see "Last Edited"} +end + +# WHEN + +When /^I set up the comment "([^"]*)" on the work "([^"]*)"$/ do |comment_text, work| + work = Work.find_by(title: work) + visit work_path(work) + fill_in("comment[comment_content]", with: comment_text) +end + +When "I set up the comment {string} on the admin post {string}" do |comment_text, admin_post| + admin_post = AdminPost.find_by(title: admin_post) + visit admin_post_path(admin_post) + fill_in("comment[comment_content]", with: comment_text) +end + +When "I set up the comment {string} on the work {string} with guest comments enabled" do |comment_text, work| + work = Work.find_by(title: work) + work.update_attribute(:comment_permissions, :enable_all) + visit work_path(work) + fill_in("comment[comment_content]", with: comment_text) +end + +When /^I attempt to comment on "([^"]*)" with a pseud that is not mine$/ do |work| + step %{I am logged in as "commenter"} + step %{I set up the comment "This is a test" on the work "#{work}"} + work_id = Work.find_by(title: work).id + pseud_id = User.first.pseuds.first.id + find("#comment_pseud_id_for_#{work_id}", visible: false).set(pseud_id) + click_button "Comment" +end + +When /^I attempt to update a comment on "([^"]*)" with a pseud that is not mine$/ do |work| + step %{I am logged in as "commenter"} + step %{I post the comment "blah blah blah" on the work "#{work}"} + step %{I follow "Edit"} + pseud_id = User.first.pseuds.first.id + find(:xpath, "//input[@name='comment[pseud_id]']", visible: false).set(pseud_id) + click_button "Update" +end + +When /^I post the comment "([^"]*)" on the work "([^"]*)"$/ do |comment_text, work| + step "I set up the comment \"#{comment_text}\" on the work \"#{work}\"" + click_button("Comment") +end + +When "I post the comment {string} on the admin post {string}" do |comment_text, work| + step "I set up the comment \"#{comment_text}\" on the admin post \"#{work}\"" + click_button("Comment") +end + +When /^I post the comment "([^"]*)" on the work "([^"]*)" as a guest(?: with email "([^"]*)")?$/ do |comment_text, work, email| + step "I start a new session" + step %{I set up the comment "#{comment_text}" on the work "#{work}" with guest comments enabled} + fill_in("Guest name", with: "guest") + fill_in("Guest email", with: (email || "guest@foo.com")) + click_button "Comment" +end + +When /^I edit a comment$/ do + step %{I follow "Edit"} + fill_in("comment[comment_content]", with: "Edited comment") + click_button "Update" +end + +# this step assumes we are on a page with a comment form +When /^I post a comment "([^"]*)"$/ do |comment_text| + fill_in("comment[comment_content]", with: comment_text) + click_button("Comment") +end + +# this step assumes that the reply-to-comment form can be opened +When /^I reply to a comment with "([^"]*)"$/ do |comment_text| + step %{I follow "Reply"} + step %{I should see the reply to comment form} + with_scope(".odd") do + fill_in("comment[comment_content]", with: comment_text) + click_button("Comment") + end +end + +When /^I visit the new comment page for the work "([^"]+)"$/ do |work| + work = Work.find_by(title: work) + visit new_work_comment_path(work, only_path: false) +end + +When /^I comment on an admin post$/ do + step "I go to the admin-posts page" + step %{I follow "Default Admin Post"} + step %{I fill in "comment[comment_content]" with "Excellent, my dear!"} + step %{I press "Comment"} +end + +When "I try to post a spam comment" do + fill_in("comment[name]", with: "spammer") + fill_in("comment[email]", with: "spammer@example.org") + fill_in("comment[comment_content]", with: "Buy my product! http://spam.org") + click_button("Comment") +end + +When "I post a spam comment" do + step "I try to post a spam comment" + step %{I should see "Comment created!"} +end + +When "Akismet will flag any comment by {string}" do |username| + allow_any_instance_of(Comment).to receive(:spam?) do |comment| + comment.name == username || comment.user.login == username + end +end + +When "Akismet will flag any comment containing {string}" do |spam_text| + allow_any_instance_of(Comment).to receive(:spam?) do |comment| + comment.comment_content.include?(spam_text) + end +end + +When "I post a guest comment {string}" do |comment_content| + fill_in("comment[name]", with: "guest") + fill_in("comment[email]", with: "guest@example.org") + fill_in("comment[comment_content]", with: comment_content) + click_button("Comment") + step %{I should see "Comment created!"} +end + +When "I post a guest comment" do + step "I post a guest comment \"This was really lovely!\"" +end + +When /^all comments by "([^"]*)" are marked as spam$/ do |name| + Comment.where(name: name).find_each(&:mark_as_spam!) +end + +When /^I compose an invalid comment(?: within "([^"]*)")?$/ do |selector| + with_scope(selector) do + fill_in("Comment", with: "Now, we can devour the gods, together! " * 270) + end +end + +When /^I delete the comment$/ do + step %{I follow "Delete" within ".odd"} + step %{I follow "Yes, delete!"} +end + +When /^I delete the reply comment$/ do + step %{I follow "Delete" within ".even"} + step %{I follow "Yes, delete!"} +end + +When /^I view the latest comment$/ do + visit comment_path(Comment.last) +end + +Given "the moderated work {string} by {string}" do |title, login| + user = ensure_user(login) + w = FactoryBot.create(:work, title: title, authors: [user.default_pseud]) + w.update_attribute(:moderated_commenting_enabled, true) +end + +Then /^comment moderation should be enabled on "([^\"]*?)"/ do |work| + w = Work.find_by(title: work) + assert w.moderated_commenting_enabled? +end + +Then /^comment moderation should not be enabled on "([^\"]*?)"/ do |work| + w = Work.find_by(title: work) + assert !w.moderated_commenting_enabled? +end + +Then /^the comment on "([^\"]*?)" should be marked as unreviewed/ do |work| + w = Work.find_by(title: work) + assert w.comments.first.unreviewed? +end + +Then /^the comment on "([^\"]*?)" should not be marked as unreviewed/ do |work| + w = Work.find_by(title: work) + assert !w.comments.first.unreviewed? +end + +When "I view {commentable} with comments" do |commentable| + if commentable.is_a?(Tag) + visit tag_comments_path(commentable) + else + visit polymorphic_path(commentable, show_comments: true) + end +end + +When /^I view the unreviewed comments page for "([^\"]*?)"/ do |work| + w = Work.find_by(title: work) + visit unreviewed_work_comments_path(w) +end + +When /^I visit the thread for the comment on "([^\"]*?)"/ do |work| + w = Work.find_by(title: work) + visit comment_path(w.comments.first) +end + +Then /^there should be (\d+) comments on "([^\"]*?)"/ do |num, work| + w = Work.find_by(title: work) + assert w.find_all_comments.count == num.to_i +end + +Given /^the moderated work "([^\"]*)" by "([^\"]*)" with the approved comment "([^\"]*)" by "([^\"]*)"/ do |work, author, comment, commenter| + step %{the moderated work "#{work}" by "#{author}"} + step %{I am logged in as "#{commenter}"} + step %{I post the comment "#{comment}" on the work "#{work}"} + step %{I am logged in as "#{author}"} + step %{I view the unreviewed comments page for "#{work}"} + step %{I press "Approve"} +end + +When /^I reload the comments on "([^\"]*?)"/ do |work| + w = Work.find_by(title: work) + w.find_all_comments.each { |c| c.reload } +end + +When "{string} posts a deeply nested comment thread on {string}" do |username, work| + work = Work.find_by(title: work) + chapter = work.chapters[0] + user = User.find_by(login: username) + + commentable = chapter + + count = ArchiveConfig.COMMENT_THREAD_MAX_DEPTH + 1 + + count.times do |i| + commentable = Comment.create( + commentable: commentable, + parent: chapter, + comment_content: "This is a comment at depth #{i}.", + pseud: user.default_pseud + ) + end + + # As long as there's only one child comment, it'll keep displaying the child. + # So we need two comments at the final depth: + 2.times do |i| + ordinal = i.zero? ? "first" : "second" + Comment.create( + commentable: commentable, + parent: chapter, + comment_content: "This is the #{ordinal} hidden comment.", + pseud: user.default_pseud + ) + end +end + +Then /^I (should|should not) see the deeply nested comments$/ do |should_or_should_not| + step %{I #{should_or_should_not} see "This is the first hidden comment."} + step %{I #{should_or_should_not} see "This is the second hidden comment."} +end + +When /^I delete all visible comments on "([^\"]*?)"$/ do |work| + work = Work.find_by(title: work) + + loop do + visit work_url(work, show_comments: true) + break unless page.has_content? "Delete" + click_link("Delete") + click_link("Yes, delete!") # TODO: Fix along with comment deletion. + end +end + +When "I mark the comment as spam" do + click_link("Spam") +end + +When "I confirm I want to mark the comment as spam" do + expect(page.accept_alert).to eq("Are you sure you want to mark this as spam?") if @javascript +end + +When "I display comments" do + click_link("Comments") +end + +When "I open the reply box" do + click_link("Reply") +end + +When "I cancel the reply box" do + click_link("Cancel") +end + +When "I reply on a new page" do + visit find(:link, "Reply")["href"] +end diff --git a/features/step_definitions/email_custom_steps.rb b/features/step_definitions/email_custom_steps.rb new file mode 100755 index 0000000..ea97134 --- /dev/null +++ b/features/step_definitions/email_custom_steps.rb @@ -0,0 +1,139 @@ +Given "the email queue is clear" do + reset_mailer +end + +Given "a locale with translated emails" do + FactoryBot.create(:locale, iso: "new", email_enabled: true) + # The footer keys are used in most emails + I18n.backend.store_translations(:new, { mailer: { general: { footer: { about: { html: "Translated footer", text: "Translated footer" } } } } }) + I18n.backend.store_translations(:new, { kudo_mailer: { batch_kudo_notification: { subject: "Translated subject" } } }) + I18n.backend.store_translations(:new, { users: { mailer: { reset_password_instructions: { subject: "Translated subject" } } } }) +end + +Given "the user {string} enables translated emails" do |user| + user = User.find_by(login: user) + $rollout.activate_user(:set_locale_preference, user) + user.preference.update!(locale: Locale.find_by(iso: "new")) +end + +When "the locale preference feature flag is disabled for user {string}" do |user| + user = User.find_by(login: user) + $rollout.deactivate_user(:set_locale_preference, user) +end + +When "translated emails are disabled for the locale" do + Locale.find_by(iso: "new").update_attribute(:email_enabled, false) +end + +Then "the email to {string} should be translated" do |user| + step(%{the email to "#{user}" should contain "Translated footer"}) + step(%{the email to "#{user}" should not contain "fan-run and fan-supported archive"}) # untranslated English text + step(%{the email to "#{user}" should not contain "translation missing"}) # missing translations in the target language fall back to English +end + +Then "the email to email address {string} should be translated" do |email_address| + step(%{the email to email address "#{email_address}" should contain "Translated footer"}) + step(%{the email to email address "#{email_address}" should not contain "fan-run and fan-supported archive"}) # untranslated English text + step(%{the email to email address "#{email_address}" should not contain "translation missing"}) # missing translations in the target language fall back to English +end + +Then "the last email to {string} should be translated" do |user| + step(%{the last email to "#{user}" should contain "Translated footer"}) + step(%{the last email to "#{user}" should not contain "fan-run and fan-supported archive"}) # untranslated English text + step(%{the last email to "#{user}" should not contain "translation missing"}) # missing translations in the target language fall back to English +end + +Then "the email to {string} should be non-translated" do |user| + step(%{the email to "#{user}" should not contain "Translated footer"}) + step(%{the email to "#{user}" should contain "fan-run and fan-supported archive"}) + step(%{the email to "#{user}" should not contain "translation missing"}) +end + +Then "the last email to {string} should be non-translated" do |user| + step(%{the last email to "#{user}" should not contain "Translated footer"}) + step(%{the last email to "#{user}" should contain "fan-run and fan-supported archive"}) + step(%{the last email to "#{user}" should not contain "translation missing"}) +end + +Then "{string} should be emailed" do |user| + @user = User.find_by(login: user) + expect(emails("to: \"#{email_for(@user.email)}\"")).not_to be_empty +end + +Then "the email address {string} should be emailed" do |email_address| + expect(emails("to: \"#{email_for(email_address)}\"")).not_to be_empty +end + +Then "{string} should not be emailed" do |user| + @user = User.find_by(login: user) + expect(emails("to: \"#{email_for(@user.email)}\"")).to be_empty +end + +Then "the email to {string} should contain {string}" do |user, text| + @user = User.find_by(login: user) + email = emails("to: \"#{email_for(@user.email)}\"").first + if email.multipart? + expect(email.text_part.body).to match(text) + expect(email.html_part.body).to match(text) + else + expect(email.body).to match(text) + end +end + +Then "the email to email address {string} should contain {string}" do |email_address, text| + email = emails("to: \"#{email_for(email_address)}\"").first + if email.multipart? + expect(email.text_part.body).to match(text) + expect(email.html_part.body).to match(text) + else + expect(email.body).to match(text) + end +end + +Then "the last email to {string} should contain {string}" do |user, text| + @user = User.find_by(login: user) + email = emails("to: \"#{email_for(@user.email)}\"").last + if email.multipart? + expect(email.text_part.body).to match(text) + expect(email.html_part.body).to match(text) + else + expect(email.body).to match(text) + end +end + +Then "the email to {string} should not contain {string}" do |user, text| + @user = User.find_by(login: user) + email = emails("to: \"#{email_for(@user.email)}\"").first + if email.multipart? + expect(email.text_part.body).not_to match(text) + expect(email.html_part.body).not_to match(text) + else + expect(email.body).not_to match(text) + end +end + +Then "the email to email address {string} should not contain {string}" do |email_address, text| + email = emails("to: \"#{email_for(email_address)}\"").first + if email.multipart? + expect(email.text_part.body).not_to match(text) + expect(email.html_part.body).not_to match(text) + else + expect(email.body).not_to match(text) + end +end + +Then "the last email to {string} should not contain {string}" do |user, text| + @user = User.find_by(login: user) + email = emails("to: \"#{email_for(@user.email)}\"").last + if email.multipart? + expect(email.text_part.body).not_to match(text) + expect(email.html_part.body).not_to match(text) + else + expect(email.body).not_to match(text) + end +end + +Then "{string} should receive {int} email(s)" do |user, count| + @user = User.find_by(login: user) + expect(emails("to: \"#{email_for(@user.email)}\"").size).to eq(count.to_i) +end diff --git a/features/step_definitions/email_steps.rb b/features/step_definitions/email_steps.rb new file mode 100755 index 0000000..4c9dafd --- /dev/null +++ b/features/step_definitions/email_steps.rb @@ -0,0 +1,105 @@ +# this file generated by script/generate pickle email +# +# add email mappings in features/support/email.rb + +ActionMailer::Base.delivery_method = :test +ActionMailer::Base.perform_deliveries = true + +Before do + ActionMailer::Base.deliveries.clear +end + +# Clear the deliveries array, useful if your background sends email that you want to ignore +Given(/^all emails? (?:have|has) been delivered$/) do + ActionMailer::Base.deliveries.clear + ActionMailer::Base.deliveries.should be_empty # Sanity check, ftw +end + +Given(/^confirmation emails have been delivered$/) do + ActionMailer::Base.deliveries.reject! do |delivery| + delivery.subject == "Confirmation instructions" + end + + ActionMailer::Base.deliveries.select do |delivery| + delivery.subject == "Confirmation instructions" + end.should be_empty +end + +Given(/^(\d)+ emails? should be delivered$/) do |count| + emails.size.should == count.to_i +end + +When(/^(?:I|they) follow "([^"]*?)" in #{capture_email}$/) do |link, email_ref| + address = email(email_ref).to.first + visit_in_email(link, address) +end + +When(/^(?:I|they) click the first link in #{capture_email}$/) do |email_ref| + click_first_link_in_email(email(email_ref).text_part) +end + +Then(/^(\d)+ emails? should be delivered to (.*)$/) do |count, to| + emails("to: \"#{email_for(to)}\"").size.should == count.to_i +end + +Then(/^(\d)+ emails? should be delivered with #{capture_fields}$/) do |count, fields| + emails(fields).size.should == count.to_i +end + +Then(/^#{capture_email} should be delivered to (.+)$/) do |email_ref, to| + email(email_ref, "to: \"#{email_for(to)}\"").should_not be_nil +end + +Then(/^#{capture_email} should not be delivered to (.+)$/) do |email_ref, to| + email(email_ref, "to: \"#{email_for(to)}\"").should be_nil +end + +Then(/^#{capture_email} should have #{capture_fields}$/) do |email_ref, fields| + email(email_ref, fields).should_not be_nil +end + +Then(/^#{capture_email} should have "(.*?)" in the subject$/) do |email_ref, text| + email(email_ref).subject.should =~ /#{text}/ +end + +Then(/^#{capture_email} should contain "(.*)"$/) do |email_ref, text| + if email(email_ref).multipart? + email(email_ref).text_part.body.should =~ /#{text}/ + email(email_ref).html_part.body.should =~ /#{text}/ + else + email(email_ref).body.should =~ /#{text}/ + end +end + +Then(/^#{capture_email} should not contain "(.*)"$/) do |email_ref, text| + if email(email_ref).multipart? + email(email_ref).text_part.body.should_not =~ /#{text}/ + email(email_ref).html_part.body.should_not =~ /#{text}/ + else + email(email_ref).body.should_not =~ /#{text}/ + end +end + +Then(/^#{capture_email} should link to (.+)$/) do |email_ref, page| + expected_url = Regexp.escape(path_to(page)).sub(/^http:/, "https:") + if email(email_ref).multipart? + email(email_ref).text_part.body.should =~ /#{expected_url}/ + email(email_ref).html_part.body.should =~ /#{expected_url}/ + else + email(email_ref).body.should =~ /#{expected_url}/ + end +end + +Then (/^#{capture_email} html body should link to (.+)$/) do |email_ref, page| + email(email_ref).html_part.body.should =~ /#{path_to(page)}/ +end + +Then(/^show me the emails?$/) do + ActionMailer::Base.deliveries.each do |email| + puts "From: #{email.from}" + puts "To: #{email.to}" + puts "Subject: #{email.subject}" + puts email.text_part.body.to_s + puts "" + end +end diff --git a/features/step_definitions/external_work_steps.rb b/features/step_definitions/external_work_steps.rb new file mode 100755 index 0000000..e562a1f --- /dev/null +++ b/features/step_definitions/external_work_steps.rb @@ -0,0 +1,101 @@ +DEFAULT_EXTERNAL_URL = "http://example.org/200" +DEFAULT_EXTERNAL_CREATOR = "Zooey Glass" +DEFAULT_EXTERNAL_TITLE = "A Work Not Posted To The AO3" +DEFAULT_EXTERNAL_SUMMARY = "This is my story, I am its author." +DEFAULT_EXTERNAL_FANDOM = "External Fandom" +DEFAULT_EXTERNAL_RELATIONSHIP = "Charater A & Character B" +DEFAULT_EXTERNAL_CATEGORY = "F/M" +DEFAULT_EXTERNAL_CHARACTERS = "Character A, Character B" +DEFAULT_BOOKMARK_NOTES = "I liked this story." +DEFAULT_BOOKMARK_TAGS = "Awesome" + +Given /^an external work$/ do + step %{I set up an external work} + click_button("Create") +end + +Given /^I set up an external work$/ do + step %{mock websites with no content} + visit new_external_work_path + fill_in("URL", with: DEFAULT_EXTERNAL_URL) + fill_in("external_work_author", with: DEFAULT_EXTERNAL_CREATOR) + fill_in("external_work_title", with: DEFAULT_EXTERNAL_TITLE) + step %{I fill in basic external work tags} + fill_in("bookmark_notes", with: DEFAULT_BOOKMARK_NOTES) + fill_in("Your tags", with: DEFAULT_BOOKMARK_TAGS) +end + +Given /^I bookmark the external work "([^\"]*)"(?: with fandom "([^"]*)")?(?: with character "([^"]*)")?$/ do |title, fandom, character| + step %{I set up an external work} + fill_in("external_work_title", with: title) + fill_in("Fandoms", with: fandom) if fandom.present? + fill_in("Characters", with: character) if character.present? + click_button("Create") +end + +Given "{string} has bookmarked an external work" do |user| + step %{mock websites with no content} + step %{basic tags} + step %{I am logged in as "#{user}"} + visit new_external_work_path + # Typically, when we write step definitions, we prefer to use a + # field's id attribute over its label. But in this case, + # we have to use the labels for some fields because the ids + # change when JavaScript is enabled. + fill_in("URL", with: DEFAULT_EXTERNAL_URL) + fill_in("external_work_author", with: DEFAULT_EXTERNAL_CREATOR) + fill_in("external_work_title", with: DEFAULT_EXTERNAL_TITLE) + fill_in("external_work_summary", with: DEFAULT_EXTERNAL_SUMMARY) + fill_in("Fandoms", with: DEFAULT_EXTERNAL_FANDOM) + select(ArchiveConfig.RATING_TEEN_TAG_NAME, from: "external_work_rating_string") + check(DEFAULT_EXTERNAL_CATEGORY) + fill_in("Relationships", with: DEFAULT_EXTERNAL_RELATIONSHIP) + fill_in("Characters", with: DEFAULT_EXTERNAL_CHARACTERS) + click_button("Create") +end + +Given "the external work {string} has {int} {word} tag(s)" do |title, count, type| + work = ExternalWork.find_by(title: title) + work.send("#{type.pluralize}=", FactoryBot.create_list(type.to_sym, count)) +end + +When /^I view the external work "([^\"]*)"$/ do |external_work| + external_work = ExternalWork.find_by_title(external_work) + visit external_work_url(external_work) +end + +When /^the (character|fandom|relationship) "(.*?)" is removed from the external work "(.*?)"$/ do |tag_type, tag, title| + external_work = ExternalWork.find_by(title: title) + tags = external_work.tags.where(type: tag_type).pluck(:name) - [tag] + tag_string = tags.join(", ") + step %{I am logged in as a "policy_and_abuse" admin} + visit edit_external_work_path(external_work) + fill_in("work_#{tag_type}", with: tag_string) + click_button("Update External work") + step %{all indexing jobs have been run} +end + +Then /^the work info for my new bookmark should match the original$/ do + works = ExternalWork.where(url: "http://example.org/200").order("created_at ASC") + original_work = works[0] + new_work = works[1] + expect(new_work.author).to eq(original_work.author) + expect(new_work.title).to eq(original_work.title) + step %{the summary and tag info for my new bookmark should match the original} +end + +Then /^the title and creator info for my new bookmark should vary from the original$/ do + works = ExternalWork.where(url: "http://example.org/200").order("created_at ASC") + original_work = works[0] + new_work = works[1] + expect(new_work.author).not_to eq(original_work.author) + expect(new_work.title).not_to eq(original_work.title) +end + +Then /^the summary and tag info for my new bookmark should match the original$/ do + works = ExternalWork.where(url: "http://example.org/200").order("created_at ASC") + original_work = works[0] + new_work = works[1] + expect(new_work.summary).to eq(original_work.summary) + expect(new_work.tags).to eq(original_work.tags) +end diff --git a/features/step_definitions/generic_steps.rb b/features/step_definitions/generic_steps.rb new file mode 100755 index 0000000..499f2b1 --- /dev/null +++ b/features/step_definitions/generic_steps.rb @@ -0,0 +1,306 @@ +When /^(?:|I )unselect "([^"]+)" from "([^"]+)"$/ do |item, selector| + unselect(item, from: selector) +end + +Then /^debug$/ do + binding.pry +end + +Then /^tell me I got (.*)$/ do |spot| + puts "got #{spot}" +end + +Then /^show me the response$/ do + puts page.body +end + +Then /^show me the html$/ do + puts page.body +end + +Then /^show me the main content$/ do + puts "\n" + find("#main").native.inner_html +end + +Then /^show me the errors$/ do + puts "\n" + find("div.error").native.inner_html +end + +Then /^show me the sidebar$/ do + puts "\n" + find("#dashboard").native.inner_html +end + +Then "the page should have a dashboard sidebar" do + expect(page).to have_css("#dashboard") +end + +Then /^I should see errors/ do + assert find("div.error") +end + +Then /^show me the form$/ do + step %{show me the 1st form} +end + +Then /^show me the (\d+)(?:st|nd|rd|th) form$/ do |index| + puts "\n" + page.all("#main form")[(index.to_i-1)].native.inner_html +end + +Then "I should see the {string} form" do |form_id| + expect(page).to have_css("form##{form_id}") +end + +Then "I should not see the {string} form" do |form_id| + expect(page).not_to have_css("form##{form_id}") +end + +Given /^I wait (\d+) seconds?$/ do |number| + Kernel::sleep number.to_i +end + +When "all AJAX requests are complete" do + wait_for_ajax if @javascript +end + +When 'I reload the page' do + visit current_url +end + +Then /^I should see Posted now$/ do + now = Time.zone.now.to_s + step "I should see \"Posted #{now}\"" +end + +When /^I fill in "([^\"]*)" with$/ do |field, value| + fill_in(field, with: value) +end + +When /^I fill in "([^\"]*)" with `([^\`]*)`$/ do |field, value| + fill_in(field, with: value) +end + +When /^I fill in "([^\"]*)" with '([^\']*)'$/ do |field, value| + fill_in(field, with: value) +end + +Then /^I should see a create confirmation message$/ do + page.should have_content('was successfully created') +end + +Then /^I should see an update confirmation message$/ do + page.should have_content('was successfully updated') +end + +Then /^I should see a save error message$/ do + step %{I should see "We couldn't save"} +end + +Then /^I should see a success message$/ do + step %{I should see "success"} +end + +def assure_xpath_present(tag, attribute, value, selector) + with_scope(selector) do + page.should have_xpath("//#{tag}[@#{attribute}='#{value}']") + end +end + +def assure_xpath_not_present(tag, attribute, value, selector) + with_scope(selector) do + page.should_not have_xpath("//#{tag}[@#{attribute}='#{value}']") + end +end + +# img attributes +Then /^I should see the image "([^"]*)" text "([^"]*)"(?: within "([^"]*)")?$/ do |attribute, text, selector| + assure_xpath_present("img", attribute, text, selector) +end + +Then /^I should not see the image "([^"]*)" text "([^"]*)"(?: within "([^"]*)")?$/ do |attribute, text, selector| + assure_xpath_not_present("img", attribute, text, selector) +end + +Then /^"([^"]*)" should be selected within "([^"]*)"$/ do |value, field| + page.has_select?(field, selected: value).should == true +end + +Then /^"(.*)?" should( not)? be an option within "(.*)?"$/ do |value, negation, field| + expect(page.has_select?(field, with_options: [value])).to be !negation +end + +Then /^I should see "([^"]*)" in the "([^"]*)" input/ do |content, labeltext| + find_field("#{labeltext}").value.should == content +end + +Then "I should see in the {string} input" do |labeltext, content| + find_field(labeltext).value.should == content +end + +Then /^I should see a button with text "(.*?)"(?: within "(.*?)")?$/ do |text, selector| + assure_xpath_present("input", "value", text, selector) +end + +Then /^I should not see a button with text "(.*?)"(?: within "(.*?)")?$/ do |text, selector| + assure_xpath_not_present("input", "value", text, selector) +end + +Then "I should see a link to {string} within {string}" do |url, selector| + assure_xpath_present("a", "href", url, selector) +end + +Then /^I should see a page link to (.+) within "(.*?)"$/ do |page_name, selector| # rubocop:disable Cucumber/RegexStepName + expect(page.find(selector)).to have_link("", href: path_to(page_name)) +end + +Then /^I should not see a page link to (.+) within "(.*?)"$/ do |page_name, selector| # rubocop:disable Cucumber/RegexStepName + expect(page.find(selector)).to_not have_link("", href: path_to(page_name)) +end + +Then "I should see a link {string} within {string}" do |text, selector| + expect(page.find(selector)).to have_link(text) +end + +Then "I should not see a link {string} within {string}" do |text, selector| + expect(page.find(selector)).to_not have_link(text) +end + +Then "the {string} input should be blank" do |label| + expect(find_field(label).value).to be_blank +end + +Then /^I should see (a|an) "([^"]*)" button(?: within "([^"]*)")?$/ do |_article, text, selector| + assure_xpath_present("input", "value", text, selector) +end + +Then /^I should not see (a|an) "([^"]*)" button(?: within "([^"]*)")?$/ do |_article, text, selector| + assure_xpath_not_present("input", "value", text, selector) +end + +When /^"([^\"]*)" is fixed$/ do |what| + puts "\nDEFERRED (#{what})" +end + +Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be disabled$/ do |label, selector| + with_scope(selector) do + field = find_field(label, disabled: true) + expect(field).to be_present + expect(field.disabled?).to be_truthy + end +end + +Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be disabled$/ do |label, selector| + with_scope(selector) do + field = find_field(label) + expect(field).to be_present + expect(field.disabled?).to be_falsey + end +end + +Then /^I should see the input with id "([^"]*)"(?: within "([^"]*)")?$/ do |id, selector| + assure_xpath_present("input", "id", id, selector) +end + +Then /^I should not see the input with id "([^"]*)"(?: within "([^"]*)")?$/ do |id, selector| + assure_xpath_not_present("input", "id", id, selector) +end + +When /^I check the (\d+)(?:st|nd|rd|th) checkbox with the value "([^"]*)"$/ do |index, value| + check(page.all("input[type='checkbox']").select {|el| el['value'] == value}[(index.to_i-1)]['id']) +end + +When /^I check the (\d+)(st|nd|rd|th) checkbox with value "([^"]*)"$/ do |index, suffix, value| + step %{I check the #{index}#{suffix} checkbox with the value "#{value}"} +end + +When /^I uncheck the (\d+)(?:st|nd|rd|th) checkbox with the value "([^"]*)"$/ do |index, value| + uncheck(page.all("input[type='checkbox']").select {|el| el['value'] == value}[(index.to_i-1)]['id']) +end + +When /^I check the (\d+)(?:st|nd|rd|th) checkbox with id matching "([^"]*)"$/ do |index, id_string| + check(page.all("input[type='checkbox']").select {|el| el['id'] && el['id'].match(/#{id_string}/)}[(index.to_i-1)]['id']) +end + +When /^I uncheck the (\d+)(?:st|nd|rd|th) checkbox with id matching "([^"]*)"$/ do |index, id_string| + uncheck(page.all("input[type='checkbox']").select {|el| el['id'] && el['id'].match(/#{id_string}/)}[(index.to_i-1)]['id']) +end + +When /^I fill in the (\d+)(?:st|nd|rd|th) field with id matching "([^"]*)" with "([^"]*)"$/ do |index, id_string, value| + fill_in(page.all("input[type='text']").select {|el| el['id'] && el['id'].match(/#{id_string}/)}[(index.to_i-1)]['id'], with: value) +end + + +# If you have multiple forms on a page you will need to specify which one you want to submit with, eg, +# "I submit with the 2nd button", but in those cases you probably want to make sure that +# the different forms have different button text anyway, and submit them using +# When I press "Button Text" +When /^I submit with the (\d+)(?:st|nd|rd|th) button$/ do |index| # rubocop:disable Cucumber/RegexStepName + page.all("input[type='submit']")[(index.to_i - 1)].click +end + +# This is for buttons generated with the button_to helper method. They use a different HTML element, +# <button> instead of <input type="submit">. +When /^I click the (\d+)(?:st|nd|rd|th) button$/ do |index| # rubocop:disable Cucumber/RegexStepName + page.all("button")[index.to_i - 1].click +end + +# This will submit the first submit button inside a <p class="submit"> by default +# That wrapping paragraph tag will be generated automatically if you use +# the submit_button or submit_fieldset helpers in application_helper.rb +# The text on the button will not matter and can be changed without breaking tests. +When /^I submit$/ do + page.all("p.submit input[type='submit']")[0].click +end + +Then "I should see the text with tags {string}" do |text| + page.body.should =~ /#{Regexp.escape(text)}/m +end + +Then "I should see the text with tags" do |text| + page.body.should =~ /#{Regexp.escape(text)}/m +end + +Then /^I should not see the text with tags '(.*)'$/ do |text| + page.body.should_not =~ /#{Regexp.escape(text)}/m +end + +Then /^I should find a checkbox "([^\"]*)"$/ do |name| + field = find_field(name) + field['checked'].respond_to? :should +end + +Then /^I should see a link "([^\"]*)"$/ do |name| + text = name + "</a>" + page.body.should =~ /#{Regexp.escape(text)}/m +end + +Then "I should see a link {string} to {string}" do |text, href| + expect(page).to have_link(text, href: href) +end + +Then /^I should not see a link "([^\"]*)"$/ do |name| + text = name + "</a>" + page.body.should_not =~ /#{Regexp.escape(text)}/m +end + +Then "the page should be hidden from search engines" do + expect(page).to have_css("meta[name=robots][content=noindex]", visible: false) + expect(page).to have_css("meta[name=googlebot][content=noindex]", visible: false) +end + +Then "the page should not be hidden from search engines" do + expect(page).not_to have_css("meta[name=robots][content=noindex]", visible: false) + expect(page).not_to have_css("meta[name=googlebot][content=noindex]", visible: false) +end + +When /^I want to search for exactly one term$/ do + Capybara.exact = true +end + +When /^I should see the correct time zone for "(.*)"$/ do |zone| + Time.zone = zone + page.body.should =~ /#{Regexp.escape(Time.zone.now.zone)}/ +end + +Then "I should see {string} exactly {int} time(s)" do |string, int| + expect(page).to have_content(string).exactly(int) +end diff --git a/features/step_definitions/gift_steps.rb b/features/step_definitions/gift_steps.rb new file mode 100755 index 0000000..4ed4cc5 --- /dev/null +++ b/features/step_definitions/gift_steps.rb @@ -0,0 +1,43 @@ +### NOTE: many of these steps rely on the background in gift.feature + +Then /^"(.+)" should be notified by email about their gift "(.+)"$/ do |recipient, title| + step %{1 email should be delivered to "#{recipient}"} + step %{the email should contain "A gift work has been posted for you"} + step %{the email should link to the "#{title}" work page} +end + +When /^I have given the work to "(.*?)"/ do |recipient| + step %{I give the work to "#{recipient}"} + step %{I post the work without preview} +end + +Given(/^I have refused the work/) do + step %{I have given the work to "giftee1"} + + # Delay to force the cache to expire when the gift is refused: + step "it is currently 1 second from now" + + step %{I am logged in as "giftee1" with password "something"} + step %{I go to giftee1's gifts page} + step %{I follow "Refuse Gift"} +end + +When /^I have removed the recipients/ do + fill_in("work_recipients", with: "") + step %{I post the work without preview} +end + +Then /^"(.*?)" should be listed as a recipient in the form/ do |recipient| + recipients = page.find("input#work_recipients")['value'] + assert recipients =~ /#{recipient}/ +end + +Then /^"(.*?)" should not be listed as a recipient in the form/ do |recipient| + recipients = page.find("input#work_recipients")['value'] + assert recipients !~ /#{recipient}/ +end + +Then(/^the gift for "(.*?)" should still exist on "(.*?)"$/) do |recipient, work| + w = Work.find_by(title: work) + assert w.gifts.map(&:recipient).include?(recipient) +end diff --git a/features/step_definitions/icon_steps.rb b/features/step_definitions/icon_steps.rb new file mode 100755 index 0000000..7ae339a --- /dev/null +++ b/features/step_definitions/icon_steps.rb @@ -0,0 +1,61 @@ +### GIVEN + +Given /^I am editing a pseud$/ do + username = "myname" + step %{I am logged in as "#{username}"} + user = User.find_by(login: username) + visit edit_user_pseud_path(user, user.default_pseud) +end + +#' cancelling highlighting + +Given /^I have an icon uploaded$/ do + step "I am editing a pseud" + step %{I attach the file "features/fixtures/icon.gif" to "icon"} + step %{I press "Update"} +end + +### WHEN +When "I attach an icon with the extension {string}" do |extension| + step %{I attach the file "features/fixtures/icon.#{extension}" to "icon"} +end + +When /^I add an icon to the collection "([^"]*)"$/ do |title| + step %{I am logged in as "moderator"} + step %{I am on "#{title}" collection's page} + step %{I follow "Settings"} + step %{I attach the file "features/fixtures/icon.gif" to "collection_icon"} + step %{I press "Update"} +end + +When /^I delete the icon from the collection "([^"]*)"$/ do |title| + step %{I am logged in as "moderator"} + step %{I am on "#{title}" collection's page} + step %{I follow "Settings"} + check("collection_delete_icon") + step %{I press "Update"} +end + +When "I delete the icon from my pseud" do + user = User.find_by(login: "myname") + visit edit_user_pseud_path(user, user.default_pseud) + check("pseud_delete_icon") + step %{I press "Update"} +end + +Then /^the "([^"]*)" collection should have an icon$/ do |title| + collection = Collection.find_by(title: title) + assert collection.icon.attached? +end + +Then /^the "([^"]*)" collection should not have an icon$/ do |title| + collection = Collection.find_by(title: title) + assert !collection.icon.attached? +end + +### THEN + +Then "I should see the icon and alt text boxes are blank" do + expect(find("#pseud_icon").value).to be_blank + expect(find("#pseud_icon_alt_text").value).to be_nil +end diff --git a/features/step_definitions/invite_steps.rb b/features/step_definitions/invite_steps.rb new file mode 100755 index 0000000..85c26c0 --- /dev/null +++ b/features/step_definitions/invite_steps.rb @@ -0,0 +1,192 @@ +### GIVEN + +Given /^an invitation(?: for "([^\"]+)") exists$/ do |invitee_email| + invite = Invitation.new + invite.invitee_email = (invitee_email ? invitee_email : "default@example.org") + invite.save +end + +def invite(attributes = {}) + @invite ||= Invitation.new + @invite.invitee_email = "default@example.org" + @invite.save + @invite +end + +Given /^account creation is disabled$/ do + steps %Q{ + Given the following admin settings are configured: + | account_creation_enabled | 0 | + | creation_requires_invite | 0 | + | invite_from_queue_enabled | 0 | + | request_invite_enabled | 0 | + } +end + +Given /^account creation is enabled$/ do + steps %Q{ + Given the following admin settings are configured: + | account_creation_enabled | 1 | + } +end + +Given /^invitations are required$/ do + steps %{ + Given I have no users + And account creation requires an invitation + And users can request invitations + } +end + +Given /^account creation requires an invitation$/ do + steps %Q{ + Given the following admin settings are configured: + | account_creation_enabled | 1 | + | creation_requires_invite | 1 | + } +end + +Given /^account creation does not require an invitation$/ do + steps %Q{ + Given the following admin settings are configured: + | account_creation_enabled | 1 | + | creation_requires_invite | 0 | + } +end + +Given /^users can request invitations$/ do + steps %Q{ + Given the following admin settings are configured: + | request_invite_enabled | 1 | + } +end + +Given /^the invitation queue is enabled$/ do + steps %Q{ + Given the following admin settings are configured: + | invite_from_queue_enabled | 1 | + } +end + +Given /^the invitation queue is disabled$/ do + steps %Q{ + Given the following admin settings are configured: + | invite_from_queue_enabled | 0 | + } +end + +Given /^"([^\"]*)" has "([^"]*)" invitations?$/ do |login, invitation_count| + user = User.find_by(login: login) + # If there are more invitations than we want, first destroy them + if invitation_count.to_i < user.invitations.count + user.invitations.destroy_all + end + # Now create the number of invitations we want + (invitation_count.to_i - user.invitations.count).times { user.invitations.create } +end + +Given /^an invitation request for "([^"]*)"$/ do |email| + visit invite_requests_path + fill_in("invite_request[email]", with: email) + click_button("Add me to the list") +end + +Given "there are {int} invite request(s) per page" do |amount| + allow(InviteRequest).to receive(:per_page).and_return(amount) +end + +Given "an invitation created by {string} and used by {string}" do |creator, invitee| + creator = User.find_by(login: creator) + invitee = User.find_by(login: invitee) + FactoryBot.create(:invitation, creator: creator, invitee: invitee) +end + +### WHEN + +When /^I use an invitation to sign up$/ do + visit signup_path(invite.token) +end + +When /^I use an already used invitation to sign up$/ do + steps %Q{ + Given the following activated user exists + | login | password | + | invited | password | + } + user = User.find_by(login: "invited") + invite.redeemed_at = Time.now + invite.mark_as_redeemed(user) + invite.save + visit signup_path(invite.token) +end + +When /^I try to invite a friend from my user page$/ do + step %{I am logged in as "user1"} + step %{I go to user1's user page} + step %{I follow "Invitations"} +end + +When /^I request some invites$/ do + step %{I try to invite a friend from my user page} + step %{I follow "Request invitations"} + step %{I fill in "How many invitations would you like? (max 10)" with "3"} + step %{I fill in "Please specify why you'd like them:" with "I want them for a friend"} + step %{I press "Send Request"} +end + +When "as {string} I request some invites" do |user| + step %{I am logged in as "#{user}"} + step %{I go to #{user}'s user page} + step %{I follow "Invitations"} + step %{I follow "Request invitations"} + step %{I fill in "How many invitations would you like? (max 10)" with "3"} + step %{I fill in "Please specify why you'd like them:" with "I want them for a friend"} + step %{I press "Send Request"} +end + +When /^I view requests as an admin$/ do + step %{I am logged in as an admin} + step %{I follow "Invitations"} + step %{I follow "Manage Requests"} +end + +When /^an admin grants the request$/ do + step %{I view requests as an admin} + step %{I fill in "requests[user1]" with "2"} + step %{I press "Update"} +end + +When /^I check how long "(.*?)" will have to wait in the invite request queue$/ do |email| + visit(status_invite_requests_path) + fill_in("email", with: "#{email}") + click_button("Look me up") +end + +When "I view the most recent invitation for {string}" do |creator| + user = User.find_by(login: creator) + invitation = user.invitations.last + visit user_invitation_path(creator, invitation) +end + +### Then + +Then /^I should see how long I have to activate my account$/ do + days_to_activate = AdminSetting.first.days_to_purge_unactivated * 7 + step %{I should see "You must activate your account within #{days_to_activate} days"} +end + +Then /^"([^"]*)" should have "([^"]*)" invitations$/ do |login, invitation_count| + user = User.find_by(login: login) + assert user.invitations.count == invitation_count.to_i +end + +Then "the invite queue should list the following:" do |desired| + actual = all("table tbody tr").map do |row| + { + "position" => row.find("td:nth-child(1)").text, + "email" => row.find("td:nth-child(2)").text + } + end + + expect(actual).to eq(desired.hashes) +end diff --git a/features/step_definitions/kudos_steps.rb b/features/step_definitions/kudos_steps.rb new file mode 100755 index 0000000..c7049a2 --- /dev/null +++ b/features/step_definitions/kudos_steps.rb @@ -0,0 +1,48 @@ +### GIVEN + +Given "a work {string} with {int} kudo(s)" do |title, count| + step "basic tags" + + work = FactoryBot.create(:work, title: title) + + count.times do |i| + user = User.find_by(login: "fan#{i + 1}") || + FactoryBot.create(:user, login: "fan#{i + 1}") + work.kudos.create(user: user) + end +end + +Given "the maximum number of kudos to show is {int}" do |count| + allow(ArchiveConfig).to receive(:MAX_KUDOS_TO_SHOW).and_return(count) +end + +### WHEN + +When /^I leave kudos on "([^\"]*)"$/ do |work_title| + step %{I view the work "#{work_title}"} + click_button("kudo_submit") +end + +When "the kudos cache has expired" do + step "it is currently #{ArchiveConfig.MINUTES_UNTIL_COMMENTABLE_KUDOS_LISTS_EXPIRE} minutes from now" +end + +### THEN + +Then /^I should see kudos on every chapter$/ do + step %{I should see "myname3 left kudos on this work!"} + step %{I follow "Next Chapter"} + step %{I should see "myname3 left kudos on this work!"} + step %{I follow "Entire Work"} + step %{I should see "myname3 left kudos on this work!"} +end + +Then /^I should see kudos on every chapter but the draft$/ do + step %{I should see "myname3 left kudos on this work!"} + step %{I follow "Next Chapter"} + step %{I should see "myname3 left kudos on this work!"} + step %{I follow "Next Chapter"} + step %{I should not see "myname3 left kudos on this work!"} + step %{I follow "Entire Work"} + step %{I should see "myname3 left kudos on this work!"} +end diff --git a/features/step_definitions/mute_steps.rb b/features/step_definitions/mute_steps.rb new file mode 100755 index 0000000..154738b --- /dev/null +++ b/features/step_definitions/mute_steps.rb @@ -0,0 +1,41 @@ +Given "the user {string} has muted the user {string}" do |muter, muted| + muter = ensure_user(muter) + muted = ensure_user(muted) + Mute.create!(muter: muter, muted: muted) +end + +Given "there are {int} muted users per page" do |amount| + allow(Mute).to receive(:per_page).and_return(amount) +end + +Given "the maximum number of accounts users can mute is {int}" do |count| + allow(ArchiveConfig).to receive(:MAX_MUTED_USERS).and_return(count) +end + +Then "the user {string} should have a mute for {string}" do |muter, muted| + muter = User.find_by(login: muter) + muted = User.find_by(login: muted) + expect(Mute.find_by(muter: muter, muted: muted)).to be_present +end + +Then "the user {string} should not have a mute for {string}" do |muter, muted| + muter = User.find_by(login: muter) + muted = User.find_by(login: muted) + expect(Mute.find_by(muter: muter, muted: muted)).to be_blank +end + +Then "the blurb should say when {string} muted {string}" do |muter, muted| + muter = User.find_by(login: muter) + muted = User.find_by(login: muted) + mute = Mute.where(muter: muter, muted: muted).first + # Find the blurb for the specified mute using the h4 with the muted user's name, navigate back up to div, and then down to the datetime p + expect(page).to have_xpath("//li/div/h4/a[text()[contains(., '#{muted.login}')]]/parent::h4/parent::div/p[text()[contains(., '#{mute.created_at}')]]") +end + +Then "the blurb should not say when {string} muted {string}" do |muter, muted| + muter = User.find_by(login: muter) + muted = User.find_by(login: muted) + mute = Mute.where(muter: muter, muted: muted).first + # Find the blurb for the specified mute using the h4 with the muted user's name, navigate back up to div, and then down to where the datetime p would be + expect(page).not_to have_xpath("//li/div/h4/a[text()[contains(., '#{muted.login}')]]/parent::h4/parent::div/p[text()[contains(., '#{mute.created_at}')]]") +end diff --git a/features/step_definitions/orphan_steps.rb b/features/step_definitions/orphan_steps.rb new file mode 100755 index 0000000..6eddcf5 --- /dev/null +++ b/features/step_definitions/orphan_steps.rb @@ -0,0 +1,70 @@ +When /^I choose to take my pseud off$/ do + step %{I choose "Take my pseud off as well"} + step %{I press "Yes, I'm sure"} + step %{I should see "Orphaning was successful."} +end + +When /^I choose to (?:keep|leave) my pseud on$/ do + step %{I choose "Leave a copy of my pseud on"} + step %{I press "Yes, I'm sure"} + step %{I should see "Orphaning was successful."} +end + +When /^I begin orphaning the work "([^"]*)"$/ do |name| + step %{I wait 1 second} + step %{I edit the work "#{name}"} + step %{I follow "Orphan Work"} + step %{I should see "Orphan Works"} +end + +When /^I begin orphaning the series "([^"]*)"$/ do |name| + step %{I wait 1 second} + step %{I view the series "#{name}"} + step %{I follow "Orphan Series"} + step %{I should see "Orphan Series"} +end + +When /^I orphan(?:| and take my pseud off) the (work|series) "([^"]*)"$/ do |type, name| + step %{I begin orphaning the #{type} "#{name}"} + step %{I choose to take my pseud off} +end + +When "I orphan and leave my pseud on the series {string}" do |name| + step %{I begin orphaning the series "#{name}"} + step %{I choose to keep my pseud on} +end + +When "{string} orphans and takes their pseud off the work {string}" do |author, work| + u = User.find_by(login: author) + w = Work.find_by(title: work) + Creatorship.orphan(u.pseuds, [w], true) +end + +When "{string} orphans and keeps their pseud on the work {string}" do |author, work| + u = User.find_by(login: author) + w = Work.find_by(title: work) + Creatorship.orphan(u.pseuds, [w], false) +end + +Then /^"([^"]*)" (should|should not) be (?:a|the) (?:|co-)creator (?:of|on) the work "([^"]*)"$/ do |user, should_or_should_not, work| + step %{I view the work "#{work}"} + step %{I #{should_or_should_not} see "#{user}" within ".byline"} +end + +Then /^"([^"]*)" (should|should not) be (?:a|the) (?:|co-)creator (?:of|on) Chapter (\d+) of "([^"]*)"$/ do |user, should_or_should_not, chapter, work| + step %{I view the work "#{work}"} + step %{I view the #{chapter}th chapter} + + if page.has_css? ".chapter .byline" + # the chapter has different co-authors from the full work + step %{I #{should_or_should_not} see "#{user}" within ".chapter .byline"} + else + # the chapter's co-authors are the same as the full work's + step %{I #{should_or_should_not} see "#{user}" within ".byline"} + end +end + +Then /^"([^"]*)" (should|should not) be (?:a|the) (?:|co-)creator (?:of|on) the series "([^"]*)"$/ do |user, should_or_should_not, series| + step %{I view the series "#{series}"} + step %{I #{should_or_should_not} see "#{user}" within ".series.meta"} +end diff --git a/features/step_definitions/page_title_steps.rb b/features/step_definitions/page_title_steps.rb new file mode 100755 index 0000000..3d41329 --- /dev/null +++ b/features/step_definitions/page_title_steps.rb @@ -0,0 +1,11 @@ +Then "I should see the page title {string}" do |text| + expect(page.title).to include(text) +end + +Then "the page title should include {string}" do |text| + expect(page.title).to include(text) +end + +Then "the page title should not include {string}" do |text| + expect(page.title).not_to include(text) +end diff --git a/features/step_definitions/pickle_steps.rb b/features/step_definitions/pickle_steps.rb new file mode 100755 index 0000000..756c073 --- /dev/null +++ b/features/step_definitions/pickle_steps.rb @@ -0,0 +1,100 @@ +# this file generated by script/generate pickle + +# create a model +Given(/^#{capture_model} exists?(?: with #{capture_fields})?$/) do |name, fields| + create_model(name, fields) +end + +# create n models +Given(/^(\d+) #{capture_plural_factory} exist(?: with #{capture_fields})?$/) do |count, plural_factory, fields| + count.to_i.times { create_model(plural_factory.singularize, fields) } +end + +# create models from a table +Given(/^the following #{capture_plural_factory} exists?:?$/) do |plural_factory, table| + create_models_from_table(plural_factory, table) +end + +# find a model +Then(/^#{capture_model} should exist(?: with #{capture_fields})?$/) do |name, fields| + find_model!(name, fields) +end + +# not find a model +Then(/^#{capture_model} should not exist(?: with #{capture_fields})?$/) do |name, fields| + find_model(name, fields).should be_nil +end + +# find models with a table +Then(/^the following #{capture_plural_factory} should exists?:?$/) do |plural_factory, table| + find_models_from_table(plural_factory, table).should_not be_any(&:nil?) +end + +# find exactly n models +Then(/^(\d+) #{capture_plural_factory} should exist(?: with #{capture_fields})?$/) do |count, plural_factory, fields| + find_models(plural_factory.singularize, fields).size.should == count.to_i +end + +# assert equality of models +Then(/^#{capture_model} should be #{capture_model}$/) do |a, b| + model!(a).should == model!(b) +end + +# assert model is in another model's has_many assoc +Then(/^#{capture_model} should be (?:in|one of|amongst) #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association| + model!(owner).send(association).should include(model!(target)) +end + +# assert model is not in another model's has_many assoc +Then(/^#{capture_model} should not be (?:in|one of|amongst) #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association| + model!(owner).send(association).should_not include(model!(target)) +end + +# assert model is another model's has_one/belongs_to assoc +Then(/^#{capture_model} should be #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association| + model!(owner).send(association).should == model!(target) +end + +# assert model is not another model's has_one/belongs_to assoc +Then(/^#{capture_model} should not be #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association| + model!(owner).send(association).should_not == model!(target) +end + +# assert model.predicate? +Then(/^#{capture_model} should (?:be|have) (?:an? )?#{capture_predicate}$/) do |name, predicate| + if model!(name).respond_to?("has_#{predicate.gsub(' ', '_')}") + model!(name).should send("have_#{predicate.gsub(' ', '_')}") + else + model!(name).should send("be_#{predicate.gsub(' ', '_')}") + end +end + +# assert not model.predicate? +Then(/^#{capture_model} should not (?:be|have) (?:an? )?#{capture_predicate}$/) do |name, predicate| + if model!(name).respond_to?("has_#{predicate.gsub(' ', '_')}") + model!(name).should_not send("have_#{predicate.gsub(' ', '_')}") + else + model!(name).should_not send("be_#{predicate.gsub(' ', '_')}") + end +end + +# model.attribute.should eql(value) +# model.attribute.should_not eql(value) +Then(/^#{capture_model}'s (\w+) (should(?: not)?) be #{capture_value}$/) do |name, attribute, expectation, expected| + actual_value = model(name).send(attribute) + expectation = expectation.gsub(' ', '_') + + case expected + when 'nil', 'true', 'false' + actual_value.send(expectation, send("be_#{expected}")) + when /^[+-]?[0-9_]+(\.\d+)?$/ + actual_value.send(expectation, eql(expected.to_f)) + else + actual_value.to_s.send(expectation, eql(eval(expected))) + end +end + +# assert size of association +Then /^#{capture_model} should have (\d+) (\w+)$/ do |name, size, association| + model!(name).send(association).size.should == size.to_i +end diff --git a/features/step_definitions/potential_match_steps.rb b/features/step_definitions/potential_match_steps.rb new file mode 100755 index 0000000..3b2e8d9 --- /dev/null +++ b/features/step_definitions/potential_match_steps.rb @@ -0,0 +1,182 @@ +# frozen_string_literal: true + +Given /^I create the gift exchange "([^\"]*)" with the following options$/ do |name, table| + # Set up the gift exchange with the correct owner. + step %{the user "moderator" exists and is activated} + user = User.find_by(login: "moderator") + collection = Collection.new( + name: name, + title: name, + challenge_type: "GiftExchange" + ) + + collection.collection_participants.build( + pseud_id: user.default_pseud.id, + participant_role: "Owner" + ) + + # Create the new collection. + collection.challenge = GiftExchange.new + collection.challenge.request_restriction = PromptRestriction.new + collection.challenge.offer_restriction = PromptRestriction.new + collection.challenge.potential_match_settings = PotentialMatchSettings.new + + potential_match_settings = collection.challenge.potential_match_settings + + # Go through each of the types, and set up the request/offer/matching + # requirements accordingly. + table.hashes.each do |hash| + # Get the type (prompt/fandom/character/etc.) that we're restricting. + type = hash["value"].downcase.singularize + + # Constraints on the prompts. + required = (hash["minimum"] || "0").to_i + allowed = (hash["maximum"] || "0").to_i + any = %w(y t yes true).include?(hash["any"] || "yes") + unique = %w(y t yes true).include?(hash["unique"] || "yes") + optional = %w(y t yes true).include?(hash["optional"] || "no") + + # Constraints on the matching. + match = (hash["match"] || hash["minimum"] || "0").to_i + + if type == "prompt" + # Prompts aren't a type of tag, so we have to set them up differently. + collection.challenge.requests_num_required = required + collection.challenge.requests_num_allowed = allowed + collection.challenge.offers_num_required = required + collection.challenge.offers_num_allowed = allowed + potential_match_settings.num_required_prompts = match + else + attributes = { + "#{type}_num_required" => required, + "#{type}_num_allowed" => allowed, + "allow_any_#{type}" => any, + "require_unique_#{type}" => unique + } + + attributes["optional_tags_allowed"] = true if optional + + # We treat requests and offers identically, in order to make the + # constraints simpler to express. (The tests are designed to verify + # potential match generation, not challenge signups, so we don't need + # that kind of fine-grained control.) + collection.challenge.request_restriction.update!(attributes) + collection.challenge.offer_restriction.update!(attributes) + + potential_match_settings.update_attribute( + "num_required_#{type.pluralize}", match + ) + + potential_match_settings.update_attribute( + "include_optional_#{type.pluralize}", optional + ) + end + end + + # Save all the things! + collection.save! + collection.challenge.save! + collection.challenge.request_restriction.save! + collection.challenge.offer_restriction.save! + collection.challenge.potential_match_settings.save! +end + +Given /^the user "([^\"]*)" signs up for "([^\"]*)" with the following prompts$/ do |user_name, collection_name, table| + # Set up the username. + step %{the user "#{user_name}" exists and is activated} + user = User.find_by(login: user_name).default_pseud + + # Set up the basics of the signup. + collection = Collection.find_by(name: collection_name) + signup = ChallengeSignup.new(pseud: user, collection: collection) + offers = [] + requests = [] + + table.hashes.each do |hash| + # Each row of the table is a prompt -- either a request, or an offer. + prompt_type = hash["type"].downcase + prompt = prompt_type.classify.constantize.new( + collection: collection, + pseud: user + ) + + tagset = TagSet.new + optional_tag_set = nil + TagSet::TAG_TYPES.each do |type| + optional = hash["optional #{type}"] || hash["optional #{type.pluralize}"] + unless optional.nil? + optional_tag_set ||= TagSet.new + + tag_names = optional.split(/ *, */) + tag_names.each do |tag_name| + tag = type.classify.constantize.create_canonical(tag_name) + optional_tag_set.tags << tag + end + end + + value = hash[type] || hash[type.pluralize] + next if value.nil? + value = value.downcase + + # Allow the test to specify "any" for the type. + if value == "any" + prompt.update_attribute("any_#{type}", true) + else + tag_names = value.split(/ *, */) + tag_names.each do |tag_name| + tag = type.classify.constantize.create_canonical(tag_name) + tagset.tags << tag + end + end + end + + tagset.save! + prompt.tag_set = tagset + + optional_tag_set.save! if optional_tag_set + prompt.optional_tag_set = optional_tag_set + + requests << prompt if prompt_type == "request" + offers << prompt if prompt_type == "offer" + end + + # Save the final signup. + signup.requests = requests + signup.offers = offers + signup.save! +end + +When /^potential matches are generated for "([^\"]*)"$/ do |name| + collection = Collection.find_by(name: name) + PotentialMatch.generate_in_background collection.id +end + +Then /^there should be no potential matches for "([^\"]*)"$/ do |name| + collection = Collection.find_by(name: name) + collection.potential_matches.count.should == 0 +end + +Then /^the potential matches for "([^\"]*)" should be$/ do |name, table| + # First extract the set of potential matches for the given challenge. + collection = Collection.find_by(name: name) + matches = collection.potential_matches.includes( + request_signup: :pseud, + offer_signup: :pseud + ) + + match_names = matches.map do |pm| + [pm.request_signup.pseud.name, pm.offer_signup.pseud.name] + end + + match_names.sort! + + # Next extract the set of potential matches from the table. + desired_names = [] + table.hashes.each do |hash| + desired_names << [hash["request"], hash["offer"]] + end + + desired_names.sort! + + match_names.should == desired_names +end diff --git a/features/step_definitions/preferences_steps.rb b/features/step_definitions/preferences_steps.rb new file mode 100755 index 0000000..9be516b --- /dev/null +++ b/features/step_definitions/preferences_steps.rb @@ -0,0 +1,147 @@ +Given /^I set my preferences to View Full Work mode by default$/ do + step %{I follow "My Preferences"} + check("preference_view_full_works") + click_button("Update") +end + +Given(/^the user "(.*?)" disallows co-creators$/) do |login| + user = User.where(login: login).first + user = find_or_create_new_user(login, DEFAULT_PASSWORD) if user.nil? + user.preference.allow_cocreator = false + user.preference.save +end + +Given(/^the user "(.*?)" allows co-creators$/) do |login| + user = User.where(login: login).first + user = find_or_create_new_user(login, DEFAULT_PASSWORD) if user.nil? + user.preference.allow_cocreator = true + user.preference.save +end + +Given "the user {string} disallows gifts" do |login| + user = User.where(login: login).first + user = find_or_create_new_user(login, DEFAULT_PASSWORD) if user.nil? + user.preference.allow_gifts = false + user.preference.save +end + +Given "the user {string} allows gifts" do |login| + user = User.where(login: login).first + user = find_or_create_new_user(login, DEFAULT_PASSWORD) if user.nil? + user.preference.allow_gifts = true + user.preference.save +end + +When "the user {string} turns off guest comment replies" do |login| + user = User.where(login: login).first + user = find_or_create_new_user(login, DEFAULT_PASSWORD) if user.nil? + user.preference.update!(guest_replies_off: true) +end + +Given "the user {string} is hidden from search engines" do |login| + user = User.find_by(login: login) + user.preference.update!(minimize_search_engines: true) +end + +When /^I set my preferences to turn off notification emails for comments$/ do + step %{I follow "My Preferences"} + check("preference_comment_emails_off") + click_button("Update") +end + +When /^I set my preferences to turn off notification emails for kudos$/ do + step %{I follow "My Preferences"} + check("preference_kudos_emails_off") + click_button("Update") +end + +When /^I set my preferences to turn off notification emails for gifts$/ do + step %{I follow "My Preferences"} + check("preference_recipient_emails_off") + click_button("Update") +end + +When /^I set my preferences to hide warnings$/ do + step %{I follow "My Preferences"} + check("preference_hide_warnings") + click_button("Update") +end + +When /^I set my preferences to hide freeform$/ do + step %{I follow "My Preferences"} + check("preference_hide_freeform") + click_button("Update") +end + +When /^I set my preferences to hide the share buttons on my work$/ do + step %{I follow "My Preferences"} + check("preference_disable_share_links") + click_button("Update") +end + +When /^I set my preferences to turn off messages to my inbox about comments$/ do + step %{I follow "My Preferences"} + check("preference_comment_inbox_off") + click_button("Update") +end + +When /^I set my preferences to turn on messages to my inbox about comments$/ do + step %{I follow "My Preferences"} + uncheck("preference_comment_inbox_off") + click_button("Update") +end + +When /^I set my preferences to turn off copies of my own comments$/ do + step %{I follow "My Preferences"} + check("preference_comment_copy_to_self_off") + click_button("Update") +end + +When /^I set my preferences to turn on copies of my own comments$/ do + step %{I follow "My Preferences"} + uncheck("preference_comment_copy_to_self_off") + click_button("Update") +end + +When /^I set my preferences to turn off the banner showing on every page$/ do + step %{I follow "My Preferences"} + check("preference_banner_seen") + click_button("Update") +end + +When /^I set my preferences to turn off history$/ do + step %{I follow "My Preferences"} + uncheck("preference_history_enabled") + click_button("Update") +end + +When "the user {string} sets the time zone to {string}" do |username, time_zone| + user = User.find_by(login: username) + user.preference.time_zone = time_zone + user.preference.save +end + +When "I set my preferences to allow collection invitations" do + step %{I follow "My Preferences"} + check("preference_allow_collection_invitation") + click_button("Update") +end + +When /^I set my preferences to hide both warnings and freeforms$/ do + step %{I follow "My Preferences"} + check("preference_hide_warnings") + check("preference_hide_freeform") + click_button("Update") +end + +When /^I set my preferences to show adult content without warning$/ do + step %{I follow "My Preferences"} + check("preference_adult") + click_button("Update") +end + +When /^I set my preferences to warn before showing adult content$/ do + step %{I follow "My Preferences"} + uncheck("preference_adult") + click_button("Update") +end diff --git a/features/step_definitions/profile_steps.rb b/features/step_definitions/profile_steps.rb new file mode 100755 index 0000000..3f7b56b --- /dev/null +++ b/features/step_definitions/profile_steps.rb @@ -0,0 +1,85 @@ +Given /^I want to edit my profile$/ do + step "I view my profile" + click_link("Edit My Profile") + step %{I should see "Edit My Profile"} +end + +When /^I fill in the details of my profile$/ do + fill_in("Title", with: "Test title thingy") + fill_in("About Me", with: "This is some text about me.") + click_button("Update") +end + +When /^I change the details in my profile$/ do + fill_in("Title", with: "Alternative title thingy") + fill_in("About Me", with: "This is some different text about me.") + click_button("Update") +end + +When /^I remove details from my profile$/ do + fill_in("Title", with: "") + fill_in("About Me", with: "") + click_button("Update") +end + +When "the email address change confirmation period is set to {int} days" do |amount| + allow(Devise).to receive(:confirm_within).and_return(amount.days) +end + +When "I start to change my email to {string}" do |email| + step %{I fill in "New email" with "#{email}"} + step %{I fill in "Enter new email again" with "#{email}"} + step %{I fill in "Password" with "password"} + step %{I press "Confirm New Email"} +end + +When "I confirm my email change request to {string}" do |email| + step %{I should see "Are you sure you want to change your email address to #{email}?"} + step %{I press "Yes, Change Email"} +end + +When "I request to change my email to {string}" do |email| + step %{I start to change my email to "#{email}"} + step %{I confirm my email change request to "#{email}"} +end + +When "I change my email to {string}" do |email| + step %{I follow "My Preferences"} + step %{I follow "Change Email"} + step %{I request to change my email to "#{email}"} + step %{1 email should be delivered to "#{email}"} + step %{I follow "confirm your email change" in the email} + step %{I should see "Your email has been successfully updated."} +end + +When /^I view my profile$/ do + step %{I follow "My Dashboard"} + step %{I should see "Dashboard"} + click_link("Profile") +end + +When /^I make a mistake typing my old password$/ do + click_link("Password") + fill_in("password", with: "newpass1") + fill_in("password_confirmation", with: "newpass1") + fill_in("password_check", with: "wrong") + click_button("Change Password") +end + + +When /^I make a typing mistake confirming my new password$/ do + click_link("Password") + fill_in("password", with: "newpass1") + fill_in("password_confirmation", with: "newpass2") + fill_in("password_check", with: "password") + click_button("Change Password") +end + + +When /^I change my password$/ do + click_link("Password") + fill_in("password", with: "newpass1") + fill_in("password_confirmation", with: "newpass1") + fill_in("password_check", with: "password") + click_button("Change Password") +end diff --git a/features/step_definitions/pseud_steps.rb b/features/step_definitions/pseud_steps.rb new file mode 100755 index 0000000..0b8d069 --- /dev/null +++ b/features/step_definitions/pseud_steps.rb @@ -0,0 +1,39 @@ +Given /^"([^"]*)" has the pseud "([^"]*)"$/ do |username, pseud| + u = ensure_user(username) + u.pseuds.create!(name: pseud) +end + +Given "there are {int} pseuds per page" do |amount| + stub_const("ArchiveConfig", OpenStruct.new(ArchiveConfig)) + ArchiveConfig.ITEMS_PER_PAGE = amount.to_i + allow(Pseud).to receive(:per_page).and_return(amount) +end + +When "{string} changes the pseud {string} to {string}" do |username, old_pseud, new_pseud| + step %{"#{username}" edits the pseud "#{old_pseud}"} + fill_in("Name", with: new_pseud) + click_button("Update") +end + +When "{string} edits the pseud {string}" do |username, pseud| + p = Pseud.where(name: pseud, user_id: User.find_by(login: username)).first + visit edit_user_pseud_path(User.find_by(login: username), p) +end + +When "{string} deletes the pseud {string}" do |username, pseud| + visit user_pseuds_path(User.find_by(login: username)) + click_link("delete_#{pseud}") +end + +When /^"([^\"]*)" creates the default pseud "([^"]*)"$/ do |username, newpseud| + visit new_user_pseud_path(username) + fill_in "Name", with: newpseud + check("pseud_is_default") + click_button "Create" +end + +When /^"([^"]*)" creates the pseud "([^"]*)"$/ do |username, newpseud| + visit new_user_pseud_path(username) + fill_in "Name", with: newpseud + click_button "Create" +end diff --git a/features/step_definitions/rake_steps.rb b/features/step_definitions/rake_steps.rb new file mode 100755 index 0000000..d9b3710 --- /dev/null +++ b/features/step_definitions/rake_steps.rb @@ -0,0 +1,14 @@ +require 'rake' + +When /^I run the rake task "(.*?)"$/ do |name| + Rails.application.load_tasks unless Rake::Task.task_defined?(name) + task = Rake::Task[name] + task.invoke + + # As in spec/support/task_example_group.rb, use "invoke" (and re-enable the + # task and its prerequisites) over "execute" (which doesn't require + # re-enabling, but doesn't run prerequisites) because it more closely matches + # the behavior of rake itself. + task.all_prerequisite_tasks.each { |prerequisite| Rake::Task[prerequisite].reenable } + task.reenable +end diff --git a/features/step_definitions/reading_steps.rb b/features/step_definitions/reading_steps.rb new file mode 100755 index 0000000..7f1ecc1 --- /dev/null +++ b/features/step_definitions/reading_steps.rb @@ -0,0 +1,13 @@ +Given /^(.*) first read "([^"]*)" on "([^"]*)"$/ do |login, title, date| + user = User.find_by(login: login) + work = Work.find_by(title: title) + time = date.to_time.in_time_zone("UTC") + # create the reading + reading_json = [user.id, time, work.id, work.major_version, work.minor_version, false].to_json + REDIS_GENERAL.sadd("Reading:new", reading_json) + step "the readings are saved to the database" +end + +When "the readings are saved to the database" do + RedisJobSpawner.perform_now("ReadingsJob") +end diff --git a/features/step_definitions/redis_mail_queue_steps.rb b/features/step_definitions/redis_mail_queue_steps.rb new file mode 100755 index 0000000..d91fe8e --- /dev/null +++ b/features/step_definitions/redis_mail_queue_steps.rb @@ -0,0 +1,15 @@ +When /^subscription notifications are sent$/ do + RedisMailQueue.deliver_subscriptions +end + +When /^the subscription queue is cleared$/ do + RedisMailQueue.clear_queue("subscription") +end + +When /^kudos are sent$/ do + RedisMailQueue.deliver_kudos +end + +When /^the kudos queue is cleared$/ do + RedisMailQueue.clear_queue("kudos") +end diff --git a/features/step_definitions/request_header_steps.rb b/features/step_definitions/request_header_steps.rb new file mode 100755 index 0000000..52a5314 --- /dev/null +++ b/features/step_definitions/request_header_steps.rb @@ -0,0 +1,14 @@ +World(Rack::Test::Methods) +# thanks to these guys: http://www.anthonyeden.com/2010/11/testing-rest-apis-with-cucumber-and-rack-test/ + +Given /^I use a PSP browser$/ do + header 'Accept', '*/*;q=0.01' +end + +Given /^I make a request for "([^\"]*)"$/ do |path| + get path +end + +Then /^the response should be "([^\"]*)"$/ do |status| + last_response.status.should == status.to_i +end diff --git a/features/step_definitions/search_steps.rb b/features/step_definitions/search_steps.rb new file mode 100755 index 0000000..43c2b83 --- /dev/null +++ b/features/step_definitions/search_steps.rb @@ -0,0 +1,31 @@ +Given /^all indexing jobs have been run$/ do + %w[main background stats].each do |reindex_type| + ScheduledReindexJob.perform(reindex_type) + end + Indexer.all.map(&:refresh_index) +end + +Given /^the max search result count is (\d+)$/ do |max| + stub_const("ArchiveConfig", OpenStruct.new(ArchiveConfig)) + ArchiveConfig.MAX_SEARCH_RESULTS = max.to_i +end + +Given /^(\d+) item(?:s)? (?:is|are) displayed per page$/ do |per_page| + stub_const("ArchiveConfig", OpenStruct.new(ArchiveConfig)) + ArchiveConfig.ITEMS_PER_PAGE = per_page.to_i +end + +Given /^(\d+) tag(?:s)? (?:is|are) displayed per search page$/ do |per_page| + stub_const("ArchiveConfig", OpenStruct.new(ArchiveConfig)) + ArchiveConfig.TAGS_PER_SEARCH_PAGE = per_page.to_i +end + +Given /^dashboard counts expire after (\d+) seconds?$/ do |seconds| + stub_const("ArchiveConfig", OpenStruct.new(ArchiveConfig)) + ArchiveConfig.SECONDS_UNTIL_DASHBOARD_COUNTS_EXPIRE = seconds.to_i +end + +When "the dashboard counts have expired" do + step "all indexing jobs have been run" + step "it is currently #{ArchiveConfig.SECONDS_UNTIL_DASHBOARD_COUNTS_EXPIRE} seconds from now" +end diff --git a/features/step_definitions/series_steps.rb b/features/step_definitions/series_steps.rb new file mode 100755 index 0000000..4b98d3d --- /dev/null +++ b/features/step_definitions/series_steps.rb @@ -0,0 +1,156 @@ +When /^I view the series "([^\"]*)"$/ do |series| + visit series_path(Series.find_by(title: series)) +end + +Given "there are {int} works per series page" do |amount| + allow(WillPaginate).to receive(:per_page).and_return(amount) +end + +When /^I add the series "([^\"]*)"$/ do |series_title| + check("series-options-show") + if Series.find_by(title: series_title) + step %{I select "#{series_title}" from "work_series_attributes_id"} + else + fill_in("work_series_attributes_title", with: series_title) + end +end + +When /^I add the work "([^\"]*)" to (?:the )?series "([^\"]*)"(?: as "([^"]*)")?$/ do |work_title, series_title, pseud| + if Work.where(title: work_title).exists? + # an existing work + step %{I edit the work "#{work_title}"} + else + # a new work + step "I set up the draft \"#{work_title}\"" + end + if pseud + select(pseud, from: "work_author_attributes_ids") + end + step %{I add the series "#{series_title}"} + click_button("Post") +end + +When /^I add the draft "([^\"]*)" to series "([^\"]*)"$/ do |work_title, series_title| + step %{I edit the work "#{work_title}"} + step %{I add the series "#{series_title}"} + click_button("Save As Draft") +end + +When /^I add the work "([^\"]*)" to "(\d+)" series "([^\"]*)"$/ do |work_title, count, series_title| + work = Work.find_by(title: work_title) + if work.blank? + step "the draft \"#{work_title}\"" + work = Work.find_by(title: work_title) + visit preview_work_path(work) + click_button("Post") + step "I should see \"Work was successfully posted.\"" + step %{all indexing jobs have been run} + step "the periodic tag count task is run" + end + + count.to_i.times do |i| + step "I edit the work \"#{work_title}\"" + check("series-options-show") + fill_in("work_series_attributes_title", with: series_title + i.to_s) + click_button("Post") + end +end + +When /^I reorder the (\d+)(?:st|nd|rd|th) work to be below the (\d+)(?:st|nd|rd|th) work in the series$/ do |n1, n2| + # Step only accounts for downward changes through a downward offset. + assert n1 < n2 + + draggable = find(".serial-position-list:nth-child(#{n1})") + droppable = find(".serial-position-list:nth-child(#{n2})") + + # Capybara's drag_to method doesn't work well with this jQuery sortable list that has a default tolerance of "intersect". + # Using another way to simulate dragging. Credit to https://stackoverflow.com/questions/72369314/ + webdriver = page.driver.browser + webdriver.action.click_and_hold(draggable.native).perform + step "I wait 1 second" # a delay is necessary. + # Add downward offset to make the rearrangement register. + webdriver.action.move_to(droppable.native, 0, 10).release.perform + + step "all AJAX requests are complete" +end + +When /^I delete the series "([^"]*)"$/ do |series| + step %{I view the series "#{series}"} + step %{I follow "Delete Series"} + step %{I press "Yes, Delete Series"} + step %{I should see "Series was successfully deleted."} + step %{all indexing jobs have been run} +end + +Then /^the series "(.*)" should be deleted/ do |series| + assert Series.where(title: series).first.nil? +end + +Then /^the work "([^\"]*)" should be part of the "([^\"]*)" series in the database$/ do |work_title, series_title| + work = Work.find_by(title: work_title) + series = Series.find_by(title: series_title) + assert SerialWork.where(series_id: series, work_id: work).exists? +end + +Then /^the work "([^\"]*)" should not be visible on the "([^\"]*)" series page$/ do |work_title, series_title| + series = Series.find_by(title: series_title) + visit series_path(series) + page.should_not have_content(work_title) +end + +Then /^the series "([^\"]*)" should not be visible on the "([^\"]*)" work page$/ do |series_title, work_title| + work = Work.find_by(title: work_title) + visit work_path(work) + page.should_not have_content(series_title) +end + +Then /^the work "([^\"]*)" should be visible on the "([^\"]*)" series page$/ do |work_title, series_title| + series = Series.find_by(title: series_title) + visit series_path(series) + page.should have_content(work_title) +end + +Then /^the series "([^\"]*)" should be visible on the "([^\"]*)" work page$/ do |series_title, work_title| + work = Work.find_by(title: work_title) + series = Series.find_by(title: series_title) + visit work_path(work) + page.should have_content(series_title) + page.should have_content("Part #{SerialWork.where(series_id: series, work_id: work).first.position}") +end + +Then /^the neighbors of "([^\"]*)" in the "([^\"]*)" series should link over it$/ do |work_title, series_title| + work = Work.find_by(title: work_title) + series = Series.find_by(title: series_title) + position = SerialWork.where(series_id: series, work_id: work).first.position + neighbors = SerialWork.where(series_id: series, position: [position - 1, position + 1]) + neighbors.each_with_index do |neighbor, index| + visit work_path(neighbor.work) + # the neighbors should link to each other if they both exist + if neighbors.count > 1 && index == 0 + click_link("Next Work →") + page.should_not have_content(work_title) + page.should have_content(neighbors[1].work.title) + elsif neighbors.count > 1 && index == 1 + click_link("← Previous Work") + page.should_not have_content(work_title) + page.should have_content(neighbors[0].work.title) + end + end +end + +Then /^the neighbors of "([^\"]*)" in the "([^\"]*)" series should link to it$/ do |work_title, series_title| + work = Work.find_by(title: work_title) + series = Series.find_by(title: series_title) + position = SerialWork.where(series_id: series, work_id: work).first.position + neighbors = SerialWork.where(series_id: series, position: [position - 1, position + 1]) + neighbors.each do |neighbor| + visit work_path(neighbor.work) + if neighbor.position > position + click_link("← Previous Work") + page.should have_content(work_title) + else + click_link("Next Work →") + page.should have_content(work_title) + end + end +end diff --git a/features/step_definitions/share_steps.rb b/features/step_definitions/share_steps.rb new file mode 100755 index 0000000..f636a55 --- /dev/null +++ b/features/step_definitions/share_steps.rb @@ -0,0 +1,6 @@ +Then /^the share modal should contain social share buttons$/ do + with_scope("#share") do + expect(page).to have_css("li.twitter", text: "Twitter") + expect(page).to have_css("li.tumblr", text: "Tumblr") + end +end diff --git a/features/step_definitions/skin_steps.rb b/features/step_definitions/skin_steps.rb new file mode 100755 index 0000000..e6118ea --- /dev/null +++ b/features/step_definitions/skin_steps.rb @@ -0,0 +1,282 @@ +# Make sure that the methods in SkinCacheHelper are available to steps in this +# file (specifically, the steps checking cache expiration): +World(SkinCacheHelper) + +DEFAULT_CSS = "\"#title { text-decoration: blink;}\"" + +Given /^basic skins$/ do + assert Skin.default + assert WorkSkin.basic_formatting +end + +Given "the skin {string} by {string}" do |skin_name, login| + user = ensure_user(login) + FactoryBot.create(:skin, title: skin_name, author_id: user.id) +end + +Given /^I set up the skin "([^"]*)"$/ do |skin_name| + visit new_skin_path + fill_in("Title", with: skin_name) + fill_in("Description", with: "Random description") + fill_in("CSS", with: "#title { text-decoration: blink;}") +end + +Given /^I set up the skin "([^"]*)" with some css$/ do |skin_name| + step %{I set up the skin "#{skin_name}" with css #{DEFAULT_CSS}} +end + +Given /^I set up the skin "([^"]*)" with css "([^"]*)"$/ do |skin_name, css| + step "I set up the skin \"#{skin_name}\"" + fill_in("CSS", with: css) +end + +Given /^I create the skin "([^"]*)" with css "([^"]*)"$/ do |skin_name, css| + step "I set up the skin \"#{skin_name}\" with css \"#{css}\"" + step %{I submit} +end + +Given /^I create the skin "([^"]*)" with some css$/ do |skin_name, css| + step "I set up the skin \"#{skin_name}\" with css \"#{css}\"" + step %{I submit} +end + +Given /^I create the skin "([^"]*)"$/ do |skin_name| + step "I create the skin \"#{skin_name}\" with css #{DEFAULT_CSS}" +end + +Given /^I edit the skin "([^"]*)"$/ do |skin_name| + skin = Skin.find_by(title: skin_name) + visit edit_skin_path(skin) +end + +Given /^the unapproved public skin "([^"]*)" with css "([^"]*)"$/ do |skin_name, css| + # Delay to make sure all skins have at least 1 second of separation in their + # creation dates, so that they will be listed in the right order: + step "it is currently 1 second from now" + + step %{I am logged in as "skinner"} + step %{I set up the skin "#{skin_name}" with css "#{css}"} + attach_file("skin_icon", "features/fixtures/skin_test_preview.png") + check("skin_public") + step %{I submit} + step %{I should see "Skin was successfully created"} +end + +Given /^the unapproved public skin "([^"]*)"$/ do |skin_name| + step "the unapproved public skin \"#{skin_name}\" with css #{DEFAULT_CSS}" +end + +Given /^I approve the skin "([^"]*)"$/ do |skin_name| + step %{I am logged in as a "superadmin" admin} + visit admin_skins_url + check("make_official_#{skin_name.downcase.gsub(/\s/, '_')}") + step %{I submit} +end + +Given /^I unapprove the skin "([^"]*)"$/ do |skin_name| + step %{I am logged in as a "superadmin" admin} + visit admin_skins_url + step "I follow \"Approved Skins\"" + check("make_unofficial_#{skin_name.downcase.gsub(/\s/, '_')}") + step %{I submit} +end + +Given /^I have loaded site skins$/ do + Skin.load_site_css +end + +Given "the approved public skin {string} with css {string}" do |skin_name, css| + step %{the unapproved public skin "#{skin_name}" with css "#{css}"} + step %{I approve the skin "#{skin_name}"} + step "I am logged out" +end + +Given /^the approved public skin "([^"]*)"$/ do |skin_name| + step "the approved public skin \"#{skin_name}\" with css #{DEFAULT_CSS}" +end + +Given "the approved public skin {string} has reserved words in the title" do |skin_name| + # Admins can't create skins, so we have to create it this way. + FactoryBot.build(:skin, title: skin_name, public: true).save!(validate: false) + + step %{I approve the skin "#{skin_name}"} + step "I am logged out" +end + +Given /^"([^"]*)" is using the approved public skin "([^"]*)" with css "([^"]*)"$/ do |login, skin_name, css| + step "the approved public skin \"public skin\" with css \"#{css}\"" + step "I am logged in as \"#{login}\"" + step "I am on #{login}'s preferences page" + select(skin_name, from: "preference_skin_id") + step %{I submit} +end + +Given /^"([^"]*)" is using the approved public skin "([^"]*)"$/ do |login, skin_name| + step "\"#{login}\" is using the approved public skin with css #{DEFAULT_CSS}" +end + +Given /^I have a skin "(.*?)" with a parent "(.*?)"$/ do |child_title, parent_title| + step %{I set up the skin "#{parent_title}"} + click_button("Submit") + step %{I set up the skin "#{child_title}"} + click_button("Submit") + + child = Skin.find_by(title: child_title) + parent = Skin.find_by(title: parent_title) + child.skin_parents.create(position: 1, parent_skin: parent) +end + +### WHEN + +When /^I change my skin to "([^\"]*)"$/ do |skin_name| + step %{I follow "My Dashboard"} + step %{I follow "Preferences"} + step %{I select "#{skin_name}" from "preference_skin_id"} + step %{I submit} + step %{I should see "Your preferences were successfully updated."} +end + +When /^I create and use a skin to make the header pink$/ do + visit new_skin_url(wizard: true) + fill_in("skin_title", with: "Pink header") + fill_in("skin_headercolor", with: "pink") + click_button("Submit") + click_button("Use") +end + +When /^I create and use a skin to change the accent color$/ do + visit new_skin_url(wizard: true) + fill_in("skin_title", with: "Blue accent") + fill_in("skin_accent_color", with: "blue") + click_button("Submit") + click_button("Use") +end + +When /^I edit the skin "([^\"]*)" with the wizard$/ do |skin_name| + skin = Skin.find_by(title: skin_name) + visit edit_skin_path(skin, wizard: true) +end + +When /^I edit my pink header skin to have a purple logo$/ do + skin = Skin.find_by(title: "Pink header") + visit edit_skin_path(skin) + fill_in("CSS", with: "#header .heading a {color: purple;}") + click_button("Update") +end + +When /^I view the skin "([^\"]*)"$/ do |skin| + skin = Skin.find_by(title: skin) + visit skin_url(skin) +end + +When /^the skin "([^\"]*)" is in the chooser$/ do |skin_name| + skin = Skin.find_by(title: skin_name) + skin.in_chooser = true + skin.save! +end + +When /^the skin "([^\"]*)" is cached$/ do |skin_name| + skin = Skin.find_by(title: skin_name) + skin.cached = true + skin.save! + skin.cache! +end + +When /^I preview the skin "([^\"]*)"$/ do |skin_name| + skin = Skin.find_by(title: skin_name) + visit preview_skin_path(skin) +end + +### THEN + +Then "I should see a parent skin text field" do + step %{I should see "Parent #"} +end + +Then "I should see {string} in the page style" do |css| + expect(page).to have_css("style", text: css, visible: false) +end + +Then "I should not see {string} in the page style" do |css| + expect(page).not_to have_css("style", text: css, visible: false) +end + +Then "the page should have the cached skin {string}" do |skin_name| + skin = Skin.find_by(title: skin_name) + expect(page).to have_css("link[href*='#{skin.skin_dirname}']", visible: false) +end + +Then "the page should not have the cached skin {string}" do |skin_name| + skin = Skin.find_by(title: skin_name) + expect(page).not_to have_css("link[href*='#{skin.skin_dirname}']", visible: false) +end + +Then "I should see a pink header" do + step %{I should see "#header .primary" in the page style} + step %{I should see "background-image: none; background-color: pink;" in the page style} +end + +Then "I should see a different accent color" do + step %{I should see "fieldset, form dl, fieldset dl dl" in the page style} + step %{I should see "background: blue; border-color: blue;" in the page style} +end + +Then "the page should have a skin with the media query {string}" do |query| + expect(page).to have_css("style[media='#{query}']", visible: false) +end + +Then /^the cache of the skin on "([^\"]*)" should expire after I save the skin$/ do |title| + skin = Skin.find_by(title: title) + orig_cache_version = skin_cache_version(skin) + visit edit_skin_path(skin) + fill_in("CSS", with: "#random { text-decoration: blink;}") + click_button("Update") + assert orig_cache_version != skin_cache_version(skin), "Cache version #{orig_cache_version} matches #{skin_cache_version(skin)}." +end + +Then(/^the cache of the skin on "(.*?)" should not expire after I save "(.*?)"$/) do |arg1, arg2| + skin = Skin.find_by(title: arg1) + save_me = Skin.find_by(title: arg2) + orig_skin_version = skin_cache_version(skin) + orig_save_me_version = skin_cache_version(save_me) + visit edit_skin_path(save_me) + fill_in("CSS", with: "#random { text-decoration: blink;}") + click_button("Update") + assert orig_save_me_version != skin_cache_version(save_me), "Cache version #{orig_save_me_version} matches #{skin_cache_version(save_me)}" + assert orig_skin_version == skin_cache_version(skin), "Cache version #{orig_skin_version} does not match #{skin_cache_version(skin)}" +end + +Then(/^the cache of the skin on "(.*?)" should expire after I save a parent skin$/) do |arg1| + skin = Skin.find_by(title: arg1) + orig_skin_version = skin_cache_version(skin) + parent_id = SkinParent.where(child_skin_id: skin.id).last.parent_skin_id + parent = Skin.find(parent_id) + parent.save! + assert orig_skin_version != skin_cache_version(skin), "Cache version #{orig_skin_version} matches #{skin_cache_version(skin)}" +end + +Then "I should see a purple logo" do + step %|I should see "#header .heading a { color: purple; }" in the page style| +end + +Then /^I should see the skin "(.*?)" in the skin chooser$/ do |skin| + with_scope("#footer .menu") do + expect(page).to have_content(skin) + end +end + +Then /^I should not see the skin chooser$/ do + expect(page).not_to have_content("Customize") +end + +Then /^the filesystem cache of the skin "(.*?)" should include "(.*?)"$/ do |title, contents| + skin = Skin.find_by(title: title) + expect(skin.cached?).to be_truthy + + directory = Skin.skins_dir + skin.skin_dirname + style = Skin.skin_dir_entries(directory, /.css$/).map do |filename| + File.read(directory + filename) + end.join("\n") + + expect(style).to include(contents) +end diff --git a/features/step_definitions/subscription_steps.rb b/features/step_definitions/subscription_steps.rb new file mode 100755 index 0000000..265c60f --- /dev/null +++ b/features/step_definitions/subscription_steps.rb @@ -0,0 +1,34 @@ +When /^I view the "([^\"]*)" works index$/ do |tag| + visit works_path(tag_id: tag.to_param) +end + +When /^I view the "([^"]*)" works feed$/ do |tag| + visit "/tags/#{Tag.find_by_name(tag).id}/feed.atom" +end + +When /^"([^\"]*)" subscribes to (author|work|series) "([^\"]*)"$/ do |user, type, name| + case type + when "author" + step %{the user "#{name}" exists and is activated} + step %{I am logged in as "#{user}"} + step %{I go to #{name}'s user page} + when "work" + unless Work.find_by(title: name) + step %{I am logged in as "wip_author"} + step %{I post the work "#{name}"} + end + step %{I am logged in as "#{user}"} + visit work_url(Work.find_by(title: name)) + when "series" + unless Series.find_by(title: name) + step %{I am logged in as "series_author"} + step %{I add the work "Blah" to series "#{name}"} + end + step %{I am logged in as "#{user}"} + step %{I view the series "#{name}"} + end + step %{I press "Subscribe"} + step %{I should see "You are now following #{name}. If you'd like to stop receiving email updates, you can unsubscribe from your Subscriptions page."} + step %{I go to the subscriptions page for "#{user}"} + step %{I should see an "Unsubscribe from #{name}" button} +end diff --git a/features/step_definitions/support_steps.rb b/features/step_definitions/support_steps.rb new file mode 100755 index 0000000..4e63bef --- /dev/null +++ b/features/step_definitions/support_steps.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +Given "Zoho ticket creation is enabled" do + allow_any_instance_of(Feedback).to receive(:zoho_enabled?).and_return(true) + WebMock.stub_request(:get, %r{/contacts/search}) + .to_return(headers: { content_type: "application/json" }, body: '{"data":[{"id":"1"}]}') + WebMock.stub_request(:post, %r{/tickets}) + .to_return(headers: { content_type: "application/json" }, body: '{"id":"3"}') +end + +Given "{string} is a permitted Archive host" do |host| + allow(ArchiveConfig).to receive(:PERMITTED_HOSTS).and_return([host]) +end + +Then "a Zoho ticket should be created with referer {string}" do |referer| + expect(WebMock).to have_requested(:post, "https://desk.zoho.com/api/v1/tickets") + .with { |req| JSON.parse(req.body)["cf"]["cf_ticket_url"] == referer } +end diff --git a/features/step_definitions/tag_set_steps.rb b/features/step_definitions/tag_set_steps.rb new file mode 100755 index 0000000..1119a20 --- /dev/null +++ b/features/step_definitions/tag_set_steps.rb @@ -0,0 +1,241 @@ +Given "a nominated tag set {string} with a tag nomination in the wrong category" do |tag_set_name| + pseud = FactoryBot.create(:pseud, user: FactoryBot.create(:user, login: "tagsetter")) + owned_tag_set = FactoryBot.create(:owned_tag_set, title: tag_set_name, owner: pseud) + tag_set_nomination = FactoryBot.create(:tag_set_nomination, pseud: pseud, owned_tag_set: owned_tag_set) + FactoryBot.create(:relationship, name: "rel tag") + invalid_nom = tag_set_nomination.fandom_nominations.build(tagname: "rel tag") # intentional mismatch in tag category + invalid_nom.save(validate: false) +end + +When /^I follow the add new tag ?set link$/ do + step %{I follow "New Tag Set"} +end + +# This takes strings like: +# ...the fandom tags "x, y, z" +# ...the category tags "a, b, c" +# If you want ratings, warnings, or categories, first load basic or default tags for those types +When /^I add (.*) to the tag ?set$/ do |tags| + tags.scan(/the (\w+) tags "([^\"]*)"/).each do |type, scanned_tags| + if type == "category" || type == "rating" || type == "warning" + tags = scanned_tags.split(/, ?/) + tags.each { |tag| check(tag) } + else + field_name = "owned_tag_set_tag_set_attributes_#{type}_tagnames_to_add" + field_name += "_autocomplete" if @javascript + fill_in(field_name, with: scanned_tags) + end + end +end + +# This takes strings like: +# ...with a visible tag list +# ...with the fandom tags "x, y, z" and the character tags "a, b, c" +# ...with an invisible tag list and the freeform tags "m, n, o" +When /^I set up the tag ?set "([^\"]*)" with(?: (?:an? )(visible|invisible) tag list and)? (.*)$/ do |title, visibility, tags| + unless OwnedTagSet.find_by(title: title).present? + visit new_tag_set_path + fill_in("owned_tag_set_title", with: title) + fill_in("owned_tag_set_description", with: "Here's my tagset") + visibility ||= "invisible" + check("owned_tag_set_visible") if visibility == "visible" + uncheck("owned_tag_set_visible") if visibility == "invisible" + step %{I add #{tags} to the tag set} + step %{I submit} + step %{I should see a create confirmation message} + end +end + +# Takes things like When I add the fandom tags "Bandom" to the tag set "MoreJoyDay". +# Don't forget the extra s, even if it's singular. +When /^I add (.*) to the tag ?set "([^\"]*)"$/ do |tags, title| + step %{I go to the "#{title}" tag set edit page} + step %{I add #{tags} to the tag set} + step %{I submit} + step %{I should see an update confirmation message} +end + +# Takes things like When I remove the fandom tags "Bandom" to the tag set "MoreJoyDay". +# Don't forget the extra s, even if it's singular. +When /^I remove (.*) from the tag ?set "([^\"]*)"$/ do |tags, title| + step %{I go to the "#{title}" tag set edit page} + tags.scan(/the (\w+) tags "([^\"]*)"/).each do |type, scanned_tags| + tags = scanned_tags.split(/, ?/) + + if type == "category" || type == "rating" || type == "warning" + tags.each { |tag| uncheck(tag) } + else + tags.each { |tag| check(tag) } + end + end + step %{I submit} + step %{I should see an update confirmation message} +end + +When /^I set up the nominated tag ?set "([^\"]*)" with (\d*) fandom noms? and (\d*) (character|relationship) noms?$/ do |title, fandom_count, nested_count, nested_type| + unless OwnedTagSet.find_by(title: "#{title}").present? + step %{I go to the new tag set page} + fill_in("owned_tag_set_title", with: title) + fill_in("owned_tag_set_description", with: "Here's my tagset") + check("Currently taking nominations?") + fill_in("Fandom nomination limit", with: fandom_count) + fill_in("#{nested_type.titleize} nomination limit", with: nested_count) + step %{I submit} + step %{I should see a create confirmation message} + end +end + +When /^I nominate (.*) fandoms and (.*) characters in the "([^\"]*)" tag ?set as "([^\"]*)"/ do |fandom_count, char_count, title, login| + step %{I am logged in as "#{login}"} + step %{I go to the "#{title}" tag set page} + step %{I follow "Nominate"} + 1.upto(fandom_count.to_i) do |i| + fill_in("Fandom #{i}", with: "Blah #{i}") + 0.upto(char_count.to_i - 1) do |j| + fill_in("tag_set_nomination_fandom_nominations_attributes_#{i - 1}_character_nominations_attributes_#{j}_tagname", with: "Foobar #{i} #{j}") + end + end +end + +When /^I have (?:a|the) nominated tag ?set "([^\"]*)"/ do |title| + step %{I am logged in as "tagsetter"} + step %{I set up the nominated tag set "#{title}" with 3 fandom noms and 3 character noms} + step %{I nominate 3 fandoms and 3 characters in the "#{title}" tagset as "nominator"} + step %{I submit} + step %{I should see a success message} +end + +When /^I start to nominate fandoms? "([^\"]*)" and characters? "([^\"]*)" in "([^\"]*)"(?: as "([^"]*)")?$/ do |fandom, char, title, user| + user ||= "nominator" + step %{I am logged in as "#{user}"} + step %{I go to the "#{title}" tag set page} + step %{I follow "Nominate"} + @fandoms = fandom.split(/, ?/) + @chars = char.split(/, ?/) + char_index = 0 + chars_per_fandom = @chars.size/@fandoms.size + 1.upto(@fandoms.size) do |i| + fill_in("Fandom #{i}", with: @fandoms[i - 1]) + 0.upto(chars_per_fandom - 1) do |j| + fill_in("tag_set_nomination_fandom_nominations_attributes_#{i - 1}_character_nominations_attributes_#{j}_tagname", with: @chars[char_index]) + char_index += 1 + end + end +end + +When /^I nominate fandoms? "([^\"]*)" and characters? "([^\"]*)" in "([^\"]*)"(?: as "([^"]*)")?$/ do |fandom, char, title, user| + user ||= "nominator" + step %{I start to nominate fandoms "#{fandom}" and characters "#{char}" in "#{title}" as "#{user}"} + step %{I submit} + step %{I should see a success message} +end + +When "I edit nominations for {string} in {string} to include character(s) {string} under fandom {string}" do |user, title, characters, fandom| + step %{I am logged in as "#{user}"} + step %{I go to the "#{title}" tag set page} + step %{I follow "My Nominations"} + step %{I follow "Edit"} + character_inputs = find("dd", text: fandom).find_all(:xpath, "..//input[contains(@id, 'character')]") + characters.split(/, ?/).each.with_index do |character, index| + character_inputs[index].fill_in(with: character) + end + step %{I submit} + step %{I should see a success message} +end + +When /^there are (\d+) unreviewed nominations$/ do |n| + (1..n.to_i).each do |i| + step %{I am logged in as \"nominator#{i}\"} + step %{I nominate 6 fandoms and 6 characters in the "Nominated Tags" tag set as \"nominator#{i}\"} + step %{I press "Submit"} + end +end + +When /^I review nominations for "([^\"]*)"/ do |title| + step %{I am logged in as "tagsetter"} + step %{I go to the "#{title}" tag set page} + step %{I follow "Review Nominations"} +end + +When /^I review associations for "([^\"]*)"/ do |title| + step %{I am logged in as "tagsetter"} + step %{I go to the "#{title}" tag set page} + step %{I follow "Review Associations"} +end + +When /^I nominate and approve fandom "([^\"]*)" and character "([^\"]*)" in "([^\"]*)"/ do |fandom, char, title| + step %{I am logged in as "tagsetter"} + step %{I set up the nominated tag set "#{title}" with 3 fandom noms and 3 character noms} + step %{I nominate fandom "#{fandom}" and character "#{char}" in "#{title}"} + step %{I review nominations for "#{title}"} + step %{I check "fandom_approve_#{fandom}"} + step %{I check "character_approve_#{char}"} + step %{I submit} + step %{I should see "Successfully added to set: #{fandom}"} + step %{I should see "Successfully added to set: #{char}"} +end + +When /^I nominate and approve tags with Unicode characters in "([^\"]*)"/ do |title| + tags = "The Hobbit - All Media Types, Dís, Éowyn, Kíli, Bifur/Óin, スマイルプリキュア, 新白雪姫伝説プリーティア".split(', ') + step %{I am logged in as "tagsetter"} + step %{I set up the nominated tag set "#{title}" with 7 fandom noms and 0 character noms} + step %{I am logged in as "nominator"} + step %{I go to the "#{title}" tag set page} + step %{I follow "Nominate"} + tags.each_with_index do |tag, i| + fill_in("Fandom #{i + 1}", with: tag) + end + step %{I submit} + step %{I should see a success message} + step %{I review nominations for "#{title}"} + tags.each do |tag| + step %{I check "fandom_approve_#{tag}"} + end + step %{I submit} + step %{I should see "Successfully added to set"} +end + +When "I approve the nominated {word} tag {string}" do |tag_type, tag_name| + check("#{tag_type.downcase}_approve_#{tag_name.tr(' ', '_')}") +end + +When /^I should see the tags with Unicode characters/ do + tags = "The Hobbit - All Media Types, Dís, Éowyn, Kíli, Bifur/Óin, スマイルプリキュア, 新白雪姫伝説プリーティア".split(', ') + tags.each do |tag| + step %{I should see "#{tag}"} + end +end + +When /^I view the tag set "([^\"]*)"/ do |tagset| + tagset = OwnedTagSet.find_by(title: tagset) + visit tag_set_path(tagset) +end + +When "the cache for the tag set {string} is expired" do |tagset| + tag_set_id = OwnedTagSet.find_by(title: tagset).tag_set_id + ActionController::Base.new.expire_fragment("tag_set_show_#{tag_set_id}") + TagSet::TAG_TYPES.each do |type| + ActionController::Base.new.expire_fragment("tag_set_show_#{tag_set_id}_#{type}") + end +end + +When /^I view associations for a tag set that does not exist/ do + id = 1 + tagset = OwnedTagSet.find_by(id: id) + tagset.destroy if tagset + visit tag_set_associations_path(id) +end + +When /^I expand the unassociated characters and relationships$/ do + find('button[data-action-target="#list_for_unassociated_char_and_rel"]').click +end + +Then /^"([^\"]*)" should be associated with the "([^\"]*)" fandom "([^\"]*)"$/ do |tag, fandom_type, fandom_name| + name = fandom_name.tr(" ", "_") + type = fandom_type.tr(" ", "_") + step %{I should see "#{tag}" within "ol#list_for_fandom_#{name}_in_#{type}_Fandoms li"} +end + +Then /^"([^\"]*)" should be an unassociated tag$/ do |tag| + step %{I should see "#{tag}" within "ol#list_for_unassociated_char_and_rel"} +end diff --git a/features/step_definitions/tag_steps.rb b/features/step_definitions/tag_steps.rb new file mode 100755 index 0000000..7bf1578 --- /dev/null +++ b/features/step_definitions/tag_steps.rb @@ -0,0 +1,492 @@ +### GIVEN + +Given /^I have no tags$/ do + # Tag.delete_all if Tag.count > 1 + # silence_warnings {load "#{Rails.root}/app/models/fandom.rb"} +end + +Given /^basic tags$/ do + step %{the default ratings exist} + step %{the basic warnings exist} + Fandom.where(name: "No Fandom", canonical: true).first_or_create + step %{the basic categories exist} + step %{all indexing jobs have been run} +end + +Given /^the default ratings exist$/ do + # TODO: "Not Rated" should be adult, to match the behavior in production, but + # there are many tests that rely on being able to view a "Not Rated" work + # without clicking through the adult content warning. So until those tests + # are fixed, we leave "Not Rated" as a non-adult rating. + [ + ArchiveConfig.RATING_DEFAULT_TAG_NAME, + ArchiveConfig.RATING_GENERAL_TAG_NAME, + ArchiveConfig.RATING_TEEN_TAG_NAME + ].each do |rating| + Rating.find_or_create_by!(name: rating, canonical: true) + end + + [ + ArchiveConfig.RATING_MATURE_TAG_NAME, + ArchiveConfig.RATING_EXPLICIT_TAG_NAME + ].each do |rating| + Rating.find_or_create_by!(name: rating, canonical: true, adult: true) + end +end + +Given /^the basic warnings exist$/ do + warnings = [ArchiveConfig.WARNING_DEFAULT_TAG_NAME, + ArchiveConfig.WARNING_NONE_TAG_NAME] + warnings.each do |warning| + ArchiveWarning.find_or_create_by!(name: warning, canonical: true) + end +end + +Given /^all warnings exist$/ do + step %{the basic warnings exist} + warnings = [ArchiveConfig.WARNING_VIOLENCE_TAG_NAME, + ArchiveConfig.WARNING_DEATH_TAG_NAME, + ArchiveConfig.WARNING_NONCON_TAG_NAME, + ArchiveConfig.WARNING_CHAN_TAG_NAME] + warnings.each do |warning| + ArchiveWarning.find_or_create_by!(name: warning, canonical: true) + end +end + +Given /^the basic categories exist$/ do + %w(Gen Other F/F Multi F/M M/M).each do |category| + Category.find_or_create_by!(name: category, canonical: true) + end +end + +Given "a set of tags for tag sort by use exists" do + { + "10 uses" => 10, + "8 uses" => 8, + "also 8 uses" => 8, + "5 uses" => 5, + "2 uses" => 2, + "0 uses" => 0 + }.each do |freeform, uses| + tag = Freeform.find_or_create_by_name(freeform.dup) + tag.taggings_count = uses + end + + step "all indexing jobs have been run" + step "the periodic tag count task is run" +end + +Given /^I have a canonical "([^\"]*)" fandom tag named "([^\"]*)"$/ do |media, fandom| + fandom = Fandom.find_or_create_by_name(fandom) + fandom.update!(canonical: true) + media = Media.find_or_create_by_name(media) + media.update!(canonical: true) + fandom.add_association media +end + +Given "I add the fandom {string} to the tag/character {string}" do |fandom, tag| + tag = Tag.find_or_create_by(name: tag) + fand = Fandom.find_or_create_by_name(fandom) + tag.add_association(fand) +end + +Given /^a canonical character "([^\"]*)" in fandom "([^\"]*)"$/ do |character, fandom| + char = Character.where(name: character, canonical: true).first_or_create + fand = Fandom.where(name: fandom, canonical: true).first_or_create + char.add_association(fand) +end + +Given /^a canonical relationship "([^\"]*)" in fandom "([^\"]*)"$/ do |relationship, fandom| + rel = Relationship.where(name: relationship, canonical: true).first_or_create + fand = Fandom.where(name: fandom, canonical: true).first_or_create + rel.add_association(fand) +end + +Given /^a (non-?canonical|canonical) (\w+) "([^\"]*)"$/ do |canonical_status, tag_type, tag_name| + t = tag_type.classify.constantize.find_or_create_by_name(tag_name) + t.canonical = canonical_status == "canonical" + t.save +end + +Given "a non-canonical character {string} in fandom {string}" do |character_name, fandom_name| + character = Character.where(name: character_name).first_or_create + character.update!(canonical: false) + fandom = Fandom.where(name: fandom_name).first_or_create + character.add_association(fandom) +end + +Given /^a synonym "([^\"]*)" of the tag "([^\"]*)"$/ do |synonym, merger| + merger = Tag.find_by_name(merger) + merger_type = merger.type + + synonym = merger_type.classify.constantize.find_or_create_by(name: synonym) + synonym.reload.merger = merger + synonym.save +end + +Given /^"([^\"]*)" is a metatag of the (\w+) "([^\"]*)"$/ do |metatag, tag_type, tag| + tag = tag_type.classify.constantize.find_or_create_by_name(tag) + metatag = tag_type.classify.constantize.find_or_create_by_name(metatag) + tag.meta_tags << metatag + tag.save +end + +Given /^I am logged in as a tag wrangler$/ do + username = "wrangler" + step %{I am logged in as "#{username}"} + user = User.find_by(login: username) + role = Role.find_or_create_by(name: "tag_wrangler") + user.roles = [role] +end + +Given /^the tag wrangler "([^\"]*)" with password "([^\"]*)" is wrangler of "([^\"]*)"$/ do |user, password, fandomname| + tw = User.find_by(login: user) + + if tw.blank? + tw = FactoryBot.create(:user, login: user, password: password) + else + tw.skip_password_change_notification! + tw.password = password + tw.password_confirmation = password + tw.save + end + + role = Role.find_or_create_by(name: "tag_wrangler") + tw.roles = [role] + + step %{I am logged in as "#{user}" with password "#{password}"} + + fandom = Fandom.where(name: fandomname, canonical: true).first_or_create + visit tag_wranglers_url + fill_in "tag_fandom_string", with: fandomname + click_button "Assign" +end + +Given /^a tag "([^\"]*)" with(?: (\d+))? comments$/ do |tagname, n_comments| + tag = Fandom.find_or_create_by_name(tagname) + + n_comments = 3 if n_comments.blank? || n_comments.zero? + FactoryBot.create_list(:comment, n_comments.to_i, :on_tag, commentable: tag) +end + +Given /^(?:a|the) canonical(?: "([^"]*)")? fandom "([^"]*)" with (\d+) works$/ do |media, tag_name, number_of_works| + fandom = FactoryBot.create(:fandom, name: tag_name, canonical: true) + fandom.add_association(Media.find_by(name: media)) if media.present? + number_of_works.to_i.times do + FactoryBot.create(:work, fandom_string: tag_name) + end + step %(the periodic filter count task is run) +end + +Given /^a period-containing tag "([^\"]*)" with(?: (\d+))? comments$/ do |tagname, n_comments| + tag = Fandom.find_or_create_by_name(tagname) + + n_comments = 3 if n_comments.blank? || n_comments.zero? + FactoryBot.create_list(:comment, n_comments.to_i, :on_tag, commentable: tag) +end + +Given /^the unsorted tags setup$/ do + 30.times do |i| + UnsortedTag.find_or_create_by_name("unsorted tag #{i}") + end +end + +Given /^the tag wrangling setup$/ do + step %{basic tags} + step %{a media exists with name: "TV Shows", canonical: true} + step %{I am logged in as a random user} + step %{I post the work "Revenge of the Sith 2" with fandom "Star Wars, Stargate SG-1" with character "Daniel Jackson" with second character "Jack O'Neil" with rating "Not Rated" with relationship "JackDaniel"} + step %{The periodic tag count task is run} + step %{all indexing jobs have been run} + step %{I flush the wrangling sidebar caches} +end + +Given /^I have posted a Wrangling Guideline?(?: titled "([^\"]*)")?$/ do |title| + step %{I am logged in as a "tag_wrangling" admin} + visit new_wrangling_guideline_path + if title + fill_in("Guideline text", with: "This is a page about how we wrangle things.") + fill_in("Title", with: title) + click_button("Post") + else + step %{I make a 1st Wrangling Guideline} + end +end + +Given(/^the following typed tags exists$/) do |table| + table.hashes.each do |hash| + type = hash["type"].downcase.to_sym + hash.delete("type") + FactoryBot.create(type, hash) + end +end + +Given /^the tag "([^"]*)" does not exist$/ do |tag_name| + tag = Tag.find_by_name(tag_name) + tag.destroy if tag.present? +end + +Given "a zero width space tag exists" do + blank_tag = FactoryBot.build(:character, name: ["200B".hex].pack("U")) + blank_tag.save!(validate: false) +end + +Given "I create the canonical media tag {string}" do |name| + step %{I am logged in as a "tag_wrangling" admin} + visit(new_tag_path) + fill_in("Name", with: name) + choose("Media") + check("Canonical") + click_button("Create Tag") +end + +Given "I create the non-canonical media tag {string}" do |name| + step %{I am logged in as a "tag_wrangling" admin} + visit(new_tag_path) + fill_in("Name", with: name) + choose("Media") + click_button("Create Tag") +end + +Given "I recategorize the {string} fandom as a {string} tag" do |name, tag_type| + step %{I am logged in as a "tag_wrangling" admin} + visit(edit_tag_path(Fandom.create(name: name))) + select(tag_type, from: "tag_type") + check("Canonical") + click_button("Save changes") +end + +### WHEN + +When /^the periodic tag count task is run$/i do + RedisJobSpawner.perform_now("TagCountUpdateJob") +end + +When /^the periodic filter count task is run$/i do + FilterCount.update_counts_for_small_queue + FilterCount.update_counts_for_large_queue +end + +When /^I check the canonical option for the tag "([^"]*)"$/ do |tagname| + tag = Tag.find_by(name: tagname) + check("canonicals_#{tag.id}") +end + +When /^I select "([^"]*)" for the unsorted tag "([^"]*)"$/ do |type, tagname| + tag = Tag.find_by(name: tagname) + select(type, from: "tags[#{tag.id}]") +end + +When /^I check the (?:mass )?wrangling option for "([^"]*)"$/ do |tagname| + tag = Tag.find_by(name: tagname) + check("selected_tags_#{tag.id}") +end + +When "I edit the tag {string}" do |tag| + tag = Tag.find_by!(name: tag) + visit edit_tag_path(tag) +end + +When /^I view the tag "([^\"]*)"$/ do |tag| + tag = Tag.find_by!(name: tag) + visit tag_path(tag) +end + +When /^I create the fandom "([^\"]*)" with id (\d+)$/ do |name, id| + tag = Fandom.new(name: name) + tag.id = id.to_i + tag.canonical = true + tag.save +end + +When /^I set up the comment "([^"]*)" on the tag "([^"]*)"$/ do |comment_text, tag| + tag = Tag.find_by!(name: tag) + visit tag_url(tag) + click_link(" comment") + fill_in("Comment", with: comment_text) +end + +When /^I post the comment "([^"]*)" on the tag "([^"]*)"$/ do |comment_text, tag| + step "I set up the comment \"#{comment_text}\" on the tag \"#{tag}\"" + click_button("Comment") +end + +When /^I post the comment "([^"]*)" on the period-containing tag "([^"]*)"$/ do |comment_text, tag| + step "I am on the search tags page" + fill_in("tag_search_name", with: tag) + click_button "Search tags" + click_link(tag) + click_link(" comment") + fill_in("Comment", with: comment_text) + click_button("Comment") +end + +When /^I post the comment "([^"]*)" on the tag "([^"]*)" via web$/ do |comment_text, tag| + step %{I view the tag "#{tag}"} + step %{I follow " comments"} + step %{I fill in "Comment" with "#{comment_text}"} + step %{I press "Comment"} + step %{I should see "Comment created!"} +end + +When /^I add "([^\"]*)" to my favorite tags$/ do |tag| + step %{I view the "#{tag}" works index} + step %{I press "Favorite Tag"} +end + +When /^I remove "([^\"]*)" from my favorite tags$/ do |tag| + step %{I view the "#{tag}" works index} + step %{I press "Unfavorite Tag"} +end + +When /^the tag "([^\"]*)" is decanonized$/ do |tag| + tag = Tag.find_by!(name: tag) + tag.canonical = false + tag.save +end + +When /^the tag "([^"]*)" is canonized$/ do |tag| + tag = Tag.find_by!(name: tag) + tag.canonical = true + tag.save +end + +When /^I make a(?: (\d+)(?:st|nd|rd|th)?)? Wrangling Guideline$/ do |n| + n = 1 if n.zero? + visit new_wrangling_guideline_path + fill_in("Guideline text", with: "Number #{n} posted Wrangling Guideline, this is.") + fill_in("Title", with: "Number #{n} Wrangling Guideline") + click_button("Post") +end + +When /^(\d+) Wrangling Guidelines? exists?$/ do |n| + (1..n).each do |i| + FactoryBot.create(:wrangling_guideline, id: i) + end +end + +When /^I flush the wrangling sidebar caches$/ do + [Fandom, Character, Relationship, Freeform].each do |klass| + Rails.cache.delete("/wrangler/counts/sidebar/#{klass}") + end +end + +When /^I syn the tag "([^"]*)" to "([^"]*)"$/ do |syn, merger| + syn = Tag.find_by(name: syn) + visit edit_tag_path(syn) + fill_in("Synonym of", with: merger) + click_button("Save changes") +end + +When /^I de-syn the tag "([^"]*)" from "([^"]*)"$/ do |syn, merger| + merger = Tag.find_by(name: merger) + syn_id = Tag.find_by(name: syn).id + visit edit_tag_path(merger) + check("child_Merger_associations_to_remove_#{syn_id}") + click_button("Save changes") +end + +When /^I subtag the tag "([^"]*)" to "([^"]*)"$/ do |subtag, metatag| + subtag = Tag.find_by(name: subtag) + visit edit_tag_path(subtag) + fill_in("Add MetaTags:", with: metatag) + click_button("Save changes") +end + +When /^I remove the metatag "([^"]*)" from "([^"]*)"$/ do |metatag, subtag| + subtag = Tag.find_by(name: subtag) + metatag_id = Tag.find_by(name: metatag).id + visit edit_tag_path(subtag) + check("parent_MetaTag_associations_to_remove_#{metatag_id}") + click_button("Save changes") +end + +When /^I view the (canonical|synonymous|unfilterable|unwrangled|unwrangleable) (character|relationship|freeform) bin for "(.*?)"$/ do |status, type, tag| + visit wrangle_tag_path(Tag.find_by(name: tag), show: type.pluralize, status: status) +end + +When "I select {string} from the {string} wrangling assigment dropdown" do |login, tagname| + tag = Tag.find_by(name: tagname) + select(login, from: "assignments_#{tag.id}_") +end + +### THEN + +Then /^I should see the tag wrangler listed as an editor of the tag$/ do + step %{I should see "wrangler" within "fieldset dl"} +end + +Then /^I should see the tag search result "([^\"]*)"(?: within "([^"]*)")?$/ do |result, selector| + with_scope(selector) do + page.has_text?(result) + end +end + +Then /^I should not see the tag search result "([^\"]*)"(?: within "([^"]*)")?$/ do |result, selector| + with_scope(selector) do + page.has_no_text?(result) + end +end + +Then /^the ([\d]+)(?:st|nd|rd|th) tag result should contain "(.*?)"$/ do |n, text| + selector = "ol.tag > li:nth-of-type(#{n})" + with_scope(selector) do + expect(page).to have_content(text) + end +end + +Then /^"([^\"]*)" should not be a tag wrangler$/ do |username| + user = User.find_by(login: username) + user.tag_wrangler.should be_falsey +end + +Then /^"([^\"]*)" should be assigned to the wrangler "([^\"]*)"$/ do |fandom, username| + user = User.find_by(login: username) + fandom = Fandom.find_by(name: fandom) + assignment = WranglingAssignment.where(user_id: user.id, fandom_id: fandom.id ).first + assignment.should_not be_nil +end + +Then /^"([^\"]*)" should not be assigned to the wrangler "([^\"]*)"$/ do |fandom, username| + user = User.find_by(login: username) + fandom = Fandom.find_by(name: fandom) + assignment = WranglingAssignment.where(user_id: user.id, fandom_id: fandom.id ).first + assignment.should be_nil +end + +Then(/^the "([^"]*)" tag should be a "([^"]*)" tag$/) do |tagname, tag_type| + tag = Tag.find_by(name: tagname) + assert tag.type == tag_type +end + +Then "the {string} tag should be an unsorted tag" do |tagname| + tag = Tag.find_by(name: tagname) + expect(tag).to be_a(UnsortedTag) +end + +Then(/^the "([^"]*)" tag should (be|not be) canonical$/) do |tagname, canonical| + tag = Tag.find_by(name: tagname) + expected = canonical == "be" + assert tag.canonical == expected +end + +Then(/^the "([^"]*)" tag should (be|not be) unwrangleable$/) do |tagname, unwrangleable| + tag = Tag.find_by(name: tagname) + expected = unwrangleable == "be" + assert tag.unwrangleable == expected +end + +Then(/^the "([^"]*)" tag should be in the "([^"]*)" fandom$/) do |tagname, fandom_name| + tag = Tag.find_by(name: tagname) + fandom = Fandom.find_by(name: fandom_name) + assert tag.has_parent?(fandom) +end + +Then(/^show me what the tag "([^"]*)" is like$/) do |tagname| + tag = Tag.find_by(name: tagname) + puts tag.inspect +end + +Then "no tag is scheduled for count update from now on" do + expect_any_instance_of(Tag).not_to receive(:update_filters_for_filterables) +end diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb new file mode 100755 index 0000000..cd0916d --- /dev/null +++ b/features/step_definitions/user_steps.rb @@ -0,0 +1,351 @@ +DEFAULT_USER = "testuser" +DEFAULT_PASSWORD = "password" +NEW_USER = "newuser" + +# GIVEN + +Given /^I have no users$/ do + User.delete_all +end + +Given /I have an orphan account/ do + user = FactoryBot.create(:user, login: 'orphan_account') +end + +Given /the following activated users? exists?/ do |table| + table.hashes.each do |hash| + user = FactoryBot.create(:user, hash) + user.pseuds.first.add_to_autocomplete + step %{confirmation emails have been delivered} + end +end + +Given /the following users exist with BCrypt encrypted passwords/ do |table| + table.hashes.each do |hash| + user = FactoryBot.create(:user, hash) + user.pseuds.first.add_to_autocomplete + + # salt = Authlogic::Random.friendly_token + # same as + salt = SecureRandom.urlsafe_base64(15) + # encrypted_password = Authlogic::CryptoProviders::BCrypt.encrypt(hash[:password], salt) + # same as + encrypted_password = BCrypt::Password.create( + [hash[:password], salt].flatten.join, + cost: ArchiveConfig.BCRYPT_COST || 14) + + user.update!( + password_salt: salt, + encrypted_password: encrypted_password + ) + end +end + +Given /the following users exist with SHA-512 encrypted passwords/ do |table| + table.hashes.each do |hash| + user = FactoryBot.create(:user, hash) + user.pseuds.first.add_to_autocomplete + + # salt = Authlogic::Random.friendly_token + # same as + salt = SecureRandom.urlsafe_base64(15) + # encrypted_password = Authlogic::CryptoProviders::Sha512.encrypt(hash[:password], salt) + # same as + encrypted_password = [hash[:password], salt].flatten.join + 20.times { encrypted_password = Digest::SHA512.hexdigest(encrypted_password) } + + user.update!( + password_salt: salt, + encrypted_password: encrypted_password + ) + end +end + +Given /the following activated users with private work skins/ do |table| + table.hashes.each do |hash| + user = FactoryBot.create(:user, hash) + FactoryBot.create(:work_skin, :private, author: user, title: "#{user.login.titleize}'s Work Skin") + step %{confirmation emails have been delivered} + end +end + +Given /the following activated tag wranglers? exists?/ do |table| + table.hashes.each do |hash| + user = FactoryBot.create(:user, hash) + role = Role.find_or_create_by(name: "tag_wrangler") + user.roles = [role] + user.pseuds.first.add_to_autocomplete + end +end + +Given /^the user "([^"]*)" exists and is activated$/ do |login| + find_or_create_new_user(login, DEFAULT_PASSWORD) + step %{confirmation emails have been delivered} +end + +Given /^the user "([^"]*)" exists and is not activated$/ do |login| + find_or_create_new_user(login, DEFAULT_PASSWORD, activate: false) +end + +Given /^the user "([^"]*)" exists and has the role "([^"]*)"/ do |login, role| + user = find_or_create_new_user(login, DEFAULT_PASSWORD) + role = Role.find_or_create_by(name: role) + user.roles = [role] +end + +Given "the role {string}" do |role| + FactoryBot.create(:role, name: role) +end + +Given /^I am logged in as "([^"]*)" with password "([^"]*)"$/ do |login, password| + user = find_or_create_new_user(login, password) + step("I start a new session") + step %{I am on the homepage} + find_link('login-dropdown').click + + fill_in "Username or email:", with: login + fill_in "Password:", with: password + check "Remember Me" + click_button "Log In" + step %{I should see "Hi, #{login}!" within "#greeting"} + step %{confirmation emails have been delivered} +end + +Given /^I am logged in as "([^"]*)"$/ do |login| + step(%{I am logged in as "#{login}" with password "#{DEFAULT_PASSWORD}"}) +end + +Given "I am logged in as a new user {string}" do |login| + step(%{I am logged in as "#{login}"}) + user = User.find_by(login: login) + user.created_at = Time.current + user.confirmed_at = Time.current + user.save! +end + +Given /^I am logged in$/ do + step(%{I am logged in as "#{DEFAULT_USER}"}) +end + +Given /^I am logged in as a random user$/ do + name = "testuser#{User.count + 1}" + step(%{I am logged in as "#{name}" with password "#{DEFAULT_PASSWORD}"}) + step(%{confirmation emails have been delivered}) +end + +Given /^user "([^"]*)" is banned$/ do |login| + user = find_or_create_new_user(login, DEFAULT_PASSWORD) + user.banned = true + user.save +end + +Given /^I start a new session$/ do + page.driver.reset! +end + +Given "the username {string} is on the forbidden list" do |username| + allow(ArchiveConfig).to receive(:FORBIDDEN_USERNAMES).and_return([username]) +end + +# TODO: This should eventually be removed in favor of the "I log out" step, +# which does the same thing (but has a shorter and less passive name). +Given /^I am logged out$/ do + step(%{I follow "Log Out"}) +end + +Given /^I log out$/ do + step(%{I follow "Log Out"}) +end + +Given /^"([^"]*)" deletes their account/ do |username| + visit user_path(username) + step(%{I follow "Profile"}) + step(%{I follow "Delete My Account"}) +end + +Given /^I am a visitor$/ do + step "I start a new session" +end + +Given(/^I coauthored the work "(.*?)" as "(.*?)" with "(.*?)"$/) do |title, login, coauthor| + step %{basic tags} + author1 = User.find_by(login: login).default_pseud + author1.user.preference.update!(allow_cocreator: true) + author2 = User.find_by(login: coauthor).default_pseud + author2.user.preference.update!(allow_cocreator: true) + work = FactoryBot.create(:work, authors: [author1, author2], title: title) + work.creatorships.unapproved.each(&:accept!) +end + +Given /^"(.*?)" has an empty series "(.*?)"$/ do |login, title| + series = Series.new(title: title) + series.creatorships.build(pseud: User.find_by(login: login).default_pseud) + series.save +end + +Given "the user {string} is a protected user" do |login| + user = User.find_by(login: login) + user.roles = [Role.find_or_create_by(name: "protected_user")] +end + +Given "the user {string} has the no resets role" do |login| + user = User.find_by(login: login) + user.roles = [Role.find_or_create_by(name: "no_resets")] +end + +Given "the user {string} with the email {string} exists" do |login, email| + FactoryBot.create(:user, login: login, email: email) +end + +Given "the user {string} was created using an invitation" do |login| + invitation = FactoryBot.create(:invitation) + FactoryBot.create(:user, login: login, invitation: invitation) +end + +# WHEN + +When /^I follow the link for "([^"]*)" first invite$/ do |login| + user = User.find_by(login: login) + invite = user.invitations.first + step(%{I follow "#{invite.token}"}) +end + +When /^the user "([^\"]*)" has failed to log in (\d+) times$/ do |login, count| + user = User.find_by(login: login) + user.update!(failed_attempts: count.to_i) +end + +When "I fill in the sign up form with valid data" do + step(%{I fill in "user_registration_login" with "#{NEW_USER}"}) + step(%{I fill in "user_registration_email" with "test@archiveofourown.org"}) + step(%{I fill in "user_registration_password" with "password1"}) + step(%{I fill in "user_registration_password_confirmation" with "password1"}) + step(%{I check "user_registration_age_over_13"}) + step(%{I check "user_registration_data_processing"}) + step(%{I check "user_registration_terms_of_service"}) +end + +When /^I try to delete my account as (.*)$/ do |login| + step(%{I go to #{login}\'s user page}) + step(%{I follow "Profile"}) + step(%{I follow "Delete My Account"}) +end + +When /^I try to delete my account$/ do + step(%{I try to delete my account as #{DEFAULT_USER}}) +end + +When /^I visit the change username page for (.*)$/ do |login| + user = User.find_by(login: login) + visit change_username_user_path(user) +end + +When "I visit the change email page for {word}" do |login| + user = User.find_by(login: login) + visit change_email_user_path(user) +end + +When /^the user "(.*?)" accepts all co-creator requests$/ do |login| + # To make sure that we don't have caching issues with the byline: + step %{I wait 1 second} + user = User.find_by(login: login) + user.creatorships.unapproved.each(&:accept!) +end + +When "I request a password reset for {string}" do |login| + step(%{I am on the login page}) + step(%{I follow "Reset password"}) + step(%{I fill in "Email address or username" with "#{login}"}) + step(%{I press "Reset Password"}) +end + +# THEN + +Then "I should get the error message for wrong username or password" do + step(%{I should see "The password or username you entered doesn't match our records. Please try again"}) +end + +Then /^I should get an activation email for "(.*?)"$/ do |login| + step(%{1 email should be delivered}) + step(%{the email should contain "Welcome to the Archive of Our Own,"}) + step(%{the email should contain "#{login}"}) + step(%{the email should contain "activate your account"}) +end + +Then /^I should get a new user activation email$/ do + step(%{I should get an activation email for "#{NEW_USER}"}) +end + +Then /^a user account should exist for "(.*?)"$/ do |login| + user = User.find_by(login: login) + expect(user).to be_present +end + +Then /^a user account should not exist for "(.*)"$/ do |login| + user = User.find_by(login: login) + expect(user).to be_blank +end + +Then /^a new user account should exist$/ do + step %{a user account should exist for "#{NEW_USER}"} +end + +Then /^I should be logged out$/ do + step %{I should not see "Log Out"} + step %{I should see "Log In"} +end + +def get_work_name(age, classname, name) + klass = classname.classify.constantize + owner = (classname == "user") ? klass.find_by(login: name) : klass.find_by(name: name) + if age == "most recent" + owner.works.order("revised_at DESC").first.title + elsif age == "oldest" + owner.works.order("revised_at DESC").last.title + end +end + +def get_series_name(age, classname, name) + klass = classname.classify.constantize + owner = (classname == "user") ? klass.find_by(login: name) : klass.find_by(name: name) + if age == "most recent" + owner.series.order("updated_at DESC").first.title + elsif age == "oldest" + owner.series.order("updated_at DESC").last.title + end +end + +Then /^I should see the (most recent|oldest) (work|series) for (pseud|user) "([^"]*)"/ do |age, type, classname, name| + title = (type == "work" ? get_work_name(age, classname, name) : get_series_name(age, classname, name)) + step %{I should see "#{title}"} +end + +Then /^I should not see the (most recent|oldest) (work|series) for (pseud|user) "([^"]*)"/ do |age, type, classname, name| + title = (type == "work" ? get_work_name(age, classname, name) : get_series_name(age, classname, name)) + step %{I should not see "#{title}"} +end + +When /^I change my username to "([^"]*)"/ do |new_name| + step %{I follow "My Preferences"} + step %{I follow "Change Username"} + fill_in("New username", with: new_name) + fill_in("Password", with: "password") + click_button("Change Username") + step %{I should get confirmation that I changed my username} +end + +Then /^I should get confirmation that I changed my username$/ do + step(%{I should see "Your username has been successfully updated."}) + step(%{1 email should be delivered}) + step(%{the email should contain "The username for your .* has been changed to"}) +end + +Then /^the user "([^"]*)" should be activated$/ do |login| + user = User.find_by(login: login) + expect(user).to be_active +end + +Then "I should see the invitation id for the user {string}" do |login| + invitation_id = User.find_by(login: login).invitation.id + step %{I should see "Invitation: #{invitation_id}"} +end diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb new file mode 100755 index 0000000..65b27cd --- /dev/null +++ b/features/step_definitions/web_steps.rb @@ -0,0 +1,289 @@ +require 'uri' +require 'cgi' + +module WithinHelpers + def with_scope(locator) + locator ? within(locator) { yield } : yield + end +end +World(WithinHelpers) + +When /^I am in (.*) browser$/ do |name| + Capybara.session_name = name +end + +Given /^(?:|I )am on (.+)$/ do |page_name| + visit path_to(page_name) +end + +When /^I take a screenshot$/ do + screenshot_and_save_page +end + +When /^I clear the network traffic$/ do + page.driver.clear_network_traffic +end + +When /^(?:|I )go to (.+)$/ do |page_name| + visit path_to(page_name) +end + +When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector| + with_scope(selector) do + click_button(button) + end +end + +When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector| + with_scope(selector) do + click_link(link) + end +end + +When /^(?:|I )follow '([^']*)'(?: within "([^"]*)")?$/ do |link, selector| + with_scope(selector) do + click_link(link) + end +end + +When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field, value, selector| + with_scope(selector) do + fill_in(field, with: value) + end +end + +When /^(?:|I )fill in "([^"]*)" for "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector| + with_scope(selector) do + fill_in(field, with: value) + end +end + +# Use this to fill in an entire form with data from a table. Example: +# +# When I fill in the following: +# | Account Number | 5002 | +# | Expiry date | 2009-11-01 | +# | Note | Nice guy | +# | Wants Email? | | +# +# TODO: Add support for checkbox, select og option +# based on naming conventions. +# +When /^(?:|I )fill in the following(?: within "([^"]*)")?:$/ do |selector, fields| + with_scope(selector) do + fields.rows_hash.each do |name, value| + step %{I fill in "#{name}" with "#{value}"} + end + end +end + +When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector| + with_scope(selector) do + select(value, from: field) + end +end + +When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector| + with_scope(selector) do + check(field) + end +end + +When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector| + with_scope(selector) do + uncheck(field) + end +end + +When /^(?:|I )choose "(.*)"$/ do |field| + choose(field) +end + +When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector| + with_scope(selector) do + attach_file(field, path) + end +end + +Then /^(?:|I )should see JSON:$/ do |expected_json| + require 'json' + expected = JSON.pretty_generate(JSON.parse(expected_json)) + actual = JSON.pretty_generate(JSON.parse(response.body)) + expected.should == actual +end + +Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector| + with_scope(selector) do + page.should have_content(text) + end +end + +Then /^(?:|I )should see the raw text "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector| + with_scope(selector) do + page.body.should =~ /#{Regexp.escape(text)}/m + end +end + +Then /^(?:|I )should see '([^']*)'(?: within "([^"]*)")?$/ do |text, selector| + with_scope(selector) do + if page.respond_to? :should + page.should have_content(text) + else + assert page.has_content?(text) + end + end +end + +Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector| + regexp = Regexp.new(regexp) + with_scope(selector) do + if page.respond_to? :should + page.should have_xpath('//*', text: regexp) + else + assert page.has_xpath?('//*', text: regexp) + end + end +end + +Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector| + with_scope(selector) do + if page.respond_to? :should + page.should have_no_content(text) + else + assert page.has_no_content?(text) + end + end +end + +Then /^(?:|I )should not see '([^']*)'(?: within "([^"]*)")?$/ do |text, selector| + with_scope(selector) do + if page.respond_to? :should + page.should have_no_content(text) + else + assert page.has_no_content?(text) + end + end +end + +Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector| + regexp = Regexp.new(regexp) + with_scope(selector) do + if page.respond_to? :should + page.should have_no_xpath('//*', text: regexp) + else + assert page.has_no_xpath?('//*', text: regexp) + end + end +end + +Then /"(.*)" should appear before "(.*)"/ do |first_example, second_example| + page.body.should =~ /#{first_example}.*#{second_example}/m +end + +Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |field, selector, value| + with_scope(selector) do + field = find_field(field) + field_value = (field.tag_name == 'textarea') ? field.text : field.value + if field_value.respond_to? :should + field_value.should =~ /#{value}/ + else + assert_match(/#{value}/, field_value) + end + end +end + +Then /^the field labeled "([^"]*)" should contain "([^"]*)"$/ do |label, value| + field = find_field(label) + field_value = (field.tag_name == 'textarea') ? field.text : field.value + if field_value.respond_to? :should + field_value.should =~ /#{value}/ + else + assert_match(/#{value}/, field_value) + end +end + +Then /^the "([^"]*)" field(?: within "([^"]*)")? should not contain "([^"]*)"$/ do |field, selector, value| + with_scope(selector) do + field = find_field(field) + field_value = (field.tag_name == 'textarea') ? field.text : field.value + if field_value.respond_to? :should_not + field_value.should_not =~ /#{value}/ + else + assert_no_match(/#{value}/, field_value) + end + end +end + +Then /^the "(.*?)" (checkbox|radio button)(?: within "(.*?)")? should be checked( and disabled)?$/ do |label, _input_type, selector, disabled| + with_scope(selector) do + assert has_checked_field?(label, disabled: disabled.present?) + end +end + +Then /^the "(.*?)" checkbox(?: within "(.*?)")? should not be checked$/ do |label, selector| + with_scope(selector) do + assert has_unchecked_field?(label) + end +end + +Then /^(?:|I )should be on (.+)$/ do |page_name| + current_path = URI.parse(current_url).path + if current_path.respond_to? :should + current_path.should == path_to(page_name) + else + assert_equal path_to(page_name), current_path + end +end + +Then /^(?:|The )url should include (.+)$/ do |url| + current_url.should include(url) +end + +Then "the url should not include {string}" do |url| + expect(current_url).not_to include(url) +end + +Then /^(?:|I )should have the following query string:$/ do |expected_pairs| + query = URI.parse(current_url).query + actual_params = query ? CGI.parse(query) : {} + expected_params = {} + expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')} + + if actual_params.respond_to? :should + actual_params.should == expected_params + else + assert_equal expected_params, actual_params + end +end + +Then /^I should download a ([^"]*) file with(?: (\d+) rows and)? the header row "(.*?)"$/ do |type, rows, header| + page.response_headers['Content-Disposition'].should =~ /attachment; filename=.*?\.#{type}/i + page.response_headers['Content-Type'].should =~ /\/#{type}/i + body_without_bom = page.body.encode("UTF-8").delete!("\xEF\xBB\xBF") + csv = CSV.parse(body_without_bom, col_sep: "\t") # array of arrays + expect(csv.first.join(" ")).to eq(header) + expect(csv.size).to eq(rows) unless rows.blank? || rows.zero? +end + +Then /^show me the page$/ do + save_and_open_page + sleep 120 +end + +Then /^show me the network traffic$/ do + puts page.driver.network_traffic.to_yaml +end + +Then /^cookie "([^\"]*)" should be like "([^\"]*)"$/ do |cookie, value| + cookie_value = Capybara.current_session.driver.request.cookies.[](cookie) + if cookie_value.respond_to? :should + cookie_value.should =~ /#{value}/ + else + assert cookie_value =~ /#{value}/ + end +end + +Then /^cookie "([^"]*)" should be deleted$/ do |cookie| + cookie_value = Capybara.current_session.driver.request.cookies.[](cookie) + assert cookie_value.nil? +end diff --git a/features/step_definitions/work_deletion_steps.rb b/features/step_definitions/work_deletion_steps.rb new file mode 100755 index 0000000..538fb54 --- /dev/null +++ b/features/step_definitions/work_deletion_steps.rb @@ -0,0 +1,11 @@ +### THEN + +Then /^"(.+)" should be notified by email about the deletion of "(.+)"$/ do |user, title| + step %{1 email should be delivered to "#{user}"} + step %{the email should contain "Your work"} + step %{the email should contain "#{title}"} + step %{the email should contain "was deleted at your request"} + step %{the email should contain "If you have questions, please"} + step %{the email should link to the support page} + step %{the email should contain "Attached is a copy of your work for your reference."} +end diff --git a/features/step_definitions/work_download_steps.rb b/features/step_definitions/work_download_steps.rb new file mode 100755 index 0000000..27c7696 --- /dev/null +++ b/features/step_definitions/work_download_steps.rb @@ -0,0 +1,37 @@ +Then /^I should see the inspiring parent work link$/ do + parent = Work.find_by(title: "Worldbuilding") + inspired_link = "<a href=\"#{work_url(parent)}\">#{parent.title}</a>" + page.body.should =~ /Inspired by #{Regexp.escape(inspired_link)}/m +end + +Then /^I should see the external inspiring work link$/ do + parent = ExternalWork.find_by(title: "Example External") + inspired_link = "<a href=\"#{external_work_url(parent)}\">#{parent.title}</a>" + page.body.should =~ /Inspired by #{Regexp.escape(inspired_link)}/m +end + +Then /^I should receive a file of type "(.*?)"$/ do |filetype| + mime_type = Marcel::MimeType.for(name: "foo.#{filetype}").to_s + expect(page.response_headers['Content-Disposition']).to match(/filename=.+\.#{filetype}/) + expect(page.response_headers['Content-Length'].to_i).to be_positive + expect(page.response_headers['Content-Type']).to eq(mime_type) +end + +Then /^I should be able to download all versions of "(.*?)"$/ do |title| + (ArchiveConfig.DOWNLOAD_FORMATS - ['html']).each do |filetype| + step %{I should be able to download the #{filetype} version of "#{title}"} + end +end + +Then /^I should be able to download the (\w+) version of "(.*?)"$/ do |filetype, title| + work = Work.find_by_title(title) + visit work_url(work) + step %{I follow "#{filetype.upcase}"} + + download = Download.new(work, format: filetype) + filename = "#{download.file_name}.#{download.file_type}" + mime_type = Marcel::MimeType.for(name: filename).to_s + expect(page.response_headers['Content-Disposition']).to match(/filename="#{filename}"/) + expect(page.response_headers['Content-Length'].to_i).to be_positive + expect(page.response_headers['Content-Type']).to eq(mime_type) +end diff --git a/features/step_definitions/work_import_steps.rb b/features/step_definitions/work_import_steps.rb new file mode 100755 index 0000000..757ea32 --- /dev/null +++ b/features/step_definitions/work_import_steps.rb @@ -0,0 +1,136 @@ +require "webmock/cucumber" + +def content_fields + { + title: "Detected Title", summary: "Detected summary", fandoms: "Detected Fandom", warnings: "Underage Sex", + characters: "Detected 1, Detected 2", rating: "Explicit", relationships: "Detected 1/Detected 2", + categories: "F/F", freeform: "Detected tag 1, Detected tag 2", external_author_name: "Detected Author", + external_author_email: "detected@foo.com", notes: "This is a <i>content note</i>.", + date: "2002-01-12", chapter_title: "Detected chapter title" + } +end + +# Let the test get at external sites, but stub out anything containing certain keywords +def mock_external + WebMock.allow_net_connect! + + WebMock.stub_request(:any, /import-site-with-tags/). + to_return(status: 200, + body: + "Title: #{content_fields[:title]} +Summary: #{content_fields[:summary]} +Date: #{content_fields[:date]} +Fandom: #{content_fields[:fandoms]} +Rating: #{content_fields[:rating]} +Warnings: #{content_fields[:warnings]} +Characters: #{content_fields[:characters]} +Pairings: #{content_fields[:relationships]} +Category: #{content_fields[:categories]} +Tags: #{content_fields[:freeform]} +Author's notes: #{content_fields[:notes]} + +stubbed response", headers: {}) + + WebMock.stub_request(:any, /import-site-without-tags/). + to_return(status: 200, + body: "stubbed response", + headers: {}) + + WebMock.stub_request(:any, /second-import-site-without-tags/). + to_return(status: 200, + body: "second stubbed response", + headers: {}) + + WebMock.stub_request(:any, /no-content/). + to_return(status: 200, + body: "", + headers: {}) + + WebMock.stub_request(:any, /bar/) + .to_return(status: 404, headers: {}) + + WebMock.stub_request(:any, /second-import-site-with-tags/) + .to_return(status: 200, + headers: {}, + body: <<~BODY + <html><head> + <title>Huddling + + + + + +

    Huddling

    +

    by an_author for the otwarchive testing meme.

    + +

    "What is this place?" orphan_account asked.

    + +

    "I—don't know," Tester said.

    + +

    = End =

    + + + BODY + ) +end + +Given "I set up mock websites for importing" do + mock_external +end + +Given /^I set up importing( with a mock website)?( as an archivist)?$/ do |mock, is_archivist| + unless mock.blank? + mock_external + end + step %{basic languages} + step %{basic tags} + step %{all warnings exist} + if is_archivist.blank? + step %{I am logged in as a random user} + else + step %{I have an archivist "archivist"} + step %{I am logged in as "archivist"} + end + step %{I go to the import page} +end + +When /^I start importing "(.*)"( with a mock website)?( as an archivist)?$/ do |url, mock, is_archivist| + step %{I set up importing#{mock}#{is_archivist}} + step %{I fill in "urls" with "#{url}"} + step %{I select "English" from "Choose a language"} +end + +When "I import the mock work {string} by {string} with email {string} and by {string} with email {string}" do |url, creator_name, creator_email, cocreator_name, cocreator_email| + step(%{I start importing "#{url}" with a mock website as an archivist}) + step(%{I check "Import for others ONLY with permission"}) + step(%{I fill in "external_author_name" with "#{creator_name}"}) + step(%{I fill in "external_author_email" with "#{creator_email}"}) + step(%{I fill in "external_coauthor_name" with "#{cocreator_name}"}) + step(%{I fill in "external_coauthor_email" with "#{cocreator_email}"}) + step(%{I check "Post without previewing"}) + step(%{I press "Import"}) +end + +When /^I import "(.*)"( with a mock website)?$/ do |url, mock| + step %{I start importing "#{url}"#{mock}} + step %{I press "Import"} +end + +When /^I import the urls with mock websites( as chapters)?( without preview)?$/ do |chapters, no_preview, urls| + step %{I set up importing with a mock website} + step %{I fill in "urls" with "#{urls}"} + step %{I select "English" from "Choose a language"} + if chapters + step %{I choose "import_multiple_chapters"} + end + if no_preview + step %{I check "post_without_preview"} + end + step %{I press "Import"} +end diff --git a/features/step_definitions/work_related_steps.rb b/features/step_definitions/work_related_steps.rb new file mode 100755 index 0000000..0285042 --- /dev/null +++ b/features/step_definitions/work_related_steps.rb @@ -0,0 +1,206 @@ +### GIVEN + +Given /^I have related works setup$/ do + step "basic tags" + step "all emails have been delivered" + + inspiration = FactoryBot.create(:user, login: "inspiration", confirmed_at: Time.now.utc) + FactoryBot.create(:user, login: "translator", confirmed_at: Time.now.utc) + FactoryBot.create(:user, login: "remixer", confirmed_at: Time.now.utc) + + FactoryBot.create(:work, title: "Worldbuilding", authors: inspiration.pseuds) + FactoryBot.create(:work, title: "Worldbuilding Two", authors: inspiration.pseuds) +end + +Given /^an inspiring parent work has been posted$/ do + step "I post an inspiring parent work as testuser" +end + +# given for remixes / related works + +Given /^a related work has been posted$/ do + step %{I post a related work as remixer} +end + +Given /^a related work has been posted and approved$/ do + step %{I post a related work as remixer} + step %{I approve a related work} +end + +# given for translations + +Given /^a translation has been posted$/ do + step %{I post a translation as translator} +end + +Given /^a translation has been posted and approved$/ do + step %{I post a translation as translator} + step %{I approve a related work} +end + +### WHEN + +When "I post an inspiring parent work as testuser" do + step %{I am logged in as "testuser"} + step %{I post the work "Parent Work"} +end + +When /^I approve a related work$/ do + step %{I am logged in as "inspiration"} + step %{I follow "My Dashboard"} + step %{I follow "Related Works ("} + step %{I follow "Approve"} + step %{I press "Yes, link me!"} +end + +When /^I view my related works$/ do + step %{I follow "My Dashboard"} + step %{I follow "Related Works ("} +end + +# when for remixes / related works + +When /^I post a related work as remixer$/ do + step %{I am logged in as "remixer"} + step %{I go to the new work page} + step %{I select "Not Rated" from "Rating"} + step %{I check "No Archive Warnings Apply"} + step %{I select "English" from "Choose a language"} + step %{I fill in "Fandoms" with "Stargate"} + step %{I fill in "Work Title" with "Followup"} + step %{I fill in "content" with "That could be an amusing crossover."} + step %{I list the work "Worldbuilding" as inspiration} + step %{I press "Preview"} + step %{I press "Post"} +end + +When /^I post a related work as remixer for an external work$/ do + step %{I am logged in as "remixer"} + step %{I go to the new work page} + step %{I select "Not Rated" from "Rating"} + step %{I check "No Archive Warnings Apply"} + step %{I select "English" from "Choose a language"} + step %{I fill in "Fandoms" with "Stargate"} + step %{I fill in "Work Title" with "Followup"} + step %{I fill in "content" with "That could be an amusing crossover."} + step %{I list an external work as inspiration} + step %{I press "Preview"} + step %{I press "Post"} +end + +# when for translations + +When /^I post a translation as translator$/ do + step %{I am logged in as "translator"} + step %{I draft a translation} + step %{I press "Post"} +end + +When /^I post a translation of my own work$/ do + step %{I am logged in as "inspiration"} + step %{I draft a translation} + step %{I press "Post"} +end + +When /^I draft a translation$/ do + FactoryBot.create(:language, name: "Deutsch", short: "de") + + step %{I go to the new work page} + step %{I check "No Archive Warnings Apply"} + step %{I fill in "Fandoms" with "Stargate"} + step %{I fill in "Work Title" with "Worldbuilding Translated"} + step %{I fill in "content" with "That could be an amusing crossover."} + step %{I list the work "Worldbuilding" as inspiration} + step %{I check "This is a translation"} + step %{I select "Deutsch" from "Choose a language"} + step %{I press "Preview"} +end + +When /^I list a series as inspiration$/ do + with_scope("#parent-options") do + fill_in("URL", with: "#{ArchiveConfig.APP_HOST}/series/123") + end +end + +When /^I list a nonexistent work as inspiration$/ do + work = Work.find_by_id(123) + work.destroy unless work.nil? + with_scope("#parent-options") do + fill_in("URL", with: "#{ArchiveConfig.APP_HOST}/works/123") + end +end + +### THEN + +Then /^the original author should be emailed$/ do + step "1 email should be delivered" +end + +Then /^approving the related work should succeed$/ do + step %{I should see "Link was successfully approved"} +end + +# then for remixes / related works + +Then /^a parent related work should be seen$/ do + step %{I should see "Work was successfully posted"} + step %{I should find a list for associations} + step %{I should see "Inspired by Worldbuilding by inspiration" within ".preface .notes"} +end + +Then /^I should see the inspiring parent work in the beginning notes$/ do + step %{I should see "Inspired by Parent Work by testuser" within ".preface .notes"} +end + +Then /^I should see a beginning note about related works$/ do + step %{I should see "See the end of the work for other works inspired by this one" within ".preface .notes"} +end + +Then /^I should see the related work in the end notes$/ do + step %{I should see "Works inspired by this one:" within ".afterword .children"} + step %{I should see "Followup by remixer" within ".afterword .children"} +end + +Then "I should see the related work listed on the original work" do + step %{I should see "See the end of the work for other works inspired by this one"} + step %{I should see "Works inspired by this one:"} + step %{I should see "Followup by remixer"} +end + +Then /^I should not see the related work listed on the original work$/ do + step %{I should not see "See the end of the work for other works inspired by this one"} + step %{I should not see "Works inspired by this one:"} + step %{I should not see "Followup by remixer"} +end + +Then "I should not see the inspiring parent work in the beginning notes" do + step %{I should not see "Inspired by Parent Work by testuser" within ".preface .notes"} +end + +# then for translations + +Then /^a parent translated work should be seen$/ do + step %{I should see "Work was successfully posted"} + step %{I should find a list for associations} + step %{I should see "A translation of Worldbuilding by inspiration" within ".preface .notes"} +end + +Then "I should see the translation in the beginning notes" do + step %{I should see "Translation into Deutsch available:" within ".preface .notes"} + step %{I should see "Worldbuilding Translated by translator" within ".preface .notes"} +end + +Then "I should see the translation listed on the original work" do + step %{I should see "Translation into Deutsch available:"} + step %{I should see "Worldbuilding Translated by translator"} +end + +Then /^I should not see the translation listed on the original work$/ do + step %{I should not see "Translation into Deutsch available:"} + step %{I should not see "Worldbuilding Translated by translator"} +end + +Then /^I should not see the translation in the end notes$/ do + step %{I should not see "Translation into Deutsch available:" within ".afterword"} + step %{I should not see "Worldbuilding Translated by translator" within ".afterword"} +end diff --git a/features/step_definitions/work_search_steps.rb b/features/step_definitions/work_search_steps.rb new file mode 100755 index 0000000..f1436c5 --- /dev/null +++ b/features/step_definitions/work_search_steps.rb @@ -0,0 +1,514 @@ +### GIVEN + +Given /^a set of alternate universe works for searching$/ do + step %{basic tags} + + # Create a metatag with a syn + step %{a canonical freeform "Alternate Universe"} + step %{a synonym "AU" of the tag "Alternate Universe"} + + # Create a subtag with a syn + step %{a canonical freeform "Alternate Universe - High School"} + step %{a synonym "High School AU" of the tag "Alternate Universe - High School"} + + # Create another subtag + step %{a canonical freeform "Alternate Universe - Coffee Shops & Cafés"} + + # Set up the tree + step %{"Alternate Universe" is a metatag of the freeform "Alternate Universe - High School"} + step %{"Alternate Universe" is a metatag of the freeform "Alternate Universe - Coffee Shops & Cafés"} + + # Create a work with every tag except Alternate Universe - High School, and a + # work with the unwrangled tag Coffee Shop AU + ["Alternate Universe", + "AU", + "High School AU", + "Alternate Universe - Coffee Shops & Cafés", + "Coffee Shop AU"].each do |freeform| + FactoryBot.create(:work, freeform_string: freeform) + end + + # Create a work with a summary that is a text match for both the unwrangled + # tag (Coffee Shop AU) and the metatag's syn (AU) + FactoryBot.create(:work, summary: "A humble Coffee Shop AU") + + # Create a work with a character tag that is a text match for the metatag's + # syn (AU) + FactoryBot.create(:work, character_string: "AU Character") + + step %{all indexing jobs have been run} +end + +Given /^a set of Steve Rogers works for searching$/ do + step %{basic tags} + + # Create two fandoms + step %{a canonical fandom "Marvel Cinematic Universe"} + step %{a canonical fandom "The Avengers (Marvel Movies)"} + + # Create a character with a syn + step %{a canonical character "Steve Rogers"} + step %{a synonym "Captain America" of the tag "Steve Rogers"} + + # Create a meta tag for that character + step %{a canonical character "Steve"} + step %{"Steve" is a metatag of the character "Steve Rogers"} + + # Create a work for each character tag in each fandom + ["Marvel Cinematic Universe", "The Avengers (Marvel Movies)"].each do |fandom| + ["Steve Rogers", "Captain America"].each do |character| + FactoryBot.create(:work, + fandom_string: fandom, + character_string: character) + end + end + + # Create a work without Steve as a character but with him in a relationship + FactoryBot.create(:work, + relationship_string: "Steve Rogers/Tony Stark") + + # Create a work that only mentions Steve in the summary + FactoryBot.create(:work, + summary: "Bucky thinks about his pal Steve Rogers.") + + step %{all indexing jobs have been run} +end + +Given /^a set of Kirk\/Spock works for searching$/ do + step %{basic tags} + + # Create a relationship with two syns + step %{a canonical relationship "James T. Kirk/Spock"} + step %{a synonym "K/S" of the tag "James T. Kirk/Spock"} + step %{a synonym "Spirk" of the tag "James T. Kirk/Spock"} + + # Create a work for each tag + ["James T. Kirk/Spock", "K/S", "Spirk"].each do |relationship| + FactoryBot.create(:work, relationship_string: relationship) + end + + # Create a F/M work using one of the synonyms + FactoryBot.create(:work, + title: "The Genderswap K/S Work That Uses a Synonym", + relationship_string: "Spirk", + category_string: "F/M") + + step %{all indexing jobs have been run} +end + +Given /^a set of Spock\/Uhura works for searching$/ do + step %{basic tags} + + # Create a canonical two-character relationship with a syn + step %{a canonical relationship "Spock/Nyota Uhura"} + step %{a synonym "Uhura/Spock" of the tag "Spock/Nyota Uhura"} + + # Create a threesome with a name that is a partial match for the relationship + step %{a canonical relationship "James T. Kirk/Spock/Nyota Uhura"} + + # Create a work for each tag + ["Spock/Nyota Uhura", + "Uhura/Spock", + "James T. Kirk/Spock/Nyota Uhura"].each do |relationship| + FactoryBot.create(:work, + relationship_string: relationship) + end + + step %{all indexing jobs have been run} +end + +Given "a set of Ed Stede works for searching" do + step %{basic tags} + + # Create a relationship with a syn + step %{a canonical relationship "Blackbeard | Edward Teach/Stede Bonnet"} + step %{a synonym "Ed/Stede" of the tag "Blackbeard | Edward Teach/Stede Bonnet"} + + # Create a work for each tag or set of tags (all are otp: true) + ["Ed/Stede", + "Blackbeard | Edward Teach/Stede Bonnet", + "Blackbeard | Edward Teach/Stede Bonnet, Ed/Stede"].each do |relationship| + FactoryBot.create(:work, relationship_string: relationship) + end + + # Create a work with no relationship tag (an otp: false work) + FactoryBot.create(:work, title: "The Work Without a Relationship") + + # Create a work with two unconnected relationship tags (an otp: false work) + FactoryBot.create(:work, + title: "The Work With Multiple Ships", + relationship_string: "Ed/Stede, Ed/Izzy") + + step %{all indexing jobs have been run} +end + +Given "a set of crossover works for searching" do + step %{basic tags} + + # Create two unrelated fandoms, one with a syn + step %{a canonical fandom "Unrelated Fandom"} + step %{a canonical fandom "Hermitcraft SMP"} + step %{a synonym "Hermitcraft" of the tag "Hermitcraft SMP"} + + # Create a fandom and make it the metatag of one of the fandoms + step %{a canonical fandom "Video Blogging RPF"} + step %{"Video Blogging RPF" is a metatag of the fandom "Hermitcraft SMP"} + + # Create a work for each tag or set of tags (none are crossovers) + ["Video Blogging RPF", + "Hermitcraft SMP", + "Hermitcraft SMP, Hermitcraft", + "Hermitcraft SMP, Video Blogging RPF", + "Hermitcraft, Video Blogging RPF"].each do |fandom| + FactoryBot.create(:work, fandom_string: fandom) + end + + # Create three works with two unconnected fandom tags (crossover works) + FactoryBot.create(:work, + title: "First Work With Multiple Fandoms", + fandom_string: "Hermitcraft SMP, Unrelated Fandom") + FactoryBot.create(:work, + title: "Second Work With Multiple Fandoms", + fandom_string: "Hermitcraft, Unrelated Fandom") + FactoryBot.create(:work, + title: "Third Work With Multiple Fandoms", + fandom_string: "Video Blogging RPF, Unrelated Fandom") + + step %{all indexing jobs have been run} +end + +Given /^a set of works with various categories for searching$/ do + step %{basic tags} + + # Create one work with each category + %w(Gen Other F/F Multi F/M M/M).each do |category| + FactoryBot.create(:work, category_string: category) + end + + # Create one work using multiple categories + FactoryBot.create(:work, category_string: "M/M, F/F") + + step %{all indexing jobs have been run} +end + +Given /^a set of works with comments for searching$/ do + step %{basic tags} + + counts = { + "Work 1" => 0, + "Work 2" => 1, + "Work 3" => 1, + "Work 4" => 1, + "Work 5" => 3, + "Work 6" => 3, + "Work 7" => 10 + } + + counts.each_pair do |title, comment_count| + work = FactoryBot.create(:work, title: title) + FactoryBot.create_list(:comment, comment_count, :by_guest, + commentable: work.last_posted_chapter) + end + + step %{the statistics for all works are updated} + step %{all indexing jobs have been run} +end + +Given /^a set of Star Trek works for searching$/ do + step %{basic tags} + + # Create three related canonical fandoms + step %{a canonical fandom "Star Trek"} + step %{a canonical fandom "Star Trek: The Original Series"} + step %{a canonical fandom "Star Trek: The Original Series (Movies)"} + + # Create a syn for one of the fandoms + step %{a synonym "ST: TOS" of the tag "Star Trek: The Original Series"} + + # Create an unrelated fourth fandom we'll use for a crossover + step %{a canonical fandom "Battlestar Galactica (2003)"} + + # Set up the tree for the related fandoms + step %{"Star Trek" is a metatag of the fandom "Star Trek: The Original Series"} + step %{"Star Trek: The Original Series" is a metatag of the fandom "Star Trek: The Original Series (Movies)"} + + # Create a work using each of the related fandoms + ["Star Trek", "Star Trek: The Original Series", + "Star Trek: The Original Series (Movies)", "ST: TOS"].each do |fandom| + FactoryBot.create(:work, fandom_string: fandom) + end + + # Create a work with two fandoms (e.g. a crossover) + FactoryBot.create(:work, + fandom_string: "ST: TOS, + Battlestar Galactica (2003)") + + # Create a work with an additional tag (freeform) that references the fandom + FactoryBot.create(:work, + fandom_string: "Battlestar Galactica (2003)", + freeform_string: "Star Trek Fusion") + + step %{all indexing jobs have been run} +end + +Given /^a set of works with bookmarks for searching$/ do + step %{basic tags} + + counts = { + "Work 1" => 0, + "Work 2" => 1, + "Work 3" => 1, + "Work 4" => 2, + "Work 5" => 2, + "Work 6" => 4, + "Work 7" => 10 + } + + counts.each_pair do |title, bookmark_count| + work = FactoryBot.create(:work, title: title) + FactoryBot.create_list(:bookmark, bookmark_count, bookmarkable: work) + end + + step %{the statistics for all works are updated} + step %{all indexing jobs have been run} +end + +Given /^a set of works with various ratings for searching$/ do + step %{basic tags} + + ratings = [ArchiveConfig.RATING_DEFAULT_TAG_NAME, + ArchiveConfig.RATING_GENERAL_TAG_NAME, + ArchiveConfig.RATING_TEEN_TAG_NAME, + ArchiveConfig.RATING_MATURE_TAG_NAME, + ArchiveConfig.RATING_EXPLICIT_TAG_NAME] + + ratings.each do |rating| + FactoryBot.create(:work, rating_string: rating) + end + + FactoryBot.create(:work, + rating_string: ArchiveConfig.RATING_DEFAULT_TAG_NAME, + summary: "Nothing explicit here.") + + step %{all indexing jobs have been run} +end + +Given /^a set of works with various warnings for searching$/ do + step %{basic tags} + step %{all warnings exist} + + warnings = [ArchiveConfig.WARNING_DEFAULT_TAG_NAME, + ArchiveConfig.WARNING_NONE_TAG_NAME, + ArchiveConfig.WARNING_VIOLENCE_TAG_NAME, + ArchiveConfig.WARNING_DEATH_TAG_NAME, + ArchiveConfig.WARNING_NONCON_TAG_NAME, + ArchiveConfig.WARNING_CHAN_TAG_NAME] + + # Create a work for each warning + warnings.each do |warning| + FactoryBot.create(:work, archive_warning_string: warning) + end + + # Create a work that uses multiple warnings + FactoryBot.create(:work, + archive_warning_string: "#{ArchiveConfig.WARNING_DEFAULT_TAG_NAME}, + #{ArchiveConfig.WARNING_NONE_TAG_NAME}") + + step %{all indexing jobs have been run} +end + +Given /^a set of works with various access levels for searching$/ do + # Create a draft + FactoryBot.create(:draft, title: "Draft Work") + + # Create a work + FactoryBot.create(:work, title: "Posted Work") + + # Create a work restricted to registered users + FactoryBot.create(:work, restricted: true, title: "Restricted Work") + + # Create a work hidden by an admin + FactoryBot.create(:work, + hidden_by_admin: true, + title: "Work Hidden by Admin") + + step %{all indexing jobs have been run} +end + +Given "a set of old multilanguage works for searching" do + german = Language.find_or_create_by!(short: "de", name: "Deutsch") + + FactoryBot.create(:work, + title: "My <strong>er German Work", + language: german, + authors: [ensure_user("testuser2").default_pseud]) + + FactoryBot.create(:work, + title: "unfinished", + complete: false, + expected_number_of_chapters: 2, + authors: [ensure_user("testuser").default_pseud]) + + step %{all indexing jobs have been run} + step %{it is currently 3 years from now} +end + +Given "a set of works with stats for searching" do + many = FactoryBot.create(:work, title: "many") + FactoryBot.create_list(:kudo, 4, commentable: many) + many.stat_counter.update_attribute(:hit_count, 10_000) + + less = FactoryBot.create(:work, title: "less") + FactoryBot.create(:kudo, commentable: less) + less.stat_counter.update_attribute(:hit_count, 500) + + FactoryBot.create(:work, title: "none") + FactoryBot.create(:work, title: "unfinished", complete: false, expected_number_of_chapters: 2) + + step %{the statistics for all works are updated} + step %{all indexing jobs have been run} +end + +### WHEN + +When /^I search for a simple term from the search box$/ do + step %{I am on the homepage} + step %{I fill in "site_search" with "first"} + step %{I press "Search"} +end + +When /^I search for works containing "([^"]*)"$/ do |term| + step %{I am on the homepage} + step %{I fill in "site_search" with "#{term}"} + step %{I press "Search"} +end + +When /^I search for works by "([^"]*)"$/ do |creator| + step %{I am on the homepage} + step %{I fill in "site_search" with "creator: #{creator}"} + step %{I press "Search"} +end + +When /^I search for works without the "([^"]*)"(?: and "([^"]*)")? filter_ids?$/ do |tag1, tag2| + filter_id1 = Tag.find_by_name(tag1).filter_taggings.first.filter_id + filter_id2 = Tag.find_by_name(tag2).filter_taggings.first.filter_id if tag2 + step %{I am on the homepage} + if tag2 + fill_in("site_search", with: "-filter_ids: #{filter_id1} -filter_ids: #{filter_id2}") + else + fill_in("site_search", with: "-filter_ids: #{filter_id1}") + end + step %{I press "Search"} +end + +When /^I exclude the tags? "([^"]*)"(?: and "([^"]*)")? by filter_id$/ do |tag1, tag2| + filter_id1 = Tag.find_by_name(tag1).filter_taggings.first.filter_id + filter_id2 = Tag.find_by_name(tag2).filter_taggings.first.filter_id if tag2 + if tag2 + fill_in('work_search_query', with: "-filter_ids: #{filter_id1} -filter_ids: #{filter_id2}") + else + fill_in('work_search_query', with: "-filter_ids: #{filter_id1}") + end +end + +### THEN + +Then /^the results should contain the ([^"]*) tag "([^"]*)"$/ do |type, tag| + selector = if type == "fandom" + "ol.work .fandoms" + elsif %w(rating category).include?(type) + "ol.work .required-tags .#{type}" + else + "ol.work .tags .#{type.pluralize}" + end + expect(page).to have_css(selector, text: tag) +end + +Then /^the results should not contain the ([^"]*) tag "([^"]*)"$/ do |type, tag| + selector = if type == "fandom" + "ol.work .fandoms" + elsif %w(rating category).include?(type) + "ol.work .required-tags .#{type}" + else + "ol.work .tags .#{type.pluralize}" + end + expect(page).not_to have_css(selector, text: tag) +end + +Then /^the results should contain (?:a|the) synonyms? of "([^"]*)"$/ do |tag| + tag = Tag.find_by_name(tag) + type = tag.type.downcase.pluralize + synonyms = tag.synonyms.map(&:name) + selector = if type == "fandoms" + "ol.work .fandoms" + else + "ol.work .tags .#{type}" + end + synonyms.each do |synonym| + expect(page).to have_css(selector, text: synonym) + end +end + +Then /^the results should contain (?:a|the) subtags? of "([^"]*)"$/ do |tag| + tag = Tag.find_by_name(tag) + type = tag.type.downcase.pluralize + subtags = tag.sub_tags.map(&:name) + selector = if type == "fandoms" + "ol.work .fandoms" + else + "ol.work .tags .#{type}" + end + subtags.each do |subtag| + expect(page).to have_css(selector, text: subtag) + end +end + +Then /^the results should contain a ([^"]*) mentioning "([^"]*)"$/ do |item, term| + selector = if item == "fandom" + "ol.work .fandoms" + elsif item == "summary" + "ol.work .summary" + else + "ol.work .tags .#{item.pluralize}" + end + expect(page).to have_css(selector, text: term) +end + +Then /^the results should not contain a ([^"]*) mentioning "([^"]*)"$/ do |item, term| + selector = if item == "fandom" + "ol.work .fandoms" + elsif item == "summary" + "ol.work .summary" + else + "ol.work .tags .#{item.pluralize}" + end + expect(page).not_to have_css(selector, text: term) +end + +Then /^the ([\d]+)(?:st|nd|rd|th) result should contain "([^"]*)"$/ do |n, text| + selector = "ol.work > li:nth-of-type(#{n})" + with_scope(selector) do + page.should have_content(text) + end +end + +# If JavaScript is enabled and we want to check that information is retained +# when editing a search, we can't look at what is in the input -- we have to +# look at the contents of the ul that contains both the field and the added tags +Then /^"([^"]*)" should already be entered in the work search ([^"]*) autocomplete field$/ do |tag, field| + within(:xpath, "//input[@id=\"work_search_#{field.singularize}_names_autocomplete\"]/parent::li/parent::ul") do + page.should have_content(tag) + end +end + +Then /^the search summary should include the filter_id for "([^"]*)"$/ do |tag| + filter_id = Tag.find_by_name(tag).filter_taggings.first.filter_id + step %{I should see "filter_ids: #{filter_id}" within "#main h4.heading"} +end + +Then /^the results should contain only the restricted work$/ do + step %{I should see "Restricted Work"} + step %{I should not see "Posted Work"} + step %{I should not see "Work Hidden by Admin"} + step %{I should not see "Draft Work"} +end diff --git a/features/step_definitions/work_steps.rb b/features/step_definitions/work_steps.rb new file mode 100755 index 0000000..eafcc36 --- /dev/null +++ b/features/step_definitions/work_steps.rb @@ -0,0 +1,813 @@ +require "cgi" + +DEFAULT_TITLE = "My Work Title" +DEFAULT_FANDOM = "Stargate SG-1" +DEFAULT_RATING = "Not Rated" +DEFAULT_WARNING = "No Archive Warnings Apply" +DEFAULT_FREEFORM = "Scary tag" +DEFAULT_CONTENT = "That could be an amusing crossover." +DEFAULT_CATEGORY = "Other" + +### Setting up a work +# These steps get used a lot by many other steps and tests to create works in the archive to test with + +When /^I fill in the basic work information for "([^"]*)"$/ do |title| + step %{I fill in basic work tags} + check(DEFAULT_WARNING) + fill_in("Work Title", with: title) + select("English", from: "work_language_id") + fill_in("content", with: DEFAULT_CONTENT) +end +# Here we set up a draft and can then post it as a draft, preview and post, post, +# or fill in additional information on the work form. +# Example: I set up the draft "Foo" +# Example: I set up the draft "Foo" with fandom "Captain America" in the collection "MCU Stories" as a gift to "Bob" +# +# This is a complex regexp because it attempts to be flexible and match a lot of options (including using a/the, in/to etc) +# the (?: ) construct means: do not use the stuff in () as a capture/match +# the ()? construct means: the stuff in () is optional +# This can handle any number of the options being omitted, but you DO have to match in order +# if you are using more than one of the options. That is, if you are specifying fandom AND freeform AND collection, +# it has to be: +# with fandom "X" with freeform "Y" in collection "Z" +# and NOT: +# with freeform "Y" in collection "Z" with fandom "X" +# +# If you add to this regexp, you probably want to update all the +# similar regexps in the I post/Given the draft/the work steps below. +When /^I set up (?:a|the) draft "([^"]*)"(?: with fandom "([^"]*)")?(?: with character "([^"]*)")?(?: with second character "([^"]*)")?(?: with freeform "([^"]*)")?(?: with second freeform "([^"]*)")?(?: with category "([^"]*)")?(?: with rating "([^\"]*)")?(?: (?:in|to) (?:the )?collection "([^"]*)")?(?: as a gift (?:for|to) "([^"]*)")?(?: as part of a series "([^"]*)")?(?: with relationship "([^"]*)")?(?: using the pseud "([^"]*)")?$/ do |title, fandom, character, character2, freeform, freeform2, category, rating, collection, recipient, series, relationship, pseud| + step %{basic tags} + visit new_work_path + step %{I fill in the basic work information for "#{title}"} + select(rating.blank? ? DEFAULT_RATING : rating, from: "Rating") + check(category.blank? ? DEFAULT_CATEGORY : category) + fill_in("Fandoms", with: (fandom.blank? ? DEFAULT_FANDOM : fandom)) + fill_in("Additional Tags", with: (freeform.blank? ? DEFAULT_FREEFORM : freeform)+(freeform2.blank? ? '' : ','+freeform2)) + unless character.blank? + fill_in("work[character_string]", with: character + ( character2.blank? ? '' : ','+character2 ) ) + end + unless collection.blank? + c = Collection.find_by(title: collection) + fill_in("Collections", with: c.name) + end + unless series.blank? + if page.has_select?("work[series_attributes][id]", with_options: [series]) + select(series, from: "work[series_attributes][id]") + else + fill_in("work[series_attributes][title]", with: series) + end + end + unless relationship.blank? + fill_in("work[relationship_string]", with: relationship) + end + select(pseud, from: "work[author_attributes][ids][]") unless pseud.blank? + fill_in("work_recipients", with: "#{recipient}") unless recipient.blank? +end + +# This is the same regexp as above +When /^I post (?:a|the) (?:(\d+) chapter )?work "([^"]*)"(?: with fandom "([^"]*)")?(?: with character "([^"]*)")?(?: with second character "([^"]*)")?(?: with freeform "([^"]*)")?(?: with second freeform "([^"]*)")?(?: with category "([^"]*)")?(?: with rating "([^\"]*)")?(?: (?:in|to) (?:the )?collection "([^"]*)")?(?: as a gift (?:for|to) "([^"]*)")?(?: as part of a series "([^"]*)")?(?: with relationship "([^"]*)")?(?: using the pseud "([^"]*)")?$/ do |number_of_chapters, title, fandom, character, character2, freeform, freeform2, category, rating, collection, recipient, series, relationship, pseud| + # If the work is already a draft then visit the preview page and post it + work = Work.find_by(title: title) + if work + visit preview_work_path(work) + click_button("Post") + else + # Note: this will match the above regexp and work just fine even if all the options are blank! + step %{I set up the draft "#{title}" with fandom "#{fandom}" with character "#{character}" with second character "#{character2}" with freeform "#{freeform}" with second freeform "#{freeform2}" with category "#{category}" with rating "#{rating}" in collection "#{collection}" as a gift to "#{recipient}" as part of a series "#{series}" with relationship "#{relationship}" using the pseud "#{pseud}"} + click_button("Post") + end + # Now add the chapters + if number_of_chapters.present? && number_of_chapters.to_i > 1 + work = Work.find_by_title(title) + visit work_path(work) + (number_of_chapters.to_i - 1).times do + step %{I follow "Add Chapter"} + fill_in("content", with: "Yet another chapter.") + click_button("Post") + end + end + step %{all indexing jobs have been run} + step "the periodic tag count task is run" + step %(the periodic filter count task is run) +end + +# Again, same regexp, it just creates a draft and not a posted +# To test posting after preview, use: Given the draft "Foo" +# Then use: When I post the work "Foo" +# and the above step +Given /^the draft "([^"]*)"(?: with fandom "([^"]*)")?(?: with character "([^"]*)")?(?: with second character "([^"]*)")?(?: with freeform "([^"]*)")?(?: with second freeform "([^"]*)")?(?: with category "([^"]*)")?(?: (?:in|to) (?:the )?collection "([^"]*)")?(?: as a gift (?:for|to) "([^"]*)")?(?: as part of a series "([^"]*)")?(?: with relationship "([^"]*)")?(?: using the pseud "([^"]*)")?$/ do |title, fandom, character, character2, freeform, freeform2, category, collection, recipient, series, relationship, pseud| + step %{I set up the draft "#{title}" with fandom "#{fandom}" with character "#{character}" with second character "#{character2}" with freeform "#{freeform}" with second freeform "#{freeform2}" with category "#{category}" in collection "#{collection}" as a gift to "#{recipient}" as part of a series "#{series}" with relationship "#{relationship}" using the pseud "#{pseud}"} + click_button("Preview") +end + +When /^I post the works "([^"]*)"$/ do |worklist| + worklist.split(/, ?/).each do |work_title| + step %{I post the work "#{work_title}"} + # Ensure all works are created with different timestamps to avoid flakiness + step %{it is currently 1 second from now} + end +end + +### GIVEN + +Given /^I have no works or comments$/ do + Work.delete_all + Comment.delete_all +end + +Given /^the chaptered work(?: with ([\d]+) chapters)?(?: with ([\d]+) comments?)? "([^"]*)"$/ do |n_chapters, n_comments, title| + step %{basic tags} + + title ||= "Blabla" + n_chapters ||= 2 + + work = FactoryBot.create(:work, title: title, expected_number_of_chapters: n_chapters.to_i) + + # In order to make sure that the chapter positions are valid, we have to set + # them manually. So we can't use create_list, and have to loop instead: + (n_chapters.to_i - 1).times do |index| + FactoryBot.create(:chapter, work: work, position: index + 2) + end + + # Make sure that the word count is set properly: + work.save + + n_comments ||= 0 + FactoryBot.create_list(:comment, n_comments.to_i, :by_guest, + commentable: work.first_chapter, + comment_content: "Bla bla") +end + +Given /^I have a work "([^"]*)"$/ do |work| + step %{the work "#{work}"} +end + +Given /^I have a multi-chapter draft$/ do + step %{I am logged in as a random user} + step %{I post the chaptered draft "Multi-chapter Draft"} +end + +Given /^the work(?: "([^"]*)")? with(?: (\d+))? comments setup$/ do |title, n_comments| + step %{basic tags} + + title ||= "Blabla" + work = FactoryBot.create(:work, title: title) + + n_comments = 3 if n_comments.blank? || n_comments.zero? + FactoryBot.create_list(:comment, n_comments.to_i, :by_guest, + commentable: work.last_posted_chapter) +end + +Given /^the work(?: "([^"]*)")? with(?: (\d+))? bookmarks? setup$/ do |title, n_bookmarks| + step %{basic tags} + + title ||= "Blabla" + work = FactoryBot.create(:work, title: title) + + n_bookmarks = 3 if n_bookmarks.blank? || n_bookmarks.zero? + FactoryBot.create_list(:bookmark, n_bookmarks.to_i, bookmarkable: work) +end + +Given /^the chaptered work setup$/ do + step %{the chaptered work with 3 chapters "BigBang"} +end + +Given /^the chaptered work with comments setup$/ do + step %{the chaptered work with 3 chapters "BigBang"} + step "I am logged in as a random user" + step %{I view the work "BigBang"} + step %{I post a comment "Woohoo"} + (2..3).each do |i| + step %{I view the work "BigBang"} + step %{I view the #{i.to_s}th chapter} + step %{I post a comment "Woohoo"} + end + step "I log out" +end + +Given "the work {string}" do |title| + FactoryBot.create(:work, title: title) +end + +Given "the work {string} by {string}" do |title, login| + user = ensure_user(login) + FactoryBot.create(:work, title: title, authors: [user.default_pseud]) +end + +Given "the work {string} by {string} with fandom {string}" do |title, login, fandom| + user = ensure_user(login) + FactoryBot.create(:work, title: title, authors: [user.default_pseud], fandom_string: fandom) +end + +Given "the work {string} by {string} with guest comments enabled" do |title, login| + user = ensure_user(login) + FactoryBot.create(:work, :guest_comments_on, title: title, authors: [user.default_pseud]) +end + +Given "the work {string} by {string} and {string}" do |title, login1, login2| + user1 = ensure_user(login1) + user2 = ensure_user(login2) + FactoryBot.create(:work, title: title, authors: [user1.default_pseud, user2.default_pseud]) +end + +Given "the work {string} by {string}, {string} and {string}" do |title, login1, login2, login3| + user1 = ensure_user(login1) + user2 = ensure_user(login2) + user3 = ensure_user(login3) + FactoryBot.create(:work, title: title, authors: [user1.default_pseud, user2.default_pseud, user3.default_pseud]) +end + +Given "the work {string} by {string} and {string} with guest comments enabled" do |title, login1, login2| + user1 = ensure_user(login1) + user2 = ensure_user(login2) + FactoryBot.create(:work, :guest_comments_on, title: title, authors: [user1.default_pseud, user2.default_pseud]) +end + +Given /^the work "([^\"]*)" by "([^\"]*)" with chapter two co-authored with "([^\"]*)"$/ do |work, author, coauthor| + step %{I am logged in as "#{author}"} + step %{I post the work "#{work}"} + step %{a chapter with the co-author "#{coauthor}" is added to "#{work}"} +end + +Given /^there is a work "([^"]*)" in an unrevealed collection "([^"]*)"$/ do |work, collection| + step %{I have the hidden collection "#{collection}"} + step %{I am logged in as a random user} + step %{I post the work "#{work}" to the collection "#{collection}"} + step %{I log out} +end + +Given /^there is a work "([^"]*)" in an anonymous collection "([^"]*)"$/ do |work, collection| + step %{I have the anonymous collection "#{collection}"} + step %{I am logged in as a random user} + step %{I post the work "#{work}" to the collection "#{collection}"} + step %{I log out} +end + +Given /^I am logged in as the author of "([^"]*)"$/ do |work| + work = Work.find_by_title(work) + step %{I am logged in as "#{work.users.first.login}"} +end + +Given "the spam work {string}" do |work| + FactoryBot.create(:work, title: work).update_attribute(:spam, true) +end + +Given "the hidden work {string}" do |work| + FactoryBot.create(:work, title: work).update_attribute(:hidden_by_admin, true) +end + +Given "the work {string} is marked as spam" do |work| + w = Work.find_by(title: work) + w.update_attribute(:spam, true) +end + +Given "the user-defined tag limit is {int}" do |count| + allow(ArchiveConfig).to receive(:USER_DEFINED_TAGS_MAX).and_return(count) +end + +Given "the work {string} has {int} {word} tag(s)" do |title, count, type| + work = Work.find_by(title: title) + work.send("#{type.pluralize}=", FactoryBot.create_list(type.to_sym, count)) +end + +### WHEN + +When /^I view the ([\d]+)(?:st|nd|rd|th) chapter$/ do |chapter_no| + (chapter_no.to_i - 1).times do |i| + step %{I follow "Next Chapter"} + end +end + +When /^I view the work "([^"]*)"(?: in (full|chapter-by-chapter) mode)?$/ do |work, mode| + work = Work.find_by_title(work) + visit work_path(work) + step %{I follow "Entire Work"} if mode == "full" + step %{I follow "Chapter by Chapter"} if mode == "chapter-by-chapter" +end + +When /^I view a deleted work$/ do + visit "/works/12345/chapters/12345" +end + +When /^I view a deleted chapter$/ do + step "the draft \"DeletedChapterWork\"" + work = Work.find_by(title: "DeletedChapterWork") + visit "/works/#{work.id}/chapters/12345" +end + +When /^I edit the work "([^"]*)"$/ do |work| + work = Work.find_by(title: work) + visit edit_work_path(work) +end +When /^I edit the draft "([^"]*)"$/ do |draft| + step %{I edit the work "#{draft}"} +end + +When /^I post the chaptered work "([^"]*)"(?: in the collection "([^"]*)")?$/ do |title, collection| + step %{I post the work "#{title}" in the collection "#{collection}"} + step %{I follow "Add Chapter"} + fill_in("content", with: "Another Chapter.") + click_button("Preview") + step %{I press "Post"} + step %{all indexing jobs have been run} + step "the periodic tag count task is run" +end + +When /^I post the chaptered draft "([^"]*)"$/ do |title| + step %{the draft "#{title}"} + step %{a draft chapter is added to "#{title}"} +end + +When /^I post the work "([^"]*)" without preview$/ do |title| + # we now post as our default test case + step %{I post the work "#{title}"} +end + +When "I post the work {string} with guest comments enabled" do |title| + step %{I set up the draft "#{title}"} + choose("Registered users and guests can comment") + step "I post the work without preview" +end + +When /^a chapter is added to "([^"]*)"$/ do |work_title| + step %{a draft chapter is added to "#{work_title}"} + click_button("Post") + step %{all indexing jobs have been run} + step "the periodic tag count task is run" +end + +When /^a chapter with the co-author "([^\"]*)" is added to "([^\"]*)"$/ do |coauthor, work_title| + step %{a chapter is set up for "#{work_title}"} + step %{I invite the co-author "#{coauthor}"} + click_button("Post") + step %{the user "#{coauthor}" accepts all co-creator requests} + step %{all indexing jobs have been run} + step "the periodic tag count task is run" +end + +When /^a draft chapter is added to "([^"]*)"$/ do |work_title| + step %{a chapter is set up for "#{work_title}"} + step %{I press "Preview"} + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end + +When /^I delete chapter ([\d]+) of "([^"]*)"$/ do |chapter, title| + step %{I edit the work "#{title}"} + step %{I follow "#{chapter}"} + step %{I follow "Delete Chapter"} + step %{I press "Yes, Delete Chapter"} + step %{all indexing jobs have been run} +end + +# Posts a chapter for the current user +When /^I post a chapter for the work "([^"]*)"(?: as "(.*?)")?$/ do |work_title, pseud| + work = Work.find_by(title: work_title) + visit work_url(work) + step %{I follow "Add Chapter"} + step %{I fill in "content" with "la la la la la la la la la la la"} + select(pseud, from: "chapter_author_attributes_ids") if pseud.present? + step %{I post the chapter} +end + +When /^a chapter is set up for "([^"]*)"$/ do |work_title| + work = Work.find_by(title: work_title) + user = work.users.first + step %{I am logged in as "#{user.login}"} + visit work_url(work) + step %{I follow "Add Chapter"} + step %{I fill in "content" with "la la la la la la la la la la la"} +end + +# meant to be used in conjunction with above step +When /^I post the(?: draft)? chapter$/ do + click_button("Post") + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end + +Then /^I should see the default work content$/ do + page.should have_content(DEFAULT_CONTENT) +end + +Then /^I should not see the default work content$/ do + page.should_not have_content(DEFAULT_CONTENT) +end + +When /^I fill in basic work tags$/ do + select(DEFAULT_RATING, from: "Rating") + fill_in("Fandoms", with: DEFAULT_FANDOM) + fill_in("Additional Tags", with: DEFAULT_FREEFORM) +end + +When /^I fill in basic external work tags$/ do + select(DEFAULT_RATING, from: "Rating") + fill_in("Fandoms", with: DEFAULT_FANDOM) + fill_in("Your tags", with: DEFAULT_FREEFORM) +end + +When /^I set the fandom to "([^"]*)"$/ do |fandom| + fill_in("Fandoms", with: fandom) +end +# on the edit multiple works page +When /^I select "([^"]*)" for editing$/ do |title| + id = Work.find_by(title: title).id + check("work_ids_#{id}") +end + +When /^I edit the multiple works "([^"]*)" and "([^"]*)"/ do |title1, title2| + # check if the works have been posted yet + unless Work.where(title: title1).exists? + step %{I post the work "#{title1}"} + end + unless Work.where(title: title2).exists? + step %{I post the work "#{title2}"} + end + step %{I follow "My Dashboard"} + step %{I follow "Works ("} + step %{I follow "Edit Works"} + step %{I select "#{title1}" for editing} + step %{I select "#{title2}" for editing} + step %{I press "Edit"} +end + +When /^I edit multiple works with different comment moderation settings$/ do + step %{I set up the draft "Work with Comment Moderation Enabled"} + check("work_moderated_commenting_enabled") + choose("Registered users and guests can comment") + step %{I post the work without preview} + step %{I post the work "Work with Comment Moderation Disabled"} + step %{I follow "My Dashboard"} + step %{I follow "Works ("} + step %{I follow "Edit Works"} + step %{I select "Work with Comment Moderation Enabled" for editing} + step %{I select "Work with Comment Moderation Disabled" for editing} + step %{I press "Edit"} +end + +When /^I edit multiple works with different commenting settings$/ do + step %{I set up the draft "Work with All Commenting Enabled"} + choose("Registered users and guests can comment") + step %{I post the work without preview} + + step %{I set up the draft "Work with Anonymous Commenting Disabled"} + choose("Only registered users can comment") + step %{I post the work without preview} + + step %{I set up the draft "Work with All Commenting Disabled"} + choose("No one can comment") + step %{I post the work without preview} + + step %{I follow "My Dashboard"} + step %{I follow "Works ("} + step %{I follow "Edit Works"} + step %{I select "Work with All Commenting Enabled" for editing} + step %{I select "Work with Anonymous Commenting Disabled" for editing} + step %{I select "Work with All Commenting Disabled" for editing} + step %{I press "Edit"} +end + +When /^I edit multiple works coauthored as "(.*)" with "(.*)"$/ do |author, coauthor| + step %{I coauthored the work "Shared Work 1" as "#{author}" with "#{coauthor}"} + step %{I coauthored the work "Shared Work 2" as "#{author}" with "#{coauthor}"} + step %{I follow "My Dashboard"} + step %{I follow "Works ("} + step %{I follow "Edit Works"} + step %{I select "Shared Work 1" for editing} + step %{I select "Shared Work 2" for editing} + step %{I press "Edit"} +end + +When /^the purge_old_drafts rake task is run$/ do + step %{I run the rake task "work:purge_old_drafts"} +end + +When /^the work "([^"]*)" was created (\d+) days ago$/ do |title, number| + step "the draft \"#{title}\"" + work = Work.find_by(title: title) + work.update_attribute(:created_at, number.to_i.days.ago) + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end + +When /^I post the locked work "([^"]*)"$/ do |title| + work = Work.find_by(title: work) + if work.blank? + step "the locked draft \"#{title}\"" + work = Work.find_by(title: title) + end + visit preview_work_url(work) + click_button("Post") + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end + +When /^the locked draft "([^"]*)"$/ do |title| + step "basic tags" + visit new_work_url + step %{I fill in the basic work information for "#{title}"} + check("work_restricted") + click_button("Preview") +end + +When /^I lock the work$/ do + check("work_restricted") +end + +When /^I lock the work "([^"]*)"$/ do |work| + step %{I edit the work "#{work}"} + step %{I lock the work} + step %{I post the work} +end + +When /^I unlock the work$/ do + uncheck("work_restricted") +end + +When /^I unlock the work "([^"]*)"$/ do |work| + step %{I edit the work "#{work}"} + step %{I unlock the work} + step %{I post the work} +end + +When /^I list the work "([^"]*)" as inspiration$/ do |title| + work = Work.find_by(title: title) + check("parent-options-show") + url_of_work = work_url(work).sub("www.example.com", ArchiveConfig.APP_HOST) + with_scope("#parent-options") do + fill_in("URL", with: url_of_work) + end +end + +When /^I list an external work as inspiration$/ do + check("parent-options-show") + with_scope("#parent-options") do + fill_in("URL", with: "https://example.com") + fill_in("Title", with: "Example External") + fill_in("Author", with: "External Author") + select("English", from: "Language") + end +end + +When /^I set the publication date to (\d+) (.*) (\d+)$/ do |day, month, year| + if page.has_selector?("#backdate-options-show") + check("backdate-options-show") if page.find("#backdate-options-show") + select(day.to_s, from: "work[chapter_attributes][published_at(3i)]") + select(month, from: "work[chapter_attributes][published_at(2i)]") + select(year.to_s, from: "work[chapter_attributes][published_at(1i)]") + else + select(day.to_s, from: "chapter[published_at(3i)]") + select(month, from: "chapter[published_at(2i)]") + select(year.to_s, from: "chapter[published_at(1i)]") + end +end + +When /^I set the publication date to today$/ do + today = Date.current + month = today.strftime("%B") + step %{I set the publication date to #{today.day} #{month} #{today.year}} +end + +When /^I browse the "(.*?)" works$/ do |tagname| + tag = Tag.find_by_name(tagname) + visit tag_works_path(tag) + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end + +When /^I browse the "(.*?)" works with page parameter "(.*?)"$/ do |tagname, page| + tag = Tag.find_by_name(tagname) + visit tag_works_path(tag, page: page) + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end + +When "I browse works in language {string}" do |language_name| + step %{all indexing jobs have been run} + step "the periodic tag count task is run" + + language = Language.find_by(name: language_name) + visit language_works_path(language) +end + +When /^I delete the work "([^"]*)"$/ do |work| + work = Work.find_by(title: CGI.escapeHTML(work)) + visit edit_work_path(work) + step %{I follow "Delete Work"} + + # If JavaScript is enabled, window.confirm will be used and we'll have to accept + if @javascript + expect(page.accept_alert).to eq("Are you sure you want to delete this work? This will destroy all comments and kudos on this work as well and CANNOT BE UNDONE!") + else + click_button("Yes, Delete Work") + end + + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end + +When /^I preview the work$/ do + click_button("Preview") + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end +When /^I update the work$/ do + click_button("Update") + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end +When /^I post the work without preview$/ do + click_button "Post" + step %{all indexing jobs have been run} + + step "the periodic tag count task is run" +end +When /^I post the work$/ do + click_button "Post" + step %{all indexing jobs have been run} +end + +When /^the statistics for all works are updated$/ do + RedisJobSpawner.perform_now("StatCounterJob") + step %{the hit counts for all works are updated} +end + +When /^I add the co-author "([^"]*)" to the work "([^"]*)"$/ do |coauthor, work| + step %{I edit the work "#{work}"} + step %{I invite the co-author "#{coauthor}"} + step %{I post the work without preview} + step %{the user "#{coauthor}" accepts the creator invite for the work "#{work}"} +end + +When /^the user "([^"]*)" accepts the creator invite for the work "([^"]*)"/ do |user, work| + # Make sure that we don't have caching issues with the byline: + step %{I wait 1 second} + u = User.find_by(login: user) + w = Work.find_by(title: work) + w.creatorships.unapproved.for_user(u).each(&:accept!) +end + +When(/^I try to invite the co-authors? "([^"]*)"$/) do |coauthor| + check("co-authors-options-show") + fill_in("pseud_byline", with: "#{coauthor}") +end + +When /^I invite the co-authors? "([^"]*)"$/ do |coauthor| + coauthor.split(",").map(&:strip).reject(&:blank?).each do |user| + step %{the user "#{user}" allows co-creators} + end + step %{I try to invite the co-authors "#{coauthor}"} +end + +When "I give the work to {string}" do |recipient| + fill_in("Gift this work to", with: recipient) +end + +When /^I give the work "([^"]*)" to the user "([^"]*)"$/ do |work_title, recipient| + step %{the user "#{recipient}" exists and is activated} + visit edit_work_path(Work.find_by(title: work_title)) + fill_in("work_recipients", with: "#{recipient}") + click_button("Post") +end + +When /^I add the beginning notes "([^"]*)"$/ do |notes| + check("at the beginning") + fill_in("work_notes", with: "#{notes}") +end + +When /^I add the end notes "([^"]*)"$/ do |notes| + check("at the end") + fill_in("work_endnotes", with: "#{notes}") +end + +When "I add the beginning notes {string} to the work {string}" do |notes, work| + step %{I am logged in as the author of "#{work}"} + step %{I edit the work "#{work}"} + step %{I add the beginning notes "#{notes}"} + step %{I post the work} +end + +When "I add the end notes {string} to the work {string}" do |notes, work| + step %{I am logged in as the author of "#{work}"} + step %{I edit the work "#{work}"} + step %{I add the end notes "#{notes}"} + step %{I post the work} +end + +When /^I mark the work "([^"]*)" for later$/ do |work| + work = Work.find_by(title: work) + visit work_url(work) + step %{I press "Mark for Later"} + step "the readings are saved to the database" +end + +When /^I follow the recent chapter link for the work "([^\"]*)"$/ do |work| + work = Work.find_by_title(work) + work_id = work.id.to_s + find("#work_#{work_id} dd.chapters a").click +end + +When "I follow the kudos link for the work {string}" do |work| + work = Work.find_by(title: work) + find("#work_#{work.id} dd.kudos a").click +end + +When "I follow the comments link for the work {string}" do |work| + work = Work.find_by(title: work) + find("#work_#{work.id} dd.comments a").click +end + +When "the cache for the work {string} is cleared" do |title| + work = Work.find_by(title: title) + + # Delay to force the updated_at that gets set by .touch to be new + step "it is currently 1 second from now" + # Touch the work to actually expire the cache + work.touch +end + +When "the statistics for the work {string} are updated" do |title| + step %{the statistics for all works are updated} + step %{all indexing jobs have been run} + step %{the cache for the work "#{title}" is cleared} +end + +When /^the hit counts for all works are updated$/ do + step "all AJAX requests are complete" + RedisJobSpawner.perform_now("HitCountUpdateJob") +end + +When /^all hit count information is reset$/ do + redis = RedisHitCounter.redis + redis.keys.each do |key| + redis.del(key) + end +end + +### THEN +Then /^I should see Updated today$/ do + today = Date.current.to_s + step "I should see \"Updated:#{today}\"" +end + +Then /^I should not see Updated today$/ do + today = Date.current.to_s + step "I should not see \"Updated:#{today}\"" +end + +Then /^I should see Completed today$/ do + today = Date.current.to_s + step "I should see \"Completed:#{today}\"" +end + +Then /^I should not see Completed today$/ do + today = Date.current.to_s + step "I should not see \"Completed:#{today}\"" +end + +Then /^I should find a list for associations$/ do + page.should have_xpath("//ul[@class=\"associations\"]") +end + +Then /^I should not find a list for associations$/ do + page.should_not have_xpath("//ul[@class=\"associations\"]") +end + +Then /^the work "([^"]*)" should be deleted$/ do |work| + assert !Work.where(title: work).exists? +end + +Then /^the Remove Me As Chapter Co-Creator option should be on the ([\d]+)(?:st|nd|rd|th) chapter$/ do |chapter_number| + step %{I should see "Remove Me As Chapter Co-Creator" within "ul#sortable_chapter_list > li:nth-of-type(#{chapter_number})"} +end + +Then /^the Remove Me As Chapter Co-Creator option should not be on the ([\d]+)(?:st|nd|rd|th) chapter$/ do |chapter_number| + step %{I should not see "Remove Me As Chapter Co-Creator" within "ul#sortable_chapter_list > li:nth-of-type(#{chapter_number})"} +end + +Then "I should see {string} within the work blurb of {string}" do |content, work| + work = Work.find_by(title: work) + step %{I should see "#{content}" within "li#work_#{work.id}"} +end + +Then "I should not see {string} within the work blurb of {string}" do |content, work| + work = Work.find_by(title: work) + step %{I should not see "#{content}" within "li#work_#{work.id}"} +end + +Then "I should see an HTML comment containing the number {int} within {string}" do |expected_number, selector| + html = page.find(selector).native.inner_html + comment_match = html.match(/.*.*/) + expect(comment_match).not_to be_nil + number = comment_match[1].to_i + expect(number).to eq(expected_number) +end diff --git a/features/support/capybara.rb b/features/support/capybara.rb new file mode 100755 index 0000000..422b0c4 --- /dev/null +++ b/features/support/capybara.rb @@ -0,0 +1,78 @@ +# Produce a screenshot for each failure. +require 'capybara-screenshot/cucumber' + +# Use environment variables to set the host and the port used for tests: +CAPYBARA_HOST = ENV["DOCKER"] ? `hostname`.strip : "localhost" +CAPYBARA_PORT = ENV["CAPYBARA_PORT"] || 5100 +CAPYBARA_URL = "http://#{CAPYBARA_HOST}:#{CAPYBARA_PORT}".freeze + +Capybara.configure do |config| + # Capybara 1.x behavior. + config.match = :prefer_exact + + # Increased timeout to minimise failures on CI servers. + config.default_max_wait_time = 25 + + # Capybara 2.x behavior: match rendered text, squish whitespace by default. + config.default_normalize_ws = true + + # Capybara 3.x changes the default server to Puma; we have WEBRick + # (a dependency of Mechanize, used for importing; also used for the + # Rails development server), so we'll stick with that for now. + config.server = :webrick + + # Make server accessible from the outside world. Note that we don't use + # CAPYBARA_HOST here because this is the IP that the server binds to, not the + # host that we want to use for tests: + config.server_host = "0.0.0.0" if ENV["CHROME_URL"] + + # Specify the port used for tests: + config.server_port = CAPYBARA_PORT +end + +# Modified from https://github.com/teamcapybara/capybara/blob/49cf69c40f4b25931aecab162fb3285d8fe5bff7/lib/capybara/registrations/drivers.rb#L31-L42 +Capybara.register_driver :selenium_chrome_headless do |app| + browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts| + opts.add_argument("--headless") + + # Workaround from https://bugs.chromium.org/p/chromedriver/issues/detail?id=2660#c13 + opts.add_argument("--disable-site-isolation-trials") + end + + options = if ENV["CHROME_URL"] + # Special handling for Docker, modified from the instructions at + # https://evilmartians.com/chronicles/system-of-a-test-setting-up-end-to-end-rails-testing + { browser: :remote, options: browser_options, url: ENV["CHROME_URL"] } + else + { browser: :chrome, options: browser_options } + end + + Capybara::Selenium::Driver.new(app, **options) +end + +# Make sure we get full-page screenshots on failure: +Capybara::Screenshot.register_driver :selenium_chrome_headless do |driver, path| + # From https://github.com/madebylotus/capybara-full_screenshot/blob/bf1c3ede89e01b847f7b0dc7d71cd73b25175cd5/lib/capybara/full_screenshot/rspec_helpers.rb#L5-L8 + width = Capybara.page.execute_script(<<~WIDTH_SCRIPT.squish) + return Math.max(document.body.scrollWidth, + document.body.offsetWidth, + document.documentElement.clientWidth, + document.documentElement.scrollWidth, + document.documentElement.offsetWidth); + WIDTH_SCRIPT + + height = Capybara.page.execute_script(<<~HEIGHT_SCRIPT.squish) + return Math.max(document.body.scrollHeight, + document.body.offsetHeight, + document.documentElement.clientHeight, + document.documentElement.scrollHeight, + document.documentElement.offsetHeight); + HEIGHT_SCRIPT + + Capybara.current_session.current_window.resize_to(width + 100, height + 100) + + driver.browser.save_screenshot(path) +end + +Capybara.default_driver = :rack_test +Capybara.javascript_driver = :selenium_chrome_headless diff --git a/features/support/elapsed_time.rb b/features/support/elapsed_time.rb new file mode 100755 index 0000000..2040ce2 --- /dev/null +++ b/features/support/elapsed_time.rb @@ -0,0 +1,6 @@ +module ElapsedTime + def print_elapsed_time(io, start_time) + elapsed_time = (((Time.now - start_time) * 100).to_i / 100.0) + io.print " (#{elapsed_time}s)" + end +end diff --git a/features/support/email.rb b/features/support/email.rb new file mode 100755 index 0000000..f8e0b2f --- /dev/null +++ b/features/support/email.rb @@ -0,0 +1,25 @@ +module EmailHelpers + # Maps a name to an email address. Used by email_steps + + def email_for(to) + case to + + # add your own name => email address mappings here + + when /^#{capture_model}$/ + model($1).email + + when /^"([^@]*)"$/ + user = User.find_by(login: $1) + user.email + + when /^"(.*)"$/ + $1 + + else + to + end + end +end + +World(EmailHelpers) diff --git a/features/support/env.rb b/features/support/env.rb new file mode 100755 index 0000000..0208ec3 --- /dev/null +++ b/features/support/env.rb @@ -0,0 +1,76 @@ +# The only manually edited section of this file. +# SimpleCov must be required before any application code. + +require "simplecov" + +# Make sure that we define the hook for creating all ratings, warnings, and +# categories before we define the database cleaner hooks, so that we aren't +# constantly erasing and recreating all ratings/warnings/categories: +Before do + # TODO: Combine these three tag steps and remove them from all scenarios, + # since they're already run at the start of every scenario: + step %{the default ratings exist} + step %{the basic warnings exist} + step %{the basic categories exist} +end + +# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. +# It is recommended to regenerate this file in the future when you upgrade to a +# newer version of cucumber-rails. Consider adding your own code to a new file +# instead of editing this one. Cucumber will automatically load all features/**/*.rb +# files. + +require 'cucumber/rails' + +# frozen_string_literal: true + +# Capybara defaults to CSS3 selectors rather than XPath. +# If you'd prefer to use XPath, just uncomment this line and adjust any +# selectors in your step definitions to use the XPath syntax. +# Capybara.default_selector = :xpath + +# By default, any exception happening in your Rails application will bubble up +# to Cucumber so that your scenario will fail. This is a different from how +# your application behaves in the production environment, where an error page will +# be rendered instead. +# +# Sometimes we want to override this default behaviour and allow Rails to rescue +# exceptions and display an error page (just like when the app is running in production). +# Typical scenarios where you want to do this is when you test your error pages. +# There are two ways to allow Rails to rescue exceptions: +# +# 1) Tag your scenario (or feature) with @allow-rescue +# +# 2) Set the value below to true. Beware that doing this globally is not +# recommended as it will mask a lot of errors for you! +# +ActionController::Base.allow_rescue = false + +# Remove/comment out the lines below if your app doesn't have a database. +# For some databases (like MongoDB and CouchDB) you may need to use :truncation instead. +begin + DatabaseCleaner.strategy = :transaction +rescue NameError + raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it." +end + +# You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios. +# See the DatabaseCleaner documentation for details. Example: +# +# Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do +# # { except: [:widgets] } may not do what you expect here +# # as Cucumber::Rails::Database.javascript_strategy overrides +# # this setting. +# DatabaseCleaner.strategy = :truncation +# end +# +# Before('not @no-txn', 'not @selenium', 'not @culerity', 'not @celerity', 'not @javascript') do +# DatabaseCleaner.strategy = :transaction +# end +# + +# Possible values are :truncation and :transaction +# The :transaction strategy is faster, but might give you threading problems. +# See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature +Cucumber::Rails::Database.javascript_strategy = :truncation + diff --git a/features/support/formatter.rb b/features/support/formatter.rb new file mode 100755 index 0000000..5bcfa91 --- /dev/null +++ b/features/support/formatter.rb @@ -0,0 +1,51 @@ +# Adapted from https://github.com/tpope/fivemat +require "cucumber/formatter/progress" +require_relative "./elapsed_time" + +module Ao3Cucumber + class Formatter < ::Cucumber::Formatter::Progress + include ::ElapsedTime + + def on_test_case_started(event) + super + feature = gherkin_document.feature + + return if same_feature_as_previous_test_case?(feature) + + after_feature unless @current_feature.nil? + before_feature(feature) + end + + def on_test_run_finished(_event) + after_feature + super + end + + private + + def before_feature(feature) + # Print the feature's file name. + @io.puts current_feature_uri + @io.flush + @current_feature = feature + @start_time = Time.current + end + + def after_feature + print_elapsed_time @io, @start_time + @io.puts + @io.puts + @io.flush + + print_elements(@pending_step_matches, :pending, "steps") + print_elements(@failed_results, :failed, "steps") + + @pending_step_matches = [] + @failed_results = [] + end + + def same_feature_as_previous_test_case?(feature) + @current_feature && @current_feature.location == feature.location + end + end +end diff --git a/features/support/hooks.rb b/features/support/hooks.rb new file mode 100755 index 0000000..e6b830b --- /dev/null +++ b/features/support/hooks.rb @@ -0,0 +1,79 @@ +require "cucumber/rspec/doubles" +require "cucumber/timecop" +require "email_spec/cucumber" + +Before do + # Create default settings if necessary, since the database is truncated + # after every test. + # + # Enable our experimental caching, skipping validations which require + # setting an admin as the last updater. + AdminSetting.default.update_attribute(:enable_test_caching, true) + + # Create default language and locale. + Locale.default + + # Clears used values for all generators. + Faker::UniqueGenerator.clear + + # Reset global locale setting. + I18n.locale = I18n.default_locale + + # Assume all spam checks pass by default. + allow(Akismetor).to receive(:spam?).and_return(false) + + # Don't authenticate for Zoho. + allow_any_instance_of(ZohoAuthClient).to receive(:access_token) + + # Clear Memcached + Rails.cache.clear + + # Remove old tag feeds + page_cache_dir = Rails.root.join("public/test_cache") + FileUtils.remove_dir(page_cache_dir, true) if Dir.exist?(page_cache_dir) + + # Clear Redis + REDIS_AUTOCOMPLETE.flushall + REDIS_GENERAL.flushall + REDIS_HITS.flushall + REDIS_KUDOS.flushall + REDIS_RESQUE.flushall + REDIS_ROLLOUT.flushall + + Indexer.all.map(&:prepare_for_testing) +end + +After do + Indexer.all.map(&:delete_index) +end + +@javascript = false +Before "@javascript" do + @javascript = true + + Capybara.app_host = CAPYBARA_URL +end + +Before "not @javascript" do + Capybara.app_host = "http://www.example.com" +end + +Before "@disable_caching" do + ActionController::Base.perform_caching = false +end + +After "@disable_caching" do + ActionController::Base.perform_caching = true +end + +Before "@set-default-skin" do + # Create a default skin: + AdminSetting.current.update_attribute(:default_skin, Skin.default) +end + +Before "@load-default-skin" do + # Load the site skin and make it the default: + Skin.load_site_css + Skin.set_default_to_current_version + AdminSetting.current.update_attribute(:default_skin, Skin.default) +end diff --git a/features/support/minitest.rb b/features/support/minitest.rb new file mode 100755 index 0000000..fe896e7 --- /dev/null +++ b/features/support/minitest.rb @@ -0,0 +1,3 @@ +# https://github.com/cucumber/cucumber-ruby/issues/751 + +World(MultiTest::MinitestWorld) diff --git a/features/support/paths.rb b/features/support/paths.rb new file mode 100755 index 0000000..9f7751f --- /dev/null +++ b/features/support/paths.rb @@ -0,0 +1,311 @@ +module NavigationHelpers + # Maps a name to a path. Used by the + # + # When /^I go to (.+)$/ do |page_name| + # + # step definition in web_steps.rb + # + def path_to(page_name) + case page_name + + when /the home\s?page/ + '/' + when /the media page/ + media_index_path + when /^the search bookmarks page$/i + step %{all indexing jobs have been run} + search_bookmarks_path + when /^the search tags page$/i + step %{all indexing jobs have been run} + search_tags_path + when /^the search works page$/i + step %{all indexing jobs have been run} + search_works_path + when /^the search people page$/i + step %{all indexing jobs have been run} + search_people_path + when /^the bookmarks page$/i + # This cached page only expires by time, not by any user action; + # just clear it every time. + Rails.cache.delete "bookmarks/index/latest/v2_true" + bookmarks_path + when /^the works page$/i + # This cached page only expires by time, not by any user action; + # just clear it every time. + Rails.cache.delete "works/index/latest/v1" + works_path + when /^the admin login page$/i + new_admin_session_path + when /^the redirect page$/i + redirect_path + + # the following are examples using path_to_pickle + + when /^#{capture_model}(?:'s)? page$/ # eg. the forum's page + path_to_pickle $1 + + when /^#{capture_model}(?:'s)? #{capture_model}(?:'s)? page$/ # eg. the forum's post's page + path_to_pickle $1, $2 + + when /^#{capture_model}(?:'s)? #{capture_model}'s (.+?) page$/ # eg. the forum's post's comments page + path_to_pickle $1, $2, extra: $3 # or the forum's post's edit page + + when /^#{capture_model}(?:'s)? (.+?) page$/ # eg. the forum's posts page + path_to_pickle $1, extra: $2 # or the forum's edit page + + # Add more mappings here. + + when /^the tagsets page$/i + tag_sets_path + when /^the login page$/i + new_user_session_path + when /^account creation page$/i + signup_path + when /^invite requests page$/i + invite_requests_path + when /^the manage invite queue page$/i + manage_invite_requests_path + when /the blocked users page for "([^"]*)"/ + user_blocked_users_path(Regexp.last_match(1)) + when /the muted users page for "([^"]*)"/ + user_muted_users_path(Regexp.last_match(1)) + when /^(.*)'s claims page$/ + user_claims_path(Regexp.last_match(1)) + when /^(.*)'s signups page$/ + user_signups_path(Regexp.last_match(1)) + when /^(.*)'s inbox page$/ + user_inbox_path(Regexp.last_match(1)) + when /^(.*)'s co-creator requests page$/ + user_creatorships_path(Regexp.last_match(1)) + when /the gifts page$/ + gifts_path + when /the gifts page for the recipient (.*)$/ + gifts_path(recipient: $1) + when /^the assignments page for "(.*)"$/ + user_assignments_path(Regexp.last_match(1)) + when /^(.*)'s collection items page$/ + user_collection_items_path(Regexp.last_match(1)) + when /^(.*)'s gifts page/ + user_gifts_path(user_id: $1) + when /the import page/ + new_work_path(import: 'true') + when /the public skins page/ + skins_path + when /the work-skins page/ + skins_path(skin_type: "WorkSkin") + when /^(.*?)(?:'s)? user page$/i + user_path(id: $1) + when /^the (user|dashboard) page for user "(.*?)" with pseud "(.*?)"$/i + user_pseud_path(user_id: Regexp.last_match(2), id: Regexp.last_match(3)) + when /^(.*?)(?:'s)? user url$/i + user_url(id: $1) + when /^([^ ]*?)(?:'s)? works page$/i + step %{all indexing jobs have been run} + user_works_path(user_id: $1) + when /^the works page for user "(.*?)" with pseud "(.*?)"$/i + step %{all indexing jobs have been run} + user_pseud_works_path(user_id: Regexp.last_match(1), pseud_id: Regexp.last_match(2)) + when /^the "(.*)" work page/ + # TODO: Avoid this in favor of 'the work "title"', and eventually remove. + work_path(Work.find_by(title: $1)) + when /^the work page with title (.*)/ + # TODO: Avoid this in favor of 'the work "title"', and eventually remove. + work_path(Work.find_by(title: $1)) + when /^the work "(.*?)"$/ + work_path(Work.find_by(title: $1)) + when /^the work "(.*?)" in full mode$/ + work_path(Work.find_by(title: $1), view_full_work: true) + when /^the ([\d]+)(?:st|nd|rd|th) chapter of the work "(.*?)"$/ + work = Work.find_by(title: $2) + chapter = work.chapters_in_order(include_content: false)[$1.to_i - 1] + work_chapter_path(work, chapter) + when /^the bookmarks page for user "(.*)" with pseud "(.*)"$/i + step %{all indexing jobs have been run} + user_pseud_bookmarks_path(user_id: $1, pseud_id: $2) + when /^(.*?)(?:'s)? bookmarks page$/i + step %{all indexing jobs have been run} + user_bookmarks_path(user_id: $1) + when /^(.*?)(?:'s)? pseuds page$/i + user_pseuds_path(user_id: $1) + when /^(.*?)(?:'s)? manage invitations page$/i + manage_user_invitations_path(user_id: $1) + when /^(.*?)(?:'s)? invitations page$/i + user_invitations_path(user_id: $1) + when /^(.*?)(?:'s)? reading page$/i + user_readings_path(user_id: $1) + when /^(.*?)(?:'s)? series page$/i + user_series_index_path(user_id: $1) + when /^the series page for user "(.*?)" with pseud "(.*?)"$/i + step %{all indexing jobs have been run} + user_pseud_series_index_path(user_id: Regexp.last_match(1), pseud_id: Regexp.last_match(2)) + when /^(.*?)(?:'s)? stats page$/i + user_stats_path(user_id: $1) + when /^(.*?)(?:'s)? preferences page$/i + user_preferences_path(user_id: $1) + when /^(.*?)(?:'s)? related works page$/i + user_related_works_path(user_id: $1) + when /^the subscriptions page for "(.*)"$/i + user_subscriptions_path(user_id: $1) + when /^(.*?)(?:'s)? profile page$/i + user_profile_path(user_id: $1) + when /^(.*)'s skins page/ + user_skins_path(user_id: $1) + when /^"(.*)" skin page/ + skin_path(Skin.find_by(title: $1)) + when /^the new skin page/ + new_skin_path + when /^the new wizard skin page/ + new_skin_path(wizard: true) + when /^"(.*)" edit skin page/ + edit_skin_path(Skin.find_by(title: $1)) + when /^"(.*)" edit wizard skin page/ + edit_skin_path(Skin.find_by(title: $1), wizard: true) + when /^the new collection page/ + new_collection_path + when /^"(.*)" collection's page$/i # e.g. when I go to "Collection name" collection's page + step %{all indexing jobs have been run} # reindex to show recent works/bookmarks + collection_path(Collection.find_by(title: $1)) + when /^"(.*)" collection edit page$/i + edit_collection_path(Collection.find_by(title: $1)) + when /^the "(.*)" signups page$/i # e.g. when I go to the "Collection name" signup page + collection_signups_path(Collection.find_by(title: $1)) + when /^the "(.*)" requests page$/i # e.g. when I go to the "Collection name" signup page + collection_requests_path(Collection.find_by(title: $1)) + when /^the "(.*)" assignments page$/i # e.g. when I go to the "Collection name" assignments page + collection_assignments_path(Collection.find_by(title: $1)) + when /^the "(.*)" participants page$/i # e.g. when I go to the "Collection name" participants page + collection_participants_path(Collection.find_by(title: $1)) + when /^"(.*)" collection's url$/i # e.g. when I go to "Collection name" collection's url + collection_url(Collection.find_by(title: $1)) + when /^"(.*)" gift exchange edit page$/i + edit_collection_gift_exchange_path(Collection.find_by(title: $1)) + when /^"(.*)" gift exchange matching page$/i + collection_potential_matches_path(Collection.find_by(title: $1)) + when /^the works tagged "(.*?)" in collection "(.*?)"$/i + step %{all indexing jobs have been run} + collection_tag_works_path(Collection.find_by(title: $2), Tag.find_by_name($1)) + when /^the works tagged "(.*)"$/i + step %{all indexing jobs have been run} + tag_works_path(Tag.find_by_name($1)) + when /^the bookmarks tagged "(.*)"$/i + step %{all indexing jobs have been run} + tag_bookmarks_path(Tag.find_by_name($1)) + when /^the bookmarks in collection "(.*)"$/i + step %{all indexing jobs have been run} + collection_bookmarks_path(Collection.find_by(title: $1)) + when /^the first bookmark for the work "(.*?)"$/i + work = Work.find_by(title: Regexp.last_match(1)) + bookmark_path(work.bookmarks.first) + when /^the new bookmark page for work "(.*?)"$/i + new_work_bookmark_path(Work.find_by(title: Regexp.last_match(1))) + when /^the tag comments? page for "(.*)"$/i + tag_comments_path(Tag.find_by_name($1)) + when /^the work comments? page for "(.*?)"$/i + work_comments_path(Work.find_by(title: $1), show_comments: true) + when /^the work kudos page for "(.*?)"$/i + work_kudos_path(Work.find_by(title: $1)) + when /^the FAQ reorder page$/i + manage_archive_faqs_path + when /^the Wrangling Guidelines reorder page$/i + manage_wrangling_guidelines_path + when /^the tos page$/i + tos_path + when /^the faq page$/i + archive_faqs_path + when /^the wrangling guidelines page$/i + wrangling_guidelines_path + when /^the support page$/i + new_feedback_report_path + when /^the new tag ?set page$/i + new_tag_set_path + when /^the "(.*)" tag ?set edit page$/i + edit_tag_set_path(OwnedTagSet.find_by(title: $1)) + when /^the "(.*)" tag ?set page$/i + tag_set_path(OwnedTagSet.find_by(title: $1)) + when /^the Open Doors tools page$/i + opendoors_tools_path + when /^the Open Doors external authors page$/i + opendoors_external_authors_path + when /^the claim page for "(.*)"$/i + claim_path(invitation_token: Invitation.find_by(invitee_email: $1).token) + when /^the languages page$/i + languages_path + when /^the wranglers page$/i + tag_wranglers_path + when /^the wrangling page for "(.*)"$/i + tag_wrangler_path(User.find_by(login: Regexp.last_match(1))) + when /^the unassigned fandoms page $/i + unassigned_fandoms_path + when /^the "(.*)" fandoms page$/i + media_fandoms_path(Media.find_by(name: Regexp.last_match(1))) + when /^the "(.*)" tag page$/i + tag_path(Tag.find_by_name($1)) + when /^the '(.*)' tag edit page$/i + edit_tag_path(Tag.find_by(name: Regexp.last_match(1))) + when /^the "(.*)" tag edit page$/i + edit_tag_path(Tag.find_by(name: Regexp.last_match(1))) + when /^the new tag page$/i + new_tag_path + when /^the wrangling tools page$/ + tag_wranglings_path + when /^the new external work page$/i + new_external_work_path + when /^the external works page$/i + external_works_path + when /^the external works page with only duplicates$/i + external_works_path(show: :duplicates) + when /^the new user password page$/i + new_user_password_path + when /^the edit user password page$/i + edit_user_password_path + when /^the (.*) mass bin$/i + tag_wranglings_path(show: Regexp.last_match(1).pluralize) + when /^the tags page$/i + tags_path + when /^the orphan all works page$/i + new_orphan_path + + # Admin Pages + when /^the admin-posts page$/i + admin_posts_path + when /^the "(.*)" admin post page$/i + admin_post_path(AdminPost.find_by(title: Regexp.last_match(1))) + when /^the unreviewed comments page for the admin post "(.*)"$/i + unreviewed_admin_post_comments_path(AdminPost.find_by(title: Regexp.last_match(1))) + when /^the admin-settings page$/i + admin_settings_path + when /^the admin-activities page$/i + admin_activities_path + when /^the admin-blacklist page$/i + admin_blacklisted_emails_path + when /^the manage users page$/ + step "all indexing jobs have been run" + admin_users_path + when /^the bulk email search page$/i + bulk_search_admin_users_path + when /^the user administration page for "(.*)"$/i + admin_user_path(User.find_by(login: $1)) + when /^the new admin password page$/i + new_admin_password_path + when /^the edit admin password page$/i + edit_admin_password_path + + # Here is an example that pulls values out of the Regexp: + # + # when /^(.*)'s profile page$/i + # user_profile_path(User.find_by(login: $1)) + + else + begin + page_name =~ /the (.*) page/ + path_components = $1.split(/\s+/) + self.send(path_components.push('path').join('_').to_sym) + rescue Object => e + raise "Can't find mapping from \"#{page_name}\" to a path.\n" + + "Now, go and add a mapping in #{__FILE__}" + end + end + end +end + +World(NavigationHelpers) diff --git a/features/support/pickle.rb b/features/support/pickle.rb new file mode 100755 index 0000000..3ec15d1 --- /dev/null +++ b/features/support/pickle.rb @@ -0,0 +1,26 @@ +# this file generated by script/generate pickle [paths] [email] +# +# Make sure that you are loading your factory of choice in your cucumber environment +# +# For machinist add: features/support/machinist.rb +# +# require 'machinist/active_record' # or your chosen adaptor +# require File.dirname(__FILE__) + '/../../spec/blueprints' # or wherever your blueprints are +# Before { Sham.reset } # to reset Sham's seed between scenarios so each run has same random sequences +# +# For FactoryBot add: features/support/factory_bot.rb +# +# require 'factory_bot' +# require File.dirname(__FILE__) + '/../../spec/factories' # or wherever your factories are +# +# You may also need to add gem dependencies on your factory of choice in config/environments/cucumber.rb + +require 'pickle/world' +# Example of configuring pickle: +# +# Pickle.configure do |config| +# config.adapters = [:machinist] +# config.map 'I', 'myself', 'me', 'my', to: 'user: "me"' +# end +require 'pickle/path/world' +require 'pickle/email/world' diff --git a/features/support/user.rb b/features/support/user.rb new file mode 100755 index 0000000..36dd65d --- /dev/null +++ b/features/support/user.rb @@ -0,0 +1,33 @@ +module UserHelpers + def find_or_create_new_user(login, password, activate: true) + user = User.find_by(login: login) + if user.blank? + params = { login: login, password: password } + params[:confirmed_at] = nil unless activate + user = FactoryBot.create(:user, params) + # Explicitly add pseud to autocomplete in test env as FactoryBot is not + # triggering Sweeper hooks + user.pseuds.first.add_to_autocomplete + else + user.skip_password_change_notification! + user.password = password + user.password_confirmation = password + user.save + end + user + end + + # Like find_or_create_new_user above, but with fewer options, and it doesn't + # invalidate the session for any pre-existing users (because it's not setting + # the password). + def ensure_user(login) + user = User.find_by(login: login) + return user unless user.nil? + + FactoryBot.create(:user, login: login).tap do |u| + u.default_pseud.add_to_autocomplete + end + end +end + +World(UserHelpers) diff --git a/features/support/vcr.rb b/features/support/vcr.rb new file mode 100755 index 0000000..bad5b54 --- /dev/null +++ b/features/support/vcr.rb @@ -0,0 +1,46 @@ +require 'vcr' + +VCR.configure do |c| + c.ignore_localhost = true + c.cassette_library_dir = 'features/cassette_library' + c.hook_into :webmock + c.allow_http_connections_when_no_cassette = true + + # Cassettes are now deleted and re-recorded after 30 days. This will ensure + # that LJ/DW/DA don't update their HTML and break our story parser without us + # knowing about it. + c.default_cassette_options = { + record: :once, + re_record_interval: 30.days + } +end + +VCR.cucumber_tags do |t| + t.tags "@archivist_import", use_scenario_name: true + + t.tags "@work_import_special_characters_auto_utf" + t.tags "@work_import_special_characters_auto_latin" + t.tags "@work_import_special_characters_man_latin" + t.tags "@work_import_special_characters_man_cp" + t.tags "@work_import_special_characters_man_utf" + + t.tags "@import_da_title_link" + t.tags "@import_da_gallery_link" + t.tags "@import_da_fic" + + t.tags "@import_dw" + t.tags "@import_dw_tables" + t.tags "@import_dw_tables_no_backdate" + t.tags "@import_dw_comm" + t.tags "@import_dw_multi_chapter" + + t.tags "@import_ffn" + t.tags "@import_ffn_multi_chapter" + + t.tags "@import_lj" + t.tags "@import_lj_tables" + t.tags "@import_lj_no_backdate" + t.tags "@import_lj_comm" + t.tags "@import_lj_multi_chapter" + t.tags "@import_lj_underscores" +end diff --git a/features/support/wait_for_ajax.rb b/features/support/wait_for_ajax.rb new file mode 100755 index 0000000..1679ef1 --- /dev/null +++ b/features/support/wait_for_ajax.rb @@ -0,0 +1,11 @@ +# from https://thoughtbot.com/blog/automatically-wait-for-ajax-with-capybara + +def wait_for_ajax + Timeout.timeout(Capybara.default_max_wait_time) do + loop until finished_all_ajax_requests? + end +end + +def finished_all_ajax_requests? + page.evaluate_script('jQuery.active').zero? +end diff --git a/features/support/webmock.rb b/features/support/webmock.rb new file mode 100755 index 0000000..93de180 --- /dev/null +++ b/features/support/webmock.rb @@ -0,0 +1 @@ +require "webmock/cucumber" diff --git a/features/tag_sets/tag_set.feature b/features/tag_sets/tag_set.feature new file mode 100755 index 0000000..d3fbeb6 --- /dev/null +++ b/features/tag_sets/tag_set.feature @@ -0,0 +1,175 @@ +# encoding: utf-8 +@tag_sets +Feature: Creating and editing tag sets + + Scenario: A user should be able to create a tag set with a title + Given I am logged in as "tagsetter" + And I go to the tagsets page + And I follow the add new tagset link + And I fill in "Title" with "Empty Tag Set" + And I submit + Then I should see a create confirmation message + And I should see "About Empty Tag Set" + And I should see "tagsetter" within ".meta" + + Scenario: A user should be able to create a tag set with noncanonical tags + Given I am logged in as "tagsetter" + And I set up the tag set "Noncanonical Tags" with the fandom tags "Ywerwe, Blah di blah, Foooo" + Then I should see a create confirmation message + And I should see "Ywerwe" + + Scenario: A user should be able to add additional tags to an existing set + Given I am logged in as "tagsetter" + And I set up the tag set "Noncanonical Tags" with the fandom tags "Ywerwe, Blah di blah, Foooo" + When I add the character tags "Bababa, Lalala" and the freeform tags "wheee, gloopy" to the tag set "Noncanonical Tags" + Then I should see an update confirmation message + And I should see "wheee" + + Scenario: A user should be able to add and remove fandom tags for a tag set they own + Given I am logged in + And I set up the tag set "Fandoms" with the fandom tags "One, Two" + When I add the fandom tags "Three, Four" to the tag set "Fandoms" + Then I should see "One" + And I should see "Two" + And I should see "Three" + And I should see "Four" + When I remove the fandom tags "One, Three" from the tag set "Fandoms" + Then I should see "Two" + And I should see "Four" + And I should not see "One" + And I should not see "Three" + + Scenario: A user should be able to add and remove character tags for a tag set they own + Given I am logged in + And I set up the tag set "Characters" with the character tags "Character 1, Character 2" + When I add the character tags "Character 3, Character 4" to the tag set "Characters" + Then I should see "Character 1" + And I should see "Character 2" + And I should see "Character 3" + And I should see "Character 4" + When I remove the character tags "Character 2, Character 4" from the tag set "Characters" + Then I should see "Character 1" + And I should see "Character 3" + And I should not see "Character 2" + And I should not see "Character 4" + + Scenario: A user should be able to add and remove relationship tags for a tag set they own + Given I am logged in + And I set up the tag set "Relationships" with the relationship tags "One/Two, 1 & 2" + When I add the relationship tags "3/4, Three & Four" to the tag set "Relationships" + Then I should see "One/Two" + And I should see "1 & 2" + And I should see "3/4" + And I should see "Three & Four" + When I remove the relationship tags "One/Two, Three & Four" from the tag set "Relationships" + Then I should see "1 & 2" + And I should see "3/4" + And I should not see "One/Two" + And I should not see "Three & Four" + + Scenario: A user should be able to add and remove rating tags for a tag set they own + Given the default ratings exist + And I am logged in + And I set up the tag set "Ratings" with the rating tags "Explicit, Mature" + When I add the rating tags "Teen And Up Audiences, General Audiences" to the tag set "Ratings" + Then I should see "Explicit" + And I should see "Mature" + And I should see "Teen And Up Audiences" + And I should see "General Audiences" + When I remove the rating tags "Explicit, Teen And Up Audiences" from the tag set "Ratings" + Then I should see "Mature" + And I should see "General Audiences" + And I should not see "Explicit" + And I should not see "Teen And Up Audiences" + + Scenario: A user should be able to add and remove category tags for a tag set they own + Given the basic categories exist + And I am logged in + And I set up the tag set "Categories" with the category tags "Other, F/M" + When I add the category tags "F/F, M/M" to the tag set "Categories" + Then I should see "Other" + And I should see "F/M" + And I should see "M/M" + And I should see "F/F" + When I remove the category tags "F/F, Other" from the tag set "Categories" + Then I should see "M/M" + And I should see "F/M" + And I should not see "F/F" + And I should not see "Other" + + Scenario: A user should be able to add and remove warning tags for a tag set they own + Given the basic warnings exist + And I am logged in + And I set up the tag set "Archive Warnings" with the warning tags "Choose Not To Use Archive Warnings" + When I add the warning tags "No Archive Warnings Apply" to the tag set "Archive Warnings" + Then I should see "Choose Not To Use Archive Warnings" + And I should see "No Archive Warnings Apply" + When I remove the warning tags "Choose Not To Use Archive Warnings" from the tag set "Archive Warnings" + Then I should see "No Archive Warnings Apply" + And I should not see "Choose Not To Use Archive Warnings" + + Scenario: If a tag set does not have a visible tag list, only a moderator should be able to see the tags in the set, but everyone should be able to see the tag set + Given I am logged in as "tagsetter" + And I set up the tag set "Tag Set with Non-visible Tag List" with an invisible tag list and the fandom tags "Dallas, Knots Landing, Models Inc" + Then I should see "Dallas" + And I should see "Knots Landing" + And I should see "Models Inc" + When I go to the tagsets page + Then I should see "Tag Set with Non-visible Tag List" + When I log out + And I go to the tagsets page + Then I should see "Tag Set with Non-visible Tag List" + When I follow "Tag Set with Non-visible Tag List" + Then I should not see "Dallas" + And I should not see "Knots Landing" + And I should not see "Models Inc" + And I should see "The moderators have chosen not to make the tags in this set visible to the public (possibly while nominations are underway)." + + Scenario: If a tag set has a visible tag list, everyone should be able to see the tags in the set + Given I am logged in as "tagsetter" + And I set up the tag set "Tag Set with Visible Tag List" with a visible tag list and the fandom tags "Dallas, Knots Landing, Models Inc" + Then I should see "Dallas" + And I should see "Knots Landing" + And I should see "Models Inc" + When I log out + And I view the tag set "Tag Set with Visible Tag List" + Then I should see "Dallas" + And I should see "Knots Landing" + And I should see "Models Inc" + + @javascript + Scenario: A moderator should be able to manually set up and remove associations between tags in their set on the main tag set edit page + Given I am logged in + And I set up the tag set "Associations" with the fandom tags "Major Crimes, The Closer" and the character tags "Brenda Leigh Johnson, Sharon Raydor" + When I go to the "Associations" tag set edit page + And I follow "Add Association" + And I select "Sharon Raydor" from "Tag" + And I select "The Closer" from "Parent tag" + And I press "Update" + Then I should see an update confirmation message + And I should see "Uncategorized Fandoms (2)" + And I should see "Unassociated Characters & Relationships (1)" + When I press "Expand All" + Then I should see "The Closer (1)" + And I should see "Major Crimes (0)" + And "Sharon Raydor" should be associated with the "Uncategorized" fandom "The Closer" + When I go to the "Associations" tag set edit page + And I check "Sharon Raydor (The Closer)" + And I press "Update" + Then I should see an update confirmation message + And I should see "Unassociated Characters & Relationships (2)" + When I press "Expand All" + Then I should see "The Closer (0)" + And I should see "Major Crimes (0)" + When I expand the unassociated characters and relationships + Then "Sharon Raydor" should be an unassociated tag + + Scenario: A moderator can't change the tag set's nomination settings if there + are already nominations + Given I have the nominated tag set "Nominated Tags" + And I am logged in as "tagsetter" + When I go to the "Nominated Tags" tag set edit page + And I fill in "Fandom nomination limit" with "1" + And I fill in "Character nomination limit" with "1" + And I submit + Then I should see "You cannot make changes to nomination settings when nominations already exist. Please review and delete existing nominations first." diff --git a/features/tag_sets/tag_set_associations.feature b/features/tag_sets/tag_set_associations.feature new file mode 100755 index 0000000..bcb3e90 --- /dev/null +++ b/features/tag_sets/tag_set_associations.feature @@ -0,0 +1,123 @@ +# encoding: utf-8 +@tag_sets +Feature: Reviewing tag set associations + + Scenario: If a nominated tag and its parent are approved they should appear on the associations page + Given I nominate and approve fandom "Floobry" and character "Zarrr" in "Nominated Tags" + And I am logged in as "tagsetter" + And I go to the "Nominated Tags" tag set page + Then I should see "don't seem to be associated" + When I follow "Review Associations" + Then I should see "Zarrr → Floobry" + When I check "Zarrr → Floobry" + And I submit + Then I should see "Nominated associations were added" + And I should not see "don't seem to be associated" + + Scenario: If a nominated tag is wrangled into its nominated parent after approval, it should be automatically associated with the parent + Given I nominate and approve fandom "Floobry" and character "Zarrr" in "Nominated Tags" + And the tag "Floobry" is canonized + And I add the fandom "Floobry" to the character "Zarrr" + And the tag "Zarrr" is canonized + When I review associations for "Nominated Tags" + Then I should not see "Zarrr → Floobry" + # TODO: Remove this step when AO3-3757 is fixed: + When the cache for the tag set "Nominated Tags" is expired + And I view the tag set "Nominated Tags" + Then I should not see "Unassociated Characters & Relationships" + And I should not see "don't seem to be associated" + And "Zarrr" should be associated with the "Uncategorized" fandom "Floobry" + + Scenario: If a nominated tag is wrangled to a different fandom after approval, it should still be possible to associate them + Given I nominate and approve fandom "Floobry" and character "Zarrr" in "Nominated Tags" + And a canonical fandom "Barbar" + And I add the fandom "Barbar" to the character "Zarrr" + And the tag "Zarrr" is canonized + When I review associations for "Nominated Tags" + Then I should see "Zarrr → Floobry" + When I check "Zarrr → Floobry" + And I submit + Then I should see "Nominated associations were added" + And I should not see "Unassociated Characters & Relationships" + And I should not see "don't seem to be associated" + And "Zarrr" should be associated with the "Uncategorized" fandom "Floobry" + + Scenario: If a tag set does not exist, no one should be able to see its associations + Given I am logged in as "tagsetter" + When I view associations for a tag set that does not exist + Then I should see "What tag set did you want to look at?" + And I should be on the tagsets page + When I log out + And I view associations for a tag set that does not exist + Then I should see "What tag set did you want to look at?" + And I should be on the tagsets page + + Scenario: Nominating a canonical tag in its fandom does not generate associations for review + Given a canonical character "Jack Carter" in fandom "Eureka" + And I nominate and approve fandom "Eureka" and character "Jack Carter" in "Canonical Associations" + When I review associations for "Canonical Associations" + Then I should not see "Jack Carter" + And I should not see "Eureka" + + Scenario: Nominating a canonical tag in another fandom generates associations for review + Given a canonical character "Nathan Stark" in fandom "Eureka" + And I nominate and approve fandom "Iron Man" and character "Nathan Stark" in "Canonical Associations" + When I review associations for "Canonical Associations" + Then I should see "Nathan Stark → Iron Man" + But I should not see "Eureka" + + Scenario: Nominating a non-canonical tag in its own fandom generates associations for review + Given a canonical character "Jack Carter" in fandom "Eureka" + And a non-canonical character "Nathan Carter" in fandom "Eureka" + And I am logged in as "tagsetter" + And I set up the nominated tag set "Non-canonical Associations" with 1 fandom nom and 2 character noms + And I nominate fandom "Eureka" and characters "Jack Carter,Nathan Carter" in "Non-canonical Associations" as "tagsetter" + When I review nominations for "Non-canonical Associations" + And I approve the nominated fandom tag "Eureka" + And I approve the nominated character tag "Jack Carter" + And I approve the nominated character tag "Nathan Carter" + And I press "Submit" + And I review associations for "Non-canonical Associations" + Then I should see "Nathan Carter → Eureka" + + Scenario: When a nominated non-canonical is renamed, its associations remain for review + Given a canonical character "Jack Carter" in fandom "Eureka" + And a non-canonical character "nathan carter" in fandom "Nathan Stark" + And I am logged in as "tagsetter" + And I set up the nominated tag set "Non-canonical Associations" with 1 fandom nom and 2 character noms + And I nominate fandom "Eureka" and characters "Jack Carter,nathan carter" in "Non-canonical Associations" as "tagsetter" + When I am logged in as a tag wrangler + And I edit the tag "nathan carter" + And I fill in "Name" with "Nathan Carter" + And I press "Save changes" + Then I should see "Tag was updated" + When I am logged in as "tagsetter" + And I review nominations for "Non-canonical Associations" + And I approve the nominated fandom tag "Eureka" + And I approve the nominated character tag "Jack Carter" + And I approve the nominated character tag "nathan carter" + And I press "Submit" + And I review associations for "Non-canonical Associations" + Then I should see "Nathan Carter → Eureka" + + Scenario: Nominating a new tag in an approved fandom generates associations for review + Given a canonical fandom "Eureka" + And I am logged in as "tagsetter" + And I set up the nominated tag set "New Associations" with 1 fandom nom and 2 character noms + And I nominate fandom "Eureka" and character "Jack Stark" in "New Associations" as "tagsetter" + When I review nominations for "New Associations" + And I approve the nominated fandom tag "Eureka" + And I press "Submit" + And I edit nominations for "tagsetter" in "New Associations" to include characters "Jack Stark,Nathan Stark" under fandom "Eureka" + And I review nominations for "New Associations" + Then I should see "Jack Stark" + And I should see "Nathan Stark" + When I approve the nominated character tag "Jack Stark" + And I approve the nominated character tag "Nathan Stark" + And I press "Submit" + And I review associations for "New Associations" + Then I should see "Jack Stark → Eureka" + And I should see "Nathan Stark → Eureka" + + # TODO + # Scenario: Tags with brackets should work in associations diff --git a/features/tag_sets/tag_set_batch_load.feature b/features/tag_sets/tag_set_batch_load.feature new file mode 100755 index 0000000..d425457 --- /dev/null +++ b/features/tag_sets/tag_set_batch_load.feature @@ -0,0 +1,67 @@ +# encoding: utf-8 +@tag_sets +Feature: Batch loading tags and associations for a tag set + + Scenario: Batch load character tags should successfully load characters that are canonical and return characters that are not + Given a fandom exists with name: "MASH (TV)", canonical: true + And a fandom exists with name: "Dallas (TV)", canonical: true + And a character exists with name: "Hawkeye Pierce", canonical: true + And a character exists with name: "Maxwell Klinger", canonical: true + And a character exists with name: "Henry Blake", canonical: true + And a character exists with name: "J. R. Ewing", canonical: true + And a character exists with name: "Sue Ellen Ewing", canonical: true + When I am logged in as "tagsetter" + And I set up the tag set "Batch Loading Characters" with a visible tag list + And I follow "Batch Load" + When I fill in "Batch Load Tag Associations" with + """ + MASH (TV),Hawkeye Pierce,Maxwell Klinger,Henry Blake + Dallas (TV), J. R. Ewing, Sue Ellen Ewing, Pam Ewing + """ + And I press "Submit" + Then I should see "We couldn't add all the tags and associations you wanted -- the ones left below didn't work. See the help for suggestions!" + And I should see "Dallas (TV),Pam Ewing" + And I should not see "MASH (TV),Hawkeye Pierce,Maxwell Klinger,Henry Blake" + And I should not see "Dallas (TV), J. R. Ewing, Sue Ellen Ewing, Pam Ewing" + When I go to the "Batch Loading Characters" tag set page + Then I should see "MASH (TV)" + And I should see "Hawkeye Pierce" + And I should see "Maxwell Klinger" + And I should see "Henry Blake" + And I should see "Dallas (TV)" + And I should see "J. R. Ewing" + And I should see "Sue Ellen Ewing" + And I should not see "Pam Ewing" + + Scenario: Batch load relationship tags should successfully load relationships that are canonical and return characters that are not + Given a fandom exists with name: "MASH (TV)", canonical: true + And a fandom exists with name: "Dallas (TV)", canonical: true + And a relationship exists with name: "BJ/Hawkeye", canonical: true + And a relationship exists with name: "Hawkeye/Margaret Houlihan", canonical: true + And a relationship exists with name: "Hawkeye & Radar", canonical: true + And a relationship exists with name: "J. R. Ewing/Sue Ellen Ewing", canonical: true + And a relationship exists with name: "Ann Ewing/Bobby Ewing", canonical: true + When I am logged in as "tagsetter" + And I set up the tag set "Batch Loading Relationships" with a visible tag list + And I follow "Batch Load" + When I fill in "Batch Load Tag Associations" with + """ + MASH (TV), BJ/Hawkeye, Hawkeye/Margaret Houlihan, Hawkeye & Radar + Dallas (TV),J. R. Ewing/Sue Ellen Ewing,Ann Ewing/Sue Ellen Ewing,Ann Ewing/Bobby Ewing + """ + And I check "Relationships instead?" + And I press "Submit" + Then I should see "We couldn't add all the tags and associations you wanted -- the ones left below didn't work. See the help for suggestions!" + And I should see "Dallas (TV),Ann Ewing/Sue Ellen Ewing" + And I should not see "MASH (TV), BJ/Hawkeye, Hawkeye/Margaret Houlihan, Hawkeye & Radar" + And I should not see "Dallas (TV),J. R. Ewing/Sue Ellen Ewing,Ann Ewing/Sue Ellen Ewing,Ann Ewing/Bobby Ewing" + When I go to the "Batch Loading Relationships" tag set page + Then I should see "MASH (TV)" + And I should see "BJ/Hawkeye" + And I should see "Hawkeye/Margaret Houlihan" + And I should see "Hawkeye & Radar" + And I should see "Dallas (TV)" + And I should see "J. R. Ewing/Sue Ellen Ewing" + And I should see "Ann Ewing/Bobby Ewing" + And I should not see "Ann Ewing/Sue Ellen Ewing" + diff --git a/features/tag_sets/tag_set_delete.feature b/features/tag_sets/tag_set_delete.feature new file mode 100755 index 0000000..8cb973e --- /dev/null +++ b/features/tag_sets/tag_set_delete.feature @@ -0,0 +1,17 @@ +@tag_sets +Feature: deleting tag sets + + # Note that this test is now testing for non-JS enabled browsers. + Scenario: A user should be able to delete a tag set + Given I am logged in as "tagsetter" + And I go to the tagsets page + And I follow the add new tagset link + And I fill in "Title" with "murder_mystery_tags" + And I submit + And I should see a create confirmation message + And I should see "tagsetter" within ".meta" + When I follow "Delete" + Then I should see "Delete Tag Set?" + And I should see "Are you certain you want to delete the murder_mystery_tags Tag Set?" + And I press "Yes, Delete Tag Set" + Then I should see "Your Tag Set murder_mystery_tags was deleted." diff --git a/features/tag_sets/tag_set_nominations.feature b/features/tag_sets/tag_set_nominations.feature new file mode 100755 index 0000000..aee7353 --- /dev/null +++ b/features/tag_sets/tag_set_nominations.feature @@ -0,0 +1,340 @@ +# encoding: utf-8 +@tag_sets +Feature: Nominating and reviewing nominations for a tag set + + Scenario: A tag set should take nominations within the nomination limits + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 0 fandom noms and 3 character noms + Then I should see "Nominate" + When I follow "Nominate" + Then I should see "You can nominate up to 3 characters" + + Scenario: Tag set nominations should nest characters under fandoms if fandoms are being nominated + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 3 fandom noms and 3 character noms + Then I should see "Nominate" + When I follow "Nominate" + Then I should see "You can nominate up to 3 fandoms and up to 3 characters for each one" + + Scenario: You should be able to nominate tags + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 3 fandom noms and 3 character noms + Given I nominate 3 fandoms and 3 characters in the "Nominated Tags" tag set as "nominator" + And I submit + Then I should see "Your nominations were successfully submitted" + + Scenario: You should be able to nominate characters when the tagset doesn't allow fandom nominations + Given a canonical character "Common Character" in fandom "Canon" + And I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 0 fandom noms and 3 character noms + When I follow "Nominate" + And I fill in "Character 1" with "Obscure Character" + And I fill in "Character 2" with "Common Character" + And I press "Submit" + Then I should see "Sorry! We couldn't save this tag set nomination" + And I should see "We need to know what fandom Obscure Character belongs in." + But I should not see "We need to know what fandom Common Character belongs in." + When I fill in "Fandom?" with "Canon" + And I press "Submit" + Then I should see "Your nominations were successfully submitted." + And I should see "Obscure Character" + And I should see "Common Character" + + Scenario: You should be able to nominate relationships when the tagset doesn't allow fandom nominations + Given a canonical relationship "Common Pairing" in fandom "Canon" + And I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 0 fandom noms and 3 relationship noms + When I follow "Nominate" + And I fill in "Relationship 1" with "Rare Pairing" + And I fill in "Relationship 2" with "Common Pairing" + And I press "Submit" + Then I should see "Sorry! We couldn't save this tag set nomination" + And I should see "We need to know what fandom Rare Pairing belongs in." + But I should not see "We need to know what fandom Common Pairing belongs in." + When I fill in "Fandom?" with "Canon" + And I press "Submit" + Then I should see "Your nominations were successfully submitted." + And I should see "Rare Pairing" + And I should see "Common Pairing" + + Scenario: You should be able to edit your nominated tag sets, but cannot delete them once they've been reviewed + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Mayfly" with 3 fandom noms and 3 character noms + When I nominate fandom "Floobry" and character "Barblah" in "Mayfly" + Then I should see "Not Yet Reviewed (may be edited or deleted)" + And I should see "Floobry" + When I follow "Edit" + Then I should see the input with id "tag_set_nomination_fandom_nominations_attributes_0_tagname" within "div#main" + When I fill in "tag_set_nomination_fandom_nominations_attributes_0_tagname" with "Bloob" + When I press "Submit" + Then I should see "Your nominations were successfully updated" + Given I am logged in as "tagsetter" + When I review nominations for "Mayfly" + Then I should see "Bloob" within ".tagset" + When I check "fandom_approve_Bloob" + And I press "Submit" + Then I should see "Successfully added to set: Bloob" + Given I am logged in as "nominator" + And I go to the tagsets page + And I follow "Mayfly" + And I follow "My Nominations" + Then I should see "Partially Reviewed (unreviewed nominations may be edited)" + When I follow "Edit" + Then I should not see the input with id "tag_set_nomination_fandom_nominations_attributes_0_tagname" within "div#main" + + Scenario: You should be able to edit your nominated characters when the tagset doesn't allow fandom nominations + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 0 fandom noms and 3 character noms + When I follow "Nominate" + And I fill in "Character 1" with "My Aforvite Character" + And I fill in "Fandom?" with "My Favorite Fandom" + And I press "Submit" + Then I should see "Your nominations were successfully submitted." + And I should see "My Aforvite Character" + When I follow "Edit" + And I fill in "Character 1" with "My Favorite Character" + And I press "Submit" + Then I should see "Your nominations were successfully updated." + And I should see "My Favorite Character" + But I should not see "My Aforvite Character" + + Scenario: You should be able to edit your nominated relationships when the tagset doesn't allow fandom nominations + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 0 fandom noms and 3 relationship noms + When I follow "Nominate" + And I fill in "Relationship 1" with "My Favorite Character & Their Best Friend" + And I fill in "Fandom?" with "My Favorite Fandom" + And I press "Submit" + Then I should see "Your nominations were successfully submitted." + And I should see "My Favorite Character & Their Best Friend" + When I follow "Edit" + And I fill in "Relationship 1" with "My Favorite Character/Their Worst Enemy" + And I press "Submit" + Then I should see "Your nominations were successfully updated." + And I should see "My Favorite Character/Their Worst Enemy" + But I should not see "Their Best Friend" + + Scenario: You should be able to delete a nominated character and its fandom at once + when the tagset doesn't allow fandom nominations + Given a canonical character "Common Character" in fandom "Canon" + And I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 0 fandom noms and 3 character noms + When I follow "Nominate" + And I fill in "Character 1" with "Obscure Character" + And I fill in "Fandom?" with "Canon" + And I press "Submit" + Then I should see "Your nominations were successfully submitted." + And I should see "Obscure Character" + When I follow "Edit" + And I fill in "Character 1" with "" + And I fill in "Fandom?" with "" + And I press "Submit" + Then I should see "Your nominations were successfully updated." + And I should see "None nominated in this category." + But I should not see "We need to know what fandom belongs in." + + Scenario: Owner of a tag set can clear all nominations + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 3 fandom noms and 3 character noms + Given I nominate 3 fandoms and 3 characters in the "Nominated Tags" tag set as "nominator" + And I submit + Then I should see "Your nominations were successfully submitted" + Given I am logged in as "tagsetter" + When I review nominations for "Nominated Tags" + And I follow "Clear Nominations" + And I press "Yes, Clear Tag Set Nominations" + Then I should see "All nominations for this Tag Set have been cleared" + + Scenario: Owner of a tag set with over 30 nominations sees a message that they can't all be displayed on one page + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 6 fandom noms and 6 character noms + When there are 36 unreviewed nominations + Given I am logged in as "tagsetter" + And I review nominations for "Nominated Tags" + Then I should see "There are too many nominations to show at once, so here's a randomized selection! Additional nominations will appear after you approve or reject some" + + Scenario: If a set has received nominations, a moderator should be able to review nominated tags + Given I have the nominated tag set "Nominated Tags" + And I am logged in as "tagsetter" + When I go to the "Nominated Tags" tag set page + And I follow "Review Nominations" + Then I should see "left to review" + + Scenario: If a moderator approves a nominated tag it should no longer appear on the review page and should appear on the tag set page + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 3 fandom noms and 3 character noms + And I nominate fandom "Floobry" and character "Barblah" in "Nominated Tags" + And I review nominations for "Nominated Tags" + Then I should see "Floobry" within ".tagset" + When I check "fandom_approve_Floobry" + And I check "character_approve_Barblah" + And I submit + Then I should see "Successfully added to set: Floobry" + And I should see "Successfully added to set: Barblah" + When I follow "Review Nominations" + Then I should not see "Floobry" + And I should not see "Barblah" + + Scenario: If a moderator rejects a nominated tag or its fandom it should no longer appear on the review page + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 3 fandom noms and 3 character noms + And I nominate fandom "Floobry" and character "Barblah" in "Nominated Tags" + And I review nominations for "Nominated Tags" + When I check "fandom_reject_Floobry" + And I submit + Then I should see "Successfully rejected: Floobry" + And I should not see "Floobry" within ".tagset" + And I should not see "Barblah" + + Scenario: Tags with brackets should work with replacement + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 3 fandom noms and 3 character noms + And I nominate fandoms "Foo [Bar], Bar [Foo]" and characters "Yar [Bar], Bat [Bar]" in "Nominated Tags" + And I review nominations for "Nominated Tags" + When I check "fandom_approve_Foo__LBRACKETBar_RBRACKET" + And I check "character_reject_Yar__LBRACKETBar_RBRACKET" + And I check "fandom_approve_Bar__LBRACKETFoo_RBRACKET" + And I check "character_approve_Bat__LBRACKETBar_RBRACKET" + And I submit + Then I should see "Successfully added to set: Bar [Foo], Foo [Bar]" + And I should see "Successfully added to set: Bat [Bar]" + And I should see "Successfully rejected: Yar [Bar]" + When I go to the "Nominated Tags" tag set page + Then I should see "Foo [Bar]" + And I should see "Bar [Foo]" + And I should not see "Yar [Bar]" + When I go to the "Nominated Tags" tag set page + And I follow "Review Associations" + Then I should see "Bat [Bar] → Bar [Foo]" + When I check "Bat [Bar] → Bar [Foo]" + And I submit + Then I should see "Nominated associations were added" + And I should not see "don't seem to be associated" + + Scenario: Tags with Unicode characters should work + Given I nominate and approve tags with Unicode characters in "Nominated Tags" + And I am logged in as "tagsetter" + And I go to the "Nominated Tags" tag set page + Then I should see the tags with Unicode characters + + # Note this is now testing the non-JS method for deleting your own nominations + Scenario: You should be able to delete your nominations + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 3 fandom noms and 3 character noms + Given I nominate 3 fandoms and 3 characters in the "Nominated Tags" tag set as "nominator" + And I submit + When I should see "Your nominations were successfully submitted" + And I go to the "Nominated Tags" tag set page + And I follow "My Nominations" + And I should see "My Nominations for Nominated Tags" + And I follow "Delete" + And I should see "Delete Tag Set Nomination?" + When I press "Yes, Delete Tag Set Nominations" + Then I should see "Your nominations were deleted." + + Scenario: Two users cannot nominate the same tag for different parents (e.g. + the same character in two fandoms) + Given I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 1 fandom nom and 1 character nom + And I nominate fandom "The Closer" and character "Sharon Raydor" in "Nominated Tags" as "nominator1" + When I start to nominate fandom "Major Crimes" and character "Sharon Raydor" in "Nominated Tags" as "nominator2" + And I submit + Then I should see "Someone else has already nominated the tag Sharon Raydor for this set but in fandom The Closer. (All nominations have to be unique for the approval process to work.) Try making your nomination more specific, for instance tacking on (Major Crimes)." + + Scenario: If a tag already exists in the archive as one type of tag, it can't be + nominated as another type of tag (e.g. Veronica Mars can't be nominated as a fandom if + it exists as a character) + Given a noncanonical character "Veronica Mars" + And I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 1 fandom nom and 1 character nom + When I start to nominate fandom "Veronica Mars" and character "Keith Mars" in "Nominated Tags" + And I submit + Then I should see "The tag Veronica Mars is already in the archive as a Character tag. (All tags have to be unique.) Try being more specific, for instance tacking on the medium or the fandom." + + Scenario: If a tag was nominated as another type of tag, "My Nominations" and "Review Nominations" can still be accessed + Given a nominated tag set "bad" with a tag nomination in the wrong category + And I am logged in as "tagsetter" + And I go to the "bad" tag set page + # preexisting non-canonical tag + When I follow "My Nominations" + Then I should see "My Nominations for bad" + And I should see "rel tag" + When I review nominations for "bad" + Then I should see "Fandoms (1 left to review)" + And I should see "rel tag" + # canonical tag + When the tag "rel tag" is canonized + And I go to the "bad" tag set page + When I follow "My Nominations" + Then I should see "My Nominations for bad" + And I should see "rel tag" + When I review nominations for "bad" + Then I should see "Fandoms (1 left to review)" + And I should see "rel tag" + # synonym tag + When the tag "rel tag" is decanonized + And a canonical relationship "canon tag" + And a synonym "rel tag" of the tag "canon tag" + And I go to the "bad" tag set page + When I follow "My Nominations" + Then I should see "My Nominations for bad" + And I should see "rel tag" + When I review nominations for "bad" + Then I should see "Fandoms (1 left to review)" + And I should see "rel tag (canon tag)" + + Scenario: The zero width space tag doesn't replace deleted tag nominations + Given a canonical fandom "Treasure Chest" + And a zero width space tag exists + And I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 2 fandom noms and 3 character noms + And I nominate fandom "Treasure Chest" and character "Gold" in "Nominated Tags" + And I go to the "Nominated Tags" tag set page + And I follow "My Nominations" + Then I should see "Not Yet Reviewed (may be edited or deleted)" + When I follow "Edit" + And I fill in "Character" with "" + And I press "Submit" + Then I should see "Your nominations were successfully updated." + And I should see "Treasure Chest" + But I should not see "Gold" + And I should see "None nominated in this fandom." + + Scenario: A tag nomination with the zero width space tag doesn't prevent removing other tag nominations + Given a canonical fandom "First" + And a canonical fandom "Treasure Chest" + And a zero width space tag exists + And I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 2 fandom noms and 1 character noms + # Zero width space character tag in first fandom + And I nominate fandom "First,Treasure Chest" and character "​,Gold" in "Nominated Tags" + And I go to the "Nominated Tags" tag set page + And I follow "My Nominations" + Then I should see "First" + And I should not see "None nominated in this fandom." + And I should see "Treasure Chest" + And I should see "Gold" + When I follow "Edit" + # Empty second fandom character field + And I fill in "tag_set_nomination_fandom_nominations_attributes_1_character_nominations_attributes_0_tagname" with "" + And I press "Submit" + Then I should see "Your nominations were successfully updated." + And I should not see "Someone else has already nominated the tag for this set but in fandom First." + And I should not see "Gold" + And I should see "None nominated in this fandom." + + Scenario: A nominated canonical tag can be renamed by a tag wrangling admin without affecting the nomination + Given a canonical character "Before" in fandom "Treasure Chest" + And I am logged in as "tagsetter" + And I set up the nominated tag set "Nominated Tags" with 1 fandom nom and 1 character nom + And I nominate fandom "Treasure Chest" and character "Before" in "Nominated Tags" as "tagsetter" + When I am logged in as an "tag_wrangling" admin + And I edit the tag "Before" + And I fill in "Name" with "After" + And I press "Save changes" + Then I should see "Tag was updated." + When I am logged in as "tagsetter" + And I go to the "Nominated Tags" tag set page + And I follow "My Nominations" + Then I should see "Treasure Chest" + And I should see "Before" diff --git a/features/tags_and_wrangling/brand_new_fandoms.feature b/features/tags_and_wrangling/brand_new_fandoms.feature new file mode 100755 index 0000000..501d022 --- /dev/null +++ b/features/tags_and_wrangling/brand_new_fandoms.feature @@ -0,0 +1,114 @@ +@user @tag_wrangling +Feature: Brand new fandoms + + Background: + # The external works form will error if we don't have basic tags, and since + # we're trying to create a brand new tag, we just want to double-check that + # it doesn't exist. + Given basic tags + And the tag "My Brand New Fandom" does not exist + + Scenario: Brand new fandoms should be visible on the Uncategorized Fandoms page. + Given I am logged in as a random user + And I post a work "My New Work" with fandom "My Brand New Fandom" + And the periodic tag count task is run + And all indexing jobs have been run + When I follow "Uncategorized Fandoms" within "#header" + Then I should see "My Brand New Fandom" + + Scenario: Fandoms used only on external works should be visible on the Uncategorized Fandoms page. + Given I am logged in as a random user + And I set up an external work + And I fill in "Fandoms" with "My Brand New Fandom" + And I submit + And the periodic tag count task is run + And all indexing jobs have been run + When I follow "Uncategorized Fandoms" within "#header" + Then I should see "My Brand New Fandom" + + Scenario: When the only work with a brand new fandom is destroyed, the fandom should not be visible on the Uncategorized Fandoms page. + Given I am logged in as a random user + And I post a work "My New Work" with fandom "My Brand New Fandom" + And the periodic tag count task is run + And all indexing jobs have been run + When I follow "Edit" + And I follow "Delete Work" + And I press "Yes" + Then I should see "Your work My New Work was deleted." + When the periodic tag count task is run + And I follow "Uncategorized Fandoms" within "#header" + Then I should not see "My Brand New Fandom" + + Scenario: When the only external work with a brand new fandom is destroyed, the fandom should not be visible on the Uncategorized Fandoms page. + Given I am logged in as a random user + And I set up an external work + And I fill in "Title" with "External Work To Be Deleted" + And I fill in "Fandoms" with "My Brand New Fandom" + And I submit + And the periodic tag count task is run + And all indexing jobs have been run + When I am logged in as a "policy_and_abuse" admin + And I view the external work "External Work To Be Deleted" + And I follow "Delete External Work" + Then I should see "Item was successfully deleted." + When the periodic tag count task is run + And I follow "Uncategorized Fandoms" within "#header" + Then I should not see "My Brand New Fandom" + + Scenario: Brand new fandoms should be visible to wranglers. + Given I am logged in as a tag wrangler + And I post a work "My New Work" with fandom "My Brand New Fandom" + And the periodic tag count task is run + And all indexing jobs have been run + When I go to the fandom mass bin + Then I should see "My Brand New Fandom" + + Scenario: When the only work with a brand new fandom is destroyed, the fandom should not be visible to tag wranglers. + Given I am logged in as a tag wrangler + And I post a work "My New Work" with fandom "My Brand New Fandom" + And the periodic tag count task is run + And all indexing jobs have been run + When I follow "Edit" + And I follow "Delete Work" + And I press "Yes" + Then I should see "Your work My New Work was deleted." + When the periodic tag count task is run + And all indexing jobs have been run + And I go to the fandom mass bin + Then I should not see "My Brand New Fandom" + + Scenario: Fandoms used only on external works should not be visible to wranglers. + Given I am logged in as a tag wrangler + And I set up an external work + And I fill in "Fandoms" with "My Brand New Fandom" + And I submit + And the periodic tag count task is run + And all indexing jobs have been run + When I go to the fandom mass bin + Then I should not see "My Brand New Fandom" + + Scenario: When a brand new fandom used only on external works is tagged on a work, the fandom should be visible to tag wranglers. + Given I am logged in as a tag wrangler + And I set up an external work + And I fill in "Fandoms" with "My Brand New Fandom" + And I submit + When I post the work "Great work" with fandom "My Brand New Fandom" + And the periodic tag count task is run + And all indexing jobs have been run + And I am logged in as a tag wrangler + And I go to the fandom mass bin + Then I should see "My Brand New Fandom" + + Scenario: When the only draft using a brand new fandom is published, the fandom should be visible to tag wranglers. + Given I am logged in as a tag wrangler + And I set up the draft "Generic Work" with fandom "My Brand New Fandom" + And I press "Preview" + And the periodic tag count task is run + And all indexing jobs have been run + When I go to the fandom mass bin + Then I should not see "My Brand New Fandom" + When I post the work "Generic Work" + And the periodic tag count task is run + And all indexing jobs have been run + And I go to the fandom mass bin + Then I should see "My Brand New Fandom" diff --git a/features/tags_and_wrangling/favorite_tags.feature b/features/tags_and_wrangling/favorite_tags.feature new file mode 100755 index 0000000..4926734 --- /dev/null +++ b/features/tags_and_wrangling/favorite_tags.feature @@ -0,0 +1,39 @@ +Feature: Favorite Tags + In order to browse more efficiently + As an archive user + I should be able to list my favorite tags on my homepage + + Scenario: A user can add a canonical tag to their favorite tags + Given a canonical fandom "Dallas (TV 2012)" + When I am logged in as "bourbon" with password "andbranch" + And I go to the homepage + Then I should see "Find your favorites" + And I should see "Browse fandoms by media or favorite up to 20 tags to have them listed here!" + When I view the "Dallas (TV 2012)" works index + Then I should see a "Favorite Tag" button + When I press "Favorite Tag" + Then I should see "You have successfully added Dallas (TV 2012) to your favorite tags." + When I go to the homepage + Then I should see "Dallas (TV 2012)" + + Scenario: A user can remove a tag from their favorite tags + Given a canonical relationship "John Ross Ewing/Elena Ramos" + When I am logged in as "bourbon" with password "andbranch" + And I add "John Ross Ewing/Elena Ramos" to my favorite tags + When I view the "John Ross Ewing/Elena Ramos" works index + Then I should see a "Unfavorite Tag" button + When I press "Unfavorite Tag" + Then I should see "You have successfully removed John Ross Ewing/Elena Ramos from your favorite tags." + When I go to the homepage + Then I should not see "John Ross Ewing/Elena Ramos" + And I should see "Browse fandoms by media or favorite up to 20 tags to have them listed here!" + + Scenario: A tag that is decanonized should be removed from users' favorite tags + Given a canonical character "Rebecca Sutter" + When I am logged in as "bourbon" with password "andbranch" + And I add "Rebecca Sutter" to my favorite tags + When I go to the homepage + Then I should see "Rebecca Sutter" + When the tag "Rebecca Sutter" is decanonized + And I go to the homepage + Then I should not see "Rebecca Sutter" diff --git a/features/tags_and_wrangling/tag_cloud.feature b/features/tags_and_wrangling/tag_cloud.feature new file mode 100755 index 0000000..1bfa0ba --- /dev/null +++ b/features/tags_and_wrangling/tag_cloud.feature @@ -0,0 +1,110 @@ +@tags + +Feature: Tag Cloud + In order to browse by the most used additional tags + As an archive user or visitor + I should be able to view some tags in a tag cloud + +Scenario: tag cloud should only contain top-level canonical freeforms in "No Fandom" + I want to check that: + non-canonical used freeforms do not show up in cloud, whether unwrangled, fandomish or no fandomish + canonical freeforms within No Fandom but with no uses at all do not show + canonical freeforms that are fandomish or unwrangled do not show up, even used + canonical freeforms within No Fandom, with no uses but with used mergers show up TODO + canonical freeforms within No Fandom, with uses, show up TODO + metatag freeforms with uses show up and their subtags do not anymore TODO + metatag freeforms with no uses do not show and neither do their subtags (which I think is bad) TODO + + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + And basic tags + And a fandom exists with name: "Firefly", canonical: true + And a freeform exists with name: "Non-canonical NoFandom", canonical: false + And a freeform exists with name: "Non-canonical Fandomish", canonical: false + And a freeform exists with name: "Non-canonical unwrangled", canonical: false + And a freeform exists with name: "Canonical unused NoFandom", canonical: true + And a freeform exists with name: "Canonical Fandomish", canonical: true + And a freeform exists with name: "Canonical unwrangled", canonical: true + + # post a work with some fun tags and some boring tags + + When I am logged in as "author" with password "password" + And I go to the new work page + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "Firefly" + And I fill in "Work Title" with "Silliness" + And I fill in "Additional Tags" with "100 words, five things, objects in space, Sentient Serenity, Episode Tag, Non-canonical NoFandom, Non-canonical Fandomish, Non-canonical unwrangled, Canonical Fandomish, Canonical unwrangled" + And I fill in "content" with "And then everyone was kidnapped by an alien bus." + And I press "Preview" + And I press "Post" + Then I should see "Work was successfully posted." + + # test the tags with fun names + + When I am logged out + And I follow "Tags" within "ul.navigation" + Then I should not see "100 words" + And I should not see "five things" + + When I am logged in as "Enigel" with password "wrangulate!" + And I edit the tag "five things" + And I fill in "Fandoms" with "No Fandom" + And I press "Save changes" + And I follow "New Tag" + And I fill in "Name" with "5 Things" + And I choose "Additional Tag" + And I check "Canonical" + And I press "Create Tag" + And I follow "New Tag" + And I fill in "Name" with "N Things" + And I choose "Additional Tag" + And I check "Canonical" + And I press "Create Tag" + And I follow "Tags" + Then I should not see "Five Things" + And I should not see "5 Things" + And I should not see "N Things" + When I post the work "Test" + And I edit the work "Test" + And I fill in "Additional Tags" with "Five Things" + And I press "Preview" + And I press "Update" + And I follow "Tags" + Then I should not see "Five Things" + + # set up boringly-named tags + + When I edit the tag "Non-canonical NoFandom" + And I fill in "Fandoms" with "No Fandom" + And I press "Save changes" + And I edit the tag "Non-canonical Fandomish" + And I fill in "Fandoms" with "Firefly" + And I press "Save changes" + And I edit the tag "Canonical unused NoFandom" + And I fill in "Fandoms" with "No Fandom" + And I press "Save changes" + And I edit the tag "Canonical Fandomish" + And I fill in "Fandoms" with "Firefly" + And I press "Save changes" + Then I should see "Tag was updated" + + # check the cloud for the boring tags + + When I follow "Tags" + Then I should not see "Non-canonical NoFandom" + And I should not see "Non-canonical Fandomish" + And I should not see "Non-canonical unwrangled" + And I should not see "Canonical unused NoFandom" + And I should not see "Canonical Fandomish" + And I should not see "Canonical unwrangled" + + When I follow "Random" + Then I should not see "Non-canonical NoFandom" + And I should not see "Non-canonical Fandomish" + And I should not see "Non-canonical unwrangled" + And I should not see "Canonical unused NoFandom" + And I should not see "Canonical Fandomish" + And I should not see "Canonical unwrangled" diff --git a/features/tags_and_wrangling/tag_comment.feature b/features/tags_and_wrangling/tag_comment.feature new file mode 100755 index 0000000..c52a277 --- /dev/null +++ b/features/tags_and_wrangling/tag_comment.feature @@ -0,0 +1,216 @@ +@tags @tag_wrangling @comments +Feature: Comment on tag +As a tag wrangler +I'd like to comment on a tag' + + @disable_caching + Scenario: Comment on a tag and get taken to right page and see right date + + Given the following activated tag wranglers exist + | login | + | dizmo | + And a fandom exists with name: "Stargate Atlantis", canonical: true + And it is currently Mon Mar 27 22:00:00 UTC 2017 + When I am logged in as "dizmo" + When I view the tag "Stargate Atlantis" + Then I should see "0 comments" + When I post the comment "Shouldn't this be a metatag with Stargate?" on the tag "Stargate Atlantis" via web + Then I should see "Shouldn't this be a metatag with Stargate?" + And the comment's posted date should be nowish + And I jump in our Delorean and return to the present + + Scenario: Edit a comment on a tag + + Given the following activated tag wranglers exist + | login | + | dizmo | + And a fandom exists with name: "Stargate Atlantis", canonical: true + And it is currently Mon Mar 27 22:00:00 UTC 2017 + When I am logged in as "dizmo" + When I post the comment "Shouldn't this be a metatag with Stargate?" on the tag "Stargate Atlantis" + When it is currently 1 second from now + And I follow "Edit" + Then the "Comment" field should contain "Shouldn't this be a metatag with Stargate?" + And I should see "Cancel" + When I fill in "Comment" with "Yep, we should have a Stargate franchise metatag." + And I press "Update" + Then I should see "Comment was successfully updated." + And I should see "Yep, we should have a Stargate franchise metatag." + And I should not see "Shouldn't this be a metatag with Stargate?" + And I should see Last Edited nowish + When I jump in our Delorean and return to the present + + Scenario: Multiple comments on a tag increment correctly + + Given the following activated tag wranglers exist + | login | + | dizmo | + | someone_else | + And a fandom exists with name: "Stargate Atlantis", canonical: true + When I am logged in as "dizmo" + When I post the comment "Yep, we should have a Stargate franchise metatag." on the tag "Stargate Atlantis" + When I am logged in as "someone_else" + When I post the comment "Important policy decision" on the tag "Stargate Atlantis" + When I view the tag "Stargate Atlantis" + Then I should see "2 comments" + + Scenario: Issue 2185: email notifications for tag commenting; TO DO: replies to comments + + Given the following activated tag wranglers exist + | login | password | email | + | dizmo | wrangulator | dizmo@example.org | + | Enigel | wrangulator | enigel@example.org | + | Cesy | wrangulator | cesy@example.org | + And a canonical fandom "Eroica" + And a canonical fandom "Doctor Who" + And the tag wrangler "Enigel" with password "wrangulator" is wrangler of "Eroica" + And the tag wrangler "Cesy" with password "wrangulator" is wrangler of "Doctor Who" + And the tag wrangler "dizmo" with password "wrangulator" is wrangler of "Doctor Who" + + # receive copies of own comments + When I am logged in as "Enigel" with password "wrangulator" + And I go to Enigel's user page + And I follow "Preferences" + And I uncheck "Turn off copies of your own comments" + And I press "Update" + And I log out + + # fellow wrangler leaves a comment on a wrangler's fandom + When I am logged in as "Cesy" with password "wrangulator" + And I go to Cesy's user page + And I follow "Preferences" + And I check "Turn off copies of your own comments" + And I press "Update" + And all emails have been delivered + And I view the tag "Eroica" + And I follow "0 comments" + And I fill in "Comment" with "really clever stuff" + And I press "Comment" + Then I should see "Comment created" + And 1 email should be delivered to "enigel@example.org" + And the email should contain "really clever stuff" + And the email should contain "Cesy" + And the email should contain "left the following comment on" + And the email should contain "the tag" + + When I am logged in as "Enigel" with password "wrangulator" + And I follow "Go to the thread starting from this comment" in the email + Then I should see "Comment on Eroica" + And I should see "really clever stuff" + When I follow "Read all comments on Eroica" in the email + Then I should see "Reading Comments on Eroica" + And I should see "really clever stuff" + When I follow "Reply to this comment" in the email + Then I should see "Comment on Eroica" + And I should see "really clever stuff" + And all emails have been delivered + + When I view the tag "Doctor Who" + And I follow "0 comments" + And I fill in "Comment" with "really clever stuff" + And I press "Comment" + Then I should see "Comment created" + And 1 email should be delivered to "cesy@example.org" + And 1 email should be delivered to "dizmo@example.org" + And 1 email should be delivered to "enigel@example.org" + When I follow "Edit" + And all emails have been delivered + And I press "Update" + Then I should see "Comment was successfully updated" + And 3 emails should be delivered + + Scenario: Email notifications for tag comments should ignore work comments settings + + Given the following activated tag wranglers exist + | login | password | email | + | dizmo | wrangulator | dizmo@example.org | + | Enigel | wrangulator | enigel@example.org| + And a fandom exists with name: "Doctor Who", canonical: true + And the tag wrangler "Enigel" with password "wrangulator" is wrangler of "Doctor Who" + And I am logged in as "Enigel" + And I set my preferences to turn off notification emails for comments + When I am logged in as "dizmo" with password "wrangulator" + And I post the comment "Heads up" on the tag "Doctor Who" + Then 1 email should be delivered to "enigel@example.org" + + Scenario: comments on synonym fandoms should be received by the wrangler of the canonical merger + + Given the following activated tag wranglers exist + | login | password | email | + | dizmo | wrangulator | dizmo@example.org | + | Enigel | wrangulator | enigel@example.org| + And a canonical fandom "Doctor Who" + And the tag wrangler "Enigel" with password "wrangulator" is wrangler of "Doctor Who" + And a synonym "Dr Who" of the tag "Doctor Who" + When I am logged in as "dizmo" with password "wrangulator" + And I post the comment "Heads up" on the tag "Dr Who" + Then 1 email should be delivered to "enigel@example.org" + + Scenario: Comments pagination for a regular tag + + Given a tag "No Punctuation Here" with 34 comments + And I am logged in as a tag wrangler + When I view the tag "No Punctuation Here" + # link to comments should exist + Then I should see "34 comments" + When I follow "34 comments" + # link to the next page of comments should exist + Then I should see "Next" within ".pagination" + When I follow "Next" within ".pagination" + And I post a comment "Checking redirect after commenting on a tag" + # should redirect to the same page you were on before commenting + Then I should see "Comment created" + And I should see "Checking redirect after commenting on a tag" + + Scenario: Comments pagination for a tag with slashes in the name + + Given a tag "hack/sign" with 34 comments + And I am logged in as a tag wrangler + When I post the comment "And now things should not break!" on the tag "hack/sign" + Then I should see "Comment created" + # all it checks is that the pagination links aren't broken + When I follow "Next" within ".pagination" + Then I should see "And now things should not break!" + + Scenario: Comments pagination for a tag with periods in the name + + Given a period-containing tag "sign.me" with 34 comments + And I am logged in as a tag wrangler + When I post the comment "And now things should not break!" on the tag "sign.me" + Then I should see "Comment created" + # all it checks is that the pagination links aren't broken + When I follow "Next" within ".pagination" + Then I should see "And now things should not break!" + + Scenario: Comments pagination for a tag with slashes and periods in the name + + Given a tag "hack/sign.me" with 34 comments + And I am logged in as a tag wrangler + When I post the comment "And now things should not break!" on the tag "hack/sign.me" + Then I should see "Comment created" + # all it checks is that the pagination links aren't broken + When I follow "Next" within ".pagination" + Then I should see "And now things should not break!" + + Scenario: Comments on a tag should not be visible to non-wranglers. + + Given a canonical fandom "World Domination" + And I am logged in as a tag wrangler + And I post the comment "Top-secret plans." on the tag "World Domination" + And I am logged out + + When I view the latest comment + + Then I should not see "Top-secret plans." + + Scenario: Comments replying to a comment on a tag should not be visible to non-wranglers. + + Given a canonical fandom "World Domination" + And I am logged in as a tag wrangler + And I post the comment "Anyone have a plan?" on the tag "World Domination" + And I reply to a comment with "Top-secret plans." + And I am logged out + + When I view the latest comment + + Then I should not see "Top-secret plans." diff --git a/features/tags_and_wrangling/tag_search.feature b/features/tags_and_wrangling/tag_search.feature new file mode 100755 index 0000000..cbcbb63 --- /dev/null +++ b/features/tags_and_wrangling/tag_search.feature @@ -0,0 +1,250 @@ +@tags @tag_wrangling @search +Feature: Search Tags + In order to find tags + As a user + I want to use tag search + + Scenario: Search tags + Given I have no tags + And a fandom exists with name: "first fandom", canonical: false + And a character exists with name: "first last", canonical: true + And a relationship exists with name: "first last/someone else", canonical: false + And all indexing jobs have been run + When I am on the search tags page + And I fill in "Tag name" with "first" + And I press "Search Tags" + Then I should see "3 Found" + And I should see the tag search result "Fandom: first fandom (0)" + And I should not see the tag search result "Fandom: first fandom (0)" within ".canonical" + And I should see the tag search result "Character: first last (0)" within ".canonical" + And I should see the tag search result "Relationship: first last/someone else (0)" + # test search with slash + When I am on the search tags page + And I fill in "Tag name" with "first last\/someone else" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "first last/someone else (0)" + + Scenario: Search for fandom with slash in name + Given I have no tags + And a fandom exists with name: "first/fandom", canonical: false + And all indexing jobs have been run + When I am on the search tags page + And I fill in "Tag name" with "first" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "Fandom: first/fandom (0)" + + Scenario: Search for fandom with period in name + Given I have no tags + And a fandom exists with name: "first.fandom", canonical: false + And all indexing jobs have been run + When I am on the search tags page + And I fill in "Tag name" with "first.fandom" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "Fandom: first.fandom (0)" + When I follow "first.fandom" + Then I should see "This tag belongs to the Fandom Category" + + When I am on the search tags page + # possibly a bug rather than desired behaviour, to be discussed later + And I fill in "Tag name" with "first" + And I press "Search Tags" + Then I should see "0 Found" + And I should not see "Fandom: first.fandom (0)" + + Scenario: Search for tag in canonical fandom(s) + Given a canonical character "Anna Anderson" in fandom "Fandom A" + And a canonical character "Abby Anderson" in fandom "Fandom B" + And I add the fandom "Fandom A" to the character "Abby Anderson" + And a character exists with name: "Null Anderson" + And a fandom exists with name: "Not Canon Fandom", canonical: false + And all indexing jobs have been run + # Tag in one canonical fandom + When I am on the search tags page + And I fill in "Tag name" with "Anderson" + And I fill in "Fandom" with "Fandom A" + And I press "Search Tags" + Then I should see "2 Found" + And I should see the tag search result "Anna Anderson" + And I should see the tag search result "Abby Anderson" + And I should not see the tag search result "Null Anderson" + # Tag in multiple canonical fandoms + When I am on the search tags page + And I fill in "Tag name" with "Anderson" + And I fill in "Fandom" with "Fandom A, Fandom B" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "Abby Anderson" + And I should not see the tag search result "Anna Anderson" + And I should not see the tag search result "Null Anderson" + # Search with non-canonical fandom will yield no results + When I am on the search tags page + And I fill in "Tag name" with "Anderson" + And I fill in "Fandom" with "Not Canon Fandom" + And I press "Search Tags" + Then I should see "0 Found" + # Search with non-existent fandom ignores non-existent fandom (like People Search) + When I am on the search tags page + And I fill in "Tag name" with "Anderson" + And I fill in "Fandom" with "non-existent fandom" + And I press "Search Tags" + Then I should see "3 Found" + And I should see the tag search result "Abby Anderson" + And I should see the tag search result "Anna Anderson" + And I should see the tag search result "Null Anderson" + # Search with non-existent fandom and canonical fandom filters by canonical fandom + When I am on the search tags page + And I fill in "Tag name" with "Anderson" + And I fill in "Fandom" with "non-existent fandom, Fandom A" + And I press "Search Tags" + Then I should see "2 Found" + And I should see the tag search result "Anna Anderson" + And I should see the tag search result "Abby Anderson" + And I should not see the tag search result "Null Anderson" + + Scenario: Search by Type of tags + Given a fandom exists with name: "first fandom" + And a character exists with name: "first character" + And a relationship exists with name: "first last/someone else" + And a freeform exists with name: "first fic please be nice" + And all indexing jobs have been run + When I am on the search tags page + And I fill in "Tag name" with "first" + And I choose "Fandom" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "Fandom: first fandom" + And I should not see the tag search result "Character: first character" + And I should not see the tag search result "Relationship: first last/somone else" + And I should not see the tag search result "Freeform: first fic please be nice" + When I am on the search tags page + And I fill in "Tag name" with "first" + And I choose "Character" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "Character: first character" + And I should not see the tag search result "Fandom: first fandom" + And I should not see the tag search result "Relationship: first last/somone else" + And I should not see the tag search result "Freeform: first fic please be nice" + When I am on the search tags page + And I fill in "Tag name" with "first" + And I choose "Relationship" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "Relationship: first last/somone else" + And I should not see the tag search result "Fandom: first fandom" + And I should not see the tag search result "Character: first character" + And I should not see the tag search result "Freeform: first fic please be nice" + When I am on the search tags page + And I fill in "Tag name" with "first" + And I choose "Freeform" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "Freeform: first fic please be nice" + And I should not see the tag search result "Fandom: first fandom" + And I should not see the tag search result "Character: first character" + And I should not see the tag search result "Relationship: first last/somone else" + + Scenario: Search by wrangling status + Given a fandom exists with name: "Not Canon Fandom", canonical: false + And a character exists with name: "Canon Character", canonical: true + And a synonym "Same Canon Character" of the tag "Canon Character" + And all indexing jobs have been run + When I am on the search tags page + And I fill in "Tag name" with "Canon" + And I choose "Canonical" + And I press "Search Tags" + Then I should see "1 Found" + And I should not see the tag search result "Fandom: Not Canon Fandom (0)" + And I should see the tag search result "Character: Canon Character (0)" + And I should not see the tag search result "Character: Same Canon Character (0)" + When I am on the search tags page + And I fill in "Tag name" with "Canon" + And I choose "Non-canonical" + And I press "Search Tags" + Then I should see "2 Found" + And I should see the tag search result "Fandom: Not Canon Fandom (0)" + And I should not see the tag search result "Character: Canon Character (0)" + And I should see the tag search result "Character: Same Canon Character (0)" + When I am on the search tags page + And I fill in "Tag name" with "Canon" + And I choose "Synonymous" + And I press "Search Tags" + Then I should see "1 Found" + And I should not see the tag search result "Fandom: Not Canon Fandom (0)" + And I should not see the tag search result "Character: Canon Character (0)" + And I should see the tag search result "Character: Same Canon Character (0)" + When I am on the search tags page + And I fill in "Tag name" with "Canon" + And I choose "Canonical or synonymous" + And I press "Search Tags" + Then I should see "2 Found" + And I should not see the tag search result "Fandom: Not Canon Fandom (0)" + And I should see the tag search result "Character: Canon Character (0)" + And I should see the tag search result "Character: Same Canon Character (0)" + When I am on the search tags page + And I fill in "Tag name" with "Canon" + And I choose "Non-canonical and non-synonymous" + And I press "Search Tags" + Then I should see "1 Found" + And I should see the tag search result "Fandom: Not Canon Fandom (0)" + And I should not see the tag search result "Character: Canon Character (0)" + And I should not see the tag search result "Character: Same Canon Character (0)" + When I am on the search tags page + And I fill in "Tag name" with "Canon" + And I choose "Any status" + And I press "Search Tags" + Then I should see "3 Found" + And I should see the tag search result "Fandom: Not Canon Fandom (0)" + And I should see the tag search result "Character: Canon Character (0)" + And I should see the tag search result "Character: Same Canon Character (0)" + + Scenario: Search and sort by Date Created in descending and ascending order + Given a freeform exists with name: "created first", created_at: "2008-01-01 20:00:00 Z" + And a freeform exists with name: "created second", created_at: "2009-01-01 20:00:00 Z" + And a freeform exists with name: "created third", created_at: "2010-01-01 20:00:00 Z" + And a freeform exists with name: "created fourth", created_at: "2011-01-01 20:00:00 Z" + And all indexing jobs have been run + When I am on the search tags page + And I fill in "Tag name" with "created" + And I select "Date Created" from "Sort by" + And I select "Descending" from "Sort direction" + And I press "Search Tags" + Then I should see "4 Found" + And the 1st tag result should contain "created fourth" + And the 2nd tag result should contain "created third" + And the 3rd tag result should contain "created second" + And the 4th tag result should contain "created first" + When I select "Ascending" from "Sort direction" + And I press "Search Tags" + Then I should see "4 Found" + And the 1st tag result should contain "created first" + And the 2nd tag result should contain "created second" + And the 3rd tag result should contain "created third" + And the 4th tag result should contain "created fourth" + + Scenario: Search and sort by Uses in descending and ascending order + Given a set of tags for tag sort by use exists + When I am on the search tags page + And I fill in "Tag name" with "uses" + And I select "Uses" from "Sort by" + And I select "Descending" from "Sort direction" + And I press "Search Tags" + Then I should see "6 Found" + And the 1st tag result should contain "10 uses" + And the 2nd tag result should contain "8 uses" + And the 3rd tag result should contain "8 uses" + And the 4th tag result should contain "5 uses" + And the 5th tag result should contain "2 uses" + And the 6th tag result should contain "0 uses" + When I select "Ascending" from "Sort direction" + And I press "Search Tags" + Then I should see "6 Found" + And the 1st tag result should contain "0 uses" + And the 2nd tag result should contain "2 uses" + And the 3rd tag result should contain "5 uses" + And the 4th tag result should contain "8 uses" + And the 5th tag result should contain "8 uses" + And the 6th tag result should contain "10 uses" diff --git a/features/tags_and_wrangling/tag_wrangling.feature b/features/tags_and_wrangling/tag_wrangling.feature new file mode 100755 index 0000000..fc6565a --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling.feature @@ -0,0 +1,383 @@ +@users @tag_wrangling +Feature: Tag wrangling + + Scenario: Admin can create a tag wrangler using the interface + + Given the role "tag_wrangler" + When I am logged in as "dizmo" + Then I should not see "Tag Wrangling" within "#header" + When I am logged in as a "tag_wrangling" admin + And I go to the manage users page + And I fill in "Name" with "dizmo" + And I press "Find" + Then I should see "dizmo" within "#admin_users_table" + # admin making user tag wrangler + When I check the "tag_wrangler" role checkbox + And I press "Update" + Then I should see "User was successfully updated" + # accessing wrangling pages + When I am logged in as "dizmo" + And I follow "Tag Wrangling" within "#header" + Then I should see "Wrangling Home" + # no access otherwise + When I log out + Then I should see "Sorry, you don't have permission" + + Scenario Outline: Tag wrangler navigation/sidebar + Given the tag wrangling setup + And I am logged in as a tag wrangler + When I go to the wrangling page for "wrangler" + Then I should see "Wrangling Home" + And I should see "Fandoms by media (2)" + And I should see "Characters by fandom (2)" + And I should see "Relationships by fandom (1)" + When I follow + Then I should see + + Examples: + | link_text | heading | + | "Wranglers" | "Tag Wrangling Assignments" | + | "Wrangling Tools" | "Tag Wrangling" | + | "Characters by fandom (2)" | "Mass Wrangle New/Unwrangled Tags" | + | "Relationships by fandom (1)" | "Mass Wrangle New/Unwrangled Tags" | + | "Fandoms by media (2)" | "Mass Wrangle New/Unwrangled Tags" | + + Scenario: Edit tag page + Given the tag wrangling setup + And I am logged in as a tag wrangler + When I go to the "Daniel Jackson" tag page + And I follow "Edit" within ".header" + Then I should see "Edit Daniel Jackson Tag" + And I should see "Name" + And I should see "Category" + And I should see "Canonical" + And I should see "Synonym" + And I should see "Unwrangleable" + And I should see "Fandom" + And I should see "Meta" + + Scenario: Making a fandom canonical and assigning media to it + Given the tag wrangling setup + And I am logged in as a tag wrangler + When I go to the "Stargate SG-1" tag edit page + When I check "tag_canonical" + And I fill in "tag_media_string" with "TV Shows" + And I press "Save changes" + Then I should see "Tag was updated" + And the "Stargate SG-1" tag should be canonical + + Scenario: Assign wrangler to a fandom + Given the tag wrangling setup + And I have a canonical "TV Shows" fandom tag named "Stargate SG-1" + And I am logged in as a tag wrangler + When I go to the wrangling page for "wrangler" + And I follow "Wranglers" + And I fill in "tag_fandom_string" with "Stargate SG-1" + And I press "Assign" + Then "Stargate SG-1" should be assigned to the wrangler "wrangler" + When I follow "Wrangling Home" + Then I should see "Stargate SG-1" + When I follow "Wranglers" + Then I should see "Stargate SG-1" + And I should see "wrangler" within "ul.wranglers" + + Scenario: Making a character canonical and assigning it to a fandom + Given the tag wrangling setup + And I have a canonical "TV Shows" fandom tag named "Stargate SG-1" + And I am logged in as a tag wrangler + When I go to the "Daniel Jackson" tag edit page + And I fill in "Fandoms" with "Stargate SG-1" + And I check "tag_canonical" + And I press "Save changes" + Then I should see "Tag was updated" + And the "Daniel Jackson" tag should be canonical + And the "Daniel Jackson" tag should be in the "Stargate SG-1" fandom + + Scenario: Assigning a fandom to a non-canonical character + Given the tag wrangling setup + And I have a canonical "TV Shows" fandom tag named "Stargate SG-1" + And I am logged in as a tag wrangler + When I go to the "Daniel Jackson" tag edit page + And I fill in "Fandoms" with "Stargate SG-1" + And I press "Save changes" + Then I should see "Tag was updated" + And the "Daniel Jackson" tag should not be canonical + And the "Daniel Jackson" tag should be in the "Stargate SG-1" fandom + + Scenario: Merging canonical and non-canonical character tags + Given the tag wrangling setup + And I have a canonical "TV Shows" fandom tag named "Stargate SG-1" + And I add the fandom "Stargate SG-1" to the character "Jack O'Neil" + And I am logged in as a tag wrangler + When I go to the "Jack O'Neil" tag edit page + And I fill in "Synonym of" with "Jack O'Neill" + And I press "Save changes" + And I follow "Jack O'Neill" + Then I should see "Stargate SG-1" + When I view the tag "Stargate SG-1" + Then I should see "Jack O'Neil" + And I should see "Jack O'Neill" + + Scenario Outline: Creating new non-canonical tags + Given I am logged in as a tag wrangler + And I go to the wrangling page for "wrangler" + When I follow "New Tag" + And I fill in "Name" with "MyNewTag" + And I choose + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "MyNewTag" tag should be a tag + And the "MyNewTag" tag should not be canonical + + Examples: + | type | + | "Fandom" | + | "Character" | + + Scenario Outline: Creating new canonical tags + Given I am logged in as a tag wrangler + And I go to the wrangling page for "wrangler" + When I follow "New Tag" + And I fill in "Name" with "MyNewTag" + And I choose + And I check "Canonical" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "MyNewTag" tag should be a tag + And the "MyNewTag" tag should be canonical + + Examples: + | type | + | "Fandom" | + | "Character" | + + Scenario: Trying to assign a non-canonical fandom to a character + Given the tag wrangling setup + And a non-canonical fandom "Stargate Atlantis" + And I have a canonical "TV Shows" fandom tag named "Stargate SG-1" + And I am logged in as a tag wrangler + When I go to the "Jack O'Neil" tag edit page + And I fill in "Fandoms" with "Stargate Atlantis" + And I press "Save changes" + Then I should see "Cannot add association to 'Stargate Atlantis':" + And I should see "Parent tag is not canonical." + And I should not see "Stargate Atlantis" within "form" + + Scenario: Assigning a fandom to a non-canonical relationship tag + Given the tag wrangling setup + And I have a canonical "TV Shows" fandom tag named "Stargate Atlantis" + And I am logged in as a tag wrangler + When I go to the "JackDaniel" tag edit page + And I fill in "Fandoms" with "Stargate Atlantis" + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "JackDaniel" + Then I should see "Stargate Atlantis" + + Scenario: Creating a canonical merger and adding characters to a non-canonical relationship + Given I have a canonical "TV Shows" fandom tag named "RWBY" + And a canonical character "Blake Belladonna" in fandom "RWBY" + And a canonical character "Yang Xiao Long" in fandom "RWBY" + And a non-canonical relationship "Bumbleby" + And I am logged in as a tag wrangler + When I go to the "Bumbleby" tag edit page + And I fill in "Synonym of" with "Blake/Yang" + And I fill in "Fandoms" with "RWBY" + And I fill in "Characters" with "Blake Belladonna, Yang Xiao Long" + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "RWBY" + And I should see "Blake/Yang" + And I should see "Blake Belladonna" + And I should see "Yang Xiao Long" + And the "Blake/Yang" tag should be canonical + + Scenario: Check sidebar links and pages for wrangling within a fandom + Given I have a canonical "TV Shows" fandom tag named "Stargate SG-1" + And a canonical character "Samantha Carter" in fandom "Stargate SG-1" + And a canonical character "Teal'c" in fandom "Stargate SG-1" + And a synonym "Tealc" of the tag "Teal'c" + And the tag wrangler "wrangler" with password "password" is wrangler of "Stargate SG-1" + And I post the work "Test Work" with fandom "Stargate SG-1" with character "Janet Fraiser" with second character "Apophis" + When I go to the "Apophis" tag edit page + And I check "Unwrangleable" + And I fill in "Fandoms" with "Stargate SG-1" + And I press "Save changes" + Then I should see "Tag was updated" + And the "Apophis" tag should be unwrangleable + When I go to the wrangling page for "wrangler" + And I follow "Stargate SG-1" + Then I should see "Wrangle Tags for Stargate SG-1" + When I follow "Characters (4)" + Then I should see "Wrangle Tags for Stargate SG-1" + And I should see "Showing All Character Tags" + And I should see "Apophis" + And I should see "Samantha Carter" + And I should see "Teal'c" + And I should see "Tealc" + When I follow "Canonical" + Then I should see "Showing Canonical Character Tags" + And I should see "Samantha Carter" + And I should see "Teal'c" + But I should not see "Tealc" + When I follow "Synonymous" + Then I should see "Showing Synonymous Character Tags" + And I should see "Teal'c" + And I should see "Tealc" within "tbody th" + And I should not see "Teal'c" within "tbody td" + And I should not see "Samantha Carter" + When I follow "Unwrangleable" + Then I should see "Showing Unwrangleable Character Tags" + And I should see "Apophis" + And I should not see "Samantha Carter" + When I follow "Unwrangled" + Then I should see "Showing Unwrangled Character Tags" + And I should see "Janet Fraiser" + And I should not see "Samantha Carter" + When I follow "Relationships (0)" + Then I should see "Wrangle Tags for Stargate SG-1" + And I should see "Showing All Relationship Tags" + When I follow "Freeforms (0)" + Then I should see "Wrangle Tags for Stargate SG-1" + And I should see "Showing All Freeform Tags" + When I follow "SubTags (0)" + Then I should see "Wrangle Tags for Stargate SG-1" + And I should see "Showing All Sub Tag Tags" + When I follow "Mergers (0)" + Then I should see "Wrangle Tags for Stargate SG-1" + And I should see "Showing All Merger Tags" + + Scenario: Wrangler has option to troubleshoot a work + + Given the work "Indexing Issues" + And I am logged in as a tag wrangler + When I view the work "Indexing Issues" + Then I should see "Troubleshoot" + + @javascript + Scenario: AO3-1698 Sign up for a fandom from the edit fandom page, + then from editing a child tag of a fandom + + Given a canonical fandom "'Allo 'Allo" + And a canonical fandom "From Eroica with Love" + And a canonical fandom "Cabin Pressure" + And a noncanonical relationship "Dorian/Martin" + + # I want to sign up from the edit page of an unassigned fandom + When I am logged in as a tag wrangler + And I edit the tag "'Allo 'Allo" + Then I should see "Sign Up" + When I follow "Sign Up" + Then I should see "Assign fandoms to yourself" + And I should see "'Allo 'Allo" within ".autocomplete .added" + When I press "Assign" + Then I should see "Wranglers were successfully assigned" + When I edit the tag "'Allo 'Allo" + Then I should not see "Sign Up" + And I should see the tag wrangler listed as an editor of the tag + + # I want to sign up from the edit page of a relationship that belongs to two unassigned fandoms + When I edit the tag "Dorian/Martin" + Then I should not see "Sign Up" + When I fill in "Fandoms" with "From Eroica with Love, Cabin Pressure" + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "Sign Up" + And I choose "Cabin Pressure" from the "Enter as many fandoms as you like." autocomplete + And I choose "From Eroica with Love" from the "Enter as many fandoms as you like." autocomplete + And I press "Assign" + Then I should see "Wranglers were successfully assigned" + When I edit the tag "From Eroica with Love" + Then I should not see "Sign Up" + And I should see the tag wrangler listed as an editor of the tag + When I edit the tag "Cabin Pressure" + Then I should not see "Sign Up" + And I should see the tag wrangler listed as an editor of the tag + + Scenario: A user can not see the troubleshoot button on a tag page + + Given a canonical fandom "Cowboy Bebop" + And I am logged in as a random user + When I view the tag "Cowboy Bebop" + Then I should not see "Troubleshoot" + + Scenario: A tag wrangler can see the troubleshoot button on a tag page + + Given a canonical fandom "Cowboy Bebop" + And the tag wrangler "lain" with password "lainnial" is wrangler of "Cowboy Bebop" + When I view the tag "Cowboy Bebop" + Then I should see "Troubleshoot" + + Scenario: An admin can see the troubleshoot button on a tag page + + Given a canonical fandom "Cowboy Bebop" + And I am logged in as a "tag_wrangling" admin + When I view the tag "Cowboy Bebop" + Then I should see "Troubleshoot" + + Scenario: Can simultaneously add a grandparent metatag as a direct metatag and remove the parent metatag + Given a canonical fandom "Grandparent" + And a canonical fandom "Parent" + And a canonical fandom "Child" + And "Grandparent" is a metatag of the fandom "Parent" + And "Parent" is a metatag of the fandom "Child" + And I am logged in as a random user + And I post the work "Oldest" with fandom "Grandparent" + And I post the work "Middle" with fandom "Parent" + And I post the work "Youngest" with fandom "Child" + And I am logged in as a tag wrangler + + When I edit the tag "Child" + And I check the 1st checkbox with id matching "MetaTag" + And I fill in "tag_meta_tag_string" with "Grandparent" + # Ensure a new cache key will be used + And it is currently 1 second from now + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Grandparent" within "#parent_MetaTag_associations_to_remove_checkboxes" + But I should not see "Parent" within "#parent_MetaTag_associations_to_remove_checkboxes" + + When I view the tag "Child" + Then I should see "Grandparent" within ".meta" + But I should not see "Parent" within ".meta" + + When I go to the works tagged "Grandparent" + Then I should see "Oldest" + And I should see "Middle" + And I should see "Youngest" + + When I go to the works tagged "Parent" + Then I should see "Middle" + But I should not see "Oldest" + And I should not see "Youngest" + + When I go to the works tagged "Child" + Then I should see "Youngest" + But I should not see "Oldest" + And I should not see "Middle" + + Scenario: No call to Redis when no action is taken + Given the tag wrangling setup + And I am logged in as a tag wrangler + Then no tag is scheduled for count update from now on + When I go to the wrangling page for "wrangler" + Then I should see "Wrangling Home" + And I should see "Characters by fandom (2)" + When I follow "Characters by fandom (2)" + Then I should see "Mass Wrangle New/Unwrangled Tags" + + Scenario: Subtags are listed in alphabetical order + Given a canonical freeform "Angst" + And a canonical freeform "Angstc" + And it is currently 1 second from now + And a canonical freeform "Angstb" + And it is currently 1 second from now + And a canonical freeform "Angsta" + And "Angst" is a metatag of the freeform "Angstc" + And it is currently 1 second from now + And "Angst" is a metatag of the freeform "Angstb" + And it is currently 1 second from now + And "Angst" is a metatag of the freeform "Angsta" + When I view the tag "Angst" + Then "Angsta" should appear before "Angstb" + And "Angstb" should appear before "Angstc" diff --git a/features/tags_and_wrangling/tag_wrangling_admin.feature b/features/tags_and_wrangling/tag_wrangling_admin.feature new file mode 100755 index 0000000..a7d9151 --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_admin.feature @@ -0,0 +1,172 @@ +@users @tag_wrangling @admin +Feature: Tag wrangling + + Scenario: Admin can rename a tag and it updates works and bookmarks. + + Given I am logged in as "audrey" with password "password" + And I post the work "Renoir's Boating Party" + And I bookmark the work "Renoir's Boating Party" with the tags "Amelie" + And I post the work "Luncheon" with fandom "Amelie" + # Visit the relevant pages to make sure the data gets cached. + And I go to audrey's bookmarks page + And I go to audrey's works page + And I go to the work "Luncheon" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "Amelie" + And I fill in "Synonym of" with "Amélie" + And I press "Save changes" + Then I should see "Amélie is considered the same as Amelie by the database" + And I should not see "Tag was successfully updated." + When I fill in "Name" with "Amélie" + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Amélie" + And I should not see "Amelie" + When I go to audrey's works page + Then I should not see "Amelie" + And I should see "Amélie" + When I go to the work "Luncheon" + Then I should not see "Amelie" + And I should see "Amélie" + When I go to audrey's bookmarks page + Then I should not see "Amelie" + And I should see "Amélie" + + Scenario: Admin can rename a tag using Eastern characters + + Given I am logged in as a "tag_wrangling" admin + And a fandom exists with name: "先生", canonical: false + When I edit the tag "先生" + And I fill in "Name" with "てりやき" + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "てりやき" + And I should not see "先生" + + Scenario: Tag wrangler cannot rename a tag using Eastern characters + + Given I am logged in as a tag wrangler + And a fandom exists with name: "先生", canonical: false + When I edit the tag "先生" + And I fill in "Name" with "てりやき" + And I press "Save changes" + Then I should not see "Tag was updated" + And I should see "Only changes to capitalization and diacritic marks are permitted" + + Scenario: Admin can remove a user's wrangling privileges from the manage users page (this will leave assignments intact) + + Given the tag wrangler "tangler" with password "wr@ngl3r" is wrangler of "Testing" + When I am logged in as a "tag_wrangling" admin + And I am on the manage users page + When I fill in "Name" with "tangler" + And I press "Find" + Then I should see "tangler" within "#admin_users_table" + When I uncheck the "tag_wrangler" role checkbox + And I press "Update" + Then I should see "User was successfully updated." + And "tangler" should not be a tag wrangler + And "Testing" should be assigned to the wrangler "tangler" + + Scenario: Admin can remove a user's wrangling assignments + + Given the tag wrangler "tangler" with password "wr@ngl3r" is wrangler of "Testing" + When I am logged in as a "tag_wrangling" admin + And I am on the wranglers page + And I follow "x" + Then I should see "Wranglers were successfully unassigned!" + And "Testing" should not be assigned to the wrangler "tangler" + When I edit the tag "Testing" + Then I should see "Sign Up" + + Scenario: Tag wrangling admins can download a wrangler's wrangled tags report CSV + + Given the tag wrangler "tangler" with password "wr@ngl3r" is wrangler of "Testing" + And I am logged in as a "tag_wrangling" admin + When I go to the wrangling page for "tangler" + Then I should see "Tags Wrangled (CSV)" + When I follow "Tags Wrangled (CSV)" + Then I should download a csv file with the header row "Name Last Updated Type Merger Fandoms Unwrangleable" + + Scenario Outline: Authorized admins have the tag wrangling item in the admin navbar + + Given I am logged in as a "" admin + Then I should see "Tag Wrangling" within "ul.admin.primary.navigation" + + Examples: + | role | + | superadmin | + | tag_wrangling | + + Scenario Outline: Unauthorized admins do not have the tag wrangling item in the admin navbar + + Given I am logged in as a "" admin + Then I should not see "Tag Wrangling" within "ul.admin.primary.navigation" + + Examples: + | role | + | board | + | board_assistants_team | + | communications | + | development_and_membership | + | docs | + | elections | + | legal | + | translation | + | support | + | policy_and_abuse | + | open_doors | + + Scenario Outline: Fully-authorized admins get the wrangling dashboard sidebar + + Given I am logged in as a "" admin + And basic tags + When I go to the tags page + Then I should see "Wrangling Tools" within "div#dashboard" + And I should see "Wranglers" within "div#dashboard" + And I should see "Search Tags" within "div#dashboard" + And I should see "New Tag" within "div#dashboard" + But I should not see "Wrangling Home" within "div#dashboard" + + Examples: + | role | + | superadmin | + | tag_wrangling | + + Scenario Outline: Read-authorized admins get a partial wrangling dashboard sidebar + + Given I am logged in as a "" admin + And basic tags + When I go to the tags page + Then I should see "Wrangling Tools" within "div#dashboard" + And I should see "Search Tags" within "div#dashboard" + But I should not see "Wranglers" within "div#dashboard" + And I should not see "New Tag" within "div#dashboard" + And I should not see "Wrangling Home" within "div#dashboard" + + Examples: + | role | + | policy_and_abuse | + + Scenario Outline: Unauthorized admins do not get the wrangling dashboard sidebar + + Given I am logged in as a "" admin + And basic tags + When I go to the tags page + Then I should not see "Wrangling Tools" + And I should not see "Wranglers" + And I should not see "Search Tags" + And I should not see "New Tag" + And I should not see "Wrangling Home" + + Examples: + | role | + | board | + | board_assistants_team | + | communications | + | development_and_membership | + | docs | + | elections | + | legal | + | translation | + | support | + | open_doors | diff --git a/features/tags_and_wrangling/tag_wrangling_characters.feature b/features/tags_and_wrangling/tag_wrangling_characters.feature new file mode 100755 index 0000000..6c9c2e3 --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_characters.feature @@ -0,0 +1,168 @@ +@tags @users @tag_wrangling @search + +Feature: Tag Wrangling - Characters + +@javascript +Scenario: character wrangling - syns, mergers, characters, autocompletes + + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + And basic tags + And a fandom exists with name: "Doctor Who", canonical: true + And a relationship exists with name: "First Doctor/TARDIS", canonical: true + And I am logged in as "Enigel" with password "wrangulate!" + + # create a new canonical character from tag wrangling interface + When I follow "Tag Wrangling" + And I follow "New Tag" + And I fill in "Name" with "The First Doctor" + And I choose "Character" + And I check "Canonical" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "Canonical" checkbox should be checked + And the "Canonical" checkbox should not be disabled + + # create a new non-canonical character from tag wrangling interface + When I follow "New Tag" + And I fill in "Name" with "The Doctor (1st)" + And I choose "Character" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "Canonical" checkbox should not be checked + And the "Canonical" checkbox should not be disabled + + # check those two created properly + When I am on the search tags page + And all indexing jobs have been run + And I fill in "Tag name" with "Doctor" + And I press "Search Tags" + # This part of the code is a hot mess. Capybara is returning the first instance of .canonical which contains + # 'First Doctor/TARDIS', which then leaves us unable to check for 'The First Doctor' as being canonical. + # I've changed the code for now to just check that 'The Doctor (1st) as being NON-Canonical + Then I should see "The First Doctor" + And I should see "The Doctor (1st)" + And I should not see "The Doctor (1st)" within "span.canonical" + + # assigning an existing merger to a non-canonical character + When I edit the tag "The Doctor (1st)" + And I fill in "Synonym of" with "The First Doctor" + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "Edit The First Doctor" + Then I should not see "Make tag non-canonical and unhook all associations" + + Given I am logged in as a "tag_wrangling" admin + When I edit the tag "The First Doctor" + Then I should see "Make tag non-canonical and unhook all associations" + And I should see "The Doctor (1st)" + And the "Canonical" checkbox should be checked and disabled + + # creating a new canonical character by renaming + When I fill in "Synonym of" with "First Doctor" + And I press "Save changes" + Then I should see "Tag was updated" + And I should not see "Synonyms" + When I follow "Edit First Doctor" + + # creating non-canonical characters from work posting + When I am logged in as "Enigel" with password "wrangulate!" + And I go to the new work page + And I fill in the basic work information for "Silliness" + And I fill in "Fandoms" with "Doctor Who" + And I fill in "Characters" with "1st Doctor, One" + And I press "Post" + Then I should see "Work was successfully posted." + + # editing non-canonical character in order to syn it to existing canonical merger + When I follow "1st Doctor" + And I follow "Edit" + And I enter "First" in the "Synonym of" autocomplete field + Then I should see "First Doctor" in the autocomplete + But I should not see "The First Doctor" in the autocomplete + When I choose "First Doctor" from the "Synonym of" autocomplete + And I choose "Doctor Who" from the "Fandoms" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + + # adding a non-canonical synonym to a canonical, fandom should be copied + When I follow "Edit First Doctor" + Then I should see "Doctor Who" + And the "Canonical" checkbox should be disabled + And all indexing jobs have been run + When I choose "One" from the "tag_merger_string_autocomplete" autocomplete + And I fill in "Relationships" with "First Doctor/TARDIS" + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "One" + And I should see "First Doctor/TARDIS" + When I follow "One" + Then I should see "Doctor Who" + But I should not see "First Doctor/TARDIS" within ".tags" + + # metatags and subtags, transference thereof to a new canonical by an admin + When I follow "Edit First Doctor" + And I fill in "MetaTags" with "The Doctor (DW)" + And I press "Save changes" + Then I should see "Invalid metatag 'The Doctor (DW)':" + And I should see "Metatag does not exist." + And I should not see "The Doctor (DW)" within "form" + When I follow "New Tag" + And I fill in "Name" with "The Doctor (DW)" + And I check "Canonical" + And I choose "Character" + And I press "Create Tag" + And I choose "First Doctor" from the "SubTags" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "First Doctor" + Then I should see "The Doctor (DW)" + When I follow "New Tag" + And I fill in "Name" with "John Smith" + And I choose "Character" + And I check "Canonical" + And I press "Create Tag" + And I fill in "MetaTags" with "First Doctor" + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "First Doctor" + Then I should see "John Smith" + And I should see "The Doctor" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "First Doctor" + And I fill in "Synonym of" with "First Doctor (DW)" + And I press "Save changes" + Then I should see "Tag was updated" + And I should not see "John Smith" + And I should not see "The Doctor (1st)" + And I should not see "1st Doctor" + And I should not see "One" + And I should not see "The Doctor (DW)" + When I follow "Edit First Doctor (DW)" + Then I should see "John Smith" + And I should see "First Doctor" within "div#child_Merger_associations_to_remove_checkboxes" + And I should see "The Doctor (1st)" + And I should see "1st Doctor" + And I should see "One" within "div#child_Merger_associations_to_remove_checkboxes" + And I should see "The Doctor (DW)" + + # trying to syn a non-canonical to another non-canonical + When I am logged in as "Enigel" with password "wrangulate!" + And I edit the tag "First Doctor" + And I follow "New Tag" + And I fill in "Name" with "Eleventh Doctor" + And I choose "Character" + And I press "Create Tag" + And I follow "New Tag" + And I fill in "Name" with "Eleven" + And I choose "Character" + And I press "Create Tag" + And I fill in "Synonym of" with "Eleventh Doctor" + And I press "Save changes" + Then I should see "Eleventh Doctor is not a canonical tag. Please make it canonical before adding synonyms to it." + + # trying to syn a non-canonical to a canonical of a different category + When I fill in "Synonym of" with "Doctor Who" + And I press "Save changes" + Then I should see "Doctor Who is a fandom. Synonyms must belong to the same category." diff --git a/features/tags_and_wrangling/tag_wrangling_fandoms.feature b/features/tags_and_wrangling/tag_wrangling_fandoms.feature new file mode 100755 index 0000000..a440ccf --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_fandoms.feature @@ -0,0 +1,215 @@ +@tags @users @tag_wrangling + +Feature: Tag Wrangling - Fandoms + +@javascript +Scenario: fandoms wrangling - syns, mergers, autocompletes, metatags + + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + And basic tags + And a media exists with name: "TV Shows", canonical: true + And a character exists with name: "Neal Caffrey", canonical: true + And I am logged in as "Enigel" with password "wrangulate!" + + # create a new canonical fandom from tag wrangling interface + When I follow "Tag Wrangling" + And I follow "New Tag" + And I fill in "Name" with "Stargate SG-1" + And I choose "Fandom" + And I check "Canonical" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "Canonical" checkbox should be checked + And the "Canonical" checkbox should not be disabled + + # create a new non-canonical fandom from tag wrangling interface + When I follow "New Tag" + And I fill in "Name" with "SGA" + And I choose "Fandom" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "Canonical" checkbox should not be checked + And the "Canonical" checkbox should not be disabled + + # creating a new canonical fandom by synning + When I fill in "Synonym of" with "Stargate Atlantis" + And I press "Save changes" + Then I should see "Tag was updated" + And I should not see "Synonyms" + When I follow "Edit Stargate Atlantis" + And I should see "SGA" + Then the "Canonical" checkbox should be checked and disabled + + # creating non-canonical fandoms from work posting + When I go to the new work page + And I fill in the basic work information for "Silliness" + And I fill in "Fandoms" with "SG1, the whole Stargate franchise, Stargates SG-1" + And I press "Post" + Then I should see "Work was successfully posted." + + # editing non-canonical fandom in order to syn it to existing canonical merger + When I follow "SG1" + And I follow "Edit" + And I enter "Stargate" in the "Synonym of" autocomplete field + Then I should see "Stargate Atlantis" in the autocomplete + And I should see "Stargate SG-1" in the autocomplete + When I choose "Stargate SG-1" from the "Synonym of" autocomplete + And I choose "TV Shows" from the "tag_media_string_autocomplete" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + + # adding a non-canonical synonym to a canonical, fandom should be copied + When I follow "Edit Stargate SG-1" + Then I should see "TV Shows" + And I should see "SG1" + And the "Canonical" checkbox should be disabled + And all indexing jobs have been run + When I enter "The whole sta" in the "tag_merger_string_autocomplete" autocomplete field + And I should see "the whole Stargate franchise" in the autocomplete + And I should not see "Stargate SG-1" in the autocomplete + And I should not see "Stargates SG-1" in the autocomplete + When I enter "Stargate" in the "tag_merger_string_autocomplete" autocomplete field + Then I should see "Stargates SG-1" in the autocomplete + And I should see "the whole Stargate franchise" in the autocomplete + And I should not see "Stargate SG-1" in the autocomplete + When I choose "Stargates SG-1" from the "tag_merger_string_autocomplete" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Stargates SG-1" + When I follow "Stargates SG-1" + Then I should see "TV Shows" + + # metatags and subtags, transference thereof to a new canonical by an admin + When I edit the tag "Stargate Atlantis" + And I fill in "MetaTags" with "Stargate Franchise" + And I press "Save changes" + Then I should see "Invalid metatag 'Stargate Franchise':" + And I should see "Metatag does not exist." + And I should not see "Stargate Franchise" within "form" + When I follow "New Tag" + And I fill in "Name" with "Stargate Franchise" + And I check "Canonical" + And I choose "Fandom" + And I press "Create Tag" + And I choose "TV Shows" from the "Add:" autocomplete + And I choose "Stargate Atlantis" from the "Add SubTags" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "TV Shows" + And the "Canonical" checkbox should be checked + When I follow "Stargate Atlantis" + Then I should see "Stargate Franchise" within "div#parent_MetaTag_associations_to_remove_checkboxes" + When I edit the tag "Stargate SG-1" + And I choose "Stargate Franchise" from the "Add MetaTags" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "New Tag" + And I fill in "Name" with "Stargate SG-1: Ark of Truth" + And I check "Canonical" + And I choose "Fandom" + And I press "Create Tag" + And I fill in "MetaTags" with "Stargate SG-1" + And I press "Save changes" + Then I should see "Tag was updated" + When I edit the tag "Stargate SG-1" + Then I should see "Stargate SG-1: Ark of Truth" within "div#child_SubTag_associations_to_remove_checkboxes" + And I should see "Stargate Franchise" within "div#parent_MetaTag_associations_to_remove_checkboxes" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "Stargate SG-1" + And I fill in "Synonym of" with "Stargate SG-1: Greatest Show in the Universe" + And I press "Save changes" + Then I should see "Tag was updated" + And I should not see "Stargate SG-1: Ark of Truth" + And I should not see "Stargates SG-1" + And I should not see "SG1" + And I should not see "Stargate Franchise" + When I follow "Edit Stargate SG-1: Greatest Show in the Universe" + Then I should see "Stargate SG-1: Ark of Truth" + And I should see "Stargates SG-1" + And I should see "SG1" + And I should see "Stargate Franchise" + + # trying to syn a non-canonical to another non-canonical + When I am logged in as "Enigel" with password "wrangulate!" + And I edit the tag "Stargate SG-1: Greatest Show in the Universe" + And I follow "New Tag" + And I fill in "Name" with "White Collar" + And I choose "Fandom" + And I press "Create Tag" + And I follow "New Tag" + And I fill in "Name" with "WhiCo" + And I choose "Fandom" + And I press "Create Tag" + And I fill in "Synonym of" with "White Collar" + And I press "Save changes" + Then I should see "White Collar is not a canonical tag. Please make it canonical before adding synonyms to it." + + # trying to syn a non-canonical to a canonical of a different category + When I fill in "Synonym of" with "Neal Caffrey" + And I press "Save changes" + Then I should see "Neal Caffrey is a character. Synonyms must belong to the same category." + +Scenario: Checking the media pages + + Given basic tags + And a media exists with name: "TV Shows", canonical: true + And a media exists with name: "Video Games", canonical: true + And a media exists with name: "Books", canonical: true + And a canonical fandom "Stargate" + And a canonical fandom "Lord of the Rings" + And a canonical fandom "Final Fantasy" + And a canonical fandom "Yuletide RPF" + And a canonical fandom "A weird thing" + And a canonical fandom "Be another thing" + And a canonical fandom "Be a second B fandom" + And a canonical fandom "Can sort alphabetically" + And the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + When I am logged in as "Enigel" with password "wrangulate!" + And I edit the tag "Stargate" + And I fill in "tag_media_string" with "TV Shows" + And I press "Save changes" + Then I should see "Tag was updated" + When I edit the tag "Lord of the Rings" + And I fill in "tag_media_string" with "Books" + And I press "Save changes" + Then I should see "Tag was updated" + When I edit the tag "Final Fantasy" + And I fill in "tag_media_string" with "Video Games" + And I press "Save changes" + Then I should see "Tag was updated" + + Given I post the work "Test" with fandom "Yuletide RPF" + And I post the work "Test Ring" with fandom "Lord of the Rings" + When I go to the fandoms page + Then I should see "Fandoms" within "h2" + And I should see "Books" within "div#main .media" + And I should see "TV Shows" within "div#main .media" + And I should see "Video Games" within "div#main .media" + And I should see "Uncategorized Fandoms" within "div#main .media" + And I should see "Yuletide RPF" within "div#main .media" + + # Tags will show up if there's at least a work + When I follow "Books" + Then I should see "Fandoms > Books" + And I should not see "No fandoms found" + And I should see "Lord of the Rings" + And I should not see "Stargate" + And I should not see "Yuletide RPF" + + # Tags will not show up if there are no works + When I go to the fandoms page + And I follow "Video Games" + Then I should see "No fandoms found" + And I should not see "Final Fantasy" + + When I go to the media page + Then I should see "Fandoms" within "h2" + When I follow "Uncategorized Fandoms" + Then I should see "B C N W Y" within ".alphabet" + And I should see "A weird thing" within "#letter-W .tags" + And I should see "Be a second B fandom" within "#letter-B .tags" + And I should see "Be another thing" within "#letter-B .tags" diff --git a/features/tags_and_wrangling/tag_wrangling_freeforms.feature b/features/tags_and_wrangling/tag_wrangling_freeforms.feature new file mode 100755 index 0000000..f1a8786 --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_freeforms.feature @@ -0,0 +1,130 @@ +@tags @users @tag_wrangling + +Feature: Tag Wrangling - Freeforms + +@javascript +Scenario: freeforms wrangling - syns, mergers, autocompletes, metatags + + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + And basic tags + And I am logged in as "Enigel" with password "wrangulate!" + And I follow "Tag Wrangling" + + # create a new canonical freeform from tag wrangling interface + When I follow "New Tag" + And I fill in "Name" with "Alternate Universe Pirates" + And I choose "Additional Tag" + And I check "Canonical" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "Canonical" checkbox should be checked + And the "Canonical" checkbox should not be disabled + + # create a new non-canonical freeform from tag wrangling interface + When I follow "New Tag" + And I fill in "Name" with "Pirates! in Spaaaaace! AU" + And I choose "Additional Tag" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "Canonical" checkbox should not be checked + And the "Canonical" checkbox should not be disabled + + # creating a new canonical freeform by synning + When I fill in "Synonym of" with "Alternate Universe Space Pirates" + And I press "Save changes" + Then I should see "Tag was updated" + And I should not see "Synonyms" + When I follow "Edit Alternate Universe Space Pirates" + And I should see "Pirates! in Spaaaaace! AU" + And the "Canonical" checkbox should be checked and disabled + + # creating non-canonical freeforms from work posting + When I go to the new work page + And I fill in the basic work information for "Silliness" + And I fill in "Fandoms" with "Torchwood" + And I fill in "Additional Tags" with "Pirate AU, Arrr-verse" + And I press "Post" + Then I should see "Work was successfully posted." + + # editing non-canonical freeform in order to syn it to existing canonical merger + When I follow "Pirate AU" + And I follow "Edit" + And I choose "Alternate Universe Pirates" from the "Synonym of" autocomplete + And I choose "No Fandom" from the "tag_fandom_string_autocomplete" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + + # adding a non-canonical synonym to a canonical, fandom should be copied + When I follow "Edit Alternate Universe Pirates" + Then I should see "No Fandom" + And I should see "Pirate AU" + And the "Canonical" checkbox should be disabled + And all indexing jobs have been run + When I choose "Arrr-verse" from the "tag_merger_string_autocomplete" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Arrr-verse" + When I follow "Arrr-verse" + Then I should see "No Fandom" + + # metatags and subtags, transference thereof to a new canonical by an admin + When I follow "Edit Alternate Universe Pirates" + And I fill in "MetaTags" with "Alternate Universe" + And I press "Save changes" + Then I should see "Invalid metatag 'Alternate Universe':" + And I should see "Metatag does not exist." + And I should not see "Alternate Universe" within "form" + When I follow "New Tag" + And I fill in "Name" with "Alternate Universe" + And I check "Canonical" + And I choose "Additional Tag" + And I press "Create Tag" + And I fill in "Fandoms" with "No Fandom" + And I choose "Alternate Universe Pirates" from the "SubTags" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "No Fandom" + And the "Canonical" checkbox should be checked + When I follow "Alternate Universe Pirates" + Then I should see "Alternate Universe" within "div#parent_MetaTag_associations_to_remove_checkboxes" + When I edit the tag "Alternate Universe Space Pirates" + And I choose "Alternate Universe Pirates" from the "MetaTags" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "Alternate Universe Pirates" + Then I should see "Alternate Universe Space Pirates" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "Alternate Universe Pirates" + And I fill in "Synonym of" with "Alternate Universe Pirrrates" + And I press "Save changes" + Then I should see "Tag was updated" + And I should not see "Alternate Universe Space Pirates" + And I should not see "Pirate AU" + And I should not see "Arrr-verse" + When I follow "Edit Alternate Universe Pirrrates" + Then I should see "Alternate Universe Space Pirates" + And I should see "Pirate AU" + And I should see "Arrr-verse" + And I should see "Alternate Universe Pirates" + + # trying to syn a non-canonical to another non-canonical + When I am logged in as "Enigel" with password "wrangulate!" + And I edit the tag "Alternate Universe Pirates" + And I follow "New Tag" + And I fill in "Name" with "Drabble" + And I choose "Additional Tag" + And I press "Create Tag" + And I follow "New Tag" + And I fill in "Name" with "100 words" + And I choose "Additional Tag" + And I press "Create Tag" + And I fill in "Synonym of" with "Drabble" + And I press "Save changes" + Then I should see "Drabble is not a canonical tag. Please make it canonical before adding synonyms to it." + + # trying to syn a non-canonical to a canonical of a different category + When I fill in "Synonym of" with "No Fandom" + And I press "Save changes" + Then I should see "No Fandom is a fandom. Synonyms must belong to the same category." diff --git a/features/tags_and_wrangling/tag_wrangling_media.feature b/features/tags_and_wrangling/tag_wrangling_media.feature new file mode 100755 index 0000000..cd3580c --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_media.feature @@ -0,0 +1,208 @@ +@tags @tag_wrangling +Feature: Media tags + + Scenario: Wranglers do not have the option to create media tags or change + other tags to media tags + Given I am logged in as a tag wrangler + When I go to the new tag page + Then I should not see "Media" within "#new_tag" + When I fill in "Name" with "Not A Media Tag" + And I choose "Fandom" + And I press "Create Tag" + Then I should see "Tag was successfully created." + And "Fandom" should be selected within "tag_type" + # Make sure we can't see admin-only option + And "Media" should not be an option within "tag_type" + + Scenario: Admins can create media tags and then make them canonical + Given I am logged in as a "tag_wrangling" admin + When I go to the new tag page + And I fill in "Name" with "New Media 1" + And I choose "Media" + And I press "Create Tag" + Then I should see "Tag was successfully created." + And "Media" should be selected within "tag_type" + # Make sure we can see regular wrangling option + And "Fandom" should be an option within "tag_type" + When I check "Canonical" + And I press "Save changes" + Then I should see "Tag was updated." + And the "New Media 1" tag should be canonical + And the "New Media 1" tag should be a "Media" tag + + Scenario: Admins can create canonical media tags + Given I am logged in as a "tag_wrangling" admin + When I go to the new tag page + And I fill in "Name" with "New Media 2" + And I check "Canonical" + And I choose "Media" + And I press "Create Tag" + Then I should see "Tag was successfully created." + And the "New Media 2" tag should be canonical + And the "New Media 2" tag should be a "Media" tag + + Scenario: Admins can recategorize tags into media tags + Given a non-canonical fandom "Ambiguous Tag" + And I am logged in as a "tag_wrangling" admin + When I go to the "Ambiguous Tag" tag edit page + And I select "Media" from "tag_type" + And I press "Save changes" + Then I should see "Tag was updated." + And the "Ambiguous Tag" tag should be a "Media" tag + + Scenario: Admins can recategorize media tags into other types + Given a non-canonical media "Not A Media Anymore" + And I am logged in as a "tag_wrangling" admin + When I go to the "Not A Media Anymore" tag edit page + And I select "Relationship" from "tag_type" + And I press "Save changes" + Then I should see "Tag was updated." + And the "Not A Media Anymore" tag should be a "Relationship" tag + + Scenario: New canonical media tags are added to the Fandoms header menu + # Make sure the old state gets cached + When I go to the homepage + Then I should not see "New Media 3" within "#header .primary .dropdown .menu" + When I create the canonical media tag "New Media 3" + And I am logged out + When I go to the homepage + Then I should see "New Media 3" within "#header .primary .dropdown .menu" + When I follow "New Media 3" within "#header .primary .dropdown .menu" + Then I should see "Fandoms > New Media 3" + And I should see "No fandoms found" + + Scenario: New canonical media tags are added to the Fandoms list on the homepage + # Make sure the old state gets cached + Given I go to the homepage + Then I should not see "New Media 3b" within "#main .splash .browse" + When I create the canonical media tag "New Media 3b" + And I am logged out + When I go to the homepage + Then I should see "New Media 3b" within "#main .splash .browse" + When I follow "New Media 3b" within "#main .splash .browse" + Then I should see "Fandoms > New Media 3b" + And I should see "No fandoms found" + + Scenario: New canonical media tags are added to the Fandoms page + Given I create the canonical media tag "New Media 4" + When I go to the fandoms page + Then I should see "New Media 4" within "#main .media" + When I follow "New Media 4" within "#main .media" + Then I should see "Fandoms > New Media 4" + And I should see "No fandoms found" + + Scenario: New non-canonical media tags are not added to the Fandoms header menu and the Fandoms list on the homepage + # Make sure the old state gets cached + When I go to the homepage + Then I should not see "MCYT" within "#header .primary .dropdown .menu" + And I should not see "MCYT" within "#main .splash .browse" + When I create the non-canonical media tag "MCYT" + And I am logged out + When I go to the homepage + Then I should not see "MCYT" within "#header .primary .dropdown .menu" + And I should not see "MCYT" within "#main .splash .browse" + + Scenario: New non-canonical media tags are not added to the Fandoms page + Given I create the non-canonical media tag "MCYT" + When I go to the fandoms page + Then I should not see "MCYT" within "#main .media" + + Scenario: Canonizing a media tag adds it to the Fandoms header menu and the Fandoms list on the homepage + # Make sure the old state gets cached + Given a non-canonical media "MCYT" + When I go to the homepage + Then I should not see "MCYT" within "#header .primary .dropdown .menu" + And I should not see "MCYT" within "#main .splash .browse" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "MCYT" + And I check "Canonical" + And I press "Save changes" + Then I should see "Tag was updated." + When I am logged out + And I go to the homepage + Then I should see "MCYT" within "#header .primary .dropdown .menu" + And I should see "MCYT" within "#main .splash .browse" + + Scenario: Decanonizing a media tag removes it from to the Fandoms header menu and the Fandoms list on the homepage + Given a canonical media "MCYEET" + # Make sure the old state gets cached + And I go to the homepage + Then I should see "MCYEET" within "#header .primary .dropdown .menu" + And I should see "MCYEET" within "#main .splash .browse" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "MCYEET" + And I uncheck "Canonical" + And I press "Save changes" + Then I should see "Tag was updated." + When I am logged out + And I go to the homepage + Then I should not see "MCYEET" within "#header .primary .dropdown .menu" + And I should not see "MCYEET" within "#main .splash .browse" + + Scenario: Recategorizing a tag as media tag adds it to the Fandoms header menu and the Fandoms list on the homepage + # Make sure the old state gets cached + When I go to the homepage + Then I should not see "Yet Another Media" within "#header .primary .dropdown .menu" + And I should not see "Yet Another Media" within "#main .splash .browse" + When I recategorize the "Yet Another Media" fandom as a "Media" tag + And I am logged out + When I go to the homepage + Then I should see "Yet Another Media" within "#header .primary .dropdown .menu" + And I should see "Yet Another Media" within "#main .splash .browse" + + Scenario: Recategorizing a media tag removes it from to the Fandoms header menu and the Fandoms list on the homepage + Given a canonical media "Not a medium" + # Make sure the old state gets cached + And I go to the homepage + Then I should see "Not a medium" within "#header .primary .dropdown .menu" + And I should see "Not a medium" within "#main .splash .browse" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "Not a medium" + And I uncheck "Canonical" + And I press "Save changes" + Then I should see "Tag was updated." + When I edit the tag "Not a medium" + And I select "Character" from "tag_type" + And I press "Save changes" + Then I should see "Tag was updated." + And the "Not a medium" tag should be a "Character" tag + When I am logged out + And I go to the homepage + Then I should not see "Not a medium" within "#header .primary .dropdown .menu" + And I should not see "Not a medium" within "#main .splash .browse" + + Scenario: Renaming a media tag as admin changes it in the Fandoms header menu and the Fandoms list on the homepage + Given a canonical media "New Mediia Tag" + # Make sure the old state gets cached + And I go to the homepage + Then I should see "New Mediia Tag" within "#header .primary .dropdown .menu" + And I should see "New Mediia Tag" within "#main .splash .browse" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "New Mediia Tag" + And I fill in "Name" with "New Media Tag" + And I press "Save changes" + Then I should see "Tag was updated." + When I am logged out + And I go to the homepage + Then I should see "New Media Tag" within "#header .primary .dropdown .menu" + And I should see "New Media Tag" within "#main .splash .browse" + + @javascript + Scenario: Wranglers can add media tags to fandoms and fandoms to media tags + Given a canonical media "Big Media" + And a canonical fandom "Great Fandom" + And a canonical fandom "Greater Fandom" + And I am logged in as a tag wrangler + And I post the work "Some work" with fandom "Great Fandom" + And I post the work "Some other work" with fandom "Greater Fandom" + When I edit the tag "Great Fandom" + And I choose "Big Media" from the "tag_media_string_autocomplete" autocomplete + And I press "Save changes" + Then I should see "Tag was updated." + When I edit the tag "Big Media" + And I choose "Greater Fandom" from the "tag_fandom_string_autocomplete" autocomplete + And I press "Save changes" + Then I should see "Tag was updated." + When I go to the "Big Media" fandoms page + Then I should see "Great Fandom" + And I should see "Greater Fandom" diff --git a/features/tags_and_wrangling/tag_wrangling_more.feature b/features/tags_and_wrangling/tag_wrangling_more.feature new file mode 100755 index 0000000..242e2ff --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_more.feature @@ -0,0 +1,396 @@ +@tags @tag_wrangling +Feature: Tag wrangling: assigning wranglers, using the filters on the Wranglers page + + Scenario: Log in as a tag wrangler and see wrangler pages. + View new tags in your fandoms + Given a media exists with name: "TV Shows", canonical: true + And a canonical fandom "first fandom" + And a canonical character "Person A" + And a canonical fandom "Ghost Soup" + And a non-canonical fandom "second fandom" + And the following activated tag wranglers exist + | login | password | + | Enigel | wrangulator | + | dizmo | wrangulator | + + # accessing tag wrangling pages + When I am logged in as "dizmo" with password "wrangulator" + And I follow "Tag Wrangling" + Then I should see "Wrangling Home" + And I should not see "first fandom" + When I follow "Wranglers" + Then I should see "Tag Wrangling Assignments" + And I should see "first fandom" + When I view the tag "first fandom" + Then I should see "Edit" + When I follow "Edit" within ".header" + Then I should see "Edit first fandom Tag" + + # assigning media to a fandom + When I fill in "tag[media_string]" with "TV Shows" + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "Tag Wrangling" + Then I should see "Wrangling Home" + And I should not see "first fandom" + When I follow "Wranglers" + Then I should see "Tag Wrangling Assignments" + And I should see "first fandom" + + # assigning a fandom to oneself + When I fill in "tag_fandom_string" with "first fandom" + And I press "Assign" + And I follow "Wrangling Home" + And I follow "Wranglers" + Then I should see "first fandom" + And I should see "dizmo" within "ul.wranglers" + Given I add the fandom "first fandom" to the character "Person A" + + # checking that wrangling home shows unfilterables + When I follow "Wrangling Home" + Then I should see "first fandom" + And I should see "Unfilterable" + When I follow "first fandom" + Then I should see "Wrangle Tags for first fandom" + And I should see "Characters (1)" + + When I log out + And I am logged in as "Enigel" with password "wrangulator" + And I follow "Tag Wrangling" + + # assigning another wrangler to a fandom + When I follow "Wranglers" + And I fill in "fandom_string" with "Ghost" + And I press "Filter" + Then I should see "Ghost Soup" + And I should not see "first fandom" + When I select "dizmo" from the "Ghost Soup" wrangling assigment dropdown + And I press "Assign" + Then I should see "Wranglers were successfully assigned" + + # the filters on the Wranglers page + When I select "TV Shows" from "media_id" + And I fill in "fandom_string" with "" + And I press "Filter" + Then "TV Shows" should be selected within "media_id" + And I should see "first fandom" + And I should not see "second fandom" + When I select "dizmo" from "wrangler_id" + And I press "Filter" + Then I should see "first fandom" + And I should not see "Ghost Soup" + When I select "" from "media_id" + And I press "Filter" + Then "dizmo" should be selected within "wrangler_id" + And I should see "Ghost Soup" + And I should see "first fandom" + + Scenario: Wrangler can remove self from a fandom + + Given the tag wrangler "tangler" with password "wr@ngl3r" is wrangler of "Testing" + And I am logged in as "tangler" with password "wr@ngl3r" + When I am on the wranglers page + And I follow "x" + Then I should see "Wranglers were successfully unassigned!" + And "Testing" should not be assigned to the wrangler "tangler" + When I edit the tag "Testing" + Then I should see "Sign Up" + + Scenario: Wrangler can remove another wrangler from a fandom + + Given the tag wrangler "tangler" with password "wr@ngl3r" is wrangler of "Testing" + And the following activated tag wrangler exists + | login | + | wranglerette | + When I am logged in as "wranglerette" + And I am on the wranglers page + And I follow "x" + Then I should see "Wranglers were successfully unassigned!" + And "Testing" should not be assigned to the wrangler "tangler" + When I edit the tag "Testing" + Then I should see "Sign Up" + + Scenario: Updating multiple tags works. + Given a canonical fandom "Cowboy Bebop" + And a noncanonical freeform "Spike Spiegel is a sweetie" + And a noncanonical freeform "Jet Black is a sweetie" + And I am logged in as a random user + And I post the work "Brain Scratch" with fandom "Cowboy Bebop" with freeform "Spike Spiegel is a sweetie" + And I post the work "Asteroid Blues" with fandom "Cowboy Bebop" with freeform "Jet Black is a sweetie" + When the tag wrangler "lain" with password "lainnial" is wrangler of "Cowboy Bebop" + And I follow "Tag Wrangling" + And I follow "2" + And I fill in "Wrangle to Fandom(s)" with "Cowboy Bebop" + And I check the mass wrangling option for "Spike Spiegel is a sweetie" + And I check the mass wrangling option for "Jet Black is a sweetie" + And I press "Wrangle" + Then I should see "The following tags were successfully wrangled to Cowboy Bebop: Spike Spiegel is a sweetie, Jet Black is a sweetie" + + Scenario: Updating multiple tags works and set them as canonical + Given the following typed tags exists + | name | type | canonical | + | Cowboy Bebop | Fandom | true | + | Faye Valentine is a sweetie | Freeform | false | + | Ed is a sweetie | Freeform | false | + And I am logged in as a random user + And I post the work "Asteroid Blues" with fandom "Cowboy Bebop" with freeform "Ed is a sweetie" + And I post the work "Honky Tonk Women" with fandom "Cowboy Bebop" with freeform "Faye Valentine is a sweetie" + When the tag wrangler "lain" with password "lainnial" is wrangler of "Cowboy Bebop" + And I follow "Tag Wrangling" + And I follow "2" + And I fill in "fandom_string" with "Cowboy Bebop" + And I check the mass wrangling option for "Faye Valentine is a sweetie" + And I check the mass wrangling option for "Ed is a sweetie" + And I check the canonical option for the tag "Faye Valentine is a sweetie" + And I check the canonical option for the tag "Ed is a sweetie" + And I press "Wrangle" + Then I should see "The following tags were successfully wrangled to Cowboy Bebop: Faye Valentine is a sweetie, Ed is a sweetie" + And the "Faye Valentine is a sweetie" tag should be canonical + And the "Ed is a sweetie" tag should be canonical + + Scenario: Mass wrangling in the fandoms bins + Given I am logged in as a tag wrangler + And a media exists with name: "Anime & Manga", canonical: true + And the following typed tags exists + | name | type | canonical | + | Cowboy Bebop | Fandom | true | + And I post the work "Honky Tonk Women" with fandom "Cowboy Bebop" + And all indexing jobs have been run + When I go to the fandom mass bin + And I check the wrangling option for "Cowboy Bebop" + And I select "Anime & Manga" from "Wrangle to Media" + And I press "Wrangle" + Then I should not see "Cowboy Bebop" + + Scenario: A relationship can't be mass wrangled into a fandom that isn't a + canonical tag + Given I am logged in as a tag wrangler + And the following typed tags exists + | name | type | canonical | + | Toby Daye/Tybalt | Relationship | true | + | October Daye Series - Seanan McGuire | Fandom | false | + And I post the work "Honky Tonk Women" with fandom "October Daye Series - Seanan McGuire" with relationship "Toby Daye/Tybalt" + And all indexing jobs have been run + When I go to the relationship mass bin + And I check the wrangling option for "Toby Daye/Tybalt" + And I fill in "Wrangle to Fandom(s)" with "October Daye Series - Seanan McGuire" + And I press "Wrangle" + Then I should see "The following names are not canonical fandoms: October Daye Series - Seanan McGuire." + + Scenario: A relationship can be mass wrangled into a fandom that is a + canonical tag + Given I am logged in as a tag wrangler + And the following typed tags exists + | name | type | canonical | + | Toby Daye/Tybalt | Relationship | true | + | October Daye Series - Seanan McGuire | Fandom | true | + And I post the work "Honky Tonk Women" with fandom "October Daye Series - Seanan McGuire" with relationship "Toby Daye/Tybalt" + And all indexing jobs have been run + When I go to the relationship mass bin + And I check the wrangling option for "Toby Daye/Tybalt" + And I fill in "Wrangle to Fandom(s)" with "October Daye Series - Seanan McGuire" + And I press "Wrangle" + Then I should see "The following tags were successfully wrangled to October Daye Series - Seanan McGuire: Toby Daye/Tybalt" + + Scenario: A wrangler can make tags canonical while mass wrangling + Given I am logged in as a tag wrangler + And the following typed tags exists + | name | type | canonical | + | Cowboy Bebop | Fandom | true | + | Faye Valentine | Character | false | + | Ed | Character | false | + And I post the work "Honky Tonk Women" with fandom "Cowboy Bebop" with character "Faye Valentine" with second character "Ed" + And all indexing jobs have been run + When I go to the character mass bin + And I fill in "Wrangle to Fandom(s)" with "Cowboy Bebop" + And I check the canonical option for the tag "Faye Valentine" + And I check the canonical option for the tag "Ed" + And I press "Wrangle" + Then I should see "The following tags were successfully made canonical: Faye Valentine, Ed" + + Scenario: Banned tags can only be viewed by an admin + Given the following typed tags exists + | name | type | + | Cowboy Bebop | Banned | + When I am logged in as a random user + And I view the tag "Cowboy Bebop" + Then I should see "Sorry, you don't have permission to access the page you were trying to reach." + When I am logged in as a "tag_wrangling" admin + And I view the tag "Cowboy Bebop" + Then I should not see "Please log in as an admin" + And I should see "Cowboy Bebop" + + Scenario: Synning a fandom to a canonical fandom moves its unwrangled tags to the canonical's unwrangled bins; de-synning takes them out. + Given the tag wrangler "krebbs" with password "southfork" is wrangler of "Canonical Fandom" + And I post the work "Populating My Syn Fandom" with fandom "Syn Fandom" with character "Syn Fandom Character" with freeform "Syn Fandom Freeform" with relationship "Syn Fandom Relationship" + When I syn the tag "Syn Fandom" to "Canonical Fandom" + And all indexing jobs have been run + And I view the unwrangled character bin for "Canonical Fandom" + Then I should see "Syn Fandom Character" + When I view the unwrangled freeform bin for "Canonical Fandom" + Then I should see "Syn Fandom Freeform" + When I view the unwrangled relationship bin for "Canonical Fandom" + Then I should see "Syn Fandom Relationship" + When I de-syn the tag "Syn Fandom" from "Canonical Fandom" + And all indexing jobs have been run + And I view the unwrangled character bin for "Canonical Fandom" + Then I should not see "Syn Fandom Character" + When I view the unwrangled freeform bin for "Canonical Fandom" + Then I should not see "Syn Fandom Freeform" + When I view the unwrangled relationship bin for "Canonical Fandom" + Then I should not see "Syn Fandom Relationship" + + Scenario: Synning a character to a canonical character moves its unwrangled relationships to the canonical's unwrangled bin; de-synning takes them out. + Given a canonical character "Canonical Character" + And I am logged in as a tag wrangler + And I post the work "Populating My Syn Character" with character "Syn Character" with relationship "Syn Character/OC" + When I syn the tag "Syn Character" to "Canonical Character" + And all indexing jobs have been run + And I view the unwrangled relationship bin for "Canonical Character" + Then I should see "Syn Character/OC" + When I de-syn the tag "Syn Character" from "Canonical Character" + And all indexing jobs have been run + And I view the unwrangled relationship bin for "Canonical Character" + Then I should not see "Syn Character/OC" + + Scenario: Tags from draft works don't show in unwrangled bins + Given a canonical fandom "Testing" + And I am logged in as a tag wrangler + And I set up the draft "Generic Work" with fandom "Testing" with character "draft char" with freeform "draft freeform" with relationship "draft rel" + And I press "Preview" + And the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + When I view the unwrangled character bin for "Testing" + Then I should not see "draft char" + When I view the unwrangled freeform bin for "Testing" + Then I should not see "draft freeform" + When I view the unwrangled relationship bin for "Testing" + Then I should not see "draft rel" + When I go to the wrangling tools page + And I follow "Characters by fandom (0)" + Then I should not see "draft char" + When I follow "Freeforms by fandom (0)" + Then I should not see "draft freeform" + When I follow "Relationships by fandom (0)" + Then I should not see "draft rel" + + Scenario: When the only draft using a tag is posted, the tag shows up in unwrangled bins + Given a canonical fandom "Testing" + And I am logged in as a tag wrangler + And I set up the draft "Generic Work" with fandom "Testing" with character "draft char" + And I press "Preview" + And the periodic tag count task is run + And all indexing jobs have been run + When I view the unwrangled character bin for "Testing" + Then I should not see "draft char" + When I post the work "Generic Work" + And the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + And I view the unwrangled character bin for "Testing" + Then I should see "draft char" + When I go to the wrangling tools page + And I follow "Characters by fandom (1)" + Then I should see "draft char" + + Scenario: Tags from bookmarks don't show up in unwrangled bins after being sorted and assigned to a fandom + Given a canonical fandom "Testing" + And I am logged in as a tag wrangler + And I post the work "Generic Work" + And I bookmark the work "Generic Work" with the tags "bookmark rel tag, bookmark char tag" + When I go to the unsorted_tags page + And I select "Relationship" for the unsorted tag "bookmark rel tag" + And I select "Character" for the unsorted tag "bookmark char tag" + And I press "Update" + Then I should see "Tags were successfully sorted" + And the "bookmark rel tag" tag should be a "Relationship" tag + And the "bookmark char tag" tag should be a "Character" tag + When the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + And I go to the wrangling tools page + And I follow "Characters by fandom (0)" + Then I should not see "bookmark char tag" + When I follow "Relationships by fandom (0)" + Then I should not see "bookmark rel tag" + When I add the fandom "Testing" to the tag "bookmark char tag" + And I add the fandom "Testing" to the tag "bookmark rel tag" + Then the "bookmark char tag" tag should be in the "Testing" fandom + And the "bookmark rel tag" tag should be in the "Testing" fandom + And the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + When I view the unwrangled character bin for "Testing" + Then I should not see "bookmark char tag" + When I view the unwrangled relationship bin for "Testing" + Then I should not see "bookmark rel tag" + When I go to the wrangling tools page + And I follow "Characters by fandom (0)" + Then I should not see "bookmark char tag" + When I follow "Relationships by fandom (0)" + Then I should not see "bookmark rel tag" + + Scenario: Tags from unrevealed works don't show in unwrangled bins + Given a canonical fandom "Testing" + And I have the hidden collection "Unrevealed Tags" + And I am logged in as a tag wrangler + When I post the work "Hello There" with fandom "Testing" with character "unrevealed char" in the collection "Unrevealed Tags" + Given the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + When I view the unwrangled character bin for "Testing" + Then I should not see "unrevealed char" + + Scenario: Tags from unrevealed works appear in unwrangled bins when the work is revealed + Given a canonical fandom "Testing" + And I have the hidden collection "Unrevealed Tags" + And I am logged in as a tag wrangler + When I post the work "Hello There" with fandom "Testing" with character "unrevealed char" in the collection "Unrevealed Tags" + Given the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + When I view the unwrangled character bin for "Testing" + Then I should not see "unrevealed char" + When I reveal works for "Unrevealed Tags" + Given the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + And I am logged in as a tag wrangler + When I view the unwrangled character bin for "Testing" + Then I should see "unrevealed char" + + Scenario: Tags from hidden works don't appear in unwrangled bins + Given a canonical fandom "Testing" + And I am logged in as a tag wrangler + When I post the work "Hello There" with fandom "Testing" with character "hidden char" + When I am logged in as a super admin + And I hide the work "Hello There" + Given the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + And I am logged in as a tag wrangler + When I view the unwrangled character bin for "Testing" + Then I should not see "hidden char" + + Scenario: Tags from hidden works appear in unwrangled bins when the work is un-hidden + Given a canonical fandom "Testing" + And I am logged in as a tag wrangler + When I post the work "Hello There" with fandom "Testing" with character "hidden char" + When I am logged in as a super admin + And I hide the work "Hello There" + Given the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + And I am logged in as a tag wrangler + When I view the unwrangled character bin for "Testing" + Then I should not see "hidden char" + When I am logged in as a super admin + And I view the work "Hello There" + And I follow "Make Work Visible" + Given the periodic tag count task is run + And all indexing jobs have been run + And I flush the wrangling sidebar caches + And I am logged in as a tag wrangler + When I view the unwrangled character bin for "Testing" + Then I should see "hidden char" diff --git a/features/tags_and_wrangling/tag_wrangling_relationships.feature b/features/tags_and_wrangling/tag_wrangling_relationships.feature new file mode 100755 index 0000000..f997799 --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_relationships.feature @@ -0,0 +1,277 @@ +@tags @users @tag_wrangling + +Feature: Tag Wrangling - Relationships + +@javascript +Scenario: relationship wrangling - syns, mergers, characters, autocompletes + + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + And basic tags + And a canonical fandom "Torchwood" + And a canonical character "Hoban Washburne" + And a canonical character "Zoe Washburne" + And a canonical character "Jack Harkness" + And a canonical character "Ianto Jones" + And I am logged in as a "tag_wrangling" admin + And I follow "Tag Wrangling" + + # create a new canonical relationship from tag wrangling interface + When I follow "New Tag" + And I fill in "Name" with "Jack Harkness/Ianto Jones" + And I choose "Relationship" + And I check "Canonical" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "Canonical" checkbox should be checked + And the "Canonical" checkbox should not be disabled + + # create a new non-canonical relationship from tag wrangling interface + When I follow "New Tag" + And I fill in "Name" with "Wash/Zoe" + And I choose "Relationship" + And I press "Create Tag" + Then I should see "Tag was successfully created" + And the "Canonical" checkbox should not be checked + And the "Canonical" checkbox should not be disabled + + # assigning characters AND a new merger to a non-canonical relationship + When I fill in "Characters" with "Hoban Washburne, Zoe Washburne" + And I fill in "Synonym of" with "Hoban Washburne/Zoe Washburne" + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Hoban Washburne" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Zoe Washburne" within "div#parent_Character_associations_to_remove_checkboxes" + When I follow "Edit Hoban Washburne/Zoe Washburne" + Then I should see "Hoban Washburne" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Zoe Washburne" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Wash/Zoe" + And the "Canonical" checkbox should be checked and disabled + + # creating a new canonical relationship by renaming + When I fill in "Synonym of" with "Hoban 'Wash' Washburne/Zoe Washburne" + And I press "Save changes" + Then I should see "Tag was updated" + And I should not see "Synonyms" + When I follow "Edit Hoban 'Wash' Washburne/Zoe Washburne" + Then I should see "Make tag non-canonical and unhook all associations" + And I should see "Wash/Zoe" + And I should see "Hoban Washburne/Zoe Washburne" + And I should see "Hoban Washburne" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Zoe Washburne" within "div#parent_Character_associations_to_remove_checkboxes" + And the "Canonical" checkbox should be checked and disabled + + # creating non-canonical relationships from work posting + When I am logged in as "Enigel" with password "wrangulate!" + And I go to the new work page + And I fill in the basic work information for "Silliness" + And I fill in "Fandoms" with "Torchwood" + And I fill in "Relationships" with "Janto, Jack/Ianto" + And I press "Post" + Then I should see "Work was successfully posted." + + # editing non-canonical relationship in order to syn it to existing canonical merger AND add characters + When I follow "Jack/Ianto" + And I follow "Edit" + And I choose "Jack Harkness/Ianto Jones" from the "Synonym of" autocomplete + And I choose "Jack Harkness" from the "Characters" autocomplete + And I choose "Ianto Jones" from the "Characters" autocomplete + And I choose "Torchwood" from the "Fandoms" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + + # adding a non-canonical synonym to a canonical, fandom should be copied + When I follow "Edit Jack Harkness/Ianto Jones" + Then I should see "Jack Harkness" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Ianto Jones" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Torchwood" + And I should see "Jack/Ianto" + And all indexing jobs have been run + And the "Canonical" checkbox should be disabled + And I choose "Janto" from the "tag_merger_string_autocomplete" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Janto" + When I follow "Janto" + Then I should see "Torchwood" + But I should not see "Jack Harkness" within ".tags" + And I should not see "Ianto Jones" within ".tags" + + # metatags and subtags, transference thereof to a new canonical by an admin + When I follow "Edit Jack Harkness/Ianto Jones" + And I fill in "MetaTags" with "Jack Harkness/Male Character" + And I press "Save changes" + Then I should see "Invalid metatag 'Jack Harkness/Male Character':" + And I should see "Metatag does not exist." + And I should not see "Jack Harkness/Male Character" within "form" + When I follow "New Tag" + And I fill in "Name" with "Jack Harkness/Male Character" + And I check "Canonical" + And I choose "Relationship" + And I press "Create Tag" + And I choose "Jack Harkness/Ianto Jones" from the "SubTags" autocomplete + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "Jack Harkness/Ianto Jones" + Then I should see "Jack Harkness/Male Character" + When I follow "New Tag" + And I fill in "Name" with "Jack Harkness/Robot Ianto Jones" + And I choose "Relationship" + And I check "Canonical" + And I press "Create Tag" + And I fill in "MetaTags" with "Jack Harkness/Ianto Jones" + And I press "Save changes" + Then I should see "Tag was updated" + When I follow "Jack Harkness/Ianto Jones" + Then I should see "Jack Harkness/Robot Ianto Jones" + And I should see "Jack Harkness/Male Character" + When I am logged in as a "tag_wrangling" admin + And I edit the tag "Jack Harkness/Ianto Jones" + And I fill in "Synonym of" with "Captain Jack Harkness/Ianto Jones" + And I press "Save changes" + Then I should see "Tag was updated" + And I should not see "Jack Harkness/Robot Ianto Jones" + And I should not see "Jack Harkness/Male Character" + And I should not see "Janto" + And I should not see "Jack/Ianto" + When I follow "Edit Captain Jack Harkness/Ianto Jones" + Then I should see "Jack Harkness/Robot Ianto Jones" + And I should see "Jack Harkness/Male Character" + And I should see "Janto" + And I should see "Jack/Ianto" + And I should see "Jack Harkness/Ianto Jones" within "div#child_Merger_associations_to_remove_checkboxes" + + # trying to syn a non-canonical to another non-canonical + When I am logged in as "Enigel" with password "wrangulate!" + And I edit the tag "Jack Harkness/Ianto Jones" + And I follow "New Tag" + And I fill in "Name" with "James Norrington/Jack Sparrow" + And I choose "Relationship" + And I press "Create Tag" + And I follow "New Tag" + And I fill in "Name" with "Sparrington" + And I choose "Relationship" + And I press "Create Tag" + And I fill in "Synonym of" with "James Norrington/Jack Sparrow" + And I press "Save changes" + Then I should see "James Norrington/Jack Sparrow is not a canonical tag. Please make it canonical before adding synonyms to it." + + # trying to syn a non-canonical to a canonical of a different category + When I fill in "Synonym of" with "Torchwood" + And I press "Save changes" + Then I should see "Torchwood is a fandom. Synonyms must belong to the same category." + +Scenario: AO3-959 Non-canonical merger pairings + + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + And basic tags + And a canonical fandom "Testing" + And a canonical relationship "Testing McTestypants/Testing McTestySkirt" + And a noncanonical relationship "Testypants/Testyskirt" + And I am logged in as "Enigel" with password "wrangulate!" + And I follow "Tag Wrangling" + + When I edit the tag "Testing McTestypants/Testing McTestySkirt" + And I fill in "Fandoms" with "Testing" + And I press "Save changes" + Then I should see "Tag was updated" + + When I edit the tag "Testypants/Testyskirt" + And I fill in "Synonym of" with "Testing McTestypants/Testing McTestySkirt" + And I press "Save changes" + Then I should see "Tag was updated" + + When I edit the tag "Testing McTestypants/Testing McTestySkirt" + # I'm not sure how the line below was ever passing? The checkbox is disabled, and from what I can gather from + # some wranglers, it is expected behavior. + # And I uncheck "Canonical" + And I press "Save changes" + Then I should see "Tag was updated" + + When I post the work "Pants and skirts" + And I edit the work "Pants and skirts" + And I fill in "Relationships" with "Testypants/Testyskirt" + And I press "Preview" + And I press "Update" + Then I should see "Work was successfully updated" + + When all indexing jobs have been run + And I go to Enigel's works page + Then I should see "Testypants/Testyskirt" + And I should see "Testing McTestypants/Testing McTestySkirt" + When I view the tag "Testing" + Then I should see "Testing McTestypants/Testing McTestySkirt" + And I should see "Testypants/Testyskirt" + When I go to Enigel's user page + Then I should see "Testypants/Testyskirt" + And I should not see "Testing McTestypants/Testing McTestySkirt" + +Scenario: AO3-2147 Creating a new merger to a non-can tag while adding characters which belong to a fandom + + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate | + And the following activated user exists + | login | password | + | writer | password | + And basic tags + And a canonical fandom "Up with Testing" + And a canonical fandom "Coding" + And a canonical character "Testing McTestypants" + And a canonical character "Testing McTestySkirt" + + # create a relationship from posting a work as a regular user, just in case + Given I am logged in as "writer" with password "password" + And I follow "New Work" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "Up with Testing" + And I fill in "Work Title" with "whatever" + And I fill in "Relationships" with "Testypants/Testyskirt" + And I fill in "content" with "a long story about nothing" + And I press "Preview" + And I press "Post" + And I log out + + # wrangle the tags to be as close of those that have errored on beta and test + When I am logged in as "Enigel" with password "wrangulate" + And I edit the tag "Coding" + And I fill in "MetaTags" with "Up with Testing" + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Up with Testing" + + When I edit the tag "Testing McTestypants" + And I fill in "Fandoms" with "Up with Testing, Coding" + And I press "Save changes" + Then I should see "Tag was updated" + + When I edit the tag "Testing McTestySkirt" + And I fill in "Fandoms" with "Up with Testing, Coding" + And I press "Save changes" + Then I should see "Tag was updated" + + When I edit the tag "Testypants/Testyskirt" + And I fill in "Synonym of" with "Testing McTestypants/Testing McTestySkirt" + And I fill in "Characters" with "Testing McTestypants, Testing McTestySkirt" + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Testing McTestypants" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Testing McTestySkirt" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Up with Testing" within "div#parent_Fandom_associations_to_remove_checkboxes" + And I should see "Coding" within "div#parent_Fandom_associations_to_remove_checkboxes" + When I follow "Testing McTestypants/Testing McTestySkirt" + Then I should see "Testing McTestypants" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Testing McTestySkirt" within "div#parent_Character_associations_to_remove_checkboxes" + And I should see "Up with Testing" within "div#parent_Fandom_associations_to_remove_checkboxes" + And I should see "Coding" within "div#parent_Fandom_associations_to_remove_checkboxes" + And I should see "Testypants/Testyskirt" + And the "Canonical" checkbox should be checked and disabled + + When I am logged in as a "tag_wrangling" admin + And I edit the tag "Testing McTestypants/Testing McTestySkirt" + And I fill in "Synonym of" with "Dame Tester/Sir Tester" + And I press "Save changes" + Then I should see "Tag was updated" diff --git a/features/tags_and_wrangling/tag_wrangling_special.feature b/features/tags_and_wrangling/tag_wrangling_special.feature new file mode 100755 index 0000000..99ce3e1 --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_special.feature @@ -0,0 +1,182 @@ +@tags @tag_wrangling +Feature: Tag Wrangling - special cases + + Scenario: Create a new tag that differs from an existing tag by accents or other markers + Rename a tag to change accents + + Given the following activated tag wrangler exists + | login | + | wranglerette | + And I am logged in as "wranglerette" + And a fandom exists with name: "Amelie", canonical: false + And a character exists with name: "Romania", canonical: true + When I edit the tag "Amelie" + And I fill in "Synonym of" with "Amélie" + And I press "Save changes" + Then I should see "Amélie is considered the same as Amelie by the database" + And I should not see "Tag was successfully updated." + When I fill in "Name" with "Amélie" + And I press "Save changes" + Then I should see "Tag was updated" + And I should see "Amélie" + And I should not see "Amelie" + When I follow "New Tag" + And I fill in "Name" with "România" + And I check "Canonical" + And I choose "Additional Tag" + And I press "Create Tag" + Then I should see "Tag was successfully created." + But I should see "România - Freeform" + + Scenario: Create a new tag that differs by more than just accents - user cannot change name + + Given the following activated tag wrangler exists + | login | + | wranglerette | + And I am logged in as "wranglerette" + And a fandom exists with name: "Amelie", canonical: false + When I edit the tag "Amelie" + When I fill in "Name" with "Amelia" + And I press "Save changes" + Then I should see "Name can only be changed by an admin." + + Scenario: Change capitalisation of a tag + + Given the following activated tag wrangler exists + | login | + | wranglerette | + And I am logged in as "wranglerette" + And a fandom exists with name: "amelie", canonical: false + When I edit the tag "amelie" + And I fill in "Synonym of" with "Amelie" + And I press "Save changes" + Then I should see "Amelie is considered the same as amelie by the database" + And I should not see "Tag was successfully updated." + When I fill in "Name" with "Amelie" + And I press "Save changes" + Then I should see "Tag was updated" + + Scenario: Works should be updated when capitalisation is changed + See AO3-4230 for a bug with the caching of this + + Given the following activated tag wrangler exists + | login | + | wranglerette | + And a fandom exists with name: "amelie", canonical: false + And I am logged in as "author" + And I post the work "wrong" with fandom "amelie" + When I am logged in as "wranglerette" + And I edit the tag "amelie" + And I fill in "Name" with "Amelie" + And I press "Save changes" + Then I should see "Tag was updated" + When I view the work "wrong" + Then I should see "Amelie" + And I should not see "amelie" + When I am on the works page + Then I should see "Amelie" + And I should not see "amelie" + + Scenario: Works should be updated when accents are changed + See AO3-4230 for a bug with the caching of this + + Given the following activated tag wrangler exists + | login | + | wranglerette | + And a fandom exists with name: "Amelie", canonical: false + And I am logged in as "author" + And I post the work "wrong" with fandom "Amelie" + When I am logged in as "wranglerette" + And I edit the tag "Amelie" + And I fill in "Name" with "Amélie" + And I press "Save changes" + Then I should see "Tag was updated" + When I view the work "wrong" + Then I should see "Amélie" + And I should not see "Amelie" + When I am on the works page + Then I should see "Amélie" + And I should not see "Amelie" + + Scenario: Tags with non-standard characters in them - question mark and period + + Given basic tags + And the following activated tag wrangler exists + | login | + | workauthor | + And a character exists with name: "Evan ?", canonical: true + And a character exists with name: "James T. Kirk", canonical: true + When I am logged in as "workauthor" + When I post the work "Epic sci-fi" + And I follow "Edit" + And I fill in "Characters" with "Evan ?, James T. Kirk" + And I press "Preview" + And I press "Update" + Then I should see "Work was successfully updated" + And all indexing jobs have been run + When I view the tag "Evan ?" + And I follow "filter works" + Then I should see "1 Work in Evan ?" + When I view the tag "James T. Kirk" + And I follow "filter works" + Then I should see "1 Work in James T. Kirk" + + Scenario: Adding a noncanonical tag with "a.k.a.", and viewing works for that tag. + + Given basic tags + And I am logged in as a random user + + When I post the work "Escape Attempt" with fandom "a.k.a. Jessica Jones" + And I follow "a.k.a. Jessica Jones" + + Then I should see "This tag belongs to the Fandom Category" + And I should see "a.k.a. Jessica Jones" within "h2.heading" + And I should see "Escape Attempt" + + Scenario: Wranglers can edit a tag with "a.k.a." in the name. + + Given a noncanonical fandom "a.k.a. Jessica Jones" + And a canonical fandom "Jessica Jones (TV)" + + When I am logged in as a tag wrangler + And I edit the tag "a.k.a. Jessica Jones" + Then I should see "Edit a.k.a. Jessica Jones Tag" + + When I fill in "Synonym of" with "Jessica Jones (TV)" + And I press "Save changes" + Then I should see "Tag was updated" + + Scenario Outline: Tag with a, d, h, q, or s between special characters. + + Given a canonical fandom "adhqs" + + When I am logged in as a tag wrangler + And I view the tag "adhqs" + Then I should see "This tag belongs to the Fandom Category" + And I should see "Edit" + + When I follow "Edit" + Then I should see "Edit adhqs Tag" + + Examples: + | char | + | / | + | # | + | . | + | & | + | ? | + + Scenario: Error messages show correct links even if tags contain special characters + + Given the following activated tag wrangler exists + | login | password | + | Enigel | wrangulate! | + And a character exists with name: "Evelyn \"Evie\" Carnahan", canonical: false + And a character exists with name: "Evelyn \"Evy\" Carnahan", canonical: false + And I am logged in as "Enigel" with password "wrangulate!" + When I edit the tag 'Evelyn "Evy" Carnahan' + And I fill in "Synonym of" with 'Evelyn "Evie" Carnahan' + And I press "Save changes" + Then I should see "is not a canonical tag. Please make it canonical before adding synonyms to it." + When I follow 'Evelyn "Evie" Carnahan' + Then I should be on the 'Evelyn "Evie" Carnahan' tag edit page diff --git a/features/tags_and_wrangling/tag_wrangling_unsorted.feature b/features/tags_and_wrangling/tag_wrangling_unsorted.feature new file mode 100755 index 0000000..b95e004 --- /dev/null +++ b/features/tags_and_wrangling/tag_wrangling_unsorted.feature @@ -0,0 +1,106 @@ +@tags @users @tag_wrangling +Feature: Tag Wrangling - Unsorted Tags + + Scenario: Editing an unsorted tag should not allow making it unwrangleable + Given the following activated tag wrangler exists + | login | + | Enigel | + And basic tags + And I am logged in as "Enigel" + And I follow "Tag Wrangling" + And a unsorted_tag exists with name: "author regrets nothing" + # editing unsorted tag + When I edit the tag "author regrets nothing" + Then the "tag_unwrangleable" checkbox should be disabled + + Scenario: Sorting tags should keep you on the same page + Given the following activated tag wrangler exists + | login | + | dizmo | + And a fandom exists with name: "No Fandom", canonical: true + And the unsorted tags setup + When I am logged in as "dizmo" + And I go to the unsorted_tags page + And I follow "2" + And I press "Update" + Then I should see "2" within ".pagination .current" + + Scenario: Updating multiple tags works. + Given I am logged in as a tag wrangler + And the following typed tags exists + | name | type | + | Cowboy Bebop | Unsorted_tag | + | Serial experiments lain | Unsorted_tag | + | Spike Spiegel | Unsorted_tag | + | Annalise Keating & Bonnie Winterbottom | Unsorted_tag | + | i love good omens | Unsorted_tag | + When I go to the unsorted_tags page + And I select "Fandom" for the unsorted tag "Cowboy Bebop" + And I select "Fandom" for the unsorted tag "Serial experiments lain" + And I select "Character" for the unsorted tag "Spike Spiegel" + And I select "Relationship" for the unsorted tag "Annalise Keating & Bonnie Winterbottom" + And I select "Freeform" for the unsorted tag "i love good omens" + And I press "Update" + Then I should see "Tags were successfully sorted" + And the "Cowboy Bebop" tag should be a "Fandom" tag + And the "Serial experiments lain" tag should be a "Fandom" tag + And the "Spike Spiegel" tag should be a "Character" tag + And the "Annalise Keating & Bonnie Winterbottom" tag should be a "Relationship" tag + And the "i love good omens" tag should be a "Freeform" tag + + Scenario: Can return a tag to Unsorted after a different category has been set + Given I am logged in as a tag wrangler + And a unsorted_tag exists with name: "Unsorted Tag" + When I edit the tag "Unsorted Tag" + And I select "Fandom" from "tag_type" + And I press "Save changes" + Then I should see "Tag was updated." + When I select "UnsortedTag" from "tag_type" + And I press "Save changes" + Then I should see "Tag was updated." + + Scenario Outline: Editing unsorted tags as a fully authorized admin + Given an unsorted_tag exists with name: "Admin unsorted tag" + And I am logged in as a "" admin + When I go to the unsorted_tags page + And I select "Freeform" for the unsorted tag "Admin unsorted tag" + And I press "Update" + Then I should see "Tags were successfully sorted" + And the "Admin unsorted tag" tag should be a "Freeform" tag + + Examples: + | role | + | superadmin | + | tag_wrangling | + + Scenario Outline: Editing unsorted tags as a view-only admin + Given an unsorted_tag exists with name: "Admin unsorted tag" + And I am logged in as a "" admin + When I go to the unsorted_tags page + And I select "Freeform" for the unsorted tag "Admin unsorted tag" + And I press "Update" + Then I should see "Sorry, only an authorized admin can access the page you were trying to reach." + And the "Admin unsorted tag" tag should be an unsorted tag + + Examples: + | role | + | policy_and_abuse | + + Scenario Outline: Editing unsorted tags as an unauthorized admin + Given an unsorted_tag exists with name: "Admin unsorted tag" + And I am logged in as a "" admin + When I go to the unsorted_tags page + Then I should see "Sorry, only an authorized admin can access the page you were trying to reach." + + Examples: + | role | + | board | + | board_assistants_team | + | communications | + | development_and_membership | + | docs | + | elections | + | legal | + | translation | + | support | + | open_doors | diff --git a/features/tags_and_wrangling/wrangling_guidelines.feature b/features/tags_and_wrangling/wrangling_guidelines.feature new file mode 100755 index 0000000..837b070 --- /dev/null +++ b/features/tags_and_wrangling/wrangling_guidelines.feature @@ -0,0 +1,52 @@ +@admin @wrangling_guidelines +Feature: Wrangling Guidelines + In order to help people understand the wrangling system + As an admin + I want to be able to maintain wrangling guidelines + + Scenario: Post a Wrangling Guideline + + Given I am logged in as a "tag_wrangling" admin + And I am on the wrangling guidelines page + And I follow "New Wrangling Guideline" + And I fill in "Guideline text" with "This series of documents (Wrangling Guidelines) are intended to help tag wranglers remain consistent as they go about the business of wrangling tags by providing a set of formatting guidelines." + And I fill in "Title" with "Intro and General Concepts" + When I press "Post" + Then I should see "Wrangling Guideline was successfully created" + When I go to the wrangling_guidelines page + And I follow "Intro and General Concepts" + Then I should see "This series of documents (Wrangling Guidelines) are intended to help tag wranglers remain consistent as they go about the business of wrangling tags by providing a set of formatting guidelines." within ".userstuff" + + Scenario: Edit Wrangling Guideline + + Given I have posted a Wrangling Guideline + And I am on the wrangling guidelines page + When I follow "Edit" + And I fill in "Guideline text" with "These guidelines are an in-progress affair, subject to change." + When I press "Post" + Then I should see "Wrangling Guideline was successfully updated" + And I should see "These guidelines are an in-progress affair, subject to change." + + Scenario: Reorder Wrangling Guidelines + + Given I am logged in as a "tag_wrangling" admin + And 3 Wrangling Guidelines exist + When I go to the Wrangling Guidelines reorder page + And I fill in "wrangling_guidelines_1" with "3" + And I fill in "wrangling_guidelines_2" with "1" + And I fill in "wrangling_guidelines_3" with "2" + When I press "Update Positions" + Then I should see "Wrangling Guidelines order was successfully updated" + When I follow "Reorder Wrangling Guidelines" + Then I should see "1. The 2 Wrangling Guideline" + And I should see "2. The 3 Wrangling Guideline" + And I should see "3. The 1 Wrangling Guideline" + + Scenario: Delete Wrangling Guideline + + Given I am logged in as a "tag_wrangling" admin + And I have posted a Wrangling Guideline titled "Relationship Tags" + When I go to the Wrangling Guidelines page + And I follow "Delete" + Then I should see "Wrangling Guideline was successfully deleted" + And I should not see "Relationship Tags" diff --git a/features/users/authenticate_users.feature b/features/users/authenticate_users.feature new file mode 100755 index 0000000..13f9537 --- /dev/null +++ b/features/users/authenticate_users.feature @@ -0,0 +1,337 @@ +@users +@admin +Feature: User Authentication + + Scenario: Forgot password + Given I have no users + And the following activated user exists + | login | password | + | sam | secret | + And all emails have been delivered + When I am on the home page + And I fill in "Username or email:" with "sam" + And I fill in "Password:" with "test" + And I press "Log In" + Then I should see "The password or username you entered doesn't match our records" + And I should see "Forgot your password or username?" + When I follow "Reset password" + Then I should see "Please tell us the username or email address you used when you signed up for your Archive account" + When I fill in "Email address or username" with "sam" + And I press "Reset Password" + Then I should see "Check your email for instructions on how to reset your password." + And 1 email should be delivered + And the email should contain "sam" + And the email should contain "Someone has requested a password reset for your account" + And the email should not contain "translation missing" + + # existing password should still work + When I am on the homepage + And I fill in "Username or email:" with "sam" + And I fill in "Password:" with "secret" + And I press "Log In" + Then I should see "Hi, sam" + + # link from the email should not work when logged in + When I follow "Change my password." in the email + Then I should see "You are already signed in." + And I should not see "Change My Password" + + # link from the email should work + When I log out + And I follow "Change my password." in the email + Then I should see "Change My Password" + + # entering mismatched passwords should produce an error message + When I fill in "New password" with "secret" + And I fill in "Confirm new password" with "newpass" + And I press "Change Password" + Then I should see "We couldn't save this user because:" + And I should see "Password confirmation doesn't match new password." + + # and I should be able to change the password + When I fill in "New password" with "new + When I am on the home page + And I follow "Forgot password?" + And I fill in "Email address or username" with "target" + And I press "Reset Password" + Then I should be on the home page + And I should see "Password resets are disabled for that user." + And 0 emails should be delivered + When I follow "Forgot password?" + And I fill in "Email address or username" with "user@example.com" + And I press "Reset Password" + Then I should be on the home page + And I should see "Password resets are disabled for that user." + And 0 emails should be delivered + + Examples: + | role | + | is a protected user | + | has the no resets role | + + Scenario: Admin cannot log in or reset password as ordinary user. + Given the following admin exists + | login | password | + | admin | adminpassword | + When I go to the login page + And I fill in "Username or email" with "admin" + And I fill in "Password" with "adminpassword" + And I press "Log In" + Then I should not see "Successfully logged in" + And I should see "The password or username you entered doesn't match our records." + When I am logged in as an admin + And I go to the new user password page + Then I should be on the homepage + And I should see "Please log out of your admin account first!" + When I go to the edit user password page + Then I should be on the homepage + And I should see "Please log out of your admin account first!" diff --git a/features/users/blocking.feature b/features/users/blocking.feature new file mode 100755 index 0000000..76391be --- /dev/null +++ b/features/users/blocking.feature @@ -0,0 +1,137 @@ +Feature: Blocking + Scenario: Users can block from my blocked users page + Given the user "pest" exists and is activated + And I am logged in as "blocker" + When I go to the blocked users page for "blocker" + And I fill in "blocked_id" with "pest" + And I press "Block" + And I press "Yes, Block User" + Then I should see "You have blocked the user pest." + And the user "blocker" should have a block for "pest" + + Scenario Outline: Users can block from various user-related pages + Given the user "pest" exists and is activated + And I am logged in as "blocker" + When I go to + And I follow "Block" + And I press "Yes, Block User" + Then I should see "You have blocked the user pest." + And the user "blocker" should have a block for "pest" + And the blurb should not say when "blocker" blocked "pest" + + Examples: + | page | + | pest's user page | + | pest's profile page | + | the dashboard page for user "pest" with pseud "pest" | + + Scenario: Users can block from the comments + Given the work "Aftermath" + And a comment "Ugh." by "pest" on the work "Aftermath" + And I am logged in as "blocker" + When I view the work "Aftermath" with comments + And I follow "Block" + And I press "Yes, Block User" + Then I should see "You have blocked the user pest." + And the user "blocker" should have a block for "pest" + + Scenario: Users cannot block official users + Given the user "pest" exists and has the role "official" + And I am logged in as "blocker" + When I go to pest's user page + And I follow "Block" + Then I should see "Sorry, you can't block an official user." + And I should not see a "Yes, Block User" button + + Scenario: Users cannot block themselves + Given the user "pest" exists and is activated + And I am logged in as "pest" + When I go to pest's user page + Then I should not see a link "Block" + When I go to the blocked users page for "pest" + And I fill in "blocked_id" with "pest" + And I press "Block" + Then I should see "Sorry, you can't block yourself." + And I should not see a "Yes, Block User" button + + Scenario: Users can unblock from the blocked users page + Given the user "unblocker" has blocked the user "improving" + And I am logged in as "unblocker" + When I go to the blocked users page for "unblocker" + And I follow "Unblock" + And I press "Yes, Unblock User" + Then I should see "You have unblocked the user improving." + And the user "unblocker" should not have a block for "improving" + + Scenario Outline: Users can unblock from various user-related pages + Given the user "unblocker" has blocked the user "improving" + And I am logged in as "unblocker" + When I go to + And I follow "Unblock" + And I press "Yes, Unblock User" + Then I should see "You have unblocked the user improving." + And the user "unblocker" should not have a block for "improving" + + Examples: + | page | + | improving's user page | + | improving's profile page | + | the dashboard page for user "improving" with pseud "improving" | + + Scenario: Users can unblock from the comments + Given the user "unblocker" has blocked the user "improving" + And the work "Aftermath" + And a comment "Wonderful!" by "improving" on the work "Aftermath" + And I am logged in as "unblocker" + When I view the work "Aftermath" with comments + And I follow "Unblock" + And I press "Yes, Unblock User" + Then I should see "You have unblocked the user improving." + And the user "unblocker" should not have a block for "improving" + + Scenario: The blocked users page is paginated + Given there are 2 blocked users per page + And the user "blocker" has blocked the user "pest1" + And the user "blocker" has blocked the user "pest2" + And the user "blocker" has blocked the user "pest3" + And the user "blocker" has blocked the user "pest4" + When I am logged in as "blocker" + And I go to the blocked users page for "blocker" + Then I should see "pest4" within "ul.pseud li:nth-child(1)" + And I should see "pest3" within "ul.pseud li:nth-child(2)" + And I should not see "pest2" + And I should not see "pest1" + When I follow "2" within ".pagination" + Then I should see "pest2" within "ul.pseud li:nth-child(1)" + And I should see "pest1" within "ul.pseud li:nth-child(2)" + + Scenario Outline: Authorized admins can see the blocked users page + Given the user "blocker" has blocked the user "pest" + When I am logged in as a "" admin + And I go to the blocked users page for "blocker" + Then I should see "pest" + And the blurb should say when "blocker" blocked "pest" + And I should see a link "Unblock" + When I follow "Unblock" + Then I should see "Sorry, you don't have permission to access the page you were trying to reach." + And the user "blocker" should have a block for "pest" + + Examples: + | role | + | superadmin | + | policy_and_abuse | + | support | + + Scenario: Users are told about blocking effects on gift-giving + Given the user "pest" exists and is activated + And I am logged in as "blocker" + When I go to the blocked users page for "blocker" + Then I should see "giving you gift works" + Given the user "unblocker" has blocked the user "improving" + And I am logged in as "unblocker" + When I go to the blocked users page for "unblocker" + Then I should see "improving" + And I should see "giving you gift works" + When I follow "Unblock" + Then I should see a "Yes, Unblock User" button + And I should see "giving you gift works" diff --git a/features/users/muting.feature b/features/users/muting.feature new file mode 100755 index 0000000..97b011f --- /dev/null +++ b/features/users/muting.feature @@ -0,0 +1,154 @@ +Feature: Muting + Scenario: Users can mute from my muted users page + Given the user "pest" exists and is activated + And I am logged in as "muter" + When I go to the muted users page for "muter" + And I fill in "muted_id" with "pest" + And I press "Mute" + And I press "Yes, Mute User" + Then I should see "You have muted the user pest." + And the user "muter" should have a mute for "pest" + And the blurb should not say when "muter" muted "pest" + + Scenario Outline: Users can mute from various user-related pages + Given the user "pest" exists and is activated + And I am logged in as "muter" + When I go to + And I follow "Mute" + And I press "Yes, Mute User" + Then I should see "You have muted the user pest." + And the user "muter" should have a mute for "pest" + + Examples: + | page | + | pest's user page | + | pest's profile page | + | the dashboard page for user "pest" with pseud "pest" | + + Scenario: Users cannot mute official users + Given the user "pest" exists and has the role "official" + And I am logged in as "muter" + When I go to pest's user page + And I follow "Mute" + Then I should see "Sorry, you can't mute an official user." + And I should not see a "Yes, Mute User" button + + Scenario: Users cannot mute themselves + Given the user "pest" exists and is activated + And I am logged in as "pest" + When I go to pest's user page + Then I should not see a link "Mute" + When I go to the muted users page for "pest" + And I fill in "muted_id" with "pest" + And I press "Mute" + Then I should see "Sorry, you can't mute yourself." + And I should not see a "Yes, Mute User" button + + Scenario: Users can unmute from the muted users page + Given the user "unmuter" has muted the user "improving" + And I am logged in as "unmuter" + When I go to the muted users page for "unmuter" + And I follow "Unmute" + And I press "Yes, Unmute User" + Then I should see "You have unmuted the user improving." + And the user "unmuter" should not have a mute for "improving" + + Scenario Outline: Users can unmute from various user-related pages + Given the user "unmuter" has muted the user "improving" + And I am logged in as "unmuter" + When I go to + And I follow "Unmute" + And I press "Yes, Unmute User" + Then I should see "You have unmuted the user improving." + And the user "unmuter" should not have a mute for "improving" + + Examples: + | page | + | improving's user page | + | improving's profile page | + | the dashboard page for user "improving" with pseud "improving" | + + Scenario: The muted users page is paginated + Given there are 2 muted users per page + And the user "muter" has muted the user "pest1" + And the user "muter" has muted the user "pest2" + And the user "muter" has muted the user "pest3" + And the user "muter" has muted the user "pest4" + When I am logged in as "muter" + And I go to the muted users page for "muter" + Then I should see "pest4" within "ul.pseud li:nth-child(1)" + And I should see "pest3" within "ul.pseud li:nth-child(2)" + And I should not see "pest2" + And I should not see "pest1" + When I follow "2" within ".pagination" + Then I should see "pest2" within "ul.pseud li:nth-child(1)" + And I should see "pest1" within "ul.pseud li:nth-child(2)" + + Scenario Outline: Authorized admins can see the muted users page + Given the user "muter" has muted the user "pest" + When I am logged in as a "" admin + And I go to the muted users page for "muter" + Then I should see "pest" + And the blurb should say when "muter" muted "pest" + And I should see a link "Unmute" + When I follow "Unmute" + Then I should see "Sorry, you don't have permission to access the page you were trying to reach." + And the user "muter" should have a mute for "pest" + + Examples: + | role | + | superadmin | + | policy_and_abuse | + | support | + + @javascript + Scenario: Users cannot see works by a muted user + Given the user "muter" has muted the user "pest" + And the work "Annoying Work" by "pest" + When I am logged in as "muter" + And I go to pest's works page + Then I should not see "Annoying Work" + When I am logged out + And I go to pest's works page + Then I should see "Annoying Work" + + @javascript + Scenario: Users cannot see series by a muted user + Given the user "muter" has muted the user "pest" + And the work "Annoying Work" by "pest" + And I am logged in as "pest" + And I edit the work "Annoying Work" + And I add the series "Annoying Series" + And I press "Post" + When I am logged in as "muter" + And I go to pest's series page + Then I should not see "Annoying Series" + When I am logged out + And I go to pest's series page + Then I should see "Annoying Series" + + @javascript + Scenario: Users cannot see bookmarks by a muted user + Given the user "muter" has muted the user "pest" + And the work "Good Work" by "muter" + And I am logged in as "pest" + And I have a bookmark for "Good Work" + When I am logged in as "muter" + And I go to pest's bookmarks page + Then I should not see "Good Work" + When I am logged out + And I go to pest's bookmarks page + Then I should see "Good Work" + + @javascript + Scenario: Users cannot see comments by a muted user + Given the user "muter" has muted the user "pest" + And the work "Good Work" by "muter" + And I am logged in as "pest" + And I post the comment "fxxk you" on the work "Good Work" + When I am logged in as "muter" + And I view the work "Good Work" + Then I should not see "fxxk you" + When I am logged out + And I view the work "Good Work" + Then I should see "Good Work" diff --git a/features/users/password_compatibility.feature b/features/users/password_compatibility.feature new file mode 100755 index 0000000..4c121bb --- /dev/null +++ b/features/users/password_compatibility.feature @@ -0,0 +1,39 @@ +@users +Feature: + In order to ensure all users can login + No matter what strategy was originally used to encrypt their password + As a registered user + I should be able to login + + Scenario: Using Devise's default encryption strategy + Given the following activated users exist + | login | password | + | user1 | password | + When I am on the homepage + And I fill in "Username or email:" with "user1" + And I fill in "Password:" with "password" + And I press "Log In" + Then I should see "Successfully logged in." + And I should see "Hi, user1!" + + Scenario: Using Authlogic's BCrypt encryption + Given the following users exist with BCrypt encrypted passwords + | login | password | + | user1 | password | + When I am on the homepage + And I fill in "Username or email:" with "user1" + And I fill in "Password:" with "password" + And I press "Log In" + Then I should see "Successfully logged in." + And I should see "Hi, user1!" + + Scenario: Using Authlogic's SHA-512 encryption + Given the following users exist with SHA-512 encrypted passwords + | login | password | + | user1 | password | + When I am on the homepage + And I fill in "Username or email:" with "user1" + And I fill in "Password:" with "password" + And I press "Log In" + Then I should see "Successfully logged in." + And I should see "Hi, user1!" diff --git a/features/users/suspensions.feature b/features/users/suspensions.feature new file mode 100755 index 0000000..2ef5b37 --- /dev/null +++ b/features/users/suspensions.feature @@ -0,0 +1,17 @@ +Feature: Suspensions + + Scenario: Users suspended on 2024-01-11 before the unban threshold can see they will be unbanned on 2024-02-10 + Given the user "mrparis" exists and is activated + And it is currently 2024-01-11 01:00 AM + And the user "mrparis" is suspended + And I am logged in as "mrparis" + And I go to the new work page + Then I should see "suspended until Sat 10 Feb 2024" + + Scenario: Users suspended on 2024-01-11 after the unban threshold can see they will be unbanned on 2024-02-11 + Given the user "mrparis" exists and is activated + And it is currently 2024-01-11 08:00 PM + And the user "mrparis" is suspended + And I am logged in as "mrparis" + And I go to the new work page + Then I should see "suspended until Sun 11 Feb 2024" diff --git a/features/users/user_create.feature b/features/users/user_create.feature new file mode 100755 index 0000000..767ead1 --- /dev/null +++ b/features/users/user_create.feature @@ -0,0 +1,86 @@ +Feature: Sign Up for a new account + In order to add works to the Archive. + As an unregistered user. + I want to be able to create a new account. + + Background: + Given account creation is enabled + And account creation requires an invitation + And I am a visitor + And I use an invitation to sign up + + Scenario Outline: The user should see validation errors when signing up with invalid data. + When I fill in the sign up form with valid data + And I fill in "" with "" + And I press "Create Account" + Then I should see "" + And I should not see "Almost Done!" + Examples: + | field | value | error | + | user_registration_login | xx | Username is too short (minimum is 3 characters)| + | user_registration_login | 87151d8ae964d55515cb986d40394f79ca5c8329c07a8e59f2f783cbfbe401f69a780f27277275b7b2 | Username is too long (maximum is 40 characters) | + | user_registration_password | pass | Password is too short (minimum is 6 characters) | + | user_registration_password | 87151d8ae964d55515cb986d40394f79ca5c8329c07a8e59f2f783cbfbe401f69a780f27277275b7b2 | Password is too long (maximum is 40 characters) | + | user_registration_password_confirmation | password2 | Password confirmation doesn't match | + | user_registration_email | | Email should look like an email address | + | user_registration_email | fake@fake@fake | Email should look like an email address | + + Scenario Outline: The user should see validation errors when signing up without filling in required fields. + When I press "Create Account" + Then I should see "" + And I should not see "Almost Done!" + Examples: + | field | error | + | user_registration_age_over_13 | Sorry, you have to be over 13! | + | user_registration_terms_of_service | Sorry, you need to accept the Terms of Service in order to sign up. | + | user_registration_data_processing | Sorry, you need to consent to the processing of your personal data in order to sign up. | + + Scenario: The user should be able to sign up after fixing form errors. + When I fill in the sign up form with valid data + And I fill in "Valid email" with "lyingrobot@example.com" + And I uncheck "Yes, I have read the Terms of Service, including the Content Policy and Privacy Policy, and agree to them." + And I press "Create Account" + Then I should see "Sorry, you need to accept the Terms of Service in order to sign up." + And I should not see "Sorry, you have to be over 13!" + # Email should be what the user filled in, not the invitee email on the invitation + And I should see "lyingrobot@example.com" in the "Valid email" input + + When I check "Yes, I have read the Terms of Service, including the Content Policy and Privacy Policy, and agree to them." + And I fill in "Password" with "password" + And I fill in "Confirm password" with "password" + And all emails have been delivered + And I press "Create Account" + Then I should see "Almost Done!" + And 1 email should be delivered to "lyingrobot@example.com" + And I should get a new user activation email + And a new user account should exist + + Scenario: The user should not be able to sign up with a login that is already in use + Given the following users exist + | login | password | + | user1 | password | + When I fill in the sign up form with valid data + And I fill in "user_registration_login" with "user1" + And I press "Create Account" + Then I should see "Username has already been taken" + And I should not see "Almost Done!" + + Scenario: The user should not be able to sign up with a login that is already in use, no matter the case + Given the following users exist + | login | password | + | user1 | password | + When I fill in the sign up form with valid data + And I fill in "user_registration_login" with "USER1" + And I press "Create Account" + Then I should see "Username has already been taken" + And I should not see "Almost Done!" + + Scenario: The user should be able to create a new account with a valid email and password + When I fill in the sign up form with valid data + Then I should see the page title "Create Account" + When all emails have been delivered + And I press "Create Account" + Then I should see the page title "Account Created" + And I should see "Almost Done!" + And I should get a new user activation email + And a new user account should exist diff --git a/features/users/user_dashboard.feature b/features/users/user_dashboard.feature new file mode 100755 index 0000000..57e572f --- /dev/null +++ b/features/users/user_dashboard.feature @@ -0,0 +1,275 @@ +@users +Feature: User dashboard + In order to have an archive full of users + As a humble user + I want to write some works and see my dashboard + + Scenario: If I have no creations my dashboard is empty + Given I am logged in as "first_user" + And I follow "My Dashboard" + Then I should see "You don't have anything posted under this name yet" + Given I am logged in as "second_user" + And I go to first_user's user page + Then I should see "There are no works or bookmarks under this name yet" + When I am logged in as "first_user" + And I post the work "First Work" + And I follow "My Dashboard" + Then I should not see "You don't have anything posted under this name yet" + And I should see "First Work" + When I am logged in as "second_user" + And I go to first_user's user page + Then I should not see "There are no works or bookmarks under this name yet" + And I should see "First Work" + + Scenario: Canonical synonym fandoms should be used in the fandoms listing but actual tags should be displayed on the work blurb + Given I am logged in as a tag wrangler + # set up metatag and synonym + And a fandom exists with name: "Stargate SG-1", canonical: true + And a fandom exists with name: "Stargatte SG-oops", canonical: false + And a fandom exists with name: "Stargate Franchise", canonical: true + And I edit the tag "Stargate SG-1" + And I fill in "MetaTags" with "Stargate Franchise" + And I press "Save changes" + And I edit the tag "Stargatte SG-oops" + And I fill in "Synonym" with "Stargate SG-1" + And I press "Save changes" + # view user dashboard - when posting a work with the canonical, metatag and synonym should not be seen + When I am logged in as "first_user" + And I post the work "Revenge of the Sith" with fandom "Stargate SG-1" + And I follow "My Dashboard" + Then I should see "Stargate SG-1" within "#user-fandoms" + And I should not see "Stargate Franchise" + And I should not see "Stargatte SG-oops" + # now using the synonym - canonical should be seen, but metatag still not seen + When I edit the work "Revenge of the Sith" + And I fill in "Fandoms" with "Stargatte SG-oops" + And I press "Preview" + And I press "Update" + Then I should see "Work was successfully updated" + When I follow "My Dashboard" + Then I should see "Stargate SG-1" within "#user-fandoms" + And I should not see "Stargate Franchise" + And I should not see "Stargatte SG-oops" within "#user-fandoms" + And I should see "Stargatte SG-oops" within "#user-works" + + Scenario: The user dashboard should list up to five of the user's works and link to more + Given dashboard counts expire after 10 seconds + And I am logged in as "meatloaf" + And I post the works "Oldest Work, Work 2, Work 3, Work 4, Work 5" + When I go to meatloaf's user page + Then I should see "Recent works" + And I should see "Oldest Work" + And I should see "Work 5" + And I should see "Works (5)" within "#dashboard" + And I should not see "Works (" within "#user-works" + When I post the work "Newest Work" + And all indexing jobs have been run + And I go to meatloaf's user page + Then I should see "Newest Work" + And I should not see "Oldest Work" + And I should see "Works (5)" within "#dashboard" + And I should see "Works (5)" within "#user-works" + When I wait 11 seconds + And I reload the page + Then I should see "Works (6)" within "#dashboard" + When I follow "Works (6)" within "#user-works" + Then I should see "6 Works by meatloaf" + And I should see "Oldest Work" + And I should see "Newest Work" + + Scenario: The user dashboard should not list anonymous works by the user + Given I have the anonymous collection "Anon Treasury" + And I am logged in as "meatloaf" + And I post the work "Anon Work" to the collection "Anon Treasury" + When I go to meatloaf's user page + Then I should not see "Recent Works" + When I post the work "New Work" + And I go to meatloaf's user page + Then I should see "Recent works" + And I should not see "Anon Work" within "#user-works" + + Scenario: The user dashboard should list up to five of the user's series and link to more + Given I am logged in as "meatloaf" + And I post the work "My Work" + When I add the work "My Work" to the series "Oldest Series" + # Make sure all other series are more recent + And it is currently 1 second from now + And I add the work "My Work" to the series "Series 2" + And I add the work "My Work" to the series "Series 3" + And I add the work "My Work" to the series "Series 4" + And I add the work "My Work" to the series "Series 5" + When I go to meatloaf's user page + Then I should see "Recent series" + And I should see "Oldest Series" within "#user-series" + When I add the work "My Work" to the series "Newest Series" + And I go to meatloaf's user page + Then I should see "Newest Series" within "#user-series" + And I should not see "Oldest Series" within "#user-series" + When I follow "Series (6)" within "#user-series" + Then I should see "6 Series by meatloaf" + And I should see "Oldest Series" + And I should see "Newest Series" + + Scenario: The user dashboard should not list anonymous series by the user + Given I have the anonymous collection "Anon Treasury" + And I am logged in as "meatloaf" + And I post the work "Anon Work" to the collection "Anon Treasury" + And I add the work "Anon Work" to series "Anon Series" + When I go to meatloaf's user page + Then I should not see "Recent Series" + When I add the work "New Work" to series "Cool Series" + And I go to meatloaf's user page + Then I should see "Recent series" + And I should not see "Anon Series" within "#user-series" + + Scenario: The user dashboard should list up to five of the user's bookmarks and link to more + Given dashboard counts expire after 10 seconds + And I am logged in as "fruitpie" + And I post the works "Work One, Work Two, Work Three, Work Four, Work Five, Work Six" + When I am logged in as "meatloaf" + And I bookmark the works "Work One, Work Two, Work Three, Work Four, Work Five" + When I go to meatloaf's user page + Then I should see "Recent bookmarks" + And I should see "Work One" within "#user-bookmarks" + When I bookmark the work "Work Six" + And I go to meatloaf's user page + Then I should see "Work Six" within "#user-bookmarks" + And I should not see "Work One" within "#user-bookmarks" + And I should see "Bookmarks (5)" within "#dashboard" + When I wait 11 seconds + And I reload the page + Then I should see "Bookmarks (6)" within "#dashboard" + When I follow "Bookmarks (6)" within "#user-bookmarks" + Then I should see "6 Bookmarks by meatloaf" + And I should see "Work One" + And I should see "Work Six" + + Scenario Outline: The dashboard/works/bookmarks pages for a non-default pseud should display both pseud and username + Given "meatloaf" has the pseud "gravy" + When I go to meatloaf's page + Then I should not see "(meatloaf)" within "" + When I go to the page for user "meatloaf" with pseud "gravy" + Then I should see "gravy (meatloaf)" within "" + Examples: + | page_name | selector | + | user | #main .primary h2 | + | works | .works-index .heading | + | bookmarks | .bookmarks-index .heading | + | series | .series-index .heading | + + Scenario: The dashboard for a specific pseud should only list the creations owned by that pseud + Given dashboard counts expire after 10 seconds + And I am logged in as "meatloaf" + And I post the works "Oldest Work, Work 2, Work 3, Work 4, Work 5" + And I add the work "Oldest Work" to series "Oldest Series" + And I bookmark the work "Oldest Work" + And "meatloaf" creates the pseud "gravy" + When I add the work "Pseud's Work 1" to series "Pseud Series A" as "gravy" + And I bookmark the work "Work 5" as "gravy" + And I go to meatloaf's user page + And I follow "gravy" within ".pseud .expandable li" + Then I should see "Works (0)" within "#dashboard" + And I should see "Bookmarks (0)" within "#dashboard" + When I wait 11 seconds + And I reload the page + Then I should see "Recent works" + And I should see "Pseud's Work 1" + And I should see "Works (1)" within "#dashboard" + And I should not see "Works (" within "#user-works" + And I should not see "Oldest Work" within "#user-works" + And I should see "Recent series" + And I should see "Pseud Series A" within "#user-series" + And I should not see "Oldest Series" + And I should see "Recent bookmarks" + And I should see "Work 5" within "#user-bookmarks" + And I should see "Bookmarks (1)" within "#dashboard" + + Scenario: You can follow a fandom link from a user's dashboard and then use the filters to sort within that fandom. + Given a media exists with name: "TV Shows", canonical: true + And a fandom exists with name: "Star Trek", canonical: true + And a fandom exists with name: "Star Trek: Discovery", canonical: true + And I am logged in as "meatloaf" + And I post the work "Excellent" with fandom "Star Trek" + And I post the work "Even more Excellent" with fandom "Star Trek" + And I post the work "Exciting" with fandom "Star Trek: Discovery" + When I go to meatloaf's user page + And I follow "Star Trek" + Then I should see "2 Works by meatloaf in Star Trek" + When I press "Sort and Filter" + Then I should see "2 Works by meatloaf in Star Trek" + + Scenario: The dashboard sidebar series count should exclude restricted series when logged out + Given I have the anonymous collection "Anon works" + And I am logged in as "Accumulator" + And "Accumulator" creates the pseud "Battery" + And "Accumulator" creates the pseud "Centrifuge" + And I post the work "Normal work" as part of a series "Mine" using the pseud "Battery" + And I post the work "Normal work 2" as part of a series "Mine" using the pseud "Battery" + And I post the work "Restricted work" as part of a series "Restricted" using the pseud "Battery" + And I lock the work "Restricted work" + And I post the work "Another restricted work" as part of a series "Restricted" using the pseud "Battery" + And I lock the work "Another restricted work" + When I go to Accumulator's user page + Then I should see "Series (2)" within "#dashboard" + When I go to the dashboard page for user "Accumulator" with pseud "Battery" + Then I should see "Series (2)" within "#dashboard" + When I go to the dashboard page for user "Accumulator" with pseud "Centrifuge" + Then I should see "Series (0)" within "#dashboard" + When I am logged out + And I go to Accumulator's user page + Then I should see "Series (1)" within "#dashboard" + When I go to the dashboard page for user "Accumulator" with pseud "Battery" + Then I should see "Series (1)" within "#dashboard" + When I go to the dashboard page for user "Accumulator" with pseud "Centrifuge" + Then I should see "Series (0)" within "#dashboard" + # Series with anon works are never counted + When I am logged in as "Accumulator" + And I post the work "Another normal work" as part of a series "Anon" using the pseud "Battery" + And I post the work "Anon work" in the collection "Anon works" as part of a series "Anon" using the pseud "Battery" + And I go to Accumulator's user page + Then I should see "Series (2)" within "#dashboard" + When I go to the dashboard page for user "Accumulator" with pseud "Battery" + Then I should see "Series (2)" within "#dashboard" + When I go to the dashboard page for user "Accumulator" with pseud "Centrifuge" + Then I should see "Series (0)" within "#dashboard" + When I am logged out + And I go to Accumulator's user page + Then I should see "Series (1)" within "#dashboard" + When I go to the dashboard page for user "Accumulator" with pseud "Battery" + Then I should see "Series (1)" within "#dashboard" + When I go to the dashboard page for user "Accumulator" with pseud "Centrifuge" + Then I should see "Series (0)" within "#dashboard" + + Scenario Outline: User and pseud dashboards, and user profiles, contain links to the user's administration page only for authorized admins + Given "a_user" has the pseud "a_pseud" + When I am + And I go to a_user's user page + Then I should "User Administration" within ".user .primary" + When I go to a_user's profile page + Then I should "User Administration" within ".user .primary" + When I go to the user page for user "a_user" with pseud "a_pseud" + Then I should "User Administration" within ".user .primary" + Examples: + | logged_in_status | action | + | logged in as a "superadmin" admin | see | + | logged in as a "communications" admin | not see | + | logged in as a random user | not see | + | logged in as "a_user" | not see | + | a visitor | not see | + + Scenario Outline: User and pseud dashboards, and user profiles, contain links to the user's invitations page only for the user and authorized admins + Given "a_user" has the pseud "a_pseud" + When I am + And I go to a_user's user page + Then I should "Invitations" within ".user .primary" + When I go to a_user's profile page + Then I should "Invitations" within ".user .primary" + When I go to the user page for user "a_user" with pseud "a_pseud" + Then I should "Invitations" within ".user .primary" + Examples: + | logged_in_status | action | + | logged in as a "superadmin" admin | see | + | logged in as a "communications" admin | not see | + | logged in as a random user | not see | + | logged in as "a_user" | see | + | a visitor | not see | diff --git a/features/users/user_delete.feature b/features/users/user_delete.feature new file mode 100755 index 0000000..e47f9a1 --- /dev/null +++ b/features/users/user_delete.feature @@ -0,0 +1,119 @@ +@users +Feature: + In order to correct mistakes or reflect my evolving personality + As a registered user + I should be able to delete my account + +Scenario: The Delete My Account link should exist on the Profile page + Given I am logged in as "downthemall" + When I go to downthemall's user page + And I follow "Profile" + Then I should see "Delete My Account" + +Scenario: If I delete a user with no works, the user should be deleted without any prompting + Given I am logged in as "downthemall" + And I have no works or comments + When I try to delete my account as downthemall + Then I should see "You have successfully deleted your account." + And a user account should not exist for "downthemall" + And I should be logged out + +Scenario: If a user chooses "Delete Completely" when removing their account, delete the works associated with that user + Given I am logged in as "otheruser" with password "secret" + And all emails have been delivered + And I post the work "To be deleted" + When I try to delete my account as otheruser + Then I should see "What do you want to do with your works?" + And a user account should exist for "otheruser" + When I choose "Delete completely" + And I press "Save" + Then I should see "You have successfully deleted your account." + And a user account should not exist for "otheruser" + And 1 email should be delivered + And I should be logged out + When I go to the works page + Then I should not see "To be deleted" + +Scenario: Allow a user to orphan their works when deleting their account + Given I have an orphan account + When I am logged in as "orphaner" with password "secret" + And all emails have been delivered + And I post the work "To be orphaned" + And I go to the works page + Then I should see "To be orphaned" + And I should see "orphaner" within "#main" + When I try to delete my account as orphaner + Then I should see "What do you want to do with your works?" + When I choose "Change my pseud to "orphan" and attach to the orphan account" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + And I press "Save" + Then I should see "You have successfully deleted your account." + And 0 emails should be delivered + And I should be logged out + And a user account should not exist for "orphaner" + When I go to the works page + Then I should see "To be orphaned" + And I should see "orphan_account" + And I should not see "orphaner" + +Scenario: Delete a user with a collection + Given I have an orphan account + When I am logged in as "moderator" with password "password" + And all emails have been delivered + And I create the collection "fake" + And I go to the collections page + Then I should see "fake" + And I should see "moderator" within "#main" + When I try to delete my account as moderator + Then I should see "You have 1 collection(s) under the following pseuds: moderator." + When I choose "Change my pseud to "orphan" and attach to the orphan account" + # Delay before orphaning to make sure the cache is expired + And it is currently 1 second from now + And I press "Save" + Then I should see "You have successfully deleted your account." + And 0 emails should be delivered + And I should be logged out + And a user account should not exist for "moderator" + When I go to the collections page + Then I should see "fake" + And I should see "orphan_account" + And I should not see "moderator" + +Scenario: Delete a user who has coauthored a work + Given the following activated users exist + | login | password | + | otheruser | password | + And I am logged in as "testuser" + And I coauthored the work "Shared" as "testuser" with "otheruser" + And I wait 1 second + When I try to delete my account + Then I should see "What do you want to do with your works?" + When I choose "Remove me completely as co-creator" + And I press "Save" + Then I should see "You have successfully deleted your account" + And a user account should not exist for "testuser" + And I should be logged out + When I go to the works page + Then I should see "otheruser" + And I should not see "testuser" + + Scenario: Can delete a user who has an empty series + Given I am logged in as "testuser" + And "testuser" has an empty series "Empty" + When I try to delete my account + Then I should see "You have successfully deleted your account." + And a user account should not exist for "testuser" + + Scenario: Can orphan a series when deleting + Given I have an orphan account + And I am logged in as "testuser" + And I post a work "Masterpiece" as part of a series "Epic" + When I try to delete my account + Then I should see "What do you want to do with your works?" + When I choose "Change my pseud to "orphan" and attach to the orphan account" + And I press "Save" + Then I should see "You have successfully deleted your account." + And a user account should not exist for "testuser" + When I go to orphan_account's series page + Then I should see "Epic" diff --git a/features/users/user_rename.feature b/features/users/user_rename.feature new file mode 100755 index 0000000..6219175 --- /dev/null +++ b/features/users/user_rename.feature @@ -0,0 +1,293 @@ +@users +Feature: + In order to correct mistakes or reflect my evolving personality + As a registered user + I should be able to change my username + + Scenario: The user should not be able to change username without a password + Given I am logged in as "testuser" with password "password" + When I visit the change username page for testuser + And I fill in "New username" with "anothertestuser" + And I press "Change Username" + Then I should see "Your password was incorrect" + + Scenario: The user should not be able to change their username with an incorrect password + Given I am logged in as "testuser" with password "password" + When I visit the change username page for testuser + And I fill in "New username" with "anothertestuser" + And I fill in "Password" with "wrongpwd" + And I press "Change Username" + Then I should see "Your password was incorrect" + + Scenario: The user should not be able to change their username to their current username + Given I am logged in as "testuser" with password "password" + When I visit the change username page for testuser + And I fill in "New username" with "testuser" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should see "Your new username must be different from your current username" + + Scenario: The user should be able to change only the capitalization of their username + Given I am logged in as "testy" with password "password" + When I visit the change username page for testy + And I fill in "New username" with "teSty" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should get confirmation that I changed my username + And I should see "Hi, teSty!" + + Scenario: The user should not be able to change their username to another user's name + Given I have no users + And the following activated user exists + | login | password | + | otheruser | secret | + And I am logged in as "downthemall" with password "password" + When I visit the change username page for downthemall + And I fill in "New username" with "otheruser" + And I fill in "Password" with "password" + When I press "Change" + Then I should see "Username has already been taken" + + Scenario: The user should not be able to change their username to another user's name even if the capitalization is different + Given I have no users + And the following activated user exists + | login | password | + | otheruser | secret | + And I am logged in as "downthemall" with password "password" + When I visit the change username page for downthemall + And I fill in "New username" with "OtherUser" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should see "Username has already been taken" + + Scenario: The user should be able to change their username if username and password are valid + Given I am logged in as "downthemall" with password "password" + When I visit the change username page for downthemall + And I fill in "New username" with "DownThemAll" + And I fill in "Password" with "password" + And I press "Change" + Then I should get confirmation that I changed my username + And I should see "Hi, DownThemAll!" + + Scenario: The user should receive an email notification after they change their username + Given I am logged in as "before" with password "password" + And a locale with translated emails + And the user "before" enables translated emails + And it is currently 2025-01-01 00:00 AM + When I change my username to "after" + Then "after" should receive 1 email + And the email should contain "account .*before.* has been changed to .*after" + And the email should contain "usernames can only be changed once every 7 days" + And the email should contain "You will be able to change your username again on Wed, 08 Jan 2025 00:00:00 \+0000" + And the email to "after" should be translated + + Scenario: The user should be able to change their username to a similar version with underscores + Given I am logged in as "downthemall" with password "password" + When I visit the change username page for downthemall + And I fill in "New username" with "Down_Them_All" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should get confirmation that I changed my username + And I should see "Hi, Down_Them_All!" + + Scenario: Changing my username with one pseud changes that pseud + Given I have no users + And I am logged in as "oldusername" with password "password" + When I visit the change username page for oldusername + And I fill in "New username" with "newusername" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should get confirmation that I changed my username + And I should see "Hi, newusername" + When I go to newusername's pseuds page + Then I should not see "oldusername" + When I follow "Edit" + Then I should see "You cannot change the pseud that matches your username" + Then the "pseud_is_default" checkbox should be checked and disabled + + Scenario: Changing only the capitalization of my username with one pseud changes that pseud's capitalization + Given I have no users + And I am logged in as "uppercrust" with password "password" + When I visit the change username page for uppercrust + And I fill in "New username" with "Uppercrust" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should get confirmation that I changed my username + And I should see "Hi, Uppercrust" + When I go to Uppercrust's pseuds page + Then I should not see "uppercrust" + When I follow "Edit" + Then I should see "You cannot change the pseud that matches your username" + Then the "pseud_is_default" checkbox should be checked and disabled + + Scenario: Changing my username with two pseuds, one same as new, doesn't change old + Given I have no users + And the following activated user exists + | login | password | id | + | oldusername | secret | 1 | + And a pseud exists with name: "newusername", user_id: 1 + And I am logged in as "oldusername" with password "secret" + When I visit the change username page for oldusername + And I fill in "New username" with "newusername" + And I fill in "Password" with "secret" + And I press "Change Username" + Then I should get confirmation that I changed my username + And I should see "Hi, newusername" + When I follow "Pseuds (2)" + Then I should see "Edit oldusername" + And I should see "Edit newusername" + + Scenario: Changing username updates search results (bug AO3-3468) + Given I have no users + And I am logged in as "oldusername" with password "password" + And I post a work "Epic story" + And I wait 1 second + When I visit the change username page for oldusername + And I fill in "New username" with "newusername" + And I fill in "Password" with "password" + And I press "Change Username" + And all indexing jobs have been run + Then I should get confirmation that I changed my username + When I am on the works page + Then I should see "newusername" + And I should see "Epic story" + And I should not see "oldusername" + When I search for works containing "oldusername" + Then I should see "No results found" + And I should not see "Epic story" + When I search for works containing "newusername" + Then I should see "Epic story" + + Scenario: Comments reflect username changes immediately + Given the work "Interesting" + And I am logged in as "before" with password "password" + And "before" creates the pseud "mine" + When I set up the comment "Wow!" on the work "Interesting" + And I select "mine" from "comment[pseud_id]" + And I press "Comment" + And I view the work "Interesting" with comments + Then I should see "mine (before)" + When it is currently 1 second from now + And I visit the change username page for before + And I fill in "New username" with "after" + And I fill in "Password" with "password" + And I press "Change Username" + And I view the work "Interesting" with comments + Then I should see "after" within ".comment h4.byline" + And I should not see "mine (before)" + + Scenario: Collections reflect username changes of the owner after the cache expires + When I am logged in as "before" with password "password" + And I create the collection "My Collection Thing" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "before" within "#main" + When I change my username to "after" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "before" within "#main" + When the collection blurb cache has expired + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "after" within "#main" + And I should not see "before" within "#main" + + Scenario: Collections reflect username changes of moderators after the cache expires + Given I am logged in as "mod1" + And I create the collection "My Collection Thing" + And I have added a co-moderator "before" to collection "My Collection Thing" + When I go to the collections page + Then I should see "My Collection Thing" + And I should see "before" within "#main" + When I am logged in as "before" with password "password" + And I change my username to "after" + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "before" within "#main" + When the collection blurb cache has expired + And I go to the collections page + Then I should see "My Collection Thing" + And I should see "after" within "#main" + And I should not see "before" within "#main" + + Scenario: Changing username updates series blurbs + Given I have no users + And I am logged in as "oldusername" with password "password" + And I add the work "Great Work" to series "Best Series" + When I go to the dashboard page for user "oldusername" with pseud "oldusername" + And I follow "Series" + Then I should see "Best Series by oldusername" + When I visit the change username page for oldusername + And I fill in "New username" with "newusername" + And I fill in "Password" with "password" + And I press "Change Username" + Then I should get confirmation that I changed my username + And I should see "Hi, newusername" + When I follow "Series" + Then I should see "Best Series by newusername" + + Scenario: Changing username updates chapter bylines + Given the work "Title" by "pikachu" with chapter two co-authored with "before" + And I am logged in as "before" with password "password" + And I post a chapter for the work "Title" + When I view the work "Title" + And I view the 3rd chapter + Then I should see "Chapter by before" + When I visit the change username page for before + And I fill in "New username" with "after" + And I fill in "Password" with "password" + And it is currently 1 second from now + And I press "Change Username" + Then I should see "Your username has been successfully updated." + When I view the work "Title" + And I view the 3rd chapter + Then I should see "Chapter by after" + + Scenario: Changing the username from a forbidden name to non-forbidden + Given I have no users + And the following activated user exists + | login | password | + | forbidden | secret | + And the username "forbidden" is on the forbidden list + When I am logged in as "forbidden" with password "secret" + And I visit the change username page for forbidden + And I fill in "New username" with "notforbidden" + And I fill in "Password" with "secret" + And I press "Change Username" + Then I should get confirmation that I changed my username + And I should see "Hi, notforbidden" + + Scenario: Tag wrangling supervisors are emailed about tag wrangler username changes + Given the user "before" exists and is activated + And I am logged in as "before" with password "password" + And all emails have been delivered + And I visit the change username page for before + And I fill in "New username" with "after" + And I fill in "Password" with "password" + And I press "Change Username" + Then 0 email should be delivered to "tagwranglers-personnel@example.org" + When the user "wrangler_before" exists and has the role "tag_wrangler" + And I am logged in as "wrangler_before" with password "password" + And all emails have been delivered + And I visit the change username page for wrangler_before + And I fill in "New username" with "wrangler_after" + And I fill in "Password" with "password" + And I press "Change Username" + Then 1 email should be delivered to "tagwranglers-personnel@example.org" + And the email should contain "The wrangler" + And the email should contain "wrangler_before" + And the email should contain "has changed their name" + And the email should contain "wrangler_after" + + Scenario: Bookmarker's bookmark blurbs reflect username changes immediately + Given the work "Interesting" + And I am logged in as "before" + And I bookmark the work "Interesting" + And I go to before's bookmarks page + Then I should see "Bookmarked by before" + + When it is currently 1 second from now + And I change my username to "after" + And I go to after's bookmarks page + Then I should see "Bookmarked by after" + And I should not see "Bookmarked by before" diff --git a/features/works/chapter_edit.feature b/features/works/chapter_edit.feature new file mode 100755 index 0000000..eeaecc4 --- /dev/null +++ b/features/works/chapter_edit.feature @@ -0,0 +1,620 @@ +@works +Feature: Edit chapters + In order to have an work full of chapters + As a humble user + I want to add and remove chapters + + Scenario: Add chapters to an existing work, delete chapters, edit chapters, post chapters in the wrong order, use rearrange page, create draft chapter + + Given the following activated user exists + | login | password | + | epicauthor | password | + And basic tags + When I go to epicauthor's user page + Then I should see "There are no works" + When I am logged in as "epicauthor" with password "password" + + # create a basic single-chapter work + When I follow "New Work" + Then I should see "Post New Work" + When I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "New Fandom" + And I fill in "Work Title" with "New Epic Work" + And I fill in "content" with "Well, maybe not so epic." + And I press "Preview" + Then I should see "Draft was successfully created" + And I should see "1/1" + When I press "Post" + Then I should not see "Chapter 1" + And I should see "Well, maybe not so epic" + And I should see "Words:5" + + # add chapters to a single-chapter work + When I follow "Add Chapter" + And I fill in "chapter_position" with "2" + And I fill in "chapter_wip_length" with "100" + And I fill in "content" with "original chapter two" + And I press "Preview" + Then I should see "This is a draft chapter in a posted work. It will be kept unless the work is deleted." + When I press "Post" + Then I should see "2/100" + And I should see "Words:8" + When I follow "Add Chapter" + And I fill in "chapter_position" with "3" + And I fill in "chapter_wip_length" with "50" + And I fill in "content" with "entering chapter three" + And I press "Preview" + Then I should see "Chapter 3" + When I press "Post" + Then I should see "3/50" + And I should see "Words:11" + + # add chapters in the wrong order + When I follow "Add Chapter" + And I fill in "chapter_position" with "17" + And I fill in "chapter_wip_length" with "17" + And I fill in "content" with "entering fourth chapter out of order" + And I press "Preview" + Then I should see "Chapter 4" + When I press "Post" + And I should see "4/17" + And I should see "Words:17" + + # delete a chapter + When I follow "Edit" + And I follow "2" + And I follow "Delete Chapter" + And I press "Yes, Delete Chapter" + Then I should see "The chapter was successfully deleted." + And I should see "3/17" + And I should see "Words:14" + + # fill in the missing chapter + When I follow "Add Chapter" + And I fill in "chapter_position" with "2" + And I fill in "content" with "entering second chapter out of order" + And I press "Preview" + When I press "Post" + Then I should see "4/17" + And I should see "Words:20" + + # edit an existing chapter + When I follow "Edit" + And I follow "3" + And I fill in "chapter_position" with "4" + And I fill in "chapter_wip_length" with "4" + And I fill in "content" with "last chapter" + And I press "Preview" + Then I should see "Chapter 4" + When I press "Update" + Then I should see "Chapter was successfully updated" + And I should see "Chapter 4" + And I should see "4/4" + And I should see "Words:19" + When I follow "Edit" + And I follow "Manage Chapters" + Then I should see "Drag chapters to change their order." + + # view chapters in the right order + When I am logged out + And all indexing jobs have been run + And I go to epicauthor's works page + And I follow "New Epic Work" + And I follow "Entire Work" + Then I should see "Chapter 1" + And I should see "Well, maybe not so epic." within "#chapter-1" + And I should see "Chapter 2" + And I should see "entering second chapter out of order" within "#chapter-2" + And I should see "Chapter 3" + And I should see "entering fourth chapter out of order" within "#chapter-3" + And I should see "Chapter 4" + And I should see "last chapter" within "#chapter-4" + And I should not see "original chapter two" + When I follow "Chapter by Chapter" + And I follow "Chapter Index" + Then I should see "Chapter Index for New Epic Work by epicauthor" + And I should see "Chapter 1" + And I should see "Chapter 2" + And I should see "Chapter 3" + And I should see "Chapter 4" + + # move chapters around using rearrange page + When I am logged in as "epicauthor" with password "password" + And I view the work "New Epic Work" + And I follow "Edit" + And I follow "Manage Chapters" + Then I should see "Drag chapters to change their order." + When I fill in "chapters_1" with "4" + And I fill in "chapters_2" with "3" + And I fill in "chapters_3" with "2" + And I fill in "chapters_4" with "1" + And I press "Update Positions" + Then I should see "Chapter order has been successfully updated." + When I am logged out + And I go to epicauthor's works page + And I follow "New Epic Work" + And I follow "Entire Work" + Then I should see "Chapter 1" + And I should see "Well, maybe not so epic." within "#chapter-4" + And I should see "Chapter 2" + And I should see "second chapter" within "#chapter-3" + And I should see "Chapter 3" + And I should see "fourth chapter" within "#chapter-2" + And I should see "Chapter 4" + And I should see "last chapter" within "#chapter-1" + + # create a draft chapter and post it, and verify it shows up on the + # rearrange page + When I am logged in as "epicauthor" with password "password" + And a draft chapter is added to "New Epic Work" + When I view the work "New Epic Work" + And I follow "Edit" + Then I should see "5 (Draft)" + When I follow "Manage Chapters" + Then I should see "Chapter 5 (Draft)" + When I view the work "New Epic Work" + Then I should see "4/5" + When I select "5." from "selected_id" + And I press "Go" + Then I should see "This chapter is a draft and hasn't been posted yet!" + When I press "Post" + Then I should see "5/5" + When I follow "Edit" + Then I should not see "Draft" + And I should not see "draft" + When I view the work "New Epic Work" + And I select "5." from "selected_id" + And I press "Go" + Then I should not see "Draft" + And I should not see "draft" + + # create a draft chapter, preview it, edit it and then post it without preview + When I am logged in as "epicauthor" with password "password" + And I view the work "New Epic Work" + And I follow "Add Chapter" + And I fill in "Chapter Title" with "6(66) The Number of the Beast" + And I fill in "content" with "Even more awesomely epic context" + And I press "Preview" + Then I should see "This is a draft chapter in a posted work. It will be kept unless the work is deleted." + When I press "Edit" + And I fill in "content" with "Even more awesomely epic context. Plus bonus epicness" + And I press "Post" + Then I should see "Chapter was successfully posted." + And I should not see "This chapter is a draft and hasn't been posted yet!" + + # create a draft chapter, preview it, edit it, preview it again and then post it + When I am logged in as "epicauthor" with password "password" + And I view the work "New Epic Work" + And I follow "Add Chapter" + And I fill in "Chapter Title" with "6(66) The Number of the Beast" + And I fill in "content" with "Even more awesomely epic context" + And I press "Preview" + Then I should see "This is a draft chapter in a posted work. It will be kept unless the work is deleted." + When I press "Edit" + And I fill in "content" with "Even more awesomely epic context. Plus bonus epicness" + And I press "Preview" + Then I should see "Even more awesomely epic context. Plus bonus epicness" + When I press "Post" + Then I should see "Chapter was successfully posted." + And I should not see "This chapter is a draft and hasn't been posted yet!" + + + Scenario: Create a work and add a draft chapter, edit the draft chapter, and save changes to the draft chapter without previewing or posting + Given basic tags + And I am logged in as "moose" with password "muffin" + When I go to the new work page + Then I should see "Post New Work" + And I select "General Audiences" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "If You Give an X a Y" + And I fill in "Work Title" with "If You Give Users a Draft Feature" + And I fill in "content" with "They will expect it to work." + And I press "Post" + When I should see "Work was successfully posted." + And I should see "They will expect it to work." + When I follow "Add Chapter" + And I fill in "content" with "And then they will request more features for it." + And I press "Preview" + Then I should see "This is a draft chapter in a posted work. It will be kept unless the work is deleted." + And I should see "And then they will request more features for it." + When I press "Edit" + And I fill in "content" with "And then they will request more features for it. Like the ability to save easily." + And I press "Save As Draft" + Then I should see "Chapter was successfully updated." + And I should see "This chapter is a draft and hasn't been posted yet!" + And I should see "Like the ability to save easily." + + + Scenario: Chapter drafts aren't updates; posted chapter drafts are + Given I am logged in as "testuser" with password "testuser" + And I post the work "Backdated Work" + And I edit the work "Backdated Work" + And I check "backdate-options-show" + And I select "1" from "work_chapter_attributes_published_at_3i" + And I select "January" from "work_chapter_attributes_published_at_2i" + And I select "1990" from "work_chapter_attributes_published_at_1i" + And I press "Post" + Then I should see "Published:1990-01-01" + When I follow "Add Chapter" + And I fill in "content" with "this is my second chapter" + And I set the publication date to today + And I press "Preview" + And I should see "This is a draft" + And I press "Save As Draft" + Then I should not see Updated today + And I should not see Completed today + And I should not see "Updated" within ".work.meta .stats" + And I should not see "Completed" within ".work.meta .stats" + When I follow "Edit Chapter" + And I press "Post" + Then I should see Completed today + + + Scenario: Posting a new chapter without previewing should set the work's updated date to now + + Given the work "First work" by "testuser" + And it is currently 2 days from now + And I am logged in as "testuser" + When I view the work "First work" + Then I should not see Updated today + When I follow "Add Chapter" + And I fill in "content" with "this is my second chapter" + And I set the publication date to today + And I press "Post" + Then I should see Completed today + When I follow "Edit" + And I fill in "work_wip_length" with "?" + And I press "Post" + Then I should see Updated today + When I post the work "A Whole New Work" + And I go to the works page + Then "A Whole New Work" should appear before "First work" + When I view the work "First work" + When I follow "Add Chapter" + And I fill in "content" with "this is my third chapter" + And I set the publication date to today + And I press "Post" + And I go to the works page + Then "First work" should appear before "A Whole New Work" + + Scenario: Posting a new chapter with a co-creator does not add them to previous or subsequent chapters + + Given I am logged in as "karma" with password "the1nonly" + And the user "sabrina" allows co-creators + And I post the work "Summer Friends" + When a chapter is set up for "Summer Friends" + And I invite the co-author "sabrina" + And I post the chapter + Then I should not see "sabrina" + When the user "sabrina" accepts all co-creator requests + And I view the work "Summer Friends" + Then I should see "karma, sabrina" + And I should see "Chapter by karma" + When I follow "Next Chapter" + Then I should not see "Chapter by" + When a chapter is set up for "Summer Friends" + Then I should see "Current co-creators" + And the "sabrina" checkbox should not be checked + When I post the chapter + Then I should see "Chapter by karma" + + Scenario: You can edit a pre-existing chapter to invite a new co-creator + + Given I am logged in as "karma" with password "the1nonly" + And the user "amy" allows co-creators + And I post the work "Forever Friends" + And a chapter is added to "Forever Friends" + When I view the work "Forever Friends" + And I view the 2nd chapter + And I follow "Edit Chapter" + And I invite the co-author "amy" + And I post the chapter + Then I should not see "amy, karma" + And 1 email should be delivered to "amy" + And the email should contain "The user karma has invited your pseud amy to be listed as a co-creator on the following chapter" + And the email should not contain "translation missing" + When the user "amy" accepts all co-creator requests + And I view the work "Forever Friends" + Then I should see "amy, karma" + And I should see "Chapter by karma" + When I follow "Next Chapter" + Then I should not see "Chapter by" + + + Scenario: You can edit a chapter to add (not invite) a co-creator who is + already on the work + + Given I am logged in as "karma" with password "the1noly" + And I post the work "Past Friends" + And a chapter with the co-author "sabrina" is added to "Past Friends" + And all emails have been delivered + And a chapter is added to "Past Friends" + When I view the work "Past Friends" + And I view the 3rd chapter + Then I should see "Chapter by karma" + When I follow "Edit Chapter" + Then the "sabrina" checkbox should not be checked + When I check "sabrina" + # Expire cached byline + And it is currently 1 second from now + And I post the chapter + Then I should not see "Chapter by karma" + And 1 email should be delivered to "sabrina" + And the email should contain "The user karma has listed your pseud sabrina as a co-creator on the following chapter" + And the email should contain "a co-creator on a work, you can be added to new chapters regardless of your co-creation settings. You will also be added to any series the work is added to." + And the email should not contain "translation missing" + + + Scenario: Editing a chapter with a co-creator does not allow you to remove the co-creator + + Given I am logged in as "karma" with password "the1noly" + And I post the work "Camp Friends" + And a chapter with the co-author "sabrina" is added to "Camp Friends" + When I follow "Edit Chapter" + Then the "sabrina" checkbox should be checked and disabled + + + Scenario: Removing yourself as a co-creator from the chapter edit page when + you've co-created multiple chapters on the work removes you only from that + specific chapter. Removing yourself as a co-creator from the chapter edit page + of the last chapter you've co-created also removes you from the work. + + Given the work "OP's Work" by "originalposter" with chapter two co-authored with "opsfriend" + And a chapter with the co-author "opsfriend" is added to "OP's Work" + And I am logged in as "opsfriend" + When I view the work "OP's Work" + And I view the 3rd chapter + And I follow "Edit Chapter" + When I press "Remove Me As Chapter Co-Creator" + Then I should see "You have been removed as a creator from the chapter." + And I should see "Chapter 1" + When I view the 3rd chapter + Then I should see "Chapter 3" + And I should see "Chapter by originalposter" + When I follow "Previous Chapter" + And I follow "Edit Chapter" + And I press "Remove Me As Chapter Co-Creator" + Then I should see "You have been removed as a creator from the work." + When I view the work "OP's Work" + Then I should not see "Edit Chapter" + + + Scenario: Removing yourself as a co-creator from the chapter manage page + + Given the work "OP's Work" by "originalposter" with chapter two co-authored with "opsfriend" + And a chapter with the co-author "opsfriend" is added to "OP's Work" + And I am logged in as "opsfriend" + When I view the work "OP's Work" + And I follow "Edit" + And I follow "Manage Chapters" + When I follow "Remove Me As Chapter Co-Creator" + Then I should see "You have been removed as a creator from the chapter." + And I should see "Chapter 1" + When I view the 2nd chapter + Then I should see "Chapter by originalposter" + + + Scenario: The option to remove yourself as a co-creator should only be + included for chapters you are a co-creator of + + Given the work "OP's Work" by "originalposter" with chapter two co-authored with "opsfriend" + And I am logged in as "opsfriend" + When I view the work "OP's Work" + And I follow "Edit" + And I follow "Manage Chapters" + Then the Remove Me As Chapter Co-Creator option should not be on the 1st chapter + And the Remove Me As Chapter Co-Creator option should be on the 2nd chapter + When I view the work "OP's Work" + And I follow "Edit Chapter" + Then I should not see "Remove Me As Chapter Co-Creator" + When I view the work "OP's Work" + And I view the 2nd chapter + And I follow "Edit Chapter" + Then I should see "Remove Me As Chapter Co-Creator" + + + Scenario: You should be able to edit a chapter you are not already co-creator + of, and you will be added to the chapter as a co-creator and your changes will + be saved + + Given I am logged in as "originalposter" + And the user "opsfriend" allows co-creators + And I post the work "OP's Work" + And a chapter with the co-author "opsfriend" is added to "OP's Work" + When I am logged in as "opsfriend" + And I view the work "OP's Work" + Then I should see "Chapter 1" + And I should see "Chapter by originalposter" + When I follow "Edit Chapter" + Then I should not see "You're not allowed to use that pseud." + When I fill in "content" with "opsfriend was here" + And I post the chapter + Then I should see "opsfriend was here" + And I should not see "Chapter by originalposter" + + + Scenario: You should be able to add a chapter with two co-creators, one of + whom is already on the work and the other of whom is not + + Given I am logged in as "rusty" + And the user "sharon" allows co-creators + And the user "brenda" allows co-creators + And I set up the draft "Rusty Has Two Moms" + And I invite the co-author "brenda" + And I post the work without preview + And the user "brenda" accepts all co-creator requests + When a chapter is set up for "Rusty Has Two Moms" + And I invite the co-author "sharon" + And I check "brenda" + And I post the chapter + Then I should see "brenda, rusty" + And I should not see "Chapter by" + When the user "sharon" accepts all co-creator requests + And I view the work "Rusty Has Two Moms" + Then I should see "brenda, rusty, sharon" + And I should see "Chapter by brenda, rusty" + When I follow "Next Chapter" + Then I should not see "Chapter by" + + + Scenario: You should be able to add a chapter with two co-creators who are not + on the work, one of whom has an ambiguous pseud + + Given "thebadmom" has the pseud "sharon" + And "thegoodmom" has the pseud "sharon" + And the user "brenda" allows co-creators + And the user "thebadmom" allows co-creators + And the user "thegoodmom" allows co-creators + And I am logged in as "rusty" + And I post the work "Rusty Has Two Moms" + When a chapter is set up for "Rusty Has Two Moms" + And I try to invite the co-authors "sharon, brenda" + And I post the chapter + Then I should see "The pseud sharon is ambiguous." + When I select "thegoodmom" from "There's more than one user with the pseud sharon." + And I press "Post" + Then I should not see "brenda" + And I should not see "sharon" + But 1 email should be delivered to "brenda" + And 1 email should be delivered to "thegoodmom" + When the user "brenda" accepts all co-creator requests + And the user "thegoodmom" accepts all co-creator requests + And I view the work "Rusty Has Two Moms" + Then I should see "brenda, rusty, sharon (thegoodmom)" + + + Scenario: You should be able to add a chapter with two co-creators, one of + whom is already on the work and the other of whom has an ambiguous pseud + + Given "thebadmom" has the pseud "sharon" + And the user "thegoodmom" allows co-creators + And the user "thebadmom" allows co-creators + And "thegoodmom" has the pseud "sharon" + And I am logged in as "rusty" + And I set up the draft "Rusty Has Two Moms" + And I invite the co-author "brenda" + And I post the work without preview + And the user "brenda" accepts all co-creator requests + When a chapter is set up for "Rusty Has Two Moms" + And I invite the co-author "sharon" + And I check "brenda" + And I post the chapter + Then I should see "The pseud sharon is ambiguous." + When I select "thegoodmom" from "There's more than one user with the pseud sharon." + And I press "Post" + Then I should see "brenda, rusty" + When the user "thegoodmom" accepts all co-creator requests + And I view the work "Rusty Has Two Moms" + Then I should see "brenda, rusty, sharon (thegoodmom)" + + + Scenario: Users can't set a chapter publication date that is in the future, + e.g. set the date to April 30 when it is April 26 + + Given I am logged in + And it is currently Wed Apr 26 22:00:00 UTC 2017 + And I post the work "Futuristic" + And a chapter is set up for "Futuristic" + When I select "30" from "chapter[published_at(3i)]" + And I press "Post" + Then I should see "Publication date can't be in the future." + When I jump in our Delorean and return to the present + + + Scenario: The Post Draft option on your drafts page only posts the first + chapter of a multi-chapter draft + Given I have a multi-chapter draft + And I follow "My Dashboard" + And I follow "Drafts (" + When I follow "Post Draft" + Then I should see "Your work was successfully posted." + And I should not see "This chapter is a draft and hasn't been posted yet!" + When I follow "Next Chapter" + Then I should see "This chapter is a draft and hasn't been posted yet!" + + Scenario: You should be able to invite a co-creator to a chapter if they allow it. + + Given the user "brenda" allows co-creators + And I am logged in as "rusty" + And I post the work "Rusty Has Two Moms" + When a chapter is set up for "Rusty Has Two Moms" + And I invite the co-author "brenda" + And I press "Post" + Then I should see "Chapter has been posted!" + And I should not see "brenda" + But 1 email should be delivered to "brenda" + And the email should contain "The user rusty has invited your pseud brenda to be listed as a co-creator on the following chapter" + And the email should not contain "translation missing" + When I am logged in as "brenda" + And I follow "Rusty Has Two Moms" in the email + Then I should not see "Edit" + When I follow "Co-Creator Requests page" + And I check "selected[]" + # Delay before accepting the request to make sure the cache is expired: + And it is currently 1 second from now + And I press "Accept" + Then I should see "You are now listed as a co-creator on Chapter 2 of Rusty Has Two Moms." + When I follow "Rusty Has Two Moms" + Then I should see "brenda, rusty" + And I should see "Edit" + + Scenario: You should not be able to invite a co-creator to a chapter if they do not allow it. + + Given the user "brenda" disallows co-creators + And I am logged in as "rusty" + And I post the work "Rusty Has Two Moms" + When a chapter is set up for "Rusty Has Two Moms" + And I try to invite the co-author "brenda" + And I press "Post" + Then I should see "brenda does not allow others to invite them to be a co-creator." + And 0 emails should be delivered to "brenda" + When I press "Preview" + Then I should see "This is a draft chapter in a posted work. It will be kept unless the work is deleted." + When I press "Post" + Then I should see "Chapter was successfully posted." + And I should see "rusty" + And I should not see "brenda" + + Scenario: You should be able to add a co-creator to a chapter if they do not allow it, if they are a co-creator of the work. + + Given the user "thegoodmom" allows co-creators + And I am logged in as "rusty" + And I set up the draft "Rusty Has Two Moms" + And I invite the co-author "thegoodmom" + And I post the work without preview + Then I should see "Work was successfully posted." + When the user "thegoodmom" accepts all co-creator requests + And I view the work "Rusty Has Two Moms" + Then I should see "rusty, thegoodmom" + When the user "thegoodmom" disallows co-creators + And I post a chapter for the work "Rusty Has Two Moms" + Then I should see "Chapter has been posted!" + And I follow "Chapter 2" + And I should see "Chapter by rusty" + And I follow "Edit Chapter" + When I check "Add co-creators?" + And I fill in "pseud_byline" with "thegoodmom" + And I press "Post" + Then I should see "Chapter was successfully updated." + And I follow "Chapter 2" + And I follow "Edit Chapter" + And I should see "Remove Me As Chapter Co-Creator" + + Scenario: You can't add a chapter to a work with too many tags + Given the user-defined tag limit is 7 + And I am logged in as a random user + And I post the work "Over the Limit" + And the work "Over the Limit" has 2 fandom tags + And the work "Over the Limit" has 2 character tags + And the work "Over the Limit" has 2 relationship tags + And the work "Over the Limit" has 2 freeform tags + When I follow "Add Chapter" + And I fill in "content" with "this is my second chapter" + And I press "Post" + Then I should see "Fandom, relationship, character, and additional tags must not add up to more than 7. Your work has 8 of these tags, so you must remove 1 of them." + When I view the work "Over the Limit" + Then I should see "1/1" + And I should not see "Next Chapter" diff --git a/features/works/work_browse.feature b/features/works/work_browse.feature new file mode 100755 index 0000000..838d31e --- /dev/null +++ b/features/works/work_browse.feature @@ -0,0 +1,186 @@ +@works @browse +Feature: Browsing works from various contexts + +Scenario: Browsing works with incorrect page params in query string + Given a canonical fandom "Johnny Be Good" + And I am logged in + And I post the work "Whatever" with fandom "Johnny Be Good" + When I browse the "Johnny Be Good" works with page parameter "" + Then I should see "1 Work" + +Scenario: If works in a listing exceed the maximum search result count, + display a notice on the last page of results + + Given a canonical fandom "Aggressive Retsuko" + And the max search result count is 4 + And 2 items are displayed per page + And I am logged in + And I post the work "Whatever 1" with fandom "Aggressive Retsuko" + # Ensure stable work order + And it is currently 1 second from now + And I post the work "Whatever 2" with fandom "Aggressive Retsuko" + And it is currently 1 second from now + And I post the work "Whatever 3" with fandom "Aggressive Retsuko" + And it is currently 1 second from now + And I post the work "Whatever 4" with fandom "Aggressive Retsuko" + + When I browse the "Aggressive Retsuko" works with page parameter "2" + Then I should see "3 - 4 of 4 Works" + And I should not see "Please use the filters" + + When it is currently 1 second from now + And I post the work "Whatever 5" with fandom "Aggressive Retsuko" + And I browse the "Aggressive Retsuko" works + Then I should see "1 - 2 of 5 Works" + And I should not see "Please use the filters" + When I follow "Next" + Then I should see "3 - 4 of 5 Works" + And I should see "Displaying 4 results out of 5. Please use the filters" + + When I browse the "Aggressive Retsuko" works with page parameter "3" + Then I should see "3 - 4 of 5 Works" + And I should see "Displaying 4 results out of 5. Please use the filters" + When I follow "Previous" + Then I should see "1 - 2 of 5 Works" + And I should not see "Please use the filters" + +Scenario: The recent chapter link should point to the last posted chapter even +if there is a draft chapter + + Given I am logged in as a random user + And a canonical fandom "Canonical Fandom" + And I post the 2 chapter work "My WIP" with fandom "Canonical Fandom" + When I browse the "Canonical Fandom" works + And I follow the recent chapter link for the work "My WIP" + Then I should be on the 2nd chapter of the work "My WIP" + When a draft chapter is added to "My WIP" + And I browse the "Canonical Fandom" works + And I follow the recent chapter link for the work "My WIP" + Then I should be on the 2nd chapter of the work "My WIP" + +Scenario: The recent chapter link in a work's blurb should show the adult +content notice to visitors who are not logged in + + Given I am logged in as a random user + And a canonical fandom "Canonical Fandom" + And I post the 3 chapter work "WIP" with fandom "Canonical Fandom" with rating "Mature" + When I am logged out + And I browse the "Canonical Fandom" works + And I follow the recent chapter link for the work "WIP" + Then I should see "adult content" + When I follow "Yes, Continue" + Then I should be on the 3rd chapter of the work "WIP" + +Scenario: The recent chapter link in a work's blurb should honor the logged-in +user's "Show me adult content without checking" preference + + Given I am logged in as a random user + And a canonical fandom "Canonical Fandom" + And I post the 2 chapter work "WIP" with fandom "Canonical Fandom" with rating "Mature" + When I am logged in as "adultuser" + And I set my preferences to show adult content without warning + And I browse the "Canonical Fandom" works + And I follow the recent chapter link for the work "WIP" + Then I should not see "adult content" + And I should be on the 2nd chapter of the work "WIP" + When I set my preferences to warn before showing adult content + And I browse the "Canonical Fandom" works + And I follow the recent chapter link for the work "WIP" + Then I should see "adult content" + When I follow "Yes, Continue" + Then I should be on the 2nd chapter of the work "WIP" + +Scenario: The recent chapter link in a work's blurb should point to +chapter-by-chapter mode even if the logged-in user's preference is "Show the +whole work by default" + + Given I am logged in as a random user + And a canonical fandom "Canonical Fandom" + And I post the 2 chapter work "WIP" with fandom "Canonical Fandom" with rating "Mature" + When I am logged in as "fullworker" + And I set my preferences to View Full Work mode by default + And I browse the "Canonical Fandom" works + And I follow the recent chapter link for the work "WIP" + Then I should be on the 2nd chapter of the work "WIP" + +Scenario: The recent chapter link in a work's blurb points to the last posted +chapter when the chapters are reordered. + + Given I am logged in as a random user + And a canonical fandom "Canonical Fandom" + And I post the 2 chapter work "My WIP" with fandom "Canonical Fandom" + When I browse the "Canonical Fandom" works + And I follow the recent chapter link for the work "My WIP" + Then I should be on the 2nd chapter of the work "My WIP" + When I follow "Edit" + And I follow "Manage Chapters" + And I fill in "chapters_1" with "2" + And I fill in "chapters_2" with "1" + And I press "Update Positions" + Then I should see "Chapter order has been successfully updated." + When I browse the "Canonical Fandom" works + And I follow the recent chapter link for the work "My WIP" + Then I should be on the 2nd chapter of the work "My WIP" + + Scenario: Kudos link from from work browsing leads to full work page + Given the chaptered work with 2 chapters "Awesome Work" + When I am logged in as "reader" + And I go to the works page + Then I should not see "Kudos: 1" within the work blurb of "Awesome Work" + When I view the work "Awesome Work" + And I leave kudos on "Awesome Work" + Then I should see "reader left kudos on this work!" + When I am logged out + And the cache for the work "Awesome Work" is cleared + And I go to the works page + Then I should see "Kudos: 1" within the work blurb of "Awesome Work" + When I follow the kudos link for the work "Awesome Work" + Then I should be on the work "Awesome Work" + And I should see "reader left kudos on this work!" + + Scenario: Comments link from from work browsing leads to full work page + Given the chaptered work with 2 chapters "Awesome Work" + When I am logged in as "reader" + And I go to the works page + Then I should not see "Comments: 1" within the work blurb of "Awesome Work" + When I post the comment "Bravo!" on the work "Awesome Work" + Then I should see "Bravo!" + When I am logged out + And the cache for the work "Awesome Work" is cleared + And I go to the works page + Then I should see "Comments: 1" within the work blurb of "Awesome Work" + When I follow the comments link for the work "Awesome Work" + Then I should be on the work "Awesome Work" + And I should see "Bravo!" + +Scenario: Can also browse work indexed by language + Given basic languages + And Persian language + And basic tags + And I am logged in + And I post the work "Whatever 1" with fandom "Aggressive Retsuko" + And I post the work "Whatever 2" with fandom "Aggressive Retsuko" + When I go to the new work page + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I fill in "Fandoms" with "Weiß Kreuz" + And I fill in "Work Title" with "Überraschende Überraschung" + And I fill in "content" with "Dies ist eine Fanfic in Deutsch." + And I select "Deutsch" from "Choose a language" + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "Deutsch" within "dd.language" + When I browse works in language "English" + Then I should see "2 Works in English" + When I press "Sort and Filter" + Then I should see "2 Works in English" + When I browse works in language "Deutsch" + Then I should see "1 Work in Deutsch" + When I browse works in language "Persian" + Then I should see "0 Works in Persian" + +Scenario: Work blurb includes an HTML comment containing the unix epoch of the updated time + Given time is frozen at 2025-04-12 17:00 UTC + And the work "Test" + When I go to the works page + Then I should see an HTML comment containing the number 1744477200 within "li.work.blurb" diff --git a/features/works/work_create.feature b/features/works/work_create.feature new file mode 100755 index 0000000..6736ceb --- /dev/null +++ b/features/works/work_create.feature @@ -0,0 +1,427 @@ +@works @tags +Feature: Create Works + In order to have an archive full of works + As an author + I want to create new works + + Scenario: You can't create a work unless you're logged in + When I go to the new work page + Then I should see "Please log in" + + Scenario: Creating a new minimally valid work + Given basic tags + And I am logged in as "newbie" + When I go to the new work page + Then I should see "Post New Work" + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "Supernatural" + And I fill in "Work Title" with "All Hell Breaks Loose 🤬💩" + And I fill in "content" with "Bad things happen, etc. 🤬💩" + When I press "Preview" + Then I should see "Preview" + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "Bad things happen, etc. 🤬💩" + When I go to the works page + Then I should see "All Hell Breaks Loose 🤬💩" + + Scenario: Creating a new minimally valid work and posting without preview + Given I am logged in as "newbie" + When I set up the draft "All Hell Breaks Loose" + And I fill in "content" with "Bad things happen, etc." + And I press "Post" + Then I should see "Work was successfully posted." + And I should see "Bad things happen, etc." + When I go to the works page + Then I should see "All Hell Breaks Loose" + + Scenario: Creating a new minimally valid work when you have more than one pseud + Given I am logged in as "newbie" + And "newbie" creates the pseud "Pointless Pseud" + When I set up the draft "All Hell Breaks Loose" + And I unselect "newbie" from "Creator/Pseud(s)" + And I select "Pointless Pseud" from "Creator/Pseud(s)" + And I press "Post" + Then I should see "Work was successfully posted." + When I go to the works page + Then I should see "All Hell Breaks Loose" + And I should see "by Pointless Pseud" + + @javascript + Scenario: Creating a new work with everything filled in, and we do mean everything + Given basic tags + And the following activated users exist + | login | email | + | coauthor | coauthor@example.org | + | cosomeone | cosomeone@example.org | + | giftee | giftee@example.org | + | recipient | recipient@example.org | + And the user "coauthor" allows co-creators + And the user "cosomeone" allows co-creators + And the user "giftee" allows gifts + And the user "recipient" allows gifts + And I have a collection "Collection 1" with name "collection1" + And I have a collection "Collection 2" with name "collection2" + And "thorough" has the pseud "Pseud2" + And "thorough" has the pseud "Pseud3" + And I am logged in as "thorough" + And all emails have been delivered + When I go to the new work page + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I check "F/M" + And I fill in "Fandoms" with "Supernatural" + And I fill in "Work Title" with "All Something Breaks Loose" + And I fill in "content" with "Bad things happen, etc." + And I check "at the beginning" + And I fill in "Notes" with "This is my beginning note" + And I fill in "End Notes" with "This is my endingnote" + And I fill in "Summary" with "Have a short summary" + And I fill in "Characters" with "Sam Winchester, Dean Winchester," + And I fill in "Relationships" with "Harry/Ginny" + And I fill in "Additional Tags" with "An extra tag" + And I fill in "Gift this work to" with "Someone else, recipient" + And I check "This work is part of a series" + And I fill in "Or create and use a new one:" with "My new series" + And I select "Pseud2" from "Creator/Pseud(s)" + And I select "Pseud3" from "Creator/Pseud(s)" + And I fill in "pseud_byline_autocomplete" with "coauthor" + And I fill in "Post to Collections / Challenges" with "collection1, collection2" + And I press "Preview" + Then I should see "Draft was successfully created" + When I press "Post" + Then I should see "Work was successfully posted." + And 1 email should be delivered to "coauthor@example.org" + And the email should contain "The user thorough has invited your pseud coauthor to be listed as a co-creator on the following work" + And the email should not contain "translation missing" + And 1 email should be delivered to "recipient@example.org" + And the email should contain "A gift work has been posted for you" + When I go to the works page + Then I should see "All Something Breaks Loose" + When I follow "All Something Breaks Loose" + Then I should see "All Something Breaks Loose" + And I should see "Fandom: Supernatural" + And I should see "Rating: Not Rated" + And I should see "No Archive Warnings Apply" + And I should not see "Choose Not To Use Archive Warnings" + And I should see "Category: F/M" + And I should see "Characters: Sam Winchester Dean Winchester" + And I should see "Relationship: Harry/Ginny" + And I should see "Additional Tags: An extra tag" + And I should see "For Someone else, recipient" + And I should see "Collections: Collection 1, Collection 2" + And I should see "Notes" + And I should see "This is my beginning note" + And I should see "See the end of the work for more notes" + And I should see "This is my endingnote" + And I should see "Summary" + And I should see "Have a short summary" + And I should see "My new series" + And I should see "Bad things happen, etc." + And I should see "Pseud2" within ".byline" + And I should see "Pseud3" within ".byline" + But I should not see "coauthor" within ".byline" + When the user "coauthor" accepts all co-creator requests + And I view the work "All Something Breaks Loose" + Then I should see "coauthor" within ".byline" + When I follow "Add Chapter" + And I fill in "Chapter Title" with "This is my second chapter" + And I fill in "content" with "Let's write another story" + And I press "Preview" + Then I should see "Chapter 2: This is my second chapter" + And I should see "Let's write another story" + When I press "Post" + Then I should see "All Something Breaks Loose" + And I should not see "Bad things happen, etc." + And I should see "Let's write another story" + When I follow "Previous Chapter" + And I should see "Bad things happen, etc." + When I follow "Entire Work" + Then I should see "Bad things happen, etc." + And I should see "Let's write another story" + When I follow "Edit" + And I check "Add co-creators?" + And I fill in "pseud_byline_autocomplete" with "Does_not_exist" + And I press "Preview" + Then I should see "Invalid creator: Could not find a pseud Does_not_exist." + When all emails have been delivered + And I choose "cosomeone" from the "pseud_byline_autocomplete" autocomplete + And I press "Preview" + And I press "Update" + Then I should see "Work was successfully updated" + And I should see "coauthor" within ".byline" + And I should see "Pseud2" within ".byline" + And I should see "Pseud3" within ".byline" + But I should not see "cosomeone" within ".byline" + And 1 email should be delivered to "cosomeone@example.org" + When the user "cosomeone" accepts all co-creator requests + And I view the work "All Something Breaks Loose" + Then I should see "cosomeone" within ".byline" + When all emails have been delivered + And I follow "Edit" + And I remove selected values from the autocomplete field within "dd.recipient" + And I give the work to "giftee" + And I press "Preview" + And I press "Update" + Then I should see "Work was successfully updated" + And I should see "For giftee" + And 1 email should be delivered to "giftee@example.org" + When I go to giftee's user page + Then I should see "Gifts (1)" + + Scenario: Creating a new work with some maybe-invalid things + # TODO: needs some more actually invalid things as well + Given basic tags + And the following activated users exist + | login | password | email | + | coauthor | something | coauthor@example.org | + | badcoauthor | something | badcoauthor@example.org | + And I am logged in as "thorough" with password "something" + And user "badcoauthor" is banned + And the user "coauthor" allows co-creators + When I set up the draft "Bad Draft" + And I fill in "Fandoms" with "Invalid12./" + And I fill in "Work Title" with "/" + And I fill in "content" with "T" + And I check "chapters-options-show" + And I fill in "work_wip_length" with "text" + And I press "Preview" + Then I should see "Content must be at least 10 characters long." + When I fill in "content" with "Text and some longer text" + And I fill in "work_collection_names" with "collection1, collection2" + And I press "Preview" + Then I should see "Sorry! We couldn't save this work because:" + And I should see a collection not found message for "collection1" + # Collections are now parsed by collectible.rb which only shows the first failing collection and nothing else + # And I should see a collection not found message for "collection2" + When I fill in "work_collection_names" with "" + And I fill in "pseud_byline" with "badcoauthor" + And I press "Preview" + Then I should see "badcoauthor cannot be listed as a co-creator" + When I fill in "pseud_byline" with "coauthor" + And I fill in "Additional Tags" with "this is a very long tag more than one hundred fifty characters in length how would this normally even be created plus some extra words to pad this out 1" + And I press "Preview" + Then I should see "try using less than 150 characters or using commas to separate your tags" + When I fill in "Additional Tags" with "this is a shorter tag" + And I press "Preview" + Then I should see "Draft was successfully created" + And I should see "Chapter" + And I should see "1/?" + + Scenario: Creating a new work in a new series with some invalid things should return to the new work page with an error message and the newly created series selected + Given basic tags + And I am logged in as "thorough" with password "something" + When I set up the draft "Bad Draft" + And I fill in "Fandoms" with "Invalid12./" + And I fill in "Work Title" with "/" + And I fill in "content" with "T" + And I check "This work has multiple chapters" + And I fill in "Post to Collections / Challenges" with "collection1, collection2" + And I check "This work is part of a series" + And I fill in "Or create and use a new one:" with "My new series" + And I press "Preview" + Then I should see "Sorry! We couldn't save this work because:" + And I should see a collection not found message for "collection1" + And I should see "My new series" in the "Or create and use a new one:" input + And I should not see "Remove Work From Series" + + Scenario: Creating a new work in an existing series with some invalid things should return to the new work page with an error message and series information still filled in + Given basic tags + And I am logged in as "thorough" with password "something" + And I post the work "Work one" as part of a series "My existing series" + When I set up the draft "Bad Draft" + And I fill in "Fandoms" with "Invalid12./" + And I fill in "Work Title" with "/" + And I fill in "content" with "T" + And I check "This work has multiple chapters" + And I fill in "Post to Collections / Challenges" with "collection1, collection2" + And I check "This work is part of a series" + And I select "My existing series" from "Choose one of your existing series:" + And I press "Preview" + Then I should see "Sorry! We couldn't save this work because:" + And I should see a collection not found message for "collection1" + And "My existing series" should be selected within "Choose one of your existing series:" + And I should not see "Remove Work From Series" + + Scenario: test for integer title and multiple fandoms + Given I am logged in + When I set up the draft "02138" + And I fill in "Fandoms" with "Supernatural, Smallville" + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "Supernatural" + And I should see "Smallville" + And I should see "02138" within "h2.title" + + Scenario: test for < and > in title + Given I am logged in + When I set up the draft "4 > 3 and 2 < 5" + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "4 > 3 and 2 < 5" within "h2.title" + + Scenario: posting a chapter without preview + Given I am logged in as "newbie" with password "password" + And I post the work "All Hell Breaks Loose" + When I follow "Add Chapter" + And I fill in "Chapter Title" with "This is my second chapter" + And I fill in "content" with "Let's write another story" + And I press "Post" + Then I should see "Chapter 2: This is my second chapter" + And I should see "Chapter has been posted!" + And I should not see "This is a preview" + + Scenario: RTE and HTML buttons are separate + Given the default ratings exist + And I am logged in as "newbie" + When I go to the new work page + Then I should see "Post New Work" + And I should see "Rich Text" within ".rtf-html-switch" + And I should see "HTML" within ".rtf-html-switch" + + Scenario: posting a backdated work + Given I am logged in as "testuser" with password "testuser" + And I post the work "This One Stays On Top" + And I set up the draft "Backdated" + And I check "backdate-options-show" + And I select "1" from "work_chapter_attributes_published_at_3i" + And I select "January" from "work_chapter_attributes_published_at_2i" + And I select "1990" from "work_chapter_attributes_published_at_1i" + And I press "Preview" + When I press "Post" + Then I should see "Published:1990-01-01" + When I go to the works page + Then "This One Stays On Top" should appear before "Backdated" + + Scenario: Users must set something as a warning and Author Chose Not To Use Archive Warnings should not be added automatically + Given basic tags + And I am logged in + When I go to the new work page + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "Dallas" + And I fill in "Work Title" with "I Shot J.R.: Kristin's Story" + And I fill in "content" with "It wasn't my fault, you know." + And I press "Post" + Then I should see "We couldn't save this work" + And I should see "Please select at least one warning." + When I check "No Archive Warnings Apply" + And I press "Post" + Then I should see "Work was successfully posted." + And I should see "No Archive Warnings Apply" + And I should not see "Author Chose Not To Use Archive Warnings" + And I should see "It wasn't my fault, you know." + + Scenario: Users can co-create a work with a co-creator who has multiple pseuds + Given basic tags + And "myself" has the pseud "Me" + And "herself" has the pseud "Me" + And the user "myself" allows co-creators + And the user "herself" allows co-creators + When I am logged in as "testuser" with password "testuser" + And I go to the new work page + And I fill in the basic work information for "All Hell Breaks Loose" + And I check "Add co-creators?" + And I fill in "pseud_byline" with "Me" + And I check "This work is part of a series" + And I fill in "Or create and use a new one:" with "My new series" + And I press "Post" + Then I should see "There's more than one user with the pseud Me." + And I select "myself" from "Please choose the one you want:" + And I press "Preview" + Then I should see "Draft was successfully created." + And I press "Post" + Then I should see "Work was successfully posted. It should appear in work listings within the next few minutes." + And I should not see "Me (myself)" + And I should see "My new series" + When the user "myself" accepts all co-creator requests + And I view the work "All Hell Breaks Loose" + Then I should see "Me (myself), testuser" + + Scenario: Users can only create a work with a co-creator who allows it. + Given basic tags + And "Burnham" has the pseud "Michael" + And "Pike" has the pseud "Christopher" + And the user "Burnham" allows co-creators + When I am logged in as "testuser" with password "testuser" + And I go to the new work page + And I fill in the basic work information for "Thats not my Spock" + And I check "Add co-creators?" + And I fill in "pseud_byline" with "Michael,Christopher" + And I press "Post" + Then I should see "Christopher (Pike) does not allow others to invite them to be a co-creator." + When I fill in "pseud_byline" with "Michael" + And I press "Preview" + Then I should see "Draft was successfully created." + When I press "Post" + Then I should see "Work was successfully posted. It should appear in work listings within the next few minutes." + But I should not see "Michael (Burnham)" + When the user "Burnham" accepts all co-creator requests + And I view the work "Thats not my Spock" + Then I should see "Michael (Burnham), testuser" + + Scenario: Users can't set a publication date that is in the future, e.g. set + the date to April 30 when it is April 26 + Given I am logged in + And it is currently Wed Apr 26 22:00:00 UTC 2017 + And I set up a draft "Futuristic" + When I check "Set a different publication date" + And I select "30" from "work[chapter_attributes][published_at(3i)]" + And I press "Post" + Then I should see "Publication date can't be in the future." + When I jump in our Delorean and return to the present + + Scenario: Inviting a co-author adds the co-author to all existing chapters when they accept the invite + Given the user "foobar" exists and is activated + And the user "barbaz" exists and is activated + + When I am logged in as "foobar" + And I post the chaptered work "Chaptered Work" + And I edit the work "Chaptered Work" + And I invite the co-author "barbaz" + And I press "Post" + Then I should not see "barbaz" + But 1 email should be delivered to "barbaz" + When I am logged in as "barbaz" + And I view the work "Chaptered Work" + Then I should not see "Edit" + # Delay to make sure that the cache expires when we accept the request: + When it is currently 1 second from now + And I follow "Co-Creator Requests page" + And I check "selected[]" + And I press "Accept" + Then I should see "You are now listed as a co-creator on Chaptered Work." + When I follow "Chaptered Work" + Then I should see "Edit" + And I should see "barbaz, foobar" + And I should not see "Chapter by" + When I follow "Next Chapter" + Then I should see "barbaz, foobar" + And I should not see "Chapter by" + + Scenario: You cannot create a work with too many tags + Given the user-defined tag limit is 7 + And I am logged in as a random user + When I set up the draft "Over the Limit" + And I fill in "Fandoms" with "Fandom 1, Fandom 2" + And I fill in "Characters" with "Character 1, Character 2" + And I fill in "Relationships" with "Relationship 1, Relationship 2" + And I fill in "Additional Tags" with "Additional Tag 1, Additional Tag 2" + And I press "Post" + Then I should see "Fandom, relationship, character, and additional tags must not add up to more than 7. Your work has 8 of these tags, so you must remove 1 of them." + + @javascript + Scenario: "Please wait..." message disappears when validation errors are fixed + Given basic tags + And I am logged in as "test_user" + When I go to the new work page + And I fill in "Work Title" with "Unicorns Abound" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "Dallas" + And I press "Post" + Then I should see "Brevity is the soul of wit, but your content does have to be at least 10 characters long." + And I should see a button with text "Please wait..." + When I fill in "content" with "help there are unicorns everywhere" + Then I should see a button with text "Post" diff --git a/features/works/work_dates_edit.feature b/features/works/work_dates_edit.feature new file mode 100755 index 0000000..8619c1d --- /dev/null +++ b/features/works/work_dates_edit.feature @@ -0,0 +1,85 @@ +@works +Feature: Edit Works Dates + In order to have an archive full of works + As an author + I want to edit existing works + + Scenario: Editing dates on a work + When "AO3-2539" is fixed +# Given I have loaded the fixtures +# And I am logged in as "testuser" with password "testuser" +# And all indexing jobs have been run +# When I am on testuser's works page +# Then I should not see "less than 1 minute ago" +# And I should see "29 Apr 2012" +# When I follow "First work" +# Then I should see "first fandom" +# And I should see "Edit" + + # Editing a work doesn't change the published date +# When I follow "Edit" +# Then I should see "Edit Work" +# When I fill in "content" with "first chapter content" +# And I check "chapters-options-show" +# And I fill in "work_wip_length" with "3" +# And I press "Preview" +# Then I should see "Preview" +# And I should see "Fandom: first fandom" +# And I should see "first chapter content" +# And I should see "Published:2010-04-30" +# When I update the work +# Then I should see "Work was successfully updated." +# And I should see "Published:2010-04-30" +# And I should not see Updated today + + # Adding a chapter doesn't change the published date, but adds "Updated today" +# When I follow "Add Chapter" +# And I fill in "content" with "this is my second chapter" +# And I press "Preview" +# Then I should see "This is a draft chapter in a posted work. It will be kept unless the work is deleted." +# When I press "Post" +# Then I should see "Chapter was successfully posted." +# And I should see "Published:2010-04-30" +# And I should see Updated today +# When I am on testuser's works page +# Then I should see "less than 1 minute ago" +# And I should not see "29 Apr 2010" + + # Backdating the first chapter (the Work) changes published date but not the updated date +# When I edit the work "First work" +# And I check "backdate-options-show" +# When I select "1" from "work_chapter_attributes_published_at_3i" +# And I select "January" from "work_chapter_attributes_published_at_2i" +# And I select "1990" from "work_chapter_attributes_published_at_1i" +# And I press "Preview" +# And I press "Update" +# Then I should see "Published:1990-01-01" +# And I should see "first chapter content" +# And I should not see "this is my second chapter" +# And I should see Updated today + + # The entire work is backdated. Now, I want to edit chapter two to have a "Chapter Publication + # Date" date set to January 16th, 2013. This should not affect the work's published date, but + # the work's updated date should change to match the most recent chapter pub date +# When I follow "Next Chapter" +# And I follow "Edit Chapter" +# And I select "16" from "chapter_published_at_3i" +# And I select "January" from "chapter_published_at_2i" +# And I select "2013" from "chapter_published_at_1i" +# And I press "Preview" +# And I press "Update" +# Then I should see "Updated:2013-01-16" +# And I should see "Published:1990-01-01" +# When I follow "Full-page index" +# Then I should see "1. Chapter 1 (1990-01-01)" +# And I should see "2. Chapter 2 (2013-01-16)" + + Scenario: Users cannot backdate a work back to the future + Given it is currently 1/1/2019 + And I am logged in as a random user + And I post the work "Beauty and the Beast 2077" + When I edit the work "Beauty and the Beast 2077" + And I check "Set a different publication date" + And I select "December" from "work_chapter_attributes_published_at_2i" + And I press "Post" + Then I should see "Sorry! We couldn't save this work because: Publication date can't be in the future." diff --git a/features/works/work_delete.feature b/features/works/work_delete.feature new file mode 100755 index 0000000..cc0e71f --- /dev/null +++ b/features/works/work_delete.feature @@ -0,0 +1,214 @@ +@works @tags +Feature: Delete Works + Check that everything disappears correctly when deleting a work + + Scenario: Deleting a minimally valid work + Given I am logged in as "newbie" + And I post the work "All Hell Breaks Loose" + When I delete the work "All Hell Breaks Loose" + Then I should see "Your work All Hell Breaks Loose was deleted." + And "newbie" should be notified by email about the deletion of "All Hell Breaks Loose" + When I go to the works page + Then I should not see "All Hell Breaks Loose" + When I go to newbie's user page + Then I should not see "All Hell Breaks Loose" + + Scenario: Deleting a work with escapable characters in title + Given I am logged in as "newbie" + And I post the work "All Hell Breaks Loose" + When I delete the work "All Hell Breaks Loose" + Then I should see "Your work All Hell Breaks Loose was deleted." + And "newbie" should be notified by email about the deletion of "All Hell <b>Breaks</b> Loose" + When I go to the works page + Then I should not see "All Hell Breaks Loose" + When I go to newbie's user page + Then I should not see "All Hell Breaks Loose" + + Scenario: Deleting minimally valid work when you have more than one pseud + Given basic tags + And I am logged in as "newbie" + And "newbie" creates the default pseud "Pointless Pseud" + When I set up the draft "All Hell Breaks Loose" with fandom "Supernatural" + And I select "Pointless Pseud" from "Creator/Pseud(s)" + And I press "Preview" + And I press "Post" + Then I should see "Work was successfully posted." + When I go to the works page + Then I should see "All Hell Breaks Loose" + When I delete the work "All Hell Breaks Loose" + Then I should see "Your work All Hell Breaks Loose was deleted." + And 1 email should be delivered + And the email should not contain "translation missing" + When I go to the works page + Then I should not see "All Hell Breaks Loose" + When I go to newbie's user page + Then I should not see "All Hell Breaks Loose" + + @javascript + Scenario: Deleting a work with everything filled in, and we do mean everything + Given basic tags + And the following activated users exist + | login | email | + | coauthor | coauthor@example.org | + | cosomeone | cosomeone@example.org | + | giftee | giftee@example.org | + | recipient | recipient@example.org | + And the user "coauthor" allows co-creators + And the user "cosomeone" allows co-creators + And the user "giftee" allows gifts + And the user "recipient" allows gifts + And I have a collection "Collection 1" with name "collection1" + And I have a collection "Collection 2" with name "collection2" + And "thorough" has the pseud "Pseud2" + And "thorough" has the pseud "Pseud3" + And I am logged in as "thorough" + When I go to the new work page + And all emails have been delivered + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I check "F/M" + And I fill in "Fandoms" with "Supernatural" + And I fill in "Work Title" with "All Something Breaks Loose" + And I fill in "content" with "Bad things happen, etc." + And I check "at the beginning" + And I fill in "Notes" with "This is my beginning note" + And I fill in "End Notes" with "This is my endingnote" + And I fill in "Summary" with "Have a short summary" + And I fill in "Characters" with "Sam Winchester, Dean Winchester," + And I fill in "Relationships" with "Harry/Ginny" + And I fill in "Gift this work to" with "Someone else, recipient" + And I check "This work is part of a series" + And I fill in "Or create and use a new one:" with "My new series" + And I select "Pseud2" from "Creator/Pseud(s)" + And I select "Pseud3" from "Creator/Pseud(s)" + And I fill in "pseud_byline_autocomplete" with "coauthor" + And I fill in "Post to Collections / Challenges" with "collection1, collection2" + And I press "Preview" + Then I should see "Preview" + When I press "Post" + Then I should see "Work was successfully posted." + And 1 email should be delivered to "coauthor@example.org" + And the email should contain "The user thorough has invited your pseud coauthor to be listed as a co-creator" + And 1 email should be delivered to "recipient@example.org" + And the email should contain "A gift work has been posted for you" + When I go to the works page + Then I should see "All Something Breaks Loose" + When I follow "All Something Breaks Loose" + Then I should see "All Something Breaks Loose" + And I should see "Fandom: Supernatural" + And I should see "Rating: Not Rated" + And I should see "No Archive Warnings Apply" + And I should not see "Choose Not To Use Archive Warnings" + And I should see "Category: F/M" + And I should see "Characters: Sam Winchester Dean Winchester" + And I should see "Relationship: Harry/Ginny" + And I should see "For Someone else, recipient" + And I should see "Collections: Collection 1, Collection 2" + And I should see "Notes" + And I should see "This is my beginning note" + And I should see "See the end of the work for more notes" + And I should see "This is my endingnote" + And I should see "Summary" + And I should see "Have a short summary" + And I should see "My new series" + And I should see "Bad things happen, etc." + And I should see "Pseud2" within ".byline" + And I should see "Pseud3" within ".byline" + But I should not see "coauthor" within ".byline" + When the user "coauthor" accepts all co-creator requests + And I view the work "All Something Breaks Loose" + Then I should see "coauthor" within ".byline" + When I follow "Add Chapter" + And I fill in "Chapter Title" with "This is my second chapter" + And I fill in "content" with "Let's write another story" + And I press "Preview" + Then I should see "Chapter 2: This is my second chapter" + And I should see "Let's write another story" + When I press "Post" + Then I should see "All Something Breaks Loose" + And I should not see "Bad things happen, etc." + And I should see "Let's write another story" + When I follow "Previous Chapter" + Then I should see "Bad things happen, etc." + And I should not see "Let's write another story" + When I follow "Entire Work" + Then I should see "Bad things happen, etc." + And I should see "Let's write another story" + When I follow "Edit" + And I check "Add co-creators?" + And I fill in "pseud_byline_autocomplete" with "Does_not_exist" + And I press "Preview" + Then I should see "Invalid creator: Could not find a pseud Does_not_exist." + When all emails have been delivered + And I choose "cosomeone" from the "pseud_byline_autocomplete" autocomplete + And I press "Preview" + And I press "Update" + Then I should see "Work was successfully updated" + And I should see "coauthor" within ".byline" + And I should see "Pseud2" within ".byline" + And I should see "Pseud3" within ".byline" + But I should not see "cosomeone" within ".byline" + And 1 email should be delivered to "cosomeone@example.org" + When the user "cosomeone" accepts all co-creator requests + And I view the work "All Something Breaks Loose" + Then I should see "cosomeone" within ".byline" + When all emails have been delivered + And I am logged in as "someone_else" + And I view the work "All Something Breaks Loose" + And I press "Kudos" + Then I should see "someone_else left kudos on this work!" + When I follow "Bookmark" + And I fill in "Notes" with "My thoughts on the work" + And I press "Create" + Then I should see "Bookmark was successfully created" + When all indexing jobs have been run + And I go to the bookmarks page + Then I should see "All Something Breaks Loose" + When I am logged in as "thorough" + And I go to recipient's user page + Then I should see "Gifts (1)" + When I delete the work "All Something Breaks Loose" + And all indexing jobs have been run + Then I should see "Your work All Something Breaks Loose was deleted." + When I go to recipient's user page + Then I should see "Gifts (0)" + And I should not see "All Something Breaks Loose" + When I go to cosomeone's user page + Then I should not see "All Something Breaks Loose" + When I go to thorough's user page + Then I should not see "All Something Breaks Loose" + # This is correct behaviour - bookmark details are preserved even though the work is gone + When all indexing jobs have been run + And I go to the bookmarks page + Then I should not see "All Something Breaks Loose" + When I go to someone_else's bookmarks page + Then I should not see "All Something Breaks Loose" + And I should see "This has been deleted, sorry!" + And I should see "My thoughts on the work" + + Scenario: A work with too many tags can be deleted + Given the user-defined tag limit is 2 + And the work "Over the Limit" + And the work "Over the Limit" has 3 fandom tags + When I am logged in as the author of "Over the Limit" + And I delete the work "Over the Limit" + Then I should see "Your work Over the Limit was deleted." + + Scenario: Deleting a work sends translated deletion notification emails + Given a locale with translated emails + And the user "owner" exists and is activated + And the user "owner" enables translated emails + And the user "someone_else" exists and is activated + And the user "someone_else" enables translated emails + And the work "Many" by "owner", "someone_else" and "off" + And I am logged in as "owner" + When I delete the work "Many" + Then I should see "Your work Many was deleted." + And 3 emails should be delivered + And the email to "owner" should contain "was deleted at your request" + And the email to "owner" should be translated + And the email to "someone_else" should contain "was deleted at the request of" + And the email to "someone_else" should be translated + And the email to "off" should contain "was deleted at the request of" + And the email to "off" should be non-translated diff --git a/features/works/work_download.feature b/features/works/work_download.feature new file mode 100755 index 0000000..f416dab --- /dev/null +++ b/features/works/work_download.feature @@ -0,0 +1,422 @@ +@works +Feature: Download a work + + Scenario: Download a work in various formats + + Given I am logged in as "myname" + And I post the work "Tittle with doubble letters" + Then I should be able to download all versions of "Tittle with doubble letters" + + + Scenario: Download works with double quotes in title + + Given I am logged in as "myname" + And I set up the draft "Foo" + And I fill in "Work Title" with + """ + "Has double quotes" + """ + And I fill in "content" with "some random stuff" + When I press "Preview" + And I press "Post" + And I follow "PDF" + Then I should receive a file of type "pdf" + When I go to the work page with title "Has double quotes" + And I follow "MOBI" + Then I should receive a file of type "mobi" + When I go to the work page with title "Has double quotes" + And I follow "EPUB" + Then I should receive a file of type "epub" + When I go to the work page with title "Has double quotes" + And I follow "AZW3" + Then I should receive a file of type "azw3" + When I go to the work page with title "Has double quotes" + And I follow "HTML" + Then I should receive a file of type "html" + And the page title should include '"Has double quotes"' + + + Scenario: Download works with non-ASCII characters in title + + Given I am logged in as "myname" + When I post the work "Первый_маг" + Then I should be able to download all versions of "Первый_маг" + When I post the work "Hàs curly’d quotes" + Then I should be able to download all versions of "Hàs curly’d quotes" + When I post the work "♥ é Türkçe Karakterler başlıkta nasıl görünüyor" + Then I should be able to download all versions of "♥ é Türkçe Karakterler başlıkta nasıl görünüyor" + When I post the work "à ø something" + Then I should be able to download all versions of "à ø something" + When I post the work "流亡在阿尔比恩" + Then I should be able to download all versions of "流亡在阿尔比恩" + When I post the work "-dash in title-" + Then I should be able to download all versions of "-dash in title-" + When I post the work "Emjoi 🤩 Yay 🥳" + Then I should be able to download all versions of "Emjoi 🤩 Yay 🥳" + + + Scenario: Downloaded work header contains expected meta fields in expected order + + Given basic tags + And I have a collection "My Collection 1" with name "mycollection1" + And I have a collection "My Collection 2" with name "mycollection2" + And I am logged in + And I go to the new work page + And I select "General" from "Rating" + And I check "No Archive Warnings Apply" + And I check "Gen" + And I fill in "Fandoms" with "Cool Fandom" + And I fill in "Characters" with "Character 1, Character 2, Character 3" + And I fill in "Relationships" with "Character 1/Character 2, Character 1 & Character 3" + And I fill in "Additional Tags" with "Modern AU" + And I set the publication date to 10 January 2015 + And I check "This work is part of a series" + And I fill in "Or create and use a new one:" with "THE DOWN" + And I fill in "Post to Collections / Challenges" with "mycollection1, mycollection2" + And I fill in "Work Title" with "Downloadable" + And I fill in "content" with "Could be downloaded" + And I select "English" from "Choose a language" + And I press "Post" + And I follow "Add Chapter" + And I fill in "content" with "Remember, remember the 5th of November" + And I set the publication date to 5 November 2020 + And I press "Post" + When I view the work "Downloadable" + And I follow "HTML" + Then I should see "Downloadable" + And I should see "Rating: General Audiences" + And I should see "Archive Warning: No Archive Warnings Apply" + And I should see "Category: Gen" + And I should see "Fandom: Cool Fandom" + And I should see "Relationships: Character 1/Character 2, Character 1 & Character 3" + And I should see "Characters: Character 1, Character 2, Character 3" + And I should see "Additional Tags: Modern AU" + And I should see "Language: English" + And I should see "Series: Part 1 of THE DOWN" + And I should see "Collections: My Collection 1, My Collection 2" + And I should see "Published: 2015-01-10" + And I should see "Completed: 2020-11-05" + And I should see "Words: 9" + And I should see "Chapters: 2/2" + And "Rating:" should appear before "Archive Warning" + And "Archive Warning:" should appear before "Category" + And "Category:" should appear before "Fandom" + And "Fandom:" should appear before "Relationship" + And "Relationships:" should appear before "Character" + And "Characters:" should appear before "Additional Tags" + And "Additional Tags:" should appear before "Language" + And "Language:" should appear before "Series" + And "Series:" should appear before "Collections" + And "Collections:" should appear before "Published" + And "Published:" should appear before "Completed" + And "Completed:" should appear before "Chapters" + And "Words:" should appear before "Chapters:" + And "Chapters:" should appear before "Could be downloaded" + + Scenario: Downloaded work afterword does not mention author + + Given the work "Downloadable" + When I view the work "Downloadable" + And I follow "HTML" + Then I should not see "to let the author know if you enjoyed" + But I should see "to let the creator know if you enjoyed" + + Scenario: Download of chaptered works includes chapters + + Given the chaptered work "Bazinga" + When I view the work "Bazinga" + And I follow "HTML" + Then I should see "Chapter 2" + + Scenario: Download of chaptered work without posted chapters does not include chapters + + Given the work "Bazinga" + And a draft chapter is added to "Bazinga" + And I delete chapter 1 of "Bazinga" + When I view the work "Bazinga" + And I follow "HTML" + Then I should not see "Chapter 1" + And I should not see "Chapter 2" + And I should be able to download all versions of "Bazinga" + + Scenario: Download chaptered works + + Given I am logged in as "author" + When I post the chaptered work "Epic Novel" + Then I should be able to download all versions of "Epic Novel" + + + Scenario: Works can be downloaded when anonymous + + Given there is a work "Test Work" in an anonymous collection "Anonymous" + When I am a visitor + And I view the work "Test Work" + And I follow "HTML" + Then I should see "Anonymous" + And I should be able to download all versions of "Test Work" + + + Scenario: Multifandom works can be downloaded + + Given I am logged in + And I set up the draft "Many Fandom Work" + And I fill in "Fandoms" with "Fandom 1, Fandom 2, Fandom 3, Fandom 4" + And I press "Post" + When I log out + And I view the work "Many Fandom Work" + And I follow "HTML" + Then the page title should include "Multifandom" + And I should be able to download all versions of "Many Fandom Work" + + + Scenario: Download work shows inspiring work link + + Given I have related works setup + When I post a related work as remixer + And I view the work "Followup" + And I follow "HTML" + Then I should see the inspiring parent work link + + Scenario: Download work shows inspiring external inspiring work link + + Given I have related works setup + When I post a related work as remixer for an external work + And I view the work "Followup" + And I follow "HTML" + Then I should see the external inspiring work link + + Scenario: Work and chapter with notes and end notes show with "more" in the link to end notes. + + Given I am logged in + And I set up the draft "got notes?" + And I check "at the beginning" + And I fill in "Notes" with "READ THE TAGS FIRST" + And I check "at the end" + And I fill in "End Notes" with "That's all, folks!" + And I fill in "content" with "Could be downloaded" + And I press "Post" + And I follow "Add Chapter" + And I fill in "content" with "Remember, remember the 5th of November" + And I check "at the beginning" + And I fill in "Notes" with "hey guys its been a while 🙃" + And I check "at the end" + And I fill in "End Notes" with "Next update soon!!!" + And I press "Post" + When I view the work "got notes?" + And I follow "HTML" + Then I should see "Notes" + And I should see "READ THE TAGS FIRST" + And I should see "See the end of the work for more notes" + And I should not see "See the end of the work for notes" + And I should see "End Notes" + And I should see "That's all, folks!" + And I should see "Chapter Notes" + And I should see "hey guys its been a while 🙃" + And I should see "See the end of the chapter for more notes" + And I should not see "See the end of the chapter for notes" + And I should see "Chapter End Notes" + And I should see "Next update soon!!!" + + Scenario: Work and chapter with only end notes show without "more" in the link to end notes. + + Given I am logged in + And I set up the draft "got notes?" + And I check "at the end" + And I fill in "End Notes" with "That's all, folks!" + And I fill in "content" with "Could be downloaded" + And I press "Post" + And I follow "Add Chapter" + And I fill in "content" with "Remember, remember the 5th of November" + And I check "at the end" + And I fill in "End Notes" with "Next update soon!!!" + And I press "Post" + When I view the work "got notes?" + And I follow "HTML" + Then I should see "Notes" + And I should not see "See the end of the work for more notes" + And I should see "See the end of the work for notes" + And I should see "End Notes" + And I should see "That's all, folks!" + And I should see "Chapter Notes" + And I should not see "See the end of the chapter for more notes" + And I should see "See the end of the chapter for notes" + And I should see "Chapter End Notes" + And I should see "Next update soon!!!" + + Scenario: Work and chapter with only notes show without the link to end notes. + + Given I am logged in + And I set up the draft "got notes?" + And I check "at the beginning" + And I fill in "Notes" with "READ THE TAGS FIRST" + And I fill in "content" with "Could be downloaded" + And I press "Post" + And I follow "Add Chapter" + And I fill in "content" with "Remember, remember the 5th of November" + And I check "at the beginning" + And I fill in "Notes" with "hey guys its been a while 🙃" + And I press "Post" + When I view the work "got notes?" + And I follow "HTML" + Then I should see "Notes" + And I should see "READ THE TAGS FIRST" + And I should not see "See the end of the work for " + And I should not see "End Notes" + And I should see "Chapter Notes" + And I should see "hey guys its been a while 🙃" + And I should not see "See the end of the chapter for " + And I should not see "Chapter End Notes" + + Scenario: Work and chapter with no notes and no end notes show without the link to end notes or empty sections. + + Given I am logged in + And I set up the draft "got notes?" + And I fill in "content" with "Could be downloaded" + And I press "Post" + And I follow "Add Chapter" + And I fill in "content" with "Remember, remember the 5th of November" + And I press "Post" + When I view the work "got notes?" + And I follow "HTML" + Then I should not see "Notes" + And I should not see "See the end of the work for " + And I should not see "End Notes" + And I should not see "Chapter Notes" + And I should not see "See the end of the chapter for " + And I should not see "Chapter End Notes" + + Scenario: Download option is unavailable if work is unrevealed. + + Given there is a work "Blabla" in an unrevealed collection "Unrevealed" + And I am logged in as the author of "Blabla" + Then I should not see "Download" + + + Scenario: Download option is unavailable if work is unposted. + + Given I am logged in + And the draft "Unposted Work" + When I view the work "Unposted Work" + Then I should not see "Download" + + + Scenario: Download option is unavailable if work is hidden by admin. + + Given I am logged in + And I post the work "TOS Violation" + When I am logged in as a "policy_and_abuse" admin + And I hide the work "TOS Violation" + Then I should not see "Download" + + Scenario: Downloads of related work update when parent work's anonymity changes. + + Given a hidden collection "Hidden" + And I have related works setup + And I post a related work as remixer + And I post a translation as translator + And I log out + When I view the work "Followup" + And I follow "HTML" + Then I should see "Worldbuilding by inspiration" + When I view the work "Worldbuilding Translated" + And I follow "HTML" + Then I should see "Worldbuilding by inspiration" + # Going from revealed to unrevealed + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" to be in the collection "Hidden" + And I log out + And I view the work "Followup" + And I follow "HTML" + Then I should not see "inspiration" + And I should see "Inspired by a work in an unrevealed collection" + When I view the work "Worldbuilding Translated" + And I follow "HTML" + Then I should not see "inspiration" + And I should see "A translation of a work in an unrevealed collection" + # Going from unrevealed to revealed + When I reveal works for "Hidden" + And I log out + And I view the work "Followup" + And I follow "HTML" + Then I should see "Worldbuilding by inspiration" + When I view the work "Worldbuilding Translated" + And I follow "HTML" + Then I should see "Worldbuilding by inspiration" + + Scenario: Downloads of related work update when child work's anonymity changes. + + Given a hidden collection "Hidden" + And I have related works setup + And a related work has been posted and approved + When I view the work "Worldbuilding" + And I follow "HTML" + Then I should see "Followup by remixer" + And I should not see "A work in an unrevealed collection" + # Going from revealed to unrevealed + When I am logged in as "remixer" + And I edit the work "Followup" to be in the collection "Hidden" + And I view the work "Worldbuilding" + And I follow "HTML" + Then I should not see "Followup by remixer" + And I should see "A work in an unrevealed collection" + # Going from unrevealed to revealed + When I reveal works for "Hidden" + And I log out + And I view the work "Worldbuilding" + And I follow "HTML" + Then I should see "Followup by remixer" + And I should not see "A work in an unrevealed collection" + + Scenario: Downloads hide titles of restricted related works + + Given I have related works setup + And a related work has been posted and approved + And I am logged in as "remixer" + And I lock the work "Followup" + When I am logged out + And I view the work "Worldbuilding" + And I follow "HTML" + Then I should see "[Restricted Work] by remixer" + When I am logged in as "inspiration" + And I lock the work "Worldbuilding" + And I am logged in as "remixer" + And I unlock the work "Followup" + And I am logged out + And I view the work "Followup" + And I follow "HTML" + Then I should see "Inspired by [Restricted Work] by inspiration" + + Scenario: Downloads of translated work update when translation's revealed status changes. + + Given a hidden collection "Hidden" + And I have related works setup + And a translation has been posted and approved + And I log out + When I view the work "Worldbuilding" + And I follow "HTML" + Then I should see "Worldbuilding Translated by translator" + # Going from revealed to unrevealed + When I am logged in as "translator" + And I edit the work "Worldbuilding Translated" to be in the collection "Hidden" + And I log out + And I view the work "Worldbuilding" + And I follow "HTML" + Then I should not see "Worldbuilding Translated by translator" + And I should see "A work in an unrevealed collection" + # Going from unrevealed to revealed + When I reveal works for "Hidden" + And I log out + And I view the work "Worldbuilding" + And I follow "HTML" + Then I should see "Worldbuilding Translated by translator" + + Scenario: Downloads hide titles of restricted work translations + + Given I have related works setup + And a translation has been posted and approved + And I am logged in as "translator" + And I lock the work "Worldbuilding Translated" + When I am logged out + And I view the work "Worldbuilding" + And I follow "HTML" + Then I should see "[Restricted Work] by translator" diff --git a/features/works/work_drafts.feature b/features/works/work_drafts.feature new file mode 100755 index 0000000..27b8267 --- /dev/null +++ b/features/works/work_drafts.feature @@ -0,0 +1,189 @@ +@works @search +Feature: Work Drafts + + Scenario: Creating a work draft + Given I am logged in as "Scott" with password "password" + When the draft "scotts draft" + And I press "Cancel" + Then I should see "The work was not posted. It will be saved here in your drafts for one month, then deleted from the Archive." + + Scenario: Creating a work draft, editing it, and saving the changes without posting or previewing and then double check that it is saved and I didn't get the success message erroneously + Given basic tags + And I am logged in as "persnickety" with password "editingisfun" + When I go to the new work page + Then I should see "Post New Work" + And I select "General Audiences" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "MASH (TV)" + And I fill in "Work Title" with "Draft Dodging" + And I fill in "content" with "Klinger lay under his porch." + And I press "Preview" + Then I should see "Draft was successfully created. It will be scheduled for deletion on" + When I press "Edit" + Then I should see "Edit Work" + And I fill in "content" with "Klinger, in Uncle Gus's Aunt Gussie dress, lay under his porch." + And I press "Save As Draft" + Then I should see "This work is a draft and has not been posted." + And I should see "Klinger, in Uncle Gus's Aunt Gussie dress, lay under his porch." + When I am on persnickety's works page + Then I should not see "Draft Dodging" + And I should see "Drafts (1)" + When I follow "Drafts (1)" + Then I should see "Draft Dodging" + When I follow "Draft Dodging" + Then I should see "Klinger, in Uncle Gus's Aunt Gussie dress, lay under his porch." + + Scenario: Creating an draft Chapter on a draft Work + Given I am logged in as "Scott" with password "password" + And the draft "scotts other draft" + And I press "Cancel" + And I edit the work "scotts other draft" + And I follow "Add Chapter" + And I fill in "content" with "this is second chapter content" + And I press "Preview" + Then I should see "This is a draft chapter in an unposted work. The work will be scheduled for deletion on" + + Scenario: Purging old drafts + Given I am logged in as "drafter" with password "something" + When the work "old draft work" was created 31 days ago + And the work "new draft work" was created 2 days ago + When I am on drafter's works page + Then I should see "Drafts (2)" + When the purge_old_drafts rake task is run + And I reload the page + Then I should see "Drafts (1)" + + Scenario: Drafts cannot be found by search + Given I am logged in as "drafter" with password "something" + And the draft "draft to post" + Given all indexing jobs have been run + When I fill in "site_search" with "draft" + And I press "Search" + Then I should see "No results found" + + Scenario: Posting drafts from drafts page + Given I am logged in as "drafter" with password "something" + And the draft "draft to post" + When I am on drafter's works page + Then I should see "Drafts (1)" + When I follow "Drafts (1)" + Then I should see "draft to post" + And the page title should include "drafter - Drafts" + And I should see "Post Draft" within "#main .own.work.blurb .actions" + And I should see "Delete Draft" within "#main .own.work.blurb .actions" + When I follow "Post Draft" + Then I should see "draft to post" + And I should see "drafter" + And I should not see "Preview" + + Scenario: Deleting drafts from drafts page + Given I am logged in as "drafter" with password "something" + And the draft "draft to delete" + When I am on drafter's works page + Then I should see "Drafts (1)" + When I follow "Drafts (1)" + Then I should see "draft to delete" + And I should see "Post Draft" within "#main .own.work.blurb .actions" + And I should see "Delete Draft" within "#main .own.work.blurb .actions" + When I follow "Delete Draft" + Then I should not see "All bookmarks, comments, and kudos will be lost." + And I should not see "Orphan Work Instead" + When I press "Yes, Delete Draft" + Then I should see "Your work draft to delete was deleted" + + Scenario: Saving changes to an existing draft without posting and then double check that it is saved and I didn't get the success message erroneously + Given I am logged in as "drafty" with password "breezeinhere" + And the draft "Windbag" + When I am on drafty's works page + Then I should see "Drafts (1)" + When I follow "Drafts (1)" + Then I should see "Windbag" + And I should see "Edit" within "#main .own.work.blurb .actions" + When I follow "Edit" + Then I should see "Edit Work" + When I fill in "content" with "My draft has changed!" + And I press "Save As Draft" + Then I should see "This work is a draft and has not been posted" + And I should see "My draft has changed!" + When I am on drafty's works page + Then I should see "Drafts (1)" + When I follow "Drafts (1)" + Then I should see "Windbag" + When I follow "Windbag" + Then I should see "My draft has changed!" + + Scenario: Editing a draft and previewing it should warn that it has not been saved. + Given I am logged in as "ringadingding" + And the draft "Walking Into Mordor" + When I edit the draft "Walking Into Mordor" + And I press "Preview" + Then I should see "Please post your work or save as draft if you want to keep them." + + Scenario: A chaptered draft should be able to have beginning and end notes, and it should display them. + Given I am logged in as "composer" + And I post the chaptered draft "Epic in Progress" + When I edit the draft "Epic in Progress" + And I add the beginning notes "Some beginning notes." + And I add the end notes "Some end notes." + And I press "Save As Draft" + Then I should see "Some beginning notes." + And I should see "See the end of the work for more notes." + When I follow "more notes" + Then I should see "Some end notes." + + Scenario: If a chaptered draft belongs to a series, the series should be listed on the draft + Given I am logged in as "two_can_sam" + And I post the chaptered draft "Cereal Serial" + When I add the draft "Cereal Serial" to series "Aisle 5" + And I follow "Next Chapter" + Then I should see "Series this work belongs to:" + And I should see "Aisle 5" + + Scenario: Word count should appear after creating single chapter work, saving as draft, and posting draft from user's drafts page + Given I am logged in as "test_user" + And I set up the draft "Unicorns are everywhere" + And I fill in "content" with "Help there are unicorns everywhere" + And I press "Preview" + And I press "Save As Draft" + When I follow "My Dashboard" + And I follow "Drafts (" + And I follow "Post Draft" + Then I should be on the work "Unicorns are everywhere" + And I should see "Words:5" + + Scenario: Word count should equal all draft chapters' word counts if work isn't posted + Given I am logged in as "test_user" + And I set up the draft "Unicorns are everywhere" + And I fill in "content" with "Help there are unicorns everywhere" + And I press "Preview" + And I press "Save As Draft" + When a chapter is set up for "Unicorns are everywhere" + And I press "Preview" + And I press "Save As Draft" + Then I should see "Words:16" + When a chapter is set up for "Unicorns are everywhere" + And I press "Preview" + When I press "Save As Draft" + Then I should see "Words:27" + + Scenario: When posting chapter(s) in unpublished multichapter work, word count should equal posted chapter(s) word count + Given I am logged in as "test_user" + And I set up the draft "Unicorns are everywhere" + And I fill in "content" with "Help there are unicorns everywhere" + And I press "Preview" + And I press "Save As Draft" + When a chapter is set up for "Unicorns are everywhere" + And I press "Preview" + And I press "Save As Draft" + Then I should see "Words:16" + When a chapter is set up for "Unicorns are everywhere" + And I press "Preview" + And I press "Save As Draft" + Then I should see "Words:27" + When I view the work "Unicorns are everywhere" + And I press "Post Chapter" + Then I should see "Words:5" + When I follow "Next Chapter" + And I press "Post Chapter" + Then I should see "Words:16" diff --git a/features/works/work_edit.feature b/features/works/work_edit.feature new file mode 100755 index 0000000..be0c415 --- /dev/null +++ b/features/works/work_edit.feature @@ -0,0 +1,320 @@ +@works @tags +Feature: Edit Works + In order to have an archive full of works + As an author + I want to edit existing works + + Scenario: You can't edit a work unless you're logged in and it's your work + Given the work "First work" by "testuser" with fandom "first fandom" + And "testuser" has the pseud "testy" + And the work "fourth" by "testuser2" + # I'm not logged in + When I view the work "First work" + Then I should not see "Edit" + Given I am logged in as "testuser" + And all indexing jobs have been run + # This isn't my work + When I view the work "fourth" + Then I should not see "Edit" + When I am on testuser's works page + # These are my works and should all have edit links on the blurbs + Then I should see "Edit" + When I follow "First work" + # This is my individual work and should have an edit link on the show page + Then I should see "first fandom" + And I should see "Edit" + # make sure this tag isn't on before we add it + And I should not see "new tag" + When I follow "Edit" + Then I should see "Edit Work" + When I fill in "work_freeform" with "new tag" + And I fill in "content" with "first chapter content" + And I press "Preview" + Then I should see "Preview" + And I should see "Fandom: first fandom" + And I should see "Additional Tags: new tag" + And I should see "first chapter content" + And I should see "Words:3" + When I press "Update" + Then I should see "Work was successfully updated." + And I should see "Additional Tags: new tag" + And I should see "Words:3" + When all indexing jobs have been run + And I go to testuser's works page + Then I should see "First work" + And I should see "first fandom" + And I should see "new tag" + When I edit the work "First work" + And I follow "Add Chapter" + And I fill in "content" with "second chapter content" + And I press "Preview" + Then I should see "This is a draft chapter in a posted work. It will be kept unless the work is deleted." + And I should see "second chapter content" + When I press "Post" + Then I should see "Chapter was successfully posted." + And I should not see "first chapter content" + And I should see "second chapter content" + And I should see "Words:6" + When I edit the work "First work" + Then I should not see "chapter content" + When I follow "1" + And I fill in "content" with "first chapter new content" + And I press "Preview" + Then I should see "first chapter new content" + When I press "Update" + Then I should see "Chapter was successfully updated." + And I should see "first chapter new content" + And I should not see "second chapter content" + And I should see "Words:7" + When I edit the work "First Work" + And I follow "2" + And I fill in "content" with "second chapter new content" + And I press "Preview" + And I press "Cancel" + Then I should see "second chapter content" + And I should see "Words:7" + # Test changing pseuds on a work + When I go to testuser's works page + And I follow "Edit" + And I select "testy" from "work_author_attributes_ids" + And I unselect "testuser" from "work_author_attributes_ids" + # Expire byline cache + And it is currently 1 second from now + And I press "Post" + Then I should see "testy" + And I should not see "testuser," + + Scenario: Editing a work in a moderated collection + # TODO: Find a way to appove works without using this hack method I have here + Given the following activated users exist + | login | password | + | Scott | password | + And I have a moderated collection "Digital Hoarders 2013" with name "digital_hoarders_2013" + When I am logged in as "Scott" with password "password" + And I post the work "Murder in Milan" in the collection "Digital Hoarders 2013" + Then I should see "You have submitted your work to the moderated collection 'Digital Hoarders 2013'. It will not become a part of the collection until it has been approved by a moderator." + When I am logged in as "moderator" + And I go to "Digital Hoarders 2013" collection's page + And I follow "Collection Settings" + And I uncheck "This collection is moderated" + And I press "Update" + Then I should see "Collection was successfully updated" + When I am logged in as "Scott" + And I post the work "Murder by Numbers" in the collection "Digital Hoarders 2013" + Then I should see "Work was successfully posted" + When I am logged in as "moderator" + And I go to "Digital Hoarders 2013" collection's page + And I follow "Collection Settings" + And I check "This collection is moderated" + And I press "Update" + Then I should see "Collection was successfully updated" + When I am logged in as "Scott" + And I edit the work "Murder by Numbers" + And I press "Post" + And I should see "Work was successfully updated" + Then I should not see "You have submitted your work to the moderated collection 'Digital Hoarders 2013'. It will not become a part of the collection until it has been approved by a moderator." + + Scenario: Previewing edits to a posted work should not refer to the work as a draft + Given I am logged in as "editor" + And I post the work "Load of Typos" + When I edit the work "Load of Typos" + And I press "Preview" + Then I should not see "draft" + + Scenario: You can invite a co-author to an already-posted work + Given I am logged in as "leadauthor" + And the user "coauthor" exists and is activated + And the user "coauthor" allows co-creators + And I post the work "Dialogue" + When I follow "Edit" + And I invite the co-author "coauthor" + And I press "Post" + Then I should see "Work was successfully updated" + And I should not see "coauthor" within ".byline" + But 1 email should be delivered to "coauthor" + And the email should contain "The user leadauthor has invited your pseud coauthor to be listed as a co-creator on the following work" + When I am logged in as "coauthor" + And I follow "Dialogue" in the email + Then I should not see "Edit" + When I follow "Co-Creator Requests page" + And I check "selected[]" + # Expire cached byline + And it is currently 1 second from now + And I press "Accept" + Then I should see "You are now listed as a co-creator on Dialogue." + When I follow "Dialogue" + Then I should see "coauthor, leadauthor" within ".byline" + And I should see "Edit" + + Scenario: You can remove yourself as coauthor from a work + Given the following activated users exist + | login | + | coolperson | + | ex_friend | + And the user "ex_friend" allows co-creators + And I coauthored the work "Shared" as "coolperson" with "ex_friend" + And I am logged in as "coolperson" + When I view the work "Shared" + Then I should see "coolperson, ex_friend" within ".byline" + When I edit the work "Shared" + And I wait 1 second + And I press "Remove Me As Co-Creator" + Then I should see "You have been removed as a creator from the work." + And "ex_friend" should be the creator on the work "Shared" + And "coolperson" should not be a creator on the work "Shared" + + Scenario: User applies a coauthor's work skin to their work + Given the following activated users with private work skins + | login | + | lead_author | + | coauthor | + | random_user | + And the user "coauthor" allows co-creators + And I coauthored the work "Shared" as "lead_author" with "coauthor" + And I am logged in as "lead_author" + When I edit the work "Shared" + Then I should see "Lead Author's Work Skin" within "#work_work_skin_id" + And I should see "Coauthor's Work Skin" within "#work_work_skin_id" + And I should not see "Random User's Work Skin" within "#work_work_skin_id" + When I select "Coauthor's Work Skin" from "Select work skin" + And I press "Post" + Then I should see "Work was successfully updated" + + Scenario: Previewing shows changes to tags, but cancelling afterwards doesn't save those changes + Given I am logged in as a random user + And I post the work "Work 1" with fandom "testing" + When I edit the work "Work 1" + And I fill in "Fandoms" with "foobar" + And I press "Preview" + Then I should see "Fandom: foobar" + When I press "Cancel" + And I view the work "Work 1" + Then I should see "Fandom: testing" + And I should not see "Fandom: foobar" + + Scenario: A work cannot be edited to remove its fandom + Given basic tags + And I am logged in as a random user + And I post the work "Work 1" with fandom "testing" + When I edit the work "Work 1" + And I fill in "Fandoms" with "" + And I press "Post" + Then I should see "Sorry! We couldn't save this work because: Please fill in at least one fandom." + When I view the work "Work 1" + Then I should see "Fandom: testing" + + Scenario: User can cancel editing a work + Given I am logged in as a random user + And I post the work "Work 1" with fandom "testing" + And I edit the work "Work 1" + And I fill in "Fandoms" with "" + And I press "Cancel" + When I view the work "Work 1" + Then I should see "Fandom: testing" + + Scenario: A work cannot be edited to remove its only warning + Given I am logged in as a random user + And I post the work "Work 1" + When I edit the work "Work 1" + And I uncheck "No Archive Warnings Apply" + And I press "Post" + Then I should see "Sorry! We couldn't save this work because: Please select at least one warning." + When I view the work "Work 1" + Then I should see "Archive Warning: No Archive Warnings Apply" + + Scenario: A work can be edited to remove all categories + Given I am logged in as a random user + And I post the work "Work 1" with category "F/F" + When I edit the work "Work 1" + And I uncheck "F/F" + And I press "Post" + Then I should not see "F/F" + + Scenario: When editing a work, the title field should not escape HTML + Given the work "What a title! :< :& :>" by "author" + And I am logged in as "author" + And I go to the works page + And I follow "What a title! :< :& :>" + And I follow "Edit" + Then I should see "What a title! :< :& :>" in the "Work Title" input + + Scenario: When a user changes their co-creator preference, it does not remove them from works they have already co-created. + Given basic tags + And "Burnham" has the pseud "Michael" + And "Pike" has the pseud "Christopher" + And the user "Burnham" allows co-creators + When I am logged in as "testuser" with password "testuser" + And I go to the new work page + And I fill in the basic work information for "Thats not my Spock" + And I try to invite the co-authors "Michael,Christopher" + And I press "Post" + Then I should see "Christopher (Pike) does not allow others to invite them to be a co-creator." + When I press "Post" + Then I should see "Work was successfully posted. It should appear in work listings within the next few minutes." + But I should not see "Michael" + When the user "Burnham" accepts all co-creator requests + And I view the work "Thats not my Spock" + Then I should see "Michael (Burnham), testuser" + When the user "Burnham" disallows co-creators + And I edit the work "Thats not my Spock" + And I fill in "Work Title" with "Thats not my Spock, it has too much beard" + And I press "Post" + Then I should see "Thats not my Spock, it has too much beard" + And I should see "Michael (Burnham), testuser" + + Scenario: When you have a work with two co-creators, and one of them changes their preference to disallow co-creation, the other should still be able to edit the work and add a third co-creator. + Given basic tags + And "Burnham" has the pseud "Michael" + And "Georgiou" has the pseud "Philippa" + And the user "Burnham" allows co-creators + And the user "Georgiou" allows co-creators + When I am logged in as "testuser" with password "testuser" + And I go to the new work page + And I fill in the basic work information for "Thats not my Spock" + And I try to invite the co-author "Michael" + And I press "Post" + Then I should see "Work was successfully posted. It should appear in work listings within the next few minutes." + But I should not see "Michael" + When the user "Burnham" accepts all co-creator requests + And I view the work "Thats not my Spock" + Then I should see "Michael (Burnham), testuser" + When the user "Burnham" disallows co-creators + And I edit the work "Thats not my Spock" + And I fill in "Work Title" with "Thats not my Spock, it has too much beard" + And I press "Post" + Then I should see "Thats not my Spock, it has too much beard" + And I should see "Michael (Burnham), testuser" + When I edit the work "Thats not my Spock, it has too much beard" + And I invite the co-author "Georgiou" + And I press "Post" + Then I should see "Work was successfully updated" + And I should see "Michael (Burnham), testuser" + But I should not see "Georgiou" + When the user "Georgiou" accepts all co-creator requests + And I view the work "Thats not my Spock, it has too much beard" + Then I should see "Georgiou, Michael (Burnham), testuser" + + Scenario: You cannot edit a work to add too many tags + Given the user-defined tag limit is 7 + And the work "Over the Limit" + And I am logged in as the author of "Over the Limit" + When I edit the work "Over the Limit" + And I fill in "Fandoms" with "Fandom 1, Fandom 2" + And I fill in "Characters" with "Character 1, Character 2" + And I fill in "Relationships" with "Relationship 1, Relationship 2" + And I fill in "Additional Tags" with "Additional Tag 1, Additional Tag 2" + And I press "Post" + Then I should see "Fandom, relationship, character, and additional tags must not add up to more than 7. Your work has 8 of these tags, so you must remove 1 of them." + + Scenario: If a work has too many tags, you cannot update it without removing tags + Given the user-defined tag limit is 7 + And the work "Over the Limit" + And the work "Over the Limit" has 2 fandom tags + And the work "Over the Limit" has 2 character tags + And the work "Over the Limit" has 2 relationship tags + And the work "Over the Limit" has 2 freeform tags + And I am logged in as the author of "Over the Limit" + When I edit the work "Over the Limit" + And I fill in "Title" with "Over the Limit Redux" + And I press "Post" + Then I should see "Fandom, relationship, character, and additional tags must not add up to more than 7. Your work has 8 of these tags, so you must remove 1 of them." diff --git a/features/works/work_edit_multiple.feature b/features/works/work_edit_multiple.feature new file mode 100755 index 0000000..1c6f75f --- /dev/null +++ b/features/works/work_edit_multiple.feature @@ -0,0 +1,271 @@ +@works @tags +Feature: Edit Multiple Works + In order to change settings on my works more easily + As an author + I want to edit multiple works at once + + Scenario: I can delete multiple works at once + Given I am logged in as "author" + And I post the work "Glorious" with fandom "SGA" + And I post the work "Excellent" with fandom "Star Trek" + And I post the work "Lovely" with fandom "Steven Universe" + And I go to author's works page + When I follow "Edit Works" + Then I should see the page title "Edit Multiple Works" + And I should see "Edit Multiple Works" + When I select "Glorious" for editing + And I select "Excellent" for editing + And it is currently 1 second from now + And I press "Delete" + Then I should see "Are you sure you want to delete these works PERMANENTLY?" + And I should see "Glorious" + And I should see "Excellent" + And I should not see "Lovely" + When I press "Yes, Delete Works" + Then I should see "Your works Glorious, Excellent were deleted." + When all indexing jobs have been run + And I go to author's works page + Then I should not see "Glorious" + And I should not see "Excellent" + And I should see "Lovely" + + Scenario: I can edit multiple works at once + Given I am logged in as "author" + And I post the work "Glorious" with fandom "SGA" + And I post the work "Excellent" with fandom "Star Trek" + And I go to author's works page + When I follow "Edit Works" + Then I should see the page title "Edit Multiple Works" + And I should see "Edit Multiple Works" + And I should see "All" + And I should see "None" + When I select "Glorious" for editing + And I select "Excellent" for editing + And I press "Edit" + Then I should see "Your edits will be applied to all of the following works" + And I should see "Glorious" + And I should see "Excellent" + When I set the fandom to "Random" + And I press "Update All Works" + Then I should see "Your edits were put through" + And I should see "Random" + And I should not see "SGA" + And I should not see "Star Trek" + When I view the work "Glorious" + Then I should see "Random" + And I should not see "SGA" + When I view the work "Excellent" + Then I should see "Random" + And I should not see "Star Trek" + + Scenario: I can disable anon commenting on multiple works at once + Given I am logged in as "author" + And I edit the multiple works "Glorious" and "Excellent" + When I choose "Only registered users can comment" + And I press "Update All Works" + And I am logged out + And I view the work "Glorious" + Then I should see "doesn't allow non-Archive users to comment" + When I view the work "Excellent" + Then I should see "doesn't allow non-Archive users to comment" + + Scenario: I can disable commenting on multiple works at once + Given I am logged in as "author" + And I edit the multiple works "Glorious" and "Excellent" + When I choose "No one can comment" + And I press "Update All Works" + And I am logged out + And I view the work "Glorious" + Then I should see "Sorry, this work doesn't allow comments." + When I view the work "Excellent" + Then I should see "Sorry, this work doesn't allow comments." + + Scenario: I can enable comment moderation on multiple works at once + Given I am logged in as "author" + And I edit the multiple works "Glorious" and "Excellent" + And I choose "Enable comment moderation" + And I press "Update All Works" + When I am logged in as "commenter" + And I view the work "Glorious" + Then I should see "has chosen to moderate comments" + When I view the work "Excellent" + Then I should see "has chosen to moderate comments" + + Scenario: I can enable anon commenting on multiple works at once + Given I am logged in as "author" + And I edit the multiple works "Glorious" and "Excellent" + And I choose "Only registered users can comment" + And I press "Update All Works" + And I edit the multiple works "Glorious" and "Excellent" + And I choose "Registered users and guests can comment" + And I press "Update All Works" + When I am logged out + And I view the work "Glorious" + Then I should not see "doesn't allow non-Archive users to comment" + + Scenario: I can enable commenting on multiple works at once + Given I am logged in as "author" + And I edit the multiple works "Glorious" and "Excellent" + And I choose "No one can comment" + And I press "Update All Works" + And I edit the multiple works "Glorious" and "Excellent" + And I choose "Registered users and guests can comment" + And I press "Update All Works" + When I am logged out + And I view the work "Glorious" + Then I should not see "Sorry, this work doesn't allow comments." + + Scenario: I can disable comment moderation on multiple works at once + Given I am logged in as "author" + And I edit the multiple works "Glorious" and "Excellent" + And I choose "Enable comment moderation" + And I press "Update All Works" + And I edit the multiple works "Glorious" and "Excellent" + And I choose "Disable comment moderation" + And I press "Update All Works" + When I am logged out + And I view the work "Glorious" + Then I should not see "has chosen to moderate comments" + + Scenario: I can keep different comment moderation settings on different works when I edit them at once + Given I am logged in as "author" + And I edit multiple works with different comment moderation settings + When I set the fandom to "Random" + And I choose "Keep current comment moderation settings" + And I press "Update All Works" + When I am logged out + And I view the work "Work with Comment Moderation Enabled" + Then I should see "has chosen to moderate comments" + When I view the work "Work with Comment Moderation Disabled" + Then I should not see "has chosen to moderate comments" + + Scenario: I can keep different commenting settings on different works when I edit them at once + Given I am logged in as "author" + And I edit multiple works with different commenting settings + And I set the fandom to "Random" + And I choose "Keep current comment settings" + And I press "Update All Works" + + When I view the work "Work with All Commenting Disabled" + Then I should see "Sorry, this work doesn't allow comments." + + When I am logged out + And I view the work "Work with Anonymous Commenting Disabled" + Then I should see "Sorry, this work doesn't allow non-Archive users to comment." + + When I view the work "Work with All Commenting Enabled" + Then I should not see "Sorry, this work doesn't allow comments." + And I should not see "Sorry, this work doesn't allow non-Archive users to comment." + + Scenario: User can change the pseud on multiple works at once + Given I am logged in as "author" + And "author" creates the pseud "My New Pseud" + And I edit the multiple works "First" and "Second" + And it is currently 1 second from now + When I select "My New Pseud" from "Creator/Pseud(s)" + And I press "Update All Works" + Then I should see "Your edits were put through" + When I view the work "First" + Then I should see "My New Pseud" within ".byline" + When I view the work "Second" + Then I should see "My New Pseud" within ".byline" + + Scenario: User can invite a co-creator to multiple works at once + Given the following activated users exist + | login | + | lead_author | + | coauthor | + And the user "coauthor" allows co-creators + And I am logged in as "lead_author" + And I edit the multiple works "First Shared" and "Second Shared" + When I fill in "Add co-creators" with "coauthor" + And I press "Update All Works" + Then I should see "Your edits were put through" + And 2 emails should be delivered to "coauthor" + When I view the work "First Shared" + Then I should not see "coauthor" within ".byline" + When I view the work "First Shared" + Then I should not see "coauthor" within ".byline" + When the user "coauthor" accepts all co-creator requests + And I view the work "First Shared" + Then I should see "coauthor" within ".byline" + When I view the work "Second Shared" + Then I should see "coauthor" within ".byline" + + Scenario: User can remove themselves from multiple works at once + Given the following activated users exist + | login | + | lead_author | + | coauthor | + And the user "coauthor" allows co-creators + And I am logged in as "lead_author" + And I edit multiple works coauthored as "lead_author" with "coauthor" + When I check "Remove me as co-creator" + And it is currently 1 second from now + And I press "Update All Works" + Then I should see "Your edits were put through" + When I view the work "Shared Work 1" + Then I should not see "lead_author" within ".byline" + When I view the work "Shared Work 2" + Then I should not see "lead_author" within ".byline" + + Scenario: User can remove themselves from one work even if they're the only creator on the other + Given the user "lead_creator" exists and is activated + And the user "co_creator" exists and is activated + And I am logged in as "lead_creator" + And I post the work "Solo" + And I coauthored the work "Shared" as "lead_creator" with "co_creator" + When I follow "My Dashboard" + And I follow "Works (" + And I follow "Edit Works" + And I select "Solo" for editing + And I select "Shared" for editing + And I press "Edit" + And I check "Remove me as co-creator" + And it is currently 1 second from now + And I press "Update All Works" + Then I should see "You cannot remove yourself as co-creator of the work Solo because you are the only listed creator." + When I view the work "Solo" + Then I should see "lead_creator" within ".byline" + When I view the work "Shared" + Then I should not see "lead_creator" within ".byline" + + Scenario: User applies a private work skin to multiple coauthored works + Given the following activated users with private work skins + | login | + | lead_author | + | coauthor | + And the user "coauthor" allows co-creators + And I am logged in as "lead_author" + And I edit multiple works coauthored as "lead_author" with "coauthor" + Then I should see "Lead Author's Work Skin" within "#work_work_skin_id" + And I should not see "Coauthor's Work Skin" within "#work_work_skin_id" + When I select "Lead Author's Work Skin" from "Select work skin" + And I press "Update All Works" + Then I should see "Your edits were put through" + + Scenario: I can add several works to a collection at once + Given I am logged in as "author" + And I create the collection "MyCollection" + And I edit the multiple works "Glorious" and "Excellent" + When I fill in "Add to collections" with "MyCollection" + And I press "Update All Works" + Then I should see "Your edits were put through" + When I view the work "Glorious" + Then I should see "MyCollection" + When I view the work "Excellent" + Then I should see "MyCollection" + + Scenario: I can remove several works from a collection at once + Given I am logged in as "author" + And I create the collection "MyCollection" + And I post the work "Glorious" to the collection "MyCollection" + And I post the work "Excellent" to the collection "MyCollection" + And I edit the multiple works "Glorious" and "Excellent" + When I check "MyCollection" + And I press "Update All Works" + Then I should see "Your edits were put through" + When I view the work "Glorious" + Then I should not see "MyCollection" + When I view the work "Excellent" + Then I should not see "MyCollection" diff --git a/features/works/work_edit_tags.feature b/features/works/work_edit_tags.feature new file mode 100755 index 0000000..189385c --- /dev/null +++ b/features/works/work_edit_tags.feature @@ -0,0 +1,86 @@ +@tags @works +Feature: Edit tags on a work + In order to have an archive full of works + As a humble user + I want to edit the tags on one of my works + + Scenario: Edit tags on a work + + Given the following activated user exists + | login | password | + | myname | something | + And I am logged in as "myname" with password "something" + Then I should see "Hi, myname!" + And I should see "Log Out" + When I post the work "Testerwork" + Then I should see "Work was successfully posted." + And I should see "Stargate SG-1" + And I should not see "Hana Yori Dango" + And I should not see "Alternate Universe" + When I follow "myname" + Then I should see "Testerwork" + And I should see "Edit Tags" + When I follow "Edit Tags" + Then I should see "Edit Work Tags for " + And I should see "Testerwork" + And I should not see "Save As Draft" + When I fill in "Fandoms" with "Stargate SG-1, Hana Yori Dango" + And I fill in "Additional Tags" with "Alternate Universe" + And I press "Post" + Then I should see "Stargate SG-1" + And I should see "Hana Yori Dango" + And I should see "Alternate Universe" + And I should see "Work was successfully updated" + + Scenario: Edit tags on a draft + Given I am logged in as "imit" with password "tagyoure" + And the draft "Freeze Tag" + When I am on imit's works page + Then I should see "Drafts (1)" + When I follow "Drafts (1)" + Then I should see "Freeze Tag" + And I should see "Edit Tags" within "#main .own.work.blurb .actions" + When I follow "Edit Tags" + Then I should see the page title "Edit Work Tags" + And I should see "Edit Work Tags" + When I fill in "Fandoms" with "Games, Anthropomorphic" + And I fill in "Additional Tags" with "The cooler version of tag" + And I press "Save As Draft" + Then I should see "Tags were successfully updated" + And I should see "This work is a draft and has not been posted" + And I should see "Games" + And I should see "Anthropomorphic" + And I should see "The cooler version of tag" + + Scenario: Ampersands and angle brackets should display in work titles on Edit Tags page + Given the work "I am <strong>er Than Yesterday & Other Lies" by "testuser2" + And I am logged in as "testuser2" + When I view the work "I am <strong>er Than Yesterday & Other Lies" + And I follow "Edit Tags" + Then I should see "I am er Than Yesterday & Other Lies" + + Scenario: Unlike admins, regular users do not see the language option on the Edit Tags page + Given I am logged in as "regularuser" + And I post the work "Some Work" + When I view the work "Some Work" + And I follow "Edit Tags" + Then I should not see "Choose a language" + + Scenario: A work's tags cannot be edited to remove its fandom + Given I am logged in as a random user + And I post the work "Work 1" with fandom "testing" + And I view the work "Work 1" + And I follow "Edit Tags" + When I fill in "Fandoms" with "" + And I press "Post" + Then I should see "Sorry! We couldn't save this work because: Please fill in at least one fandom." + + Scenario: User can cancel editing a work's tags + Given I am logged in as a random user + And I post the work "Work 1" with fandom "testing" + And I view the work "Work 1" + And I follow "Edit Tags" + And I fill in "Fandoms" with "" + And I press "Cancel" + When I view the work "Work 1" + Then I should see "Fandom: testing" diff --git a/features/works/work_languages.feature b/features/works/work_languages.feature new file mode 100755 index 0000000..1701783 --- /dev/null +++ b/features/works/work_languages.feature @@ -0,0 +1,58 @@ +@works + +Feature: Create Works + In order to have an archive full of works + As an author + I want to create new works + + Scenario: Creating a new work with international characters + + Given basic tags + And basic languages + And I am logged in as "germanfan" with password "password" + When I go to the new work page + Then I should see "Post New Work" + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I fill in "Fandoms" with "Weiß Kreuz" + And I fill in "Work Title" with "Überraschende Überraschung" + And I fill in "content" with "Dies ist eine Fanfic in Deutsch." + And I select "Deutsch" from "Choose a language" + And I press "Preview" + Then I should see "Preview" + When I press "Post" + Then I should see "Work was successfully posted." + And I should see "Deutsch" within "dd.language" + When I go to the works page + Then I should see "Überraschende Überraschung" + When I follow "Weiß Kreuz" + Then I should see "Überraschende Überraschung" + When I follow "Überraschende Überraschung" + Then I should see "Dies ist eine Fanfic in Deutsch." + When I log out + Then I should see "Successfully logged out" + + # another example with a different character set (language not in fixtures) + + Given I am logged in as "finnishfan" with password "password" + When I go to the new work page + Then I should see "Post New Work" + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "A fandom" + And I fill in "Work Title" with "Ennen päivänlaskua ei voi" + And I fill in "content" with "A story that is long enough to count" + And I press "Preview" + Then I should see "Preview" + When I press "Post" + Then I should see "Work was successfully posted." + + Scenario: Previewing a work after changing the language should show the new language + Given basic languages + And I am logged in as a random user + And I post the work "Incorrect" + When I edit the work "Incorrect" + And I select "Deutsch" from "Choose a language" + And I press "Preview" + Then I should see "Language: Deutsch" diff --git a/features/works/work_lock.feature b/features/works/work_lock.feature new file mode 100755 index 0000000..b03f067 --- /dev/null +++ b/features/works/work_lock.feature @@ -0,0 +1,91 @@ +@works @search + +Feature: Locking works to archive users only + In order to keep my works under the radar + As a registered archive user + I should be able to make my works visible only to other registered users + +Scenario: Posting locked work + Given I am logged in as "fandomer" with password "password" + And basic tags + And I go to the new work page + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "Supernatural" + And I fill in "Characters" with "Sammy" + And I fill in "Work Title" with "Awesomeness" + And I fill in "content" with "The story of how they met and how they got into trouble" + And I lock the work + When I press "Preview" + + # shows as restricted + Then I should see the image "title" text "Restricted" within "h2.title" + When I post the work + Then I should see the image "alt" text "(Restricted)" within "h2.title" + When I go to the works tagged "Supernatural" + Then I should see "Awesomeness" within "h4" + And I should see the image "alt" text "(Restricted)" within "h4" + When all indexing jobs have been run + And I fill in "site_search" with "Awesomeness" + And I press "Search" + Then I should see "1 Found" + And I should see "fandomer" within "#main" + + # doesn't show when logged out + When I am logged out + And I go to the works tagged "Supernatural" + Then I should not see "Awesomeness" + And I should not see the image "alt" text "(Restricted)" + When I am on fandomer's works page + Then I should not see "Awesomeness" + When I fill in "site_search" with "Awesomeness" + And I press "Search" + Then I should see "No results found" + And I should not see "fandomer" + + # shows again if you log in as another user + When I am logged in as "testuser" with password "password" + And I am on fandomer's works page + Then I should see "Awesomeness" + +Scenario: Editing posted work + Given I am logged in as "fandomer" with password "password" + And I post the work "Sad generic work" + And all indexing jobs have been run + When I am logged out + And I go to fandomer's works page + Then I should see "Sad generic work" + When I am logged in as "fandomer" with password "password" + And I edit the work "Sad generic work" + And I lock the work + And I fill in "Fandoms" with "Supernatural" + When I press "Preview" + Then I should see the image "title" text "Restricted" within "h2.title" + When I update the work + Then I should see the image "alt" text "(Restricted)" within "h2.title" + When I go to the works tagged "Supernatural" + Then I should see "Sad generic work" within "h4" + And I should see the image "alt" text "(Restricted)" within "h4" + When I am logged out + And I go to the works page + Then I should not see "Sad generic work" + And I should not see the image "alt" text "(Restricted)" + When I am logged in as "fandomer" with password "password" + And I edit the work "Sad generic work" + And I fill in "Notes" with "Random blather" + And I press "Preview" + Then I should see the image "alt" text "(Restricted)" within "h2.title" + When I update the work + Then I should see "Work was successfully updated." + And I should see the image "alt" text "(Restricted)" within "h2.title" + When I edit the work "Sad generic work" + And I unlock the work + And I press "Preview" + Then I should not see the image "alt" text "(Restricted)" + When I update the work + Then I should see "Work was successfully updated." + And I should not see the image "alt" text "(Restricted)" + When I am logged out + And I go to the works page + Then I should see "Sad generic work" diff --git a/features/works/work_notes.feature b/features/works/work_notes.feature new file mode 100755 index 0000000..f0b0302 --- /dev/null +++ b/features/works/work_notes.feature @@ -0,0 +1,25 @@ +@works +Feature: Display work notes + In order to provide information about my work + As an author + I want to be able to add notes to my work + + Scenario: User posts a work without notes + Given the work "Work Without Notes" + When I view the work "Work Without Notes" + Then I should not see "Notes:" + + Scenario: User posts a work with beginning notes + Given the work "Work with Beginning Notes" + When I add the beginning notes "These are my beginning notes. There are no recipients, approved translations, inspirations, or claims here." to the work "Work with Beginning Notes" + And I view the work "Work with Beginning Notes" + Then I should see "Notes:" + And I should see "These are my beginning notes. There are no recipients, approved translations, inspirations, or claims here." + And I should not find a list for associations + + Scenario: User posts a work with end notes + Given the work "Work with End Notes" + When I add the end notes "These are my end notes." to the work "Work with End Notes" + And I view the work "Work with End Notes" + Then I should see "Notes:" within ".end" + And I should see "These are my end notes." within ".end" diff --git a/features/works/work_related.feature b/features/works/work_related.feature new file mode 100755 index 0000000..e6d8882 --- /dev/null +++ b/features/works/work_related.feature @@ -0,0 +1,786 @@ +@works +Feature: Inspirations, remixes and translations + In order to reflect the connections between some fanworks + As a fan author, part of a fan community + I want to be able to list related works + +Scenario: Posting a remix / related work emails the creator of the original work and lists the parent work in the proper location on the remix / related work + + Given I have related works setup + When I post a related work as remixer + Then a parent related work should be seen + And the original author should be emailed + +Scenario: Remixer can see their remix / related work on their related works page + + Given I have related works setup + When I post a related work as remixer + When I go to remixer's user page + Then I should see "Related Works (1)" + When I follow "Related Works" + Then I should see "Works that inspired remixer" + And I should see "Worldbuilding by inspiration" + +Scenario: Creator of original work can see a remix on their related works page + + Given I have related works setup + And a related work has been posted + When I am logged in as "inspiration" + And I view my related works + Then I should see "Works inspired by inspiration" + And I should see "Followup by remixer" + +Scenario: Posting a translation emails the creator of the original work and lists the parent work in the proper location on the translation + + Given I have related works setup + When I post a translation as translator + Then a parent translated work should be seen + And the original author should be emailed + +Scenario: Translator can see their translation on their related works page + + Given I have related works setup + When I post a translation as translator + When I go to translator's user page + Then I should see "Related Works (1)" + When I follow "Related Works" + Then I should see "Works translated by translator" + And I should see "Worldbuilding by inspiration" + And I should see "From English to Deutsch" + +Scenario: Creator of original work can see a translation on their related works page + + Given I have related works setup + And a translation has been posted + When I am logged in as "inspiration" + And I view my related works + Then I should see "Translations of inspiration's works" + And I should see "Worldbuilding Translated by translator" + And I should see "From English to Deutsch" + +Scenario: Unapproved translations do not appear or produce an associations list on the original work + + Given I have related works setup + When I post a translation as translator + When I view the work "Worldbuilding" + Then I should not see the translation listed on the original work + And I should not find a list for associations + +Scenario: Unapproved related works do not appear or produce an associations list on the original work + + Given I have related works setup + When I post a related work as remixer + When I view the work "Worldbuilding" + Then I should not see the related work listed on the original work + And I should not find a list for associations + +Scenario: The creator of the original work can approve a related work that is NOT a translation and see it referenced in the beginning notes and linked in the end notes + + Given I have related works setup + And a related work has been posted + When I am logged in as "inspiration" + And I view my related works + When I follow "Approve" + Then I should see "Approve Link" + When I press "Yes, link me!" + Then I should see "Link was successfully approved" + And I should see a beginning note about related works + And I should see the related work in the end notes + And I should not find a list for associations + +Scenario: The creator of the original work can approve a translation and see it linked in an associations list in the beginning notes, and there should not be a list of "works inspired by this one" + + Given I have related works setup + And a translation has been posted + When I approve a related work + Then I should see "Link was successfully approved" + And I should see the translation in the beginning notes + And I should not see "Works inspired by this one:" + And I should find a list for associations + +Scenario: Translation, related work, and parent work links appear in the right places even when viewing a multi-chapter work with draft chapters in chapter-by-chapter mode + + Given I have related works setup + And a translation has been posted and approved + And a related work has been posted and approved + And an inspiring parent work has been posted + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" + And I list the work "Parent Work" as inspiration + And I press "Post" + And a chapter is added to "Worldbuilding" + And a draft chapter is added to "Worldbuilding" + When I view the work "Worldbuilding" + Then I should find a list for associations + And I should see a beginning note about related works + And I should see the translation in the beginning notes + And I should see the inspiring parent work in the beginning notes + When I follow "other works inspired by this one" + Then I should see the related work in the end notes + And I should not see the translation in the end notes + +Scenario: The creator of the original work can see approved and unapproved relationships on their related works page + + Given I have related works setup + And a translation has been posted + And a related work has been posted + When I approve a related work + When I view my related works + Then I should see "Worldbuilding Approve" + And I should see "Deutsch Remove" + +Scenario: The creator of the original work can remove a previously approved related work + + Given I have related works setup + And a related work has been posted and approved + When I view my related works + And I follow "Remove" + Then I should see "Remove Link" + When I press "Remove link" + Then I should see "Link was successfully removed" + And I should not see the related work listed on the original work + +Scenario: The creator of the original work can remove a previously approved translation + + Given I have related works setup + And a translation has been posted and approved + When I view my related works + And I follow "Remove" within "#translationsofme" + Then I should see "Remove Link" + When I press "Remove link" + Then I should see "Link was successfully removed" + And I should not see the translation listed on the original work + +Scenario: Editing an existing work to add an inspiration (parent work) should send email to the creator of the original work + + Given I have related works setup + When I post a related work as remixer + And I edit the work "Followup" + And all emails have been delivered + And I list the work "Worldbuilding Two" as inspiration + And I press "Preview" + When I press "Update" + Then I should see "Work was successfully updated" + And I should see "Inspired by Worldbuilding Two by inspiration" + And "AO3-1506" is fixed + # And 1 email should be delivered + +Scenario: Remixer receives comments on remix, creator of original work doesn't + + Given I have related works setup + And a related work has been posted + And all emails have been delivered + When I am logged in as "commenter" + When I post the comment "Blah" on the work "Followup" + Then "remixer" should be emailed + And "inspiration" should not be emailed + +Scenario: Translator receives comments on translation, creator of original work doesn't + + Given I have related works setup + And a translation has been posted + And all emails have been delivered + When I am logged in as "commenter" + When I post the comment "Blah" on the work "Worldbuilding Translated" + Then "translator" should be emailed + And "inspiration" should not be emailed + +# TODO +# Scenario: Creator of original work chooses to receive comments on translation + + #Given I have related works setup + # And a translation has been posted + # And all emails have been delivered + #When I am logged in as "inspiration" + # And I approve a related work + # And I set my preferences to receive comments on translated works + #When I am logged in as "commenter" + # And I post the comment "Blah" on the work "Worldbuilding Translated" + #Then "translator" should be emailed + # And "inspiration" should be emailed + +# TODO +# Scenario: Creator of original work doesn't receive comments if they haven't approved the translation + + #Given I have related works setup + # And a translation has been posted + # And all emails have been delivered + #When I am logged in as "inspiration" + # And I set my preferences to receive comments on translated works + #When I am logged in as "commenter" + #When I post the comment "Blah" on the work "Worldbuilding Translated" + #Then "inspiration" should not be emailed + +# TODO +# Scenario: Can post a translation of a mystery work + +# TODO +# Scenario: Posting a translation of a mystery work should not allow you to see the work + +# TODO +# Scenario: Can post a translation of an anonymous work + +# TODO +# Scenario: Posting a translation of an anonymous work should not allow you to see the author + +Scenario: Translate your own work + + Given I have related works setup + When I post a translation of my own work + And I approve a related work + Then approving the related work should succeed + +Scenario: Draft works should not show up on related works + + Given I have related works setup + And I am logged in as "translator" + And I draft a translation + When I am logged in as "inspiration" + And I go to inspiration's user page + Then I should not see "Related Works (1)" + When I view my related works + Then I should not see "Worldbuilding Translated" + +Scenario: Listing external works as inspirations + + Given basic tags + And mock websites with no content + When I am logged in as "remixer" with password "password" + And I set up the draft "Followup" + And I check "parent-options-show" + And I fill in "URL" with "http://example.org/200" + And I press "Preview" + Then I should see a save error message + And I should see "The title of a parent work outside the archive can't be blank" + And I should see "The author of a parent work outside the archive can't be blank" + When I fill in "Title" with "Worldbuilding" + And I fill in "Author" with "BNF" + And I check "This is a translation" + And I press "Preview" + Then I should see "Draft was successfully created" + When I press "Post" + Then I should see "Work was successfully posted" + And I should see "A translation of Worldbuilding by BNF" + When I edit the work "Followup" + And I check "parent-options-show" + And I fill in "URL" with "http://example.org/301" + And I press "Preview" + Then I should see a save error message + And I should see "The title of a parent work outside the archive can't be blank" + And I should see "The author of a parent work outside the archive can't be blank" + When I fill in "Title" with "Worldbuilding Two" + And I fill in "Author" with "BNF" + And I press "Preview" + Then I should see "Preview" + When I press "Update" + Then I should see "Work was successfully updated" + And I should see "A translation of Worldbuilding by BNF" + And I should see "Inspired by Worldbuilding Two by BNF" + When I view my related works + Then I should see "From N/A to English" + # inactive URL should give a helpful message (AO3-1783) + # unreachable URL should give a more helpful message (A03-3536) + When I edit the work "Followup" + And I check "parent-options-show" + And I fill in "URL" with "http://example.org/404" + And I fill in "Title" with "Worldbuilding Two" + And I fill in "Author" with "BNF" + And I press "Preview" + Then I should see "Parent work URL could not be reached. If the URL is correct and the site is currently down, please try again later." + +Scenario: External work language + + Given basic tags + And basic languages + And mock websites with no content + When I am logged in as "remixer" with password "password" + And I go to the new work page + And I select "Not Rated" from "Rating" + And I check "No Archive Warnings Apply" + And I select "English" from "Choose a language" + And I fill in "Fandoms" with "Stargate" + And I fill in "Work Title" with "Followup 4" + And I fill in "content" with "That could be an amusing crossover." + And I check "parent-options-show" + And I fill in "URL" with "http://example.org/200" + And I fill in "Title" with "German Worldbuilding" + And I fill in "Author" with "BNF" + And I select "Deutsch" from "Language" + And I check "This is a translation" + And I press "Preview" + Then I should see "Draft was successfully created" + When I press "Post" + Then I should see "Work was successfully posted" + And I should see "A translation of German Worldbuilding by BNF" + When I view my related works + Then I should see "From Deutsch to English" + And I should not see "From N/A to English" + +# TODO after issue 1741 is resolved +# Scenario: Test that I can remove relationships that I initiated from my own works +# especially during posting / editing / previewing a work +# especially from the related_works page, which works but redirects to a non-existant page right now + +Scenario: Restricted works listed as Inspiration show up [Restricted] for guests + Given I have related works setup + And a related work has been posted and approved + When I am logged in as "remixer" + And I lock the work "Followup" + When I am logged out + And I view the work "Worldbuilding" + Then I should see "[Restricted Work] by remixer" + When I am logged in as "remixer" + And I unlock the work "Followup" + When I am logged out + And I view the work "Followup" + Then I should see "Inspired by Worldbuilding by inspiration" + When I am logged in as "inspiration" + And I lock the work "Worldbuilding" + When I am logged out + And I view the work "Followup" + Then I should see "Inspired by [Restricted Work] by inspiration" + +Scenario: Anonymous works listed as inspiration should have links to the authors, + but only for the authors themselves and admins + Given I have related works setup + And I have the anonymous collection "Muppets Anonymous" + And a related work has been posted and approved + + When I am logged in as "remixer" + And I edit the work "Followup" to be in the collection "Muppets_Anonymous" + And I view the work "Worldbuilding" + Then I should see "Works inspired by this one: Followup by Anonymous [remixer]" + When I follow "remixer" within ".afterword .children" + Then I should be on the dashboard page for user "remixer" with pseud "remixer" + + When I am logged in as an admin + And I view the work "Worldbuilding" + Then I should see "Works inspired by this one: Followup by Anonymous [remixer]" + When I follow "remixer" within ".afterword .children" + Then I should be on the dashboard page for user "remixer" with pseud "remixer" + + When I am logged out + And I view the work "Worldbuilding" + Then I should see "Works inspired by this one: Followup by Anonymous" + And I should not see "remixer" within ".afterword .children" + +Scenario: When a user is notified that a co-authored work has been inspired by a work they posted, + the e-mail should link to each author's URL instead of showing escaped HTML + Given I have related works setup + And the user "misterdeejay" exists and is activated + And the user "misterdeejay" allows co-creators + And I am logged in as "inspiration" + And I post the work "Seed of an Idea" + When I am logged in as "inspired" + And I set up the draft "Seedling of an Idea" + And I invite the co-author "misterdeejay" + And I preview the work + Then I should not see "misterdeejay" + But 1 email should be delivered to "misterdeejay" + And the email should contain "The user inspired has invited your pseud misterdeejay to be listed as a co-creator on the following work" + When the user "misterdeejay" accepts all co-creator requests + And I edit the work "Seedling of an Idea" + And I list the work "Seed of an Idea" as inspiration + And I preview the work + And I post the work + Then 1 email should be delivered to "inspiration" + And the email should link to inspired's user url + And the email should not contain "<a href="http://archiveofourown.org/users/inspired/pseuds/inspired"" + And the email should link to misterdeejay's user url + And the email should not contain "<a href="http://archiveofourown.org/users/misterdeejay/pseuds/misterdeejay"" + + Scenario: When using an invalid URL + Given I am logged in + And I set up a draft "Naughty" + When I check "parent-options-show" + And I fill in "URL" with "not valid." + And I fill in "Title" with "Breaking rules" + And I fill in "Author" with "human" + And I press "Post" + Then I should see a save error message + And I should see "Parent work URL does not appear to be a valid URL." + + Scenario: When using a URL on the site to cite a parent work, the URL can't be + for something that isn't a work + Given I am logged in + And I set up a draft "Inspired" + When I list a series as inspiration + And I press "Post" + Then I should see "Only a link to a work can be listed as an inspiration." + + Scenario: When using a URL on the site to cite a parent work, the URL must be + for a work that exists + Given I am logged in + And I set up a draft "Inspired" + When I list a nonexistent work as inspiration + And I press "Post" + Then I should see "The work you listed as an inspiration does not seem to exist." + + Scenario: Protected users cannot have their works cited as related works + Given I have related works setup + And the user "inspiration" is a protected user + When I post a related work as remixer + Then I should see "You can't use the related works function to cite works by the protected user inspiration." + + Scenario: When editing a work with an existing citation of a protected user's work, the citation remains + Given I have related works setup + And a related work has been posted and approved + When the user "inspiration" is a protected user + And I am logged in as "remixer" + And I edit the work "Followup" + And I fill in "Fandoms" with "I forgot about the witches" + And I press "Post" + Then I should see "Work was successfully updated." + And I should see "Inspired by Worldbuilding by inspiration" + + Scenario: Protected users can approve existing citations of their works + Given I have related works setup + And I post a related work as remixer + When the user "inspiration" is a protected user + And I am logged in as "inspiration" + And I go to inspiration's related works page + Then I should see "inspiration's Related Works" + And I should see "Followup by remixer" + And I should see "Approve" + When I follow "Approve" + And I press "Yes, link me!" + Then I should see "Link was successfully approved" + And I should see a beginning note about related works + And I should see the related work in the end notes + And I should not find a list for associations + + Scenario: Protected users can remove existing citations of their works + Given I have related works setup + And a related work has been posted and approved + When the user "inspiration" is a protected user + And I am logged in as "inspiration" + And I go to inspiration's related works page + Then I should see "inspiration's Related Works" + And I should see "Followup by remixer" + And I should see "Remove" + When I follow "Remove" + And I press "Remove link" + Then I should see "Link was successfully removed" + And I should not see the related work listed on the original work + + Scenario: Citing an anonymous work by a protected user does not break anonymity + Given an anonymous collection "Anonymous" + And I have related works setup + And the user "inspiration" is a protected user + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" to be in the collection "Anonymous" + When I post a related work as remixer + Then I should not see "You can't use the related works function to cite works by the protected user inspiration." + When I am logged in as "remixer" + And I go to remixer's related works page + Then I should see "Works that inspired remixer" + And I should see "Worldbuilding by Anonymous" + And I should not see "inspiration" + + Scenario: Citing an unrevealed work by a protected user does not break anonymity + Given a hidden collection "Hidden" + And I have related works setup + And the user "inspiration" is a protected user + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" to be in the collection "Hidden" + When I post a related work as remixer + Then I should not see "You can't use the related works function to cite works by the protected user inspiration." + When I am logged in as "remixer" + And I go to remixer's related works page + Then I should see "Works that inspired remixer" + And I should see "A work in an unrevealed collection" + And I should not see "inspiration" + + Scenario: When a remix is anonymous, it's visible on the original creator's related works page, but not on the remixer's related works page + Given an anonymous collection "Anonymous" + And I have related works setup + And I post a related work as remixer + When I am logged in as "remixer" + And I edit the work "Followup" to be in the collection "Anonymous" + And I go to remixer's related works page + Then I should see "Works that inspired remixer" + And I should see "Worldbuilding by inspiration" + When I go to inspiration's related works page + Then I should see "Works inspired by inspiration" + And I should see "Followup by Anonymous [remixer]" + When I am logged in as "inspiration" + And I go to remixer's related works page + Then I should not see "Works that inspired remixer" + And I should not see "Worldbuilding by inspiration" + When I go to inspiration's related works page + Then I should see "Works inspired by inspiration" + And I should see "Followup by Anonymous" + And I should not see "remixer" + + Scenario: When a remix is unrevealed, it's visible on the original creator's related works page, but not on the remixer's related works page + Given a hidden collection "Hidden" + And I have related works setup + And I post a related work as remixer + When I am logged in as "remixer" + And I edit the work "Followup" to be in the collection "Hidden" + And I go to remixer's related works page + Then I should see "Works that inspired remixer" + And I should see "Worldbuilding by inspiration" + When I go to inspiration's related works page + Then I should see "Works inspired by inspiration" + And I should see "A work in an unrevealed collection" + When I am logged in as "inspiration" + And I go to remixer's related works page + Then I should not see "Works that inspired remixer" + And I should not see "A work in an unrevealed collection" + And I should not see "Worldbuilding by inspiration" + When I go to inspiration's related works page + Then I should see "Works inspired by inspiration" + And I should see "A work in an unrevealed collection" + And I should not see "remixer" + + Scenario: A remix of an anonymous work is shown on the remixer's related works page, but not on the original creator's related works page + Given an anonymous collection "Anonymous" + And I have related works setup + And I post a related work as remixer + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" to be in the collection "Anonymous" + And I go to remixer's related works page + Then I should see "Works that inspired remixer" + And I should see "Worldbuilding by Anonymous [inspiration]" + When I go to inspiration's related works page + Then I should see "Works inspired by inspiration" + And I should see "Followup by remixer" + When I am logged in as "remixer" + And I go to remixer's related works page + Then I should see "Works that inspired remixer" + And I should see "Worldbuilding by Anonymous" + And I should not see "inspiration" + When I go to inspiration's related works page + Then I should not see "Works inspired by inspiration" + And I should not see "Followup" + + Scenario: A remix of an unrevealed work is shown on the remixer's related works page, but not on the original creator's related works page + Given a hidden collection "Hidden" + And I have related works setup + And I post a related work as remixer + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" to be in the collection "Hidden" + And I go to remixer's related works page + Then I should see "Works that inspired remixer" + And I should see "A work in an unrevealed collection" + When I go to inspiration's related works page + Then I should see "Works inspired by inspiration" + And I should see "Followup by remixer" + When I am logged in as "remixer" + And I go to remixer's related works page + Then I should see "Works that inspired remixer" + And I should see "A work in an unrevealed collection" + And I should not see "inspiration" + When I go to inspiration's related works page + Then I should not see "Works inspired by inspiration" + And I should not see "A work in an unrevealed collection" + And I should not see "Followup" + + Scenario: When a translation is anonymous, it's visible on the original creator's related works page, but not on the translator's related works page + Given an anonymous collection "Anonymous" + And I have related works setup + And I post a translation as translator + When I am logged in as "translator" + And I edit the work "Worldbuilding Translated" to be in the collection "Anonymous" + And I go to translator's related works page + Then I should see "Works translated by translator" + And I should see "Worldbuilding by inspiration" + And I should see "From English to Deutsch" + When I go to inspiration's related works page + Then I should see "Translations of inspiration's works" + And I should see "Worldbuilding Translated by Anonymous [translator]" + And I should see "From English to Deutsch" + When I am logged in as "inspiration" + And I go to translator's related works page + Then I should not see "Works translated by translator" + And I should not see "Worldbuilding by inspiration" + And I should not see "From English to Deutsch" + When I go to inspiration's related works page + Then I should see "Translations of inspiration's works" + And I should see "Worldbuilding Translated by Anonymous" + And I should see "From English to Deutsch" + And I should not see "translator" + + Scenario: When a translation is unrevealed, it's visible on the original creator's related works page, but not on the translator's related works page + Given a hidden collection "Hidden" + And I have related works setup + And I post a translation as translator + When I am logged in as "translator" + And I edit the work "Worldbuilding Translated" to be in the collection "Hidden" + And I go to translator's related works page + Then I should see "Works translated by translator" + And I should see "Worldbuilding by inspiration" + And I should see "From English to Deutsch" + When I go to inspiration's related works page + Then I should see "Translations of inspiration's works" + And I should see "A work in an unrevealed collection" + When I am logged in as "inspiration" + And I go to translator's related works page + Then I should not see "Works translated by translator" + And I should not see "Worldbuilding by inspiration" + And I should not see "From English to Deutsch" + When I go to inspiration's related works page + Then I should see "Translations of inspiration's works" + And I should see "A work in an unrevealed collection" + And I should not see "translator" + + Scenario: A translation of an anonymous work is shown on the translator's related works page, but not on the original creator's related works page + Given an anonymous collection "Anonymous" + And I have related works setup + And I post a translation as translator + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" to be in the collection "Anonymous" + And I go to translator's related works page + Then I should see "Works translated by translator" + And I should see "Worldbuilding by Anonymous [inspiration]" + And I should see "From English to Deutsch" + When I go to inspiration's related works page + Then I should see "Translations of inspiration's works" + And I should see "Worldbuilding Translated by translator" + And I should see "From English to Deutsch" + When I am logged in as "translator" + And I go to translator's related works page + Then I should see "Works translated by translator" + And I should see "Worldbuilding by Anonymous" + And I should see "From English to Deutsch" + And I should not see "inspiration" + When I go to inspiration's related works page + Then I should not see "Translations of inspiration's works" + And I should not see "Worldbuilding Translated by translator" + And I should not see "From English to Deutsch" + + Scenario: A translation of an unrevealed work is shown on the translator's related works page, but not on the original creator's related works page + Given a hidden collection "Hidden" + And I have related works setup + And I post a translation as translator + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" to be in the collection "Hidden" + And I go to translator's related works page + Then I should see "Works translated by translator" + And I should see "A work in an unrevealed collection" + And I should see "From English to Deutsch" + When I go to inspiration's related works page + Then I should see "Translations of inspiration's works" + And I should see "Worldbuilding Translated by translator" + And I should see "From English to Deutsch" + When I am logged in as "translator" + And I go to translator's related works page + Then I should see "Works translated by translator" + And I should see "A work in an unrevealed collection" + And I should see "From English to Deutsch" + And I should not see "inspiration" + When I go to inspiration's related works page + Then I should not see "Translations of inspiration's works" + And I should not see "A work in an unrevealed collection" + And I should not see "Worldbuilding Translated by translator" + And I should not see "From English to Deutsch" + + Scenario: Notes of related work do not break anonymity of parent work in an unrevealed collection + Given a hidden collection "Hidden" + And I have related works setup + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" to be in the collection "Hidden" + And I post a related work as remixer + And I post a translation as translator + And I log out + # Check remix + When I view the work "Followup" + Then I should not see "Worldbuilding" + And I should not see "inspiration" + And I should see "Inspired by a work in an unrevealed collection" + # Check translated work + When I view the work "Worldbuilding Translated" + Then I should not see "inspiration" + And I should see "A translation of a work in an unrevealed collection" + + Scenario: Notes of parent work do not break anonymity of child related works in an unrevealed collection + Given a hidden collection "Hidden" + And I have related works setup + And a translation has been posted and approved + And a related work has been posted and approved + When I am logged in as "translator" + And I edit the work "Worldbuilding Translated" to be in the collection "Hidden" + When I am logged in as "remixer" + And I edit the work "Followup" to be in the collection "Hidden" + And I log out + When I view the work "Worldbuilding" + Then I should not see "Worldbuilding Translated by translator" + And I should not see "Followup by remixer" + And I should see "A work in an unrevealed collection" + + Scenario: Work notes updates when anonymity of related works change + Given a hidden collection "Hidden" + And I have related works setup + And an inspiring parent work has been posted + And a translation has been posted and approved + And a related work has been posted and approved + # Going from revealed to unrevealed + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" + And I list the work "Parent Work" as inspiration + And I press "Post" + And I am logged in as "translator" + And I edit the work "Worldbuilding Translated" to be in the collection "Hidden" + And I am logged in as "remixer" + And I edit the work "Followup" to be in the collection "Hidden" + And I am logged in as "testuser" + And I edit the work "Parent Work" to be in the collection "Hidden" + And I log out + And I view the work "Worldbuilding" + Then I should not see the inspiring parent work in the beginning notes + And I should see "Translation into Deutsch available:" + And I should see "A work in an unrevealed collection" + And I should not see "Worldbuilding Translated by translator" + And I should not see "Followup by remixer" + # Going from unrevealed to revealed + When I reveal works for "Hidden" + And I log out + When I view the work "Worldbuilding" + Then I should see the inspiring parent work in the beginning notes + And I should see the translation listed on the original work + And I should see the related work listed on the original work + +Scenario: Notification emails for related works are translated + + Given a locale with translated emails + And I have related works setup + And the user "inspiration" enables translated emails + And the user "encouragement" allows co-creators + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" + And I invite the co-author "encouragement" + And I press "Post" + Then 1 email should be delivered to "encouragement" + And the email should contain "The user inspiration has invited your pseud encouragement to be listed as a co-creator on the following work" + When the user "encouragement" accepts all co-creator requests + And a related work has been posted + Then 3 emails should be delivered + And "inspiration" should receive 1 email + And the email to "inspiration" should be translated + And the email should have "Related work notification" in the subject + And "encouragement" should receive 2 emails + And the last email to "encouragement" should be non-translated + And the last email should have "Related work notification" in the subject + +Scenario: Notification emails for translations are translated + + Given a locale with translated emails + And I have related works setup + And the user "inspiration" enables translated emails + And the user "encouragement" allows co-creators + When I am logged in as "inspiration" + And I edit the work "Worldbuilding" + And I invite the co-author "encouragement" + And I press "Post" + Then 1 email should be delivered to "encouragement" + And the email should contain "The user inspiration has invited your pseud encouragement to be listed as a co-creator on the following work" + When the user "encouragement" accepts all co-creator requests + And a translation has been posted + Then 3 emails should be delivered + And "inspiration" should receive 1 email + And the email to "inspiration" should be translated + And the email should have "Related work notification" in the subject + And "encouragement" should receive 2 emails + And the last email to "encouragement" should be non-translated + And the last email should have "Related work notification" in the subject diff --git a/features/works/work_share.feature b/features/works/work_share.feature new file mode 100755 index 0000000..6f61d51 --- /dev/null +++ b/features/works/work_share.feature @@ -0,0 +1,85 @@ +# We need to load the site skin to make the share modal work properly: +@works @load-default-skin +Feature: Share Works + Testing the "Share" button on works, with Javascript emulation + + @javascript + Scenario: Share a work + Given the work "Blabla" by "testuser1" with fandom "Stargate SG-1" + And I am logged in as "testuser1" + When I view the work "Blabla" + Then I should see "Share" + When I follow "Share" + Then I should see "Copy and paste the following code to link back to this work" within "#share" + And I should see "or use the Tweet or Tumblr links to share the work" within "#share" + And I should see 'Blabla (8 words)' within "#share textarea" + And I should see 'by testuser1' within "#share textarea" + And I should see 'Fandom: Stargate SG-1' within "#share textarea" + And I should see "Rating: Not Rated" within "#share textarea" + And I should see "Warnings: No Archive Warnings Apply" within "#share textarea" + And the share modal should contain social share buttons + And I should not see "Series:" within "#share textarea" + And I should not see "Relationships:" within "#share textarea" + And I should not see "Characters:" within "#share textarea" + And I should not see "Summary:" within "#share textarea" + When I view the work "Blabla" + And I log out + Then I should see "Share" + When I follow "Share" + Then I should see "Copy and paste the following code to link back to this work" within "#share" + And I should see "or use the Tweet or Tumblr links to share the work" within "#share" + And I should see 'Blabla (8 words)' within "#share textarea" + And I should see 'by testuser1' within "#share textarea" + And I should see 'Fandom: Stargate SG-1' within "#share textarea" + And I should see "Rating: Not Rated" within "#share textarea" + And I should see "Warnings: No Archive Warnings Apply" within "#share textarea" + And the share modal should contain social share buttons + And I should not see "Series:" within "#share textarea" + And I should not see "Relationships:" within "#share textarea" + And I should not see "Characters:" within "#share textarea" + And I should not see "Summary:" within "#share textarea" + + Scenario: Share option should be disabled if all creators have set the option to disable sharing on their works + + Given I am logged in as "PrivaC" + And I set my preferences to hide the share buttons on my work + And the work "Don't Lie When You're Hurting Inside" by "PrivaC" + And the user "EitherWay" allows co-creators + When I view the work "Don't Lie When You're Hurting Inside" + Then I should not see "Share" + When I add the co-author "EitherWay" to the work "Don't Lie When You're Hurting Inside" + And I view the work "Don't Lie When You're Hurting Inside" + Then I should see "Share" + When I am logged in as "EitherWay" + And I set my preferences to hide the share buttons on my work + And I view the work "Don't Lie When You're Hurting Inside" + Then I should not see "Share" + + @javascript + Scenario: Sharing should work for multi-chapter works + Given the chaptered work "Whatever" + When I view the work "Whatever" + Then I should see "Share" + When I follow "Share" + Then I should see "Copy and paste the following code to link back to this work" + And I should see ">Whatever (10 words) b" within "#share textarea" + + @javascript + Scenario: Share URL should not be used for post-login redirect + Given I have a work "Blabla" + And the following activated user exists + | login | password | + | MadUser | password | + When I am a visitor + And I view the work "Blabla" + Then I should see "Share" + When I follow "Share" + Then I should see "Close" within "#modal" + When I follow "Close" + And I follow "Log In" + And I fill in "Username or email:" with "maduser" + And I fill in "Password:" with "password" + And I press "Log In" + Then the url should not include "share" + # Shown when the share url is accessed directly + And I should not see "Sorry, you need to have JavaScript enabled for this." diff --git a/features/works/work_view.feature b/features/works/work_view.feature new file mode 100755 index 0000000..5182b7c --- /dev/null +++ b/features/works/work_view.feature @@ -0,0 +1,82 @@ +@works @comments + +Feature: View a work with various options + + Scenario: viewing a work in explicit View Full Work mode, with JavaScript turned off (Issue 2205) + Given the chaptered work with 2 comments "Whatever" + When I view the work "Whatever" in full mode + And I follow "Comments (2)" + Then I should see "Bla bla" + + Scenario: Regular logged-in user doesn't have the option to troubleshoot a work + Given the work "Whatever" + And I am logged in + When I view the work "Whatever" + Then I should not see "Troubleshoot" + + Scenario: Logged-out user doesn't have the option to troubleshoot a work + Given the work "Whatever" + And I am a visitor + When I view the work "Whatever" + Then I should not see "Troubleshoot" + + Scenario: viewing a work when logged in and having set full mode in the preferences + Given the chaptered work "Whatever" + And I am logged in as a random user + And I set my preferences to View Full Work mode by default + When I view the work "Whatever" + Then I should see "Chapter 2" + + Scenario: viewing a work and chapter that have been deleted + Given I am logged in as a random user + And I view a deleted work + Then I should be on the homepage + And I should see "Sorry, we couldn't find the work you were looking for." + When I follow "Site Map" + And I should not see "Sorry, we couldn't find the work you were looking for." + + Scenario: viewing a deleted chapter on a work that still exists + Given I am logged in as a random user + And I view a deleted chapter + And I should see "Sorry, we couldn't find the chapter you were looking for." + And I should see "DeletedChapterWork" + And I follow "Site Map" + Then I should not see "Sorry, we couldn't find the chapter you were looking for." + + Scenario: other users cannot collect a work by default + Given the work "Whatever" + When I have the collection "test collection" with name "test_collection" + And I am logged in as "moderator" + And I view the work "Whatever" + Then I should not see a link "Invite To Collections" + And I should not see the "new_collection_item" form + + Scenario: other users can collect a work when the creator has opted-in + Given the work "Whatever" + And I am logged in as the author of "Whatever" + And I set my preferences to allow collection invitations + When I have the collection "test collection" with name "test_collection" + And I am logged in as "moderator" + And I view the work "Whatever" + Then I should see a link "Invite To Collections" + And I should see the "new_collection_item" form + + Scenario: archivists can add works to collections regardless of invitation preferences + Given the work "Imported Work" + And I have an archivist "archivist" + And I am logged in as "archivist" + When I create the collection "Open Doors Collection 1" + And I view the work "Imported Work" + Then I should see a link "Add to Collections" + And I should see the "new_collection_item" form + + Scenario: chapter title displays in View Full Work mode when chaptered work has one published chapter + Given I am logged in as a random user + And I set my preferences to View Full Work mode by default + When I set up the draft "multiChap" + And I check "This work has multiple chapters" + And I fill in "Chapter Title" with "cool chapter title" + And I fill in "Chapter 1 of" with "?" + And I press "Post" + Then I should see "Chapter 1: " + And I should see "cool chapter title" diff --git a/lib/ EXAMPLE_MODULE.rb.example b/lib/ EXAMPLE_MODULE.rb.example new file mode 100755 index 0000000..3519def --- /dev/null +++ b/lib/ EXAMPLE_MODULE.rb.example @@ -0,0 +1,23 @@ +# Describe what the module does up here +# This then gets included in whatever class you're working on: +# "include [module name]" +module Example + + # Class methods are ones that you run with "ClassName.whatever" -- you would define them + # in the class as "def self.whatever" + # Here you need to define them WITHOUT the "self." part :) + module ClassMethods + + end # CLASS METHODS + + # This last housekeeping method will load up the class methods and + # any associations or validations into your class + def self.included(base) + base.class_eval do + # put any association or validations here, eg has_many, etc + end + base.extend(ClassMethods) + end + + +end \ No newline at end of file diff --git a/lib/acts_as_commentable/comment_methods.rb b/lib/acts_as_commentable/comment_methods.rb new file mode 100755 index 0000000..24acb36 --- /dev/null +++ b/lib/acts_as_commentable/comment_methods.rb @@ -0,0 +1,150 @@ +module ActsAsCommentable::CommentMethods + + def self.included(comment) + comment.class_eval do + include InstanceMethods + + before_destroy :fix_threading_on_destroy + after_destroy :check_can_destroy_parent + end + end + + module InstanceMethods + + # Gets the object (chapter, bookmark, etc.) that the comment ultimately belongs to + def ultimate_parent + self.parent + end + + # gets the comment that is the parent of this thread + def thread_parent + self.reply_comment? ? self.commentable.thread_parent : self + end + + # Only destroys childless comments, sets is_deleted to true for the rest + def destroy_or_mark_deleted + if self.children_count > 0 + self.is_deleted = true + self.comment_content = "deleted comment" # wipe out the content + self.save(validate: false) + else + self.destroy + end + end + + # Returns true if the comment is a reply to another comment + def reply_comment? + self.commentable_type == self.class.to_s + end + + # Returns the total number of sub-comments + def children_count + self.threaded_right ? (self.threaded_right - self.threaded_left - 1)/2 : 0 + end + + # Returns all sub-comments plus the comment itself + # Returns comment itself if unthreaded + def full_set + if self.threaded_left + Comment.includes(:pseud).where("threaded_left BETWEEN (?) and (?) AND thread = (?)", + self.threaded_left, self.threaded_right, self.thread).order(:threaded_left) + else + return [self] + end + end + + # TODO: Remove when AO3-5939 is fixed. + def set_to_freeze_or_unfreeze + # Our set always starts with the comment we pressed the button on. + comment_set = [self] + + # We're going to find all of the comments on @comment's ultimate parent + # and then use the comments' commentables to figure which comments belong + # to the set (thread) we are freezing or unfreezing. + all_comments = self.ultimate_parent.find_all_comments + + # First, we'll loop through all_comments to find any direct replies to + # self. Then we'll loop through again to find any direct replies to + # _those_ replies. We'll repeat this until we find no more replies. + newest_ids = [self.id] + + while newest_ids.present? + child_comments_by_commentable = all_comments.where(commentable_id: newest_ids, commentable_type: "Comment") + + comment_set << child_comments_by_commentable unless child_comments_by_commentable.empty? + newest_ids = child_comments_by_commentable.pluck(:id) + end + comment_set.flatten + end + + # Returns all sub-comments + def all_children + self.children_count > 0 ? Comment.includes(:pseud).where("threaded_left > (?) and threaded_right < (?) and thread = (?)", + self.threaded_left, self.threaded_right, self.thread).order(:threaded_left) : [] + end + + # Returns a full comment thread + def full_thread + Comment.where("thread = (?)", self.thread).order(:threaded_left) + end + + + # Adds a child to this object in the tree. This method will update all of the + # other elements in the tree and shift them to the right, keeping everything + # balanced. + # + # Skips validations so that we can reply to invalid comments. + def add_child( child ) + if ( (self.threaded_left == nil) || (self.threaded_right == nil) ) + # Looks like we're now the root node! Woo + self.threaded_left = 1 + self.threaded_right = 4 + + return nil unless save(validate: false) + + child.commentable_id = self.id + child.threaded_left = 2 + child.threaded_right= 3 + else + # OK, we need to add and shift everything else to the right + child.commentable_id = self.id + right_bound = self.threaded_right + child.threaded_left = right_bound + child.threaded_right = right_bound + 1 + self.threaded_right += 2 + # Updates all comments in the thread to set their relative positions + Comment.transaction { + Comment.where(["thread = (?) AND threaded_left >= (?)", self.thread, right_bound]).update_all("threaded_left = (threaded_left + 2)") + Comment.where(["thread = (?) AND threaded_right >= (?)", self.thread, right_bound]).update_all("threaded_right = (threaded_right + 2)") + save(validate: false) + } + end + end + + # Adjusts left and right threading counts when a comment is deleted + # otherwise, children_count is wrong + def fix_threading_on_destroy + Comment.transaction { + Comment.where(["thread = (?) AND threaded_left > (?)", self.thread, self.threaded_left]).update_all("threaded_left = (threaded_left - 2)") + Comment.where(["thread = (?) AND threaded_right > (?)", self.thread, self.threaded_right]).update_all("threaded_right = (threaded_right - 2)") + } + end + + # When we delete a comment, we may be deleting the last of our parent's + # children. If our parent was marked as deleted (but not actually + # destroyed), we may be able to destroy it. + def check_can_destroy_parent + # We're in the middle of a cascade deletion (e.g. a work is being destroyed), + # so don't try to recursively reload and check our parents. + return if destroyed_by_association + + immediate_parent = commentable.reload + + return unless immediate_parent.is_a?(Comment) + return unless immediate_parent.is_deleted + return unless immediate_parent.children_count.zero? + + immediate_parent.destroy + end + end +end diff --git a/lib/acts_as_commentable/commentable.rb b/lib/acts_as_commentable/commentable.rb new file mode 100755 index 0000000..dc94b9b --- /dev/null +++ b/lib/acts_as_commentable/commentable.rb @@ -0,0 +1,17 @@ +module ActsAsCommentable + module Commentable + def self.included(base) + base.extend ClassMethods + end + + module ClassMethods + def acts_as_commentable + send :include, CommentableEntity + end + + def has_comment_methods + send :include, CommentMethods + end + end + end +end diff --git a/lib/acts_as_commentable/commentable_entity.rb b/lib/acts_as_commentable/commentable_entity.rb new file mode 100755 index 0000000..81cb8a7 --- /dev/null +++ b/lib/acts_as_commentable/commentable_entity.rb @@ -0,0 +1,100 @@ +module ActsAsCommentable::CommentableEntity + + def self.included(commentable) + commentable.class_eval do + has_many :comments, as: :commentable, dependent: :destroy + has_many :total_comments, class_name: 'Comment', as: :parent + extend ClassMethods + end + end + + module ClassMethods + end + + # Returns all comments + def find_all_comments + self.total_comments.order('thread, threaded_left') + end + + # Returns the total number of comments + def count_all_comments + self.total_comments.count + end + + # These below have all been redefined to work for the archive + + # The total number of visible comments on this commentable, not including + # deleted comments, spam comments, unreviewed comments, and comments hidden + # by an admin. + # + # This is the uncached version, and should only be used when calculating an + # accurate value is important (e.g. when updating the StatCounter in the + # database). + def count_visible_comments_uncached + self.total_comments.where( + hidden_by_admin: false, + is_deleted: false, + unreviewed: false, + approved: true + ).count + end + + # The total number of visible comments on this commentable. Cached to reduce + # computation. The cache is manually expired whenever a comment is added, + # removed, or changes visibility, but the cache also expires after a fixed + # amount of time in case of issues with the cache (e.g. stale data when + # calculating the count). + def count_visible_comments + @count_visible_comments ||= + Rails.cache.fetch(count_visible_comments_key, + expires_in: ArchiveConfig.SECONDS_UNTIL_COMMENT_COUNTS_EXPIRE.seconds, + race_condition_ttl: 10.seconds) do + count_visible_comments_uncached + end + end + + def count_visible_comments_key + "#{self.class.table_name}/#{self.id}/count_visible_comments" + end + + def expire_comments_count + @count_visible_comments = nil + Rails.cache.delete(count_visible_comments_key) + end + + # Return the name of this commentable object + # Should be overridden in the implementing class if necessary + def commentable_name + begin + self.title + rescue + "" + end + end + + def commentable_owners + begin + self.pseuds.map {|p| p.user}.uniq + rescue + begin + [self.pseud.user] + rescue + [] + end + end + end + + # Return the email to reach the owner of this commentable object + # Should be overridden in the implementing class if necessary + def commentable_owner_email + if self.commentable_owners.empty? + begin + self.email + rescue + "" + end + else + self.commentable_owners.email.join(',') + end + end +end diff --git a/lib/autocomplete_source.rb b/lib/autocomplete_source.rb new file mode 100755 index 0000000..3e4e58d --- /dev/null +++ b/lib/autocomplete_source.rb @@ -0,0 +1,323 @@ +module AutocompleteSource + AUTOCOMPLETE_DELIMITER = ": ".freeze + AUTOCOMPLETE_COMPLETION_KEY = "completion".freeze + AUTOCOMPLETE_SCORE_KEY = "score".freeze + AUTOCOMPLETE_CACHE_KEY = "cache".freeze + AUTOCOMPLETE_RANGE_LENGTH = 50 # not random + AUTOCOMPLETE_BOOST = 1000 # amt by which we boost results that have all the words + + # this marks a completed word in the completion set -- we use double commas because + # commas are not allowed in pseud and tag names, and double-commas have been disallowed + # from collection titles + AUTOCOMPLETE_WORD_TERMINATOR = ",,".freeze + + def transliterate(input) + input = input.to_s.mb_chars.unicode_normalize(:nfkd).gsub(/[\u0300-\u036F]/, "") + result = "" + input.each_char do |char| + tl = ActiveSupport::Inflector.transliterate(char) + # If transliterate returns "?", the original character is either unsupported + # (e.g. a non-Latin character) or was actually a question mark. + # In both cases, we should keep the original. + result << if tl == "?" + char + else + tl + end + end + result + end + + # override to define any autocomplete prefix spaces where this object should live + def autocomplete_prefixes + [self.transliterate("autocomplete_#{self.class.name.downcase}")] + end + + def autocomplete_search_string + self.transliterate(name) + end + + def autocomplete_search_string_was + self.transliterate(name_was) + end + + def autocomplete_search_string_before_last_save + self.transliterate(name_before_last_save) + end + + def autocomplete_value + "#{id}#{AUTOCOMPLETE_DELIMITER}#{name}" + (self.respond_to?(:title) ? "#{AUTOCOMPLETE_DELIMITER}#{title}" : "") + end + + def autocomplete_value_was + "#{id}#{AUTOCOMPLETE_DELIMITER}#{name_was}" + (self.respond_to?(:title) ? "#{AUTOCOMPLETE_DELIMITER}#{title_was}" : "") + end + + def autocomplete_value_before_last_save + "#{id}#{AUTOCOMPLETE_DELIMITER}#{name_before_last_save}" + (self.respond_to?(:title) ? "#{AUTOCOMPLETE_DELIMITER}#{title_before_last_save}" : "") + end + + def autocomplete_score + 0 + end + + def add_to_autocomplete(score = nil) + score = autocomplete_score unless score + self.class.autocomplete_pieces(autocomplete_search_string).each do |word_piece| + # each prefix represents an autocompletion space -- eg, "autocomplete_collection_all" + autocomplete_prefixes.each do |prefix| + # We put each prefix and the word + completion token into the set of all completions, + # with score 0 so they just get sorted lexicographically -- + # this will be used to quickly find all possible completions in this space + REDIS_AUTOCOMPLETE.zadd(self.transliterate(self.class.autocomplete_completion_key(prefix)), 0, word_piece) + + # We put each complete search string into a separate set indexed by word with specified score + if self.class.is_complete_word?(word_piece) + REDIS_AUTOCOMPLETE.zadd(self.transliterate(self.class.autocomplete_score_key(prefix, word_piece)), score, autocomplete_value) + end + end + end + end + + def remove_from_autocomplete + self.class.remove_from_autocomplete(self.autocomplete_search_string, self.autocomplete_prefixes, self.autocomplete_value) + end + + def remove_stale_from_autocomplete + self.class.remove_from_autocomplete(self.autocomplete_search_string_before_last_save, self.autocomplete_prefixes, self.autocomplete_value_before_last_save) + end + + module ClassMethods + include AutocompleteSource + + # returns a properly escaped and case-insensitive regexp for a more manual search + def get_search_regex(search_param) + Regexp.new(Regexp.escape(search_param), Regexp::IGNORECASE) + end + + # takes either an array or string of search terms (typically extra values passed in through live params, like fandom) + # and returns an array of stripped and lowercase words for actual searching or use in keys + def get_search_terms(search_term) + terms = if search_term.is_a?(Array) + search_term.map { |term| term.split(",") }.flatten + else + search_term.blank? ? [] : search_term.split(",") + end + terms.map { |term| self.transliterate(term.strip.downcase) } + end + + def parse_autocomplete_value(current_autocomplete_value) + current_autocomplete_value.split(AUTOCOMPLETE_DELIMITER, 3) + end + + def fullname_from_autocomplete(current_autocomplete_value) + current_autocomplete_value.split(AUTOCOMPLETE_DELIMITER, 2)[1] + end + + def id_from_autocomplete(current_autocomplete_value) + parse_autocomplete_value(current_autocomplete_value)[0] + end + + def name_from_autocomplete(current_autocomplete_value) + parse_autocomplete_value(current_autocomplete_value)[1] + end + + def title_from_autocomplete(current_autocomplete_value) + parse_autocomplete_value(current_autocomplete_value)[2] + end + + def autocomplete_lookup(options = {}) + options.reverse_merge!({search_param: "", autocomplete_prefix: "", sort: "down"}) + search_param = options[:search_param] + autocomplete_prefix = options[:autocomplete_prefix] + if REDIS_AUTOCOMPLETE.exists(autocomplete_cache_key(autocomplete_prefix, search_param)) + return REDIS_AUTOCOMPLETE.zrange(autocomplete_cache_key(autocomplete_prefix, search_param), 0, -1) + end + + # we assume that if the user is typing in a phrase, any words they have + # entered are the exact word they want, so we only get the prefixes for + # the very last word they have entered so far + search_pieces = autocomplete_phrase_split(search_param).map { |w| w + AUTOCOMPLETE_WORD_TERMINATOR } + + # for each complete word, we look up the phrases in that word's set + # along with their scores and add up the scores + scored_results = {} + count = {} + exact = {} + search_regex = Regexp.new(Regexp.escape(search_param), Regexp::IGNORECASE) + + search_pieces.each_with_index do |search_piece, index| + lastpiece = false + if index == search_pieces.size - 1 + lastpiece = true + search_piece.gsub!(/#{Tag::AUTOCOMPLETE_WORD_TERMINATOR}$/, '') + + break if search_pieces.size > 1 && search_piece.length == 1 + end + + # Get all the complete words which could match this search term + completions = autocomplete_word_completions(search_piece, autocomplete_prefix) + + completions.each do |word| + # O(logN + M) where M is number of items returned -- we could speed up even more by putting in a limit + phrases_with_scores = [] + if lastpiece && search_piece.length < 3 + # use a limit + phrases_with_scores = REDIS_AUTOCOMPLETE.zrevrangebyscore(autocomplete_score_key(autocomplete_prefix, word), + 'inf', 0, withscores: true, limit: [0, 50]) + else + phrases_with_scores = REDIS_AUTOCOMPLETE.zrevrangebyscore(autocomplete_score_key(autocomplete_prefix, word), + 'inf', 0, withscores: true) + end + + phrases_with_scores.each do |phrase, score| + score = score.to_i + if options[:constraint_sets] + # phrases must be in these sets or else no go + # O(logN) complexity + next unless options[:constraint_sets].all {|set| REDIS_AUTOCOMPLETE.zrank(set, phrase)} + end + + if count[phrase] + # if we've already seen this phrase, increase the score + scored_results[phrase] += score + count[phrase] += 1 + else + # initialize the score and check if it exactly matches our regexp + scored_results[phrase] = score + if lastpiece + # don't count if it only matches the last search piece + count[phrase] = 0 + else + count[phrase] = 1 + end + if phrase.match(search_regex) + exact[phrase] = true + else + exact[phrase] = false + end + end + end + end + end + + # final sort is O(NlogN) but N is only the number of complete phrase results which should be relatively small + results = scored_results.keys.sort do |k1, k2| + exact[k1] && !exact[k2] ? -1 : (exact[k2] && !exact[k1] ? 1 : + count[k1] > count[k2] ? -1 : (count[k2] > count[k1] ? 1 : + scored_results[options[:sort] == "down" ? k2 : k1].to_i <=> scored_results[options[:sort] == "down" ? k1 : k2].to_i)) + end + limit = options[:limit] || 15 + + if search_param.length <= 2 + # cache the result for really quick response when only 1-2 letters entered + # adds only a little bit to memory and saves doing a lot of processing of many phrases + results[0..limit].each_with_index {|res, index| REDIS_AUTOCOMPLETE.zadd(autocomplete_cache_key(autocomplete_prefix, search_param), index, res)} + # expire every 24 hours so new entries get added if appropriate + REDIS_AUTOCOMPLETE.expire(autocomplete_cache_key(autocomplete_prefix, search_param), 24*60*60) + end + results[0..limit] + end + + def is_complete_word?(word_piece) + word_piece.match(/#{AUTOCOMPLETE_WORD_TERMINATOR}$/) + end + + def get_word(word_piece) + word_piece.gsub(/#{AUTOCOMPLETE_WORD_TERMINATOR}$/, '') + end + + def autocomplete_score_key(autocomplete_prefix, word) + self.transliterate(autocomplete_prefix + "_" + AUTOCOMPLETE_SCORE_KEY + "_" + get_word(word)) + end + + def autocomplete_completion_key(autocomplete_prefix) + self.transliterate(autocomplete_prefix + "_" + AUTOCOMPLETE_COMPLETION_KEY) + end + + def autocomplete_cache_key(autocomplete_prefix, search_param) + self.transliterate(autocomplete_prefix + "_" + AUTOCOMPLETE_CACHE_KEY + "_" + search_param) + end + + # Split a string into words. + def autocomplete_phrase_split(string) + # Use the ActiveSupport::Multibyte::Chars class to handle downcasing + # instead of the basic string class, because it can handle downcasing + # letters with accents or other diacritics. + normalized = self.transliterate(string).downcase.to_s + + # Split on one or more spaces, ampersands, slashes, double quotation marks, + # opening parentheses, closing parentheses (just in case), tildes, hyphens, vertical bars + normalized.split(%r{(?:\s|&|/|"|\(|\)|~|-|\|)+}) + end + + def autocomplete_pieces(string) + # prefixes for autocomplete + prefixes = [] + + words = autocomplete_phrase_split(string) + + words.each do |word| + prefixes << self.transliterate(word) + AUTOCOMPLETE_WORD_TERMINATOR + word.length.downto(1).each do |last_index| + prefixes << word.slice(0, last_index) + end + end + + prefixes + end + + # overall time complexity: O(log N) + def autocomplete_word_completions(word_piece, autocomplete_prefix) + get_exact = is_complete_word?(word_piece) + + # the rank of the word piece tells us where to start looking + # in the completion set for possible completions + # O(logN) N = number of things in the completion set (ie all the possible prefixes for all the words) + start_position = REDIS_AUTOCOMPLETE.zrank(autocomplete_completion_key(autocomplete_prefix), word_piece) + return [] unless start_position + + results = [] + # start from that position and go for the specified range length + # O(logN + M) M is the range length, so reduces to logN + REDIS_AUTOCOMPLETE.zrange(autocomplete_completion_key(autocomplete_prefix), start_position, start_position + AUTOCOMPLETE_RANGE_LENGTH - 1).each do |entry| + minlen = [entry.length, word_piece.length].min + # if the entry stops matching the prefix then we've passed out of + # the completions that could belong to this word -- return + return results if entry.slice(0, minlen) != word_piece.slice(0, minlen) + + # otherwise if we've hit a complete word add it to the results + if is_complete_word?(entry) + results << entry + return results if get_exact + end + end + + results + end + + # generic method to remove pieces for given search string and value from the given autocomplete prefixes + def remove_from_autocomplete(search_string, prefixes, value) + autocomplete_pieces(search_string).each do |word_piece| + prefixes.each do |prefix| + # we leave the word pieces in the completion set so we don't accidentally trash + # parts of other completions -- doing a weekly reload for cleanup is good enough + if is_complete_word?(word_piece) + word = get_word(word_piece) + phrases = REDIS_AUTOCOMPLETE.zrevrangebyscore(autocomplete_score_key(prefix, word), 'inf', 0) + if phrases.count == 1 && phrases.first == value + # there's only one phrase for this word and we're removing it, remove the completed word from the completion set + REDIS_AUTOCOMPLETE.zrem(autocomplete_completion_key(prefix), word_piece) + end + # remove the phrase we're deleting from the score set + REDIS_AUTOCOMPLETE.zrem(autocomplete_score_key(prefix, word_piece), value) + end + end + end + end + end + + def self.included(base) + base.extend(ClassMethods) + end +end diff --git a/lib/backwards_compatible_password_decryptor.rb b/lib/backwards_compatible_password_decryptor.rb new file mode 100755 index 0000000..0a3df64 --- /dev/null +++ b/lib/backwards_compatible_password_decryptor.rb @@ -0,0 +1,45 @@ +module BackwardsCompatiblePasswordDecryptor + # http://stackoverflow.com/questions/6113375/converting-existing-password-hash-to-devise + # https://github.com/binarylogic/authlogic/blob/master/lib/authlogic/acts_as_authentic/password.rb#L361 + # https://www.ruby-forum.com/topic/217465 + # Not useful but https://github.com/plataformatec/devise/issues/511 + def self.included(base) + base.class_eval do + alias :devise_valid_password? :valid_password? + end + end + + def valid_password?(password) + begin + result = super(password) + # Now the common form is that we are using an authlogic method so let's + # test that on failure + return true if result + # This is the backwards compatibility with what we used to authenticate + # with bcrypt and authlogic. + # https://github.com/binarylogic/authlogic/blob/master/lib/authlogic/acts_as_authentic/password.rb#L361 + + # if Authlogic::CryptoProviders::BCrypt.matches?(encrypted_password, [password, password_salt].compact) + # same as + if BCrypt::Password.new(encrypted_password) == [password, password_salt].flatten.join + # I am commenting the following line so that if we need to roll back the + # migration because of reasons the authentication would still work. + # self.password = password + return true + end + return false + rescue BCrypt::Errors::InvalidHash + # Now a really old password hash + # This is the backwards compatibility for the old she512 passwords, all 1 + # of them + # http://stackoverflow.com/questions/6113375/converting-existing-password-hash-to-devise/9079088 + digest = "#{password}#{password_salt}" + 20.times { digest = Digest::SHA512.hexdigest(digest) } + return false unless digest == encrypted_password + # I am commenting the following line so that if we needed to roll back the + # migration because of reasons the authentication would still work. + # self.password = password + true + end + end +end diff --git a/lib/bookmark_count_caching.rb b/lib/bookmark_count_caching.rb new file mode 100755 index 0000000..4d4d722 --- /dev/null +++ b/lib/bookmark_count_caching.rb @@ -0,0 +1,15 @@ +module BookmarkCountCaching + def key_for_public_bookmarks_count + "/v1/public_bookmarks_count/#{self.id}" + end + + def public_bookmarks_count + Rails.cache.fetch(self.key_for_public_bookmarks_count) do + self.bookmarks.is_public.count + end + end + + def invalidate_public_bookmarks_count + Rails.cache.delete(self.key_for_public_bookmarks_count) + end +end diff --git a/lib/bookmarkable.rb b/lib/bookmarkable.rb new file mode 100755 index 0000000..f0efb4d --- /dev/null +++ b/lib/bookmarkable.rb @@ -0,0 +1,28 @@ +module Bookmarkable + + def self.included(bookmarkable) + bookmarkable.class_eval do + has_many :bookmarks, as: :bookmarkable, inverse_of: :bookmarkable + has_many :user_tags, through: :bookmarks, source: :tags + after_update :update_bookmarks_index + after_update :update_bookmarker_pseuds_index + after_destroy :update_bookmarker_pseuds_index + end + end + + def public_bookmark_count + Rails.cache.fetch("#{self.cache_key}/bookmark_count", expires_in: 2.hours) do + self.bookmarks.is_public.count + end + end + + def update_bookmarks_index + IndexQueue.enqueue_ids(Bookmark, bookmarks.pluck(:id), :background) + end + + def update_bookmarker_pseuds_index + return unless respond_to?(:should_reindex_pseuds?) + return unless should_reindex_pseuds? + IndexQueue.enqueue_ids(Pseud, bookmarks.pluck(:pseud_id), :background) + end +end diff --git a/lib/challenge_core.rb b/lib/challenge_core.rb new file mode 100755 index 0000000..c9e811d --- /dev/null +++ b/lib/challenge_core.rb @@ -0,0 +1,102 @@ +module ChallengeCore + + # Used to ensure allowed is no less than required + def update_allowed_values + self.class::PROMPT_TYPES.each do |prompt_type| + required = required(prompt_type) + eval("#{prompt_type}_num_allowed = required") if required > allowed(prompt_type) + end + end + + # make sure that challenge sign-up dates / open dates aren't contradictory + def validate_signup_dates + # some variables for clarity + error_message = [] + open_date = self.signups_open_at + close_date = self.signups_close_at + signups_open = self.signup_open + if signups_open + if close_date && close_date.past? + error_message << ts("If sign-ups are open, sign-up close date cannot be in the past.") + end + if open_date && open_date.future? + error_message << ts("If sign-ups are open, sign-up open date cannot be in the future.") + end + # rubocop:disable Style/IfUnlessModifier + if close_date && open_date && close_date.to_fs(:number) < open_date.to_fs(:number) + error_message << ts("Close date cannot be before open date.") + end + # rubocop:enable Style/IfUnlessModifier + end + unless error_message.empty? + error_message.each do |errors| + self.errors.add(:base, errors) + end + end + end + + # When Challenges are deleted, there are two references left behind that need to be reset to nil + def clear_challenge_references + collection.challenge_id = nil + collection.challenge_type = nil + collection.save! + end + + # a couple of handy shorthand methods + def required(type) + self.send("#{type}_num_required") + end + + def allowed(type) + self.send("#{type}_num_allowed") + end + + def allowed_range_string(type) + "#{required(type)}" + (allowed(type) != required(type) ? " - #{allowed(type)}" : '') + end + + #### Management + + def user_allowed_to_see_signups?(user) + self.collection.user_is_maintainer?(user) + end + + def user_allowed_to_see_assignments?(user) + self.collection.user_is_maintainer?(user) + end + + def user_allowed_to_sign_up?(user) + self.collection.user_is_maintainer?(user) || self.signup_open + end + + def user_allowed_to_see_prompt?(user, prompt) + true + end + + # whether users can change the name on their signup or not -- override in challenge class as appropriate + def allow_name_change? + true + end + + module ClassMethods + # override datetime setters so we can take strings + def override_datetime_setters + %w(signups_open_at signups_close_at assignments_due_at works_reveal_at authors_reveal_at).each do |datetime_attr| + define_method("#{datetime_attr}_string") do + return unless (datetime = self[datetime_attr]) + + datetime.in_time_zone(time_zone.presence || Time.zone).strftime(ArchiveConfig.DEFAULT_DATETIME_FORMAT) + end + + define_method("#{datetime_attr}_string=") do |datetimestring| + self[datetime_attr] = Timeliness.parse(datetimestring, zone: (time_zone.presence || Time.zone)) + end + end + end + end + + def self.included(base) + base.extend(ClassMethods) + end + +end diff --git a/lib/collectible.rb b/lib/collectible.rb new file mode 100755 index 0000000..650c704 --- /dev/null +++ b/lib/collectible.rb @@ -0,0 +1,150 @@ +module Collectible + + def self.included(collectible) + collectible.class_eval do + + has_many :collection_items, as: :item, inverse_of: :item + accepts_nested_attributes_for :collection_items, allow_destroy: true + has_many :approved_collection_items, -> { approved_by_both }, class_name: "CollectionItem", as: :item + has_many :user_approved_collection_items, -> { approved_by_user }, class_name: "CollectionItem", as: :item + + has_many :collections, + through: :collection_items, + after_add: :set_visibility, + after_remove: :set_visibility, + before_remove: :destroy_collection_item + has_many :approved_collections, + through: :approved_collection_items, + source: :collection + has_many :user_approved_collections, + through: :user_approved_collection_items, + source: :collection + has_many :rejected_collections, + -> { CollectionItem.rejected_by_user }, + through: :collection_items, + source: :collection + + # Note: this scope includes the items in the children of the specified collection + scope :in_collection, lambda { |collection| + distinct.joins(:approved_collection_items).merge(collection.all_items) + } + + after_destroy :clean_up_collection_items + end + end + + # add collections based on a comma-separated list of names + def collections_to_add=(collection_names) + old_collections = self.collection_items.collect(&:collection_id) + names = trim_collection_names(collection_names) + names.each do |name| + c = Collection.find_by(name: name) + errors.add(:base, ts("We couldn't find the collection %{name}.", name: name)) and return if c.nil? + if c.closed? + errors.add(:base, ts("The collection %{name} is not currently open.", name: name)) and return unless c.user_is_maintainer?(User.current_user) || old_collections.include?(c.id) + end + add_to_collection(c) + end + end + + # remove collections based on an array of ids + def collections_to_remove=(collection_ids) + collection_ids.reject {|id| id.blank?}.map {|id| id.is_a?(String) ? id.strip : id}.each do |id| + c = Collection.find(id) || nil + remove_from_collection(c) + end + end + def collections_to_add; nil; end + def collections_to_remove; nil; end + + def add_to_collection(collection) + if collection && !self.collections.include?(collection) + self.collections << collection + end + end + + def remove_from_collection(collection) + if collection && self.collections.include?(collection) + self.collections -= [collection] + end + end + + private + def trim_collection_names(names) + names.split(',').map{ |name| name.strip }.reject {|name| name.blank?} + end + + public + # Set ALL of an item's collections based on a list of collection names + # Refactored to use collections_to_(add,remove) above so we only have one set of code + # performing the actual add/remove actions + # This method now just does the convenience work of getting the removed ids -- any missing collections + # will be identified + # IMPORTANT: cannot delete all existing collections, or else items in closed collections + # can't be edited + def collection_names=(new_collection_names) + new_names = trim_collection_names(new_collection_names) + remove_ids = self.collections.reject {|c| new_names.include?(c.name)}.collect(&:id) + self.collections_to_add = new_names.join(",") + self.collections_to_remove = remove_ids + end + + # NOTE: better to use collections_to_add/remove above instead for more consistency + def collection_names + @collection_names ? @collection_names : self.collections.collect(&:name).uniq.join(",") + end + + + #### UNREVEALED/ANONYMOUS + + # Set the anonymous/unrevealed status of the collectible based on its collections + # We can't check for user approval because the collection item doesn't exist + # and don't need to because this only gets called when the work is a new record and + # therefore being created by its author + def set_anon_unrevealed + if self.respond_to?(:in_anon_collection) && self.respond_to?(:in_unrevealed_collection) + # if we have collection items saved here then the collectible is not a new object + if self.id.nil? || self.collection_items.empty? + self.in_anon_collection = !self.collections.select(&:anonymous?).empty? + self.in_unrevealed_collection = !self.collections.select(&:unrevealed?).empty? + else + update_anon_unrevealed + end + end + return true + end + + # TODO: need a better, DRY, long-term fix + # Collection items can be revealed independently of a collection, so we don't want + # to check the collection status when those are updated + # Only include collections approved by the user + def update_anon_unrevealed + if self.respond_to?(:in_anon_collection) && self.respond_to?(:in_unrevealed_collection) + self.in_anon_collection = self.user_approved_collection_items.anonymous.any? + self.in_unrevealed_collection = self.user_approved_collection_items.unrevealed.any? + end + end + + #### CALLBACKS + + # Calculate (but don't save) whether this work should be anonymous and/or + # unrevealed. Saving the results of this will be handled when the work saves, + # or by the collection item's callbacks. + def set_visibility(collection) + set_anon_unrevealed + end + + # We want to do this after the work is deleted to avoid issues with + # accidentally trying to reveal the work during deletion (which wouldn't + # successfully reveal the work because it'd fail while trying to save the + # partially invalid work, but would cause an error). + def clean_up_collection_items + self.collection_items.destroy_all + end + + # Destroy the collection item before the collection is deleted, so that we + # trigger the CollectionItem's after_destroy callbacks. + def destroy_collection_item(collection) + self.collection_items.find_by(collection: collection).try(:destroy) + end +end diff --git a/lib/creation_notifier.rb b/lib/creation_notifier.rb new file mode 100755 index 0000000..63a2cf4 --- /dev/null +++ b/lib/creation_notifier.rb @@ -0,0 +1,102 @@ +module CreationNotifier + def notify_after_creation # after_create + return unless self.posted? + do_notify + end + + def notify_after_update + return unless self.valid? && self.posted? + + if self.saved_change_to_posted? + do_notify + else + notify_subscribers_on_reveal + end + end + + # send the appropriate notifications + def do_notify + if self.is_a?(Work) + notify_parents + notify_subscribers + notify_prompters + elsif self.is_a?(Chapter) && self.position != 1 + notify_subscribers + end + end + + # notify recipients that they have gotten a story! + # we also need to check to see if the work is in a collection + # only notify a recipient once for each work + def notify_recipients + return unless self.posted && self.new_gifts.present? && !self.unrevealed? + + recipient_pseuds = Pseud.parse_bylines(self.new_gifts.collect(&:recipient).join(","))[:pseuds] + # check user prefs to see which recipients want to get gift notifications + # (since each user has only one preference item, this removes duplicates) + recip_preferences = Preference.where(user_id: recipient_pseuds.map(&:user_id), recipient_emails_off: false) + recip_preferences.each do |userpref| + I18n.with_locale(userpref.locale_for_mails) do + if self.collections.empty? || self.collections.first.nil? + UserMailer.recipient_notification(userpref.user_id, self.id).deliver_after_commit + else + UserMailer.recipient_notification(userpref.user_id, self.id, self.collections.first.id).deliver_after_commit + end + end + end + end + + # notify people subscribed to this creation or its authors + def notify_subscribers + work = self.respond_to?(:work) ? self.work : self + if work && !work.unrevealed? + Subscription.for_work(work).each do |subscription| + RedisMailQueue.queue_subscription(subscription, self) + end + end + end + + # Check whether the work's creator has just been revealed (whether because + # a collection has just revealed its works, or a collection has just revealed + # creators). If so, queue up creator subscription emails. + def notify_subscribers_on_reveal + # Double-check that it's a posted work. + return unless self.is_a?(Work) && self.posted + + # Bail out if the work or its creator is currently unrevealed. + return if self.in_anon_collection || self.in_unrevealed_collection + + # If we've reached here, the creator of the work must be public. + # So now we want to check whether that's a recent thing. + pertinent = %w[in_anon_collection in_unrevealed_collection] + if (pertinent & saved_changes.keys).any? + # Prior to this save, the work was either anonymous or unrevealed. + # Either way, the author was just revealed, so we should trigger + # a creator subscription email. + Subscription.where( + subscribable_id: self.pseuds.pluck(:user_id), + subscribable_type: "User" + ).each do |subscription| + RedisMailQueue.queue_subscription(subscription, self) + end + end + end + + # notify prompters of response to their prompt + def notify_prompters + if !self.challenge_claims.empty? && !self.unrevealed? + if self.collections.first.nil? + UserMailer.prompter_notification(self.id,).deliver_after_commit + else + UserMailer.prompter_notification(self.id, self.collections.first.id).deliver_after_commit + end + end + end + + # notify authors of related work + def notify_parents + return if unrevealed? + + parents_after_saving.each(&:notify_parent_owners) + end +end diff --git a/lib/css_cleaner.rb b/lib/css_cleaner.rb new file mode 100755 index 0000000..ca26a6c --- /dev/null +++ b/lib/css_cleaner.rb @@ -0,0 +1,289 @@ +# Use css parser to break up style blocks +require "css_parser" + +module CssCleaner + include CssParser + + # constant regexps for css values + ALPHA_REGEX = Regexp.new('[a-z\-]+') + UNITS_REGEX = Regexp.new('deg|cm|em|ex|in|mm|pc|pt|px|s|%', Regexp::IGNORECASE) + NUMBER_REGEX = Regexp.new('-?\.?\d{1,3}\.?\d{0,3}') + NUMBER_WITH_UNIT_REGEX = Regexp.new("#{NUMBER_REGEX}\s*#{UNITS_REGEX}?\s*,?\s*") + PAREN_NUMBER_REGEX = Regexp.new('\(\s*' + NUMBER_WITH_UNIT_REGEX.to_s + '+\s*\)') + PREFIX_REGEX = Regexp.new('moz|ms|o|webkit') + + FUNCTION_NAME_REGEX = Regexp.new('scalex?y?|translatex?y?|skewx?y?|rotatex?y?|matrix', Regexp::IGNORECASE) + TRANSFORM_FUNCTION_REGEX = Regexp.new("#{FUNCTION_NAME_REGEX}#{PAREN_NUMBER_REGEX}") + + SHAPE_NAME_REGEX = Regexp.new('rect', Regexp::IGNORECASE) + SHAPE_FUNCTION_REGEX = Regexp.new("#{SHAPE_NAME_REGEX}#{PAREN_NUMBER_REGEX}") + + RGBA_REGEX = Regexp.new("rgba?" + PAREN_NUMBER_REGEX.to_s, Regexp::IGNORECASE) + HSLA_REGEX = Regexp.new("hsla?" + PAREN_NUMBER_REGEX.to_s, Regexp::IGNORECASE) + COLOR_REGEX = Regexp.new("#[0-9a-f]{3,6}|" + ALPHA_REGEX.to_s + "|" + RGBA_REGEX.to_s + "|" + HSLA_REGEX.to_s) + COLOR_STOP_FUNCTION_REGEX = Regexp.new('color-stop\s*\(' + NUMBER_WITH_UNIT_REGEX.to_s + '\s*\,?\s*' + COLOR_REGEX.to_s + '\s*\)', Regexp::IGNORECASE) + + # list of filter functions can be found at https://developer.mozilla.org/en-US/docs/Web/CSS/filter#syntax + FILTER_NAME_REGEX = Regexp.new("blur|brightness|contrast|grayscale|hue-rotate|invert|opacity|saturate|sepia", Regexp::IGNORECASE) + FILTER_FUNCTION_REGEX = Regexp.new("#{FILTER_NAME_REGEX}#{PAREN_NUMBER_REGEX}") + + # drop-shadow can take multiple values, which are a mix of numbers and colors + DROP_SHADOW_NAME_REGEX = Regexp.new("drop-shadow", Regexp::IGNORECASE) + DROP_SHADOW_VALUE_REGEX = Regexp.new("\\(\\s*(#{NUMBER_WITH_UNIT_REGEX}|#{COLOR_REGEX}\\s*)+\\s*\\)") + DROP_SHADOW_FUNCTION_REGEX = Regexp.new("#{DROP_SHADOW_NAME_REGEX}#{DROP_SHADOW_VALUE_REGEX}") + + # Custom properties (variables) are declared using --name: value and accessed + # using property: var(--name). The var() function can be more complex, e.g., + # var(--name, fallback value), but we're keeping our implementation simple. + CUSTOM_PROPERTY_NAME_REGEXP = Regexp.new("\\-\\-[0-9a-z\\-_]+", Regexp::IGNORECASE) + PAREN_CUSTOM_PROPERTY_REGEX = Regexp.new("\\(\\s*#{CUSTOM_PROPERTY_NAME_REGEXP}\\s*\\)", Regexp::IGNORECASE) + VAR_FUNCTION_REGEX = Regexp.new("var#{PAREN_CUSTOM_PROPERTY_REGEX}", Regexp::IGNORECASE) + + # To allow the url() function, it is also necessary to include "url" in ArchiveConfig.SUPPORTED_CSS_KEYWORDS + # from the ICANN list at http://www.icann.org/en/registries/top-level-domains.htm + TOP_LEVEL_DOMAINS = %w(ac ad ae aero af ag ai al am an ao aq ar arpa as asia at au aw ax az ba bb bd be bf bg bh bi biz bj bm bn bo br bs bt bv bw by bz ca cat cc cd cf cg ch ci ck cl cm cn co com coop cr cu cv cx cy cz de dj dk dm do dz ec edu ee eg er es et eu fi fj fk fm fo fr ga gb gd ge gf gg gh gi gl gm gn gov gp gq gr gs gt gu gw gy hk hm hn hr ht hu id ie il im in info int io iq ir is it je jm jo jobs jp ke kg kh ki km kn kp kr kw ky kz la lb lc li lk lr ls lt lu lv ly ma mc md me mg mh mil mk ml mm mn mo mobi mp mq mr ms mt mu museum mv mw mx my mz na name nc ne net nf ng ni nl no np nr nu nz om org pa pe pf pg ph pk pl pm pn pr pro ps pt pw py qa re ro rs ru rw sa sb sc sd se sg sh si sj sk sl sm sn so sr st su sv sy sz tc td tel tf tg th tj tk tl tm tn to tp tr travel tt tv tw tz ua ug uk us uy uz va vc ve vg vi vn vu wf ws xn xxx ye yt za zm zw) + DOMAIN_REGEX = Regexp.new('https?://\w[\w\-\.]+\.(' + TOP_LEVEL_DOMAINS.join('|') + ')') + DOMAIN_OR_IMAGES_REGEX = Regexp.new('\/images|' + DOMAIN_REGEX.to_s) + URI_REGEX = Regexp.new(DOMAIN_OR_IMAGES_REGEX.to_s + '/[\w\-\.\/]*[\w\-]\.(' + ArchiveConfig.SUPPORTED_EXTERNAL_URLS.join('|') + ')') + URL_REGEX = Regexp.new(URI_REGEX.to_s + '|"' + URI_REGEX.to_s + '"|\'' + URI_REGEX.to_s + '\'') + URL_FUNCTION_REGEX = Regexp.new('url\(\s*' + URL_REGEX.to_s + '\s*\)') + + VALUE_REGEX = Regexp.new("#{TRANSFORM_FUNCTION_REGEX}|#{URL_FUNCTION_REGEX}|#{COLOR_STOP_FUNCTION_REGEX}|#{COLOR_REGEX}|#{NUMBER_WITH_UNIT_REGEX}|#{ALPHA_REGEX}|#{SHAPE_FUNCTION_REGEX}|#{FILTER_FUNCTION_REGEX}|#{DROP_SHADOW_FUNCTION_REGEX}|#{VAR_FUNCTION_REGEX}") + + + # For use in ActiveRecord models + # We parse and clean the CSS line by line in order to provide more helpful error messages. + # The prefix is used if you want to make sure a particular prefix appears on all the selectors in + # this block of css, eg ".userstuff p" instead of just "p" + def clean_css_code(css_code, options = {}) + return "" if !css_code.match(/\w/) # only spaces of various kinds + clean_css = "" + parser = CssParser::Parser.new + parser.add_block!(css_code) + + prefix = options[:prefix] || '' + caller_check = options[:caller_check] + + errors.add(:base, :no_valid_css) if parser.to_s.blank? + + parser.each_rule_set do |rs| + selectors = rs.selectors.map do |selector| + if selector.match(/@font-face/i) + errors.add(:base, :font_face) + next + end + # remove whitespace and convert > entities back to the > direct child selector + sel = selector.gsub(/\n/, "").gsub(">", ">").strip + (prefix.blank? || sel.start_with?(prefix)) ? sel : "#{prefix} #{sel}" + end + clean_declarations = "" + # Do not internationalize the , used as a join in these errors -- it's reflective of the comma used in the list of selectors, which does not change based on locale. + rs.each_declaration do |property, value, is_important| + if property.blank? || value.blank? + errors.add(:base, :no_valid_css_for_selectors, selectors: rs.selectors.join(", ")) + elsif sanitize_css_property(property).blank? + # If it starts with --, assume the user was trying to define a custom property. + if property.match(/\A--/) + errors.add(:base, :invalid_custom_property_name, property: property, selectors: rs.selectors.join(", ")) + else + errors.add(:base, :banned_property, property: property) + end + elsif (cleanval = sanitize_css_declaration_value(property, value)).blank? + errors.add(:base, :banned_value_for_property, property: property, selectors: rs.selectors.join(", "), value: value) + elsif !caller_check || caller_check.call(rs, property, value) + clean_declarations += " #{property}: #{cleanval}#{is_important ? ' !important' : ''};\n" + end + end + if clean_declarations.blank? + errors.add(:base, :no_rules_for_selectors, selectors: rs.selectors.join(", ")) + else + # everything looks ok, add it to the css + clean_css += "#{selectors.join(",\n")} {\n" + clean_css += clean_declarations + clean_css += "}\n\n" + end + end + return clean_css + end + + def legal_property?(property) + ArchiveConfig.SUPPORTED_CSS_PROPERTIES.include?(property) || + property.match(/-(#{PREFIX_REGEX})-(#{ArchiveConfig.SUPPORTED_CSS_PROPERTIES.join('|')})/) + end + + def legal_shorthand_property?(property) + property.match(/#{ArchiveConfig.SUPPORTED_CSS_SHORTHAND_PROPERTIES.join('|')}/) + end + + def custom_property?(property) + property.match(/\A(#{CUSTOM_PROPERTY_NAME_REGEXP})\z/) + end + + def sanitize_css_property(property) + return property if legal_property?(property) || legal_shorthand_property?(property) || custom_property?(property) + end + + # A declaration must match the format `property: value;` (space and semicolon + # are optional in user input). + # All properties must appear in ArchiveConfig.SUPPORTED_CSS_PROPERTIES or + # ArchiveConfig.SUPPORTED_CSS_SHORTHAND_PROPERTIES, or that property and its + # value will be removed and an error message will be given. + # All values are sanitized. If any values in a declaration are invalid, the + # value will be blanked out and an empty property returned, which will result + # in an error. + def sanitize_css_declaration_value(property, value) + clean = "" + if property == "font-family" + # preserve the original capitalization + clean = value if sanitize_css_font(value).present? + elsif property == "content" + # don't allow var() function + clean = value.match(/\bvar\b/i) ? "" : sanitize_css_content(value) + # The url() function can be used in the values for certain properties, + # provided "url" is included in ArchiveConfig.SUPPORTED_CSS_KEYWORDS. If + # those criteria are not met, we strip the value here. If they are met, the + # value will undergo sanitization in tokenize_and_sanitize_css_value or + # sanitize_css_value. + elsif value.match(/\burl\b/i) && (ArchiveConfig.SUPPORTED_CSS_KEYWORDS.exclude?("url") || %w[background background-image border border-image list-style list-style-image].exclude?(property)) + clean = "" + elsif legal_shorthand_property?(property) || custom_property?(property) + clean = tokenize_and_sanitize_css_value(value) + elsif legal_property?(property) + clean = sanitize_css_value(value) + end + clean.strip + end + + # divide a css value into tokens and clean them individually + def tokenize_and_sanitize_css_value(value) + cleanval = "" + scanner = StringScanner.new(value) + + # we scan until we find either a space, a comma, or an open parenthesis + while scanner.exist?(/\s+|,|\(/) + # we have some tokens left to break up + in_paren = 0 + token = scanner.scan_until(/\s+|,|\(/) + if token.blank? || token == "," + cleanval += token + next + end + in_paren = 1 if token.match(/\($/) + while in_paren > 0 + # scan until closing paren or another opening paren + nextpart = scanner.scan_until(/\(|\)/) + if nextpart + token += nextpart + in_paren += 1 if token.match(/\($/) + in_paren -= 1 if token.match(/\)$/) + else + # mismatched parens + return "" + end + end + + # we now have a single token + separator = token.match(/(\s|,)$/) || "" + token.strip! + token.chomp!(',') + cleantoken = sanitize_css_token(token) + return "" if cleantoken.blank? + cleanval += cleantoken + separator.to_s + end + + token = scanner.rest + if token && !token.blank? + cleantoken = sanitize_css_token(token) + return "" if cleantoken.blank? + cleanval += cleantoken + end + + return cleanval + end + + def sanitize_css_token(token) + if token.match?(/gradient/) + sanitize_css_gradient(token) + else + sanitize_css_value(token) + end + end + + # sanitize a CSS gradient + # background:-webkit-gradient( linear, left bottom, left top, color-stop(0, rgb(82,82,82)), color-stop(1, rgb(125,124,125))); + # -moz-linear-gradient(bottom, rgba(120,120,120,1) 5%, rgba(94,94,94,1) 50%, rgba(108,108,108,1) 55%, rgba(137,137,137,1) 100%); + def sanitize_css_gradient(value) + if value.match(/^([a-z\-]+)\((.*)\)/) + function = $1 + interior = $2 + cleaned_interior = tokenize_and_sanitize_css_value(interior) + if function.match(/gradient/) && !cleaned_interior.blank? + return "#{function}(#{cleaned_interior})" + end + end + return "" + end + + # All values must be either + # - in ArchiveConfig.SUPPORTED_CSS_KEYWORDS + # - URLs of the format url(http://url/) + # - rgba(), hsla(), hex, or named colors + # - numeric values + # - transform, shape, filter, drop shadow, or variable functions + # Comma-separated lists of these values are also allowed. + def sanitize_css_value(value) + value_stripped = strip_value(value) + + # If it's a comma-separated set of valid values, it's fine. However, we need + # to downcase any var() functions to match the css_parser gem's downcasing + # of property names. + if value_stripped.match?(/^(#{VALUE_REGEX},?\s*)+$/i) + return value unless value.match?(/#{VAR_FUNCTION_REGEX}/) + + return value.gsub(/#{VAR_FUNCTION_REGEX}/, &:downcase) + end + + # If the value is explicitly in our list of supported keywords, it's fine. + # However, note that !important is always allowed (refer to the comments on + # strip_value(value) and ArchiveConfig.SUPPORTED_CSS_KEYWORDS for more), and + # that the url() function is allowed by the VALUE_REGEX above. Excluding + # url() from SUPPORTED_CSS_KEYWORDS only strips it because of the check in + # sanitize_css_declaration_value. + return value if value_stripped.split(",").all? { |subval| ArchiveConfig.SUPPORTED_CSS_KEYWORDS.include?(subval.strip) } + + return "" + end + + def sanitize_css_content(value) + # For now we only allow a single completely quoted string + return value if value =~ /^\'([^\']*)\'$/ + return value if value =~ /^\"([^\"]*)\"$/ + + # or a valid img url + return value if value.match(Regexp.new("^#{URL_FUNCTION_REGEX}$")) + + # or "none" + return value if value == "none" + + return "" + end + + # Font family names may be alphanumeric values with dashes + def sanitize_css_font(value) + value_stripped = strip_value(value) + if value_stripped.split(',').all? {|fontname| fontname.strip =~ /^(\'?[a-z0-9\- ]+\'?|\"?[a-z0-9\- ]+\"?)$/} + return value + else + return "" + end + end + + # Remove !important and trailing spaces from values to simplify sanitization. + # In most cases, we return the original value after sanitizaiton, which + # restores the !important keyword. + # Note that this means !important is always allowed, regardless of whether it + # is included in ArchiveConfig.SUPPORTED_CSS_KEYWORDS. + def strip_value(value) + value.downcase.gsub(/(!important)/, "").strip + end +end diff --git a/lib/devise_failure_message_options.rb b/lib/devise_failure_message_options.rb new file mode 100755 index 0000000..f673e2c --- /dev/null +++ b/lib/devise_failure_message_options.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Mark the error messages as html_safe (to allow links), and define a few +# variables that can be used in all messages. +class DeviseFailureMessageOptions < Devise::FailureApp + def default_i18n_variables + @default_i18n_variables ||= { + reset_path: new_user_password_path, + problems_path: admin_post_path(12035), + app_name: ArchiveConfig.APP_SHORT_NAME + } + end + + def i18n_options(options) + options.merge(default_i18n_variables) + end + + def i18n_message(*args) + super(*args).html_safe + end +end diff --git a/lib/html_cleaner.rb b/lib/html_cleaner.rb new file mode 100755 index 0000000..c2be06c --- /dev/null +++ b/lib/html_cleaner.rb @@ -0,0 +1,160 @@ +# note, if you modify this file you have to restart the server or console +module HtmlCleaner + # If we aren't sure that this field hasn't been sanitized since the last sanitizer version, + # we sanitize it before we allow it to pass through (and save it if possible). + # For certain highly visible fields, we might want to be cautious about + # images. Use image_safety_mode: true to prevent images from embedding as-is. + def sanitize_field(object, fieldname, image_safety_mode: false) + return "" if object.send(fieldname).nil? + + sanitizer_version = object.try("#{fieldname}_sanitizer_version") + sanitized_field = + if sanitizer_version && sanitizer_version >= ArchiveConfig.SANITIZER_VERSION + # return the field without sanitizing + object.send(fieldname) + else + # no sanitizer version information, so re-sanitize + sanitize_value(fieldname, object.send(fieldname)) + end + + sanitized_field = strip_images(sanitized_field, keep_src: true) if image_safety_mode + sanitized_field + end + + # yank out bad end-of-line characters and evil msword curly quotes + def fix_bad_characters(text) + return "" if text.nil? + + # get the text into UTF-8 and get rid of invalid characters + text = text.encode("UTF-8", invalid: :replace, undef: :replace, replace: "") + + text.gsub! "<3", "<3" + + # convert carriage returns to newlines + text.gsub!(/\r\n?/, "\n") + + # argh, get rid of ____spacer____ inserts + text.gsub! "____spacer____", "" + + return text + end + + def sanitize_value(field, value) + return value if ArchiveConfig.FIELDS_WITHOUT_SANITIZATION.include?(field.to_s) + if ArchiveConfig.NONZERO_INTEGER_PARAMETERS.has_key?(field.to_s) + return (value.to_i > 0) ? value.to_i : ArchiveConfig.NONZERO_INTEGER_PARAMETERS[field.to_s] + end + return "" if value.blank? + unfrozen_value = value&.dup + unfrozen_value.strip! + if field.to_s == 'title' + # prevent invisible titles + unfrozen_value.gsub!("<", "<") + unfrozen_value.gsub!(">", ">") + end + if ArchiveConfig.FIELDS_ALLOWING_LESS_THAN.include?(field.to_s) + unfrozen_value.gsub!("<", "<") + end + if ArchiveConfig.FIELDS_ALLOWING_HTML.include?(field.to_s) + # We're allowing users to use HTML in this field + transformers = [ + Sanitize::Config::OPEN_ATTRIBUTE_TRANSFORMER, + Sanitize::Config::RELATIVE_IMAGE_PATH_TRANSFORMER + ] + if ArchiveConfig.FIELDS_ALLOWING_MEDIA_EMBEDS.include?(field.to_s) + transformers << OtwSanitize::EmbedSanitizer.transformer + transformers << OtwSanitize::MediaSanitizer.transformer + end + if ArchiveConfig.FIELDS_ALLOWING_CSS.include?(field.to_s) + transformers << OtwSanitize::UserClassSanitizer.transformer + end + # Now that we know what transformers we need, let's sanitize the unfrozen value + if ArchiveConfig.FIELDS_ALLOWING_CSS.include?(field.to_s) + unfrozen_value = Sanitize.clean(add_paragraphs_to_text(fix_bad_characters(unfrozen_value)), + Sanitize::Config::CSS_ALLOWED.merge(transformers: transformers)) + else + unfrozen_value = Sanitize.clean(add_paragraphs_to_text(fix_bad_characters(unfrozen_value)), + Sanitize::Config::ARCHIVE.merge(transformers: transformers)) + end + doc = Nokogiri::HTML5::Document.new + doc.encoding = "UTF-8" + unfrozen_value = doc.fragment(unfrozen_value).to_html + else + # clean out all tags + unfrozen_value = Sanitize.clean(fix_bad_characters(unfrozen_value)) + end + + # Plain text fields can't contain & entities: + unfrozen_value.gsub!(/&/, '&') unless (ArchiveConfig.FIELDS_ALLOWING_HTML_ENTITIES + ArchiveConfig.FIELDS_ALLOWING_HTML).include?(field.to_s) + + # Temporary hack to evade conversions by strip_html_breaks() for textarea: + # Accidentally or not, for a long time sanitization code gets nbsp unescaped, + # and this replacement keeps that behavior + unfrozen_value.gsub!(" ", "\u00A0") + unfrozen_value + end + + # grabbed from http://code.google.com/p/sanitizeparams/ and tweaked + def sanitize_params(new_params = params) + walk_hash(new_params) if new_params + end + + def walk_hash(hash) + hash.keys.each do |key| + if hash[key].is_a? String + hash[key] = sanitize_value(key, hash[key]) + elsif hash[key].is_a?(ActionController::Parameters) + hash[key] = hash[key].to_hash + elsif hash[key].is_a?(Hash) + hash[key] = walk_hash(hash[key]) + elsif hash[key].is_a? Array + hash[key] = walk_array(hash[key]) + end + end + hash + end + + def walk_array(array) + array.each_with_index do |el,i| + if el.is_a? String + array[i] = sanitize_value("", el) + elsif el.is_a? Hash + array[i] = walk_hash(el) + elsif el.is_a? Array + array[i] = walk_array(el) + end + end + array + end + + def add_paragraphs_to_text(text) + # Adding paragraphs in place of linebreaks + doc = Nokogiri::HTML5.fragment("#{text}") + myroot = doc.children.first + ParagraphMaker.process(myroot) + myroot.children.to_html + end + + ### STRIPPING FOR DISPLAY ONLY + # Regexps for stripping particular tags and attributes for display. + # These assume they are running on well-formed XHTML, which we can do + # because they will only be used on already-cleaned fields. + + # strip img tags, optionally leaving the HTML attributes (e.g. src and alt) exposed + def strip_images(value, keep_src: false) + value.gsub(%r{(?:<(img .*?) ?/?>)}, keep_src ? "\\1" : "") + end + + def strip_html_breaks_simple(value) + return "" if value.blank? + value.gsub(/\s*
    \s*/, "
    \n"). + gsub(/\s*]*>\s* \s*<\/p>\s*/, "\n\n\n"). + gsub(/\s*]*>(.*?)<\/p>\s*/m, "\n\n" + '\1'). + strip + end + + def add_break_between_paragraphs(value) + return "" if value.blank? + value.gsub(%r{\s*

    \s*

    \s*}, "


    ") + end +end diff --git a/lib/otw_sanitize/embed_sanitizer.rb b/lib/otw_sanitize/embed_sanitizer.rb new file mode 100755 index 0000000..6edf210 --- /dev/null +++ b/lib/otw_sanitize/embed_sanitizer.rb @@ -0,0 +1,205 @@ +# frozen_string_literal: true + +require "addressable/uri" +require "cgi" + +module OtwSanitize + # Creates a Sanitize transformer to sanitize embedded media + class EmbedSanitizer + ALLOWLIST_REGEXES = { + "4shared": %r{^4shared\.com/web/embed}, + audiocom: %r{^audio\.com/embed/audio/}, + archiveorg: %r{^archive\.org/embed/}, + bilibili: %r{^(player\.)?bilibili\.com/}, + criticalcommons: %r{^criticalcommons\.org/}, + eighttracks: %r{^8tracks\.com/}, + google: %r{^google\.com/}, + podfic: %r{^podfic\.com/}, + soundcloud: %r{^(w\.)?soundcloud\.com/}, + spotify: %r{^(open\.)?spotify\.com/}, + viddersnet: %r{^vidders\.net/}, + viddertube: %r{^viddertube\.com/}, + vimeo: %r{^(player\.)?vimeo\.com/}, + youtube: %r{^youtube(-nocookie)?\.com/} + }.freeze + + ALLOWS_FLASHVARS = %i[ + criticalcommons eighttracks google + podfic soundcloud spotify viddersnet + ].freeze + + SUPPORTS_HTTPS = %i[ + 4shared audiocom + archiveorg bilibili eighttracks podfic + soundcloud spotify viddersnet viddertube vimeo youtube + ].freeze + + # Creates a callable transformer for the sanitizer to use + def self.transformer + lambda do |env| + # Don't continue if this node is already safelisted. + return if env[:is_allowlisted] + + new(env[:node]).sanitized_node + end + end + + attr_reader :node + + # Takes a Nokogiri node + def initialize(node) + @node = node + end + + def sanitized_node + return unless embed_node? + return unless source_url && source + + ensure_https + + if parent_name == "object" + sanitize_object + else + sanitize_embed + end + end + + def node_name + node.name.to_s.downcase + end + + delegate :parent, to: :node + + def parent_name + parent.name.to_s.downcase if parent + end + + # Since the transformer receives the deepest nodes first, we look for a + # element whose parent is an , or an embed or iframe + def embed_node? + (node_name == "param" && parent_name == "object") || + %w[embed iframe].include?(node_name) + end + + # Compare the url to our list of allowlisted sources + # and return the appropriate source symbol + def source + return @source if @source + + ALLOWLIST_REGEXES.each_pair do |name, reg| + if source_url =~ reg + @source = name + break + end + end + @source + end + + # Get the url of the thing we're embedding and standardize it + def source_url + return @source_url if @source_url + + if node_name == "param" + # Quick XPath search to find the node that contains the video URL. + return unless (movie_node = node.parent.search('param[@name="movie"]')[0]) + + url = movie_node["value"] + else + url = node["src"] + end + @source_url = standardize_url(url) + end + + def standardize_url(url) + # strip off optional protocol and www + protocol_regex = %r{^(?:https?:)?//(?:www\.)?}i + # normalize the url + url = url&.gsub(protocol_regex, "") + begin + Addressable::URI.parse(url).normalize.to_s + rescue StandardError + nil + end + end + + # For sites that support https, ensure we use a secure embed + def ensure_https + return unless supports_https? && node["src"].present? + + node["src"] = node["src"].gsub("http:", "https:") + return unless allows_flashvars? && node["flashvars"].present? + + node["flashvars"] = node["flashvars"].gsub("http:", "https:") + node["flashvars"] = node["flashvars"].gsub("http%3A", "https%3A") + end + + # We're now certain that this is an embed from a trusted source, but we + # still need to run it through a special Sanitize step to ensure + # that no unwanted elements or attributes that don't belong in + # a video embed can sneak in. + def sanitize_object + Sanitize.clean_node!( + parent, + elements: %w[embed object param], + attributes: { + "embed" => %w[allowfullscreen height src type width], + "object" => %w[height width], + "param" => %w[name value] + } + ) + + disable_scripts(parent) + + { node_allowlist: [node, parent] } + end + + def sanitize_embed + Sanitize.clean_node!( + node, + elements: %w[embed iframe], + attributes: { + "embed" => %w[ + allowfullscreen height src type width + ] + optional_embed_attributes, + "iframe" => %w[ + allowfullscreen frameborder height src title + class type width + ] + } + ) + + if node_name == "embed" + disable_scripts(node) + node["flashvars"] = "" unless allows_flashvars? + end + { node_allowlist: [node] } + end + + # disable script access and networking + def disable_scripts(embed_node) + embed_node["allowscriptaccess"] = "never" + embed_node["allownetworking"] = "internal" + + embed_node.search("param").each do |param_node| + param_node.unlink if param_node[:name].casecmp?("allowscriptaccess") || + param_node[:name].casecmp?("allownetworking") + end + end + + def optional_embed_attributes + if allows_flashvars? + %w[wmode flashvars] + else + [] + end + end + + def allows_flashvars? + ALLOWS_FLASHVARS.include?(source) + end + + def supports_https? + SUPPORTS_HTTPS.include?(source) + end + end +end diff --git a/lib/otw_sanitize/media_sanitizer.rb b/lib/otw_sanitize/media_sanitizer.rb new file mode 100755 index 0000000..e5cab04 --- /dev/null +++ b/lib/otw_sanitize/media_sanitizer.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +# Creates a Sanitize transformer to sanitize audio and video tags +module OtwSanitize + class MediaSanitizer + # Attribute allowlists + AUDIO_ATTRIBUTES = %w[ + class controls crossorigin dir + loop muted preload src title + ].freeze + + VIDEO_ATTRIBUTES = %w[ + class controls crossorigin dir height loop + muted playsinline poster preload src title width + ].freeze + + SOURCE_ATTRIBUTES = %w[src type].freeze + TRACK_ATTRIBUTES = %w[default kind label src srclang].freeze + + ALLOWLIST_CONFIG = { + elements: %w[ + audio video source track + ] + Sanitize::Config::ARCHIVE[:elements], + attributes: { + "audio" => AUDIO_ATTRIBUTES, + "video" => VIDEO_ATTRIBUTES, + "source" => SOURCE_ATTRIBUTES, + "track" => TRACK_ATTRIBUTES + }, + add_attributes: { + "audio" => { + "controls" => "controls", + "crossorigin" => "anonymous", + "preload" => "metadata" + }, + "video" => { + "controls" => "controls", + "playsinline" => "playsinline", + "crossorigin" => "anonymous", + "preload" => "metadata" + } + }, + protocols: { + "audio" => { + "src" => %w[http https] + }, + "video" => { + "poster" => %w[http https], + "src" => %w[http https] + }, + "source" => { + "src" => %w[http https] + }, + "track" => { + "src" => %w[http https] + } + } + }.freeze + + # Creates a callable transformer for the sanitizer to use + def self.transformer + lambda do |env| + # Don't continue if this node is already safelisted. + return if env[:is_allowlisted] + + new(env[:node]).sanitized_node + end + end + + attr_reader :node + + # Takes a Nokogiri node + def initialize(node) + @node = node + end + + # Skip if it's not media or if we don't want to allowlist it + def sanitized_node + return unless media_node? + return if banned_source? + + config = Sanitize::Config.merge(Sanitize::Config::ARCHIVE, ALLOWLIST_CONFIG) + Sanitize.clean_node!(node, config) + tidy_boolean_attributes(node) + { node_allowlist: [node] } + end + + def node_name + node.name.to_s.downcase + end + + def media_node? + %w[audio video source track].include?(node_name) + end + + def source_url + node["src"] || "" + end + + def source_host + url = source_url + return nil if url.blank? + + # Just in case we're missing a protocol + url = "https://" + url unless url =~ /http/ + Addressable::URI.parse(url).normalize.host + end + + def banned_source? + return unless source_host + + ArchiveConfig.BANNED_MULTIMEDIA_SRCS.any? do |blocked| + source_host.match(blocked) + end + end + + # Sanitize outputs boolean attributes as attribute="". While this works, + # attribute="attribute" is more consistent with the way we handle the + # boolean attributes we automatically add (e.g. controls="controls"). + def tidy_boolean_attributes(node) + node["default"] = "default" if node["default"] + node["loop"] = "loop" if node["loop"] + node["muted"] = "muted" if node["muted"] + end + end +end diff --git a/lib/otw_sanitize/user_class_sanitizer.rb b/lib/otw_sanitize/user_class_sanitizer.rb new file mode 100755 index 0000000..e32651c --- /dev/null +++ b/lib/otw_sanitize/user_class_sanitizer.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# allow users to specify class attributes in their html +# scrub invalid class names +module OtwSanitize + class UserClassSanitizer + def self.transformer + lambda do |env| + # Check this node even if it is already safelisted. + new(env[:node]).sanitized_node + end + end + + attr_reader :node + + # Takes a Nokogiri node + def initialize(node) + @node = node + end + + # Update the class attribute with the sanitized value + def sanitized_node + return if user_classes.blank? + node['class'] = sanitized_classes + node + end + + # Turn the class string into an array, select the valid values + # then rejoin them + def sanitized_classes + user_classes.split(" "). + select { |user_class| valid_class?(user_class) }. + join(" ") + end + + # let through alphanumeric class names with a dash/underscore + def valid_class?(str) + str =~ /^[a-zA-Z][\w\-]+$/ + end + + # If the element is something like

    + # then the value will be the string "apple banana" + def user_classes + node['class'] + end + end +end diff --git a/lib/pagination_list_link_renderer.rb b/lib/pagination_list_link_renderer.rb new file mode 100755 index 0000000..b344dbb --- /dev/null +++ b/lib/pagination_list_link_renderer.rb @@ -0,0 +1,62 @@ +# encoding: UTF-8 +# Almost entirely taken from http://thewebfellas.com/blog/2010/8/22/revisited-roll-your-own-pagination-links-with-will_paginate-and-rails-3 +# +#

    Pages Navigation

    +# + +class PaginationListLinkRenderer < WillPaginate::ActionView::LinkRenderer + + def to_html + html = pagination.map do |item| + if item.is_a?(Integer) + page_number(item, @options[:remote]) + else + send(item) + end + end.join(@options[:link_separator]) + + @options[:container] ? html_container(html) : html + end + + protected + + def gap + tag(:li, "…", class: "gap") + end + + def page_number(page, remote = nil) + unless page == current_page + tag(:li, link(page, page, {rel: rel_value(page)}.merge(:"data-remote" => remote))) + else + tag(:li, tag(:span, page, class: "current")) + end + end + + def previous_page + num = @collection.current_page > 1 && @collection.current_page - 1 + previous_or_next_page(num, @options[:previous_label], 'previous', @options[:remote]) + end + + def next_page + num = @collection.current_page < @collection.total_pages && @collection.current_page + 1 + previous_or_next_page(num, @options[:next_label], 'next', @options[:remote]) + end + + def previous_or_next_page(page, text, classname, remote = nil) + if page + tag(:li, link(text, page, {:"data-remote" => remote}), class: classname, title: classname) + else + tag(:li, tag(:span, text, class: "disabled"), class: classname, title: classname) + end + end + + def html_container(html) + tag(:h4, "Pages Navigation", class: "landmark heading") + + tag(:ol, html, container_attributes.merge(class: "pagination actions", role: "navigation", title: "pagination")) + end + +end diff --git a/lib/paragraph_maker.rb b/lib/paragraph_maker.rb new file mode 100755 index 0000000..cc13153 --- /dev/null +++ b/lib/paragraph_maker.rb @@ -0,0 +1,280 @@ +# frozen_string_literals: true + +# Traverse a Nokogiri document tree recursively in order to insert linebreaks. +module ParagraphMaker + extend self + + # Tags that will be stripped by the sanitizer that are inline, and should be + # wrapped in paragraphs and have their contents left untouched: + INLINE_INVALID_TAGS = %w[button input label map select textarea].freeze + + # Tags that will be stripped by the sanitizer that are block tags, and should + # have nearby whitespace stripped: + BLOCK_INVALID_TAGS = %w[fieldset form].freeze + + # Tags that will be completely removed by the sanitizer, and should have + # nearby whitespace removed, and their contents left untouched: + REMOVED_INVALID_TAGS = Sanitize::Config::ARCHIVE[:remove_contents] + + # Tags whose content we don't touch + TAG_NAMES_TO_SKIP = (%w[ + a abbr acronym address audio dl embed figure h1 h2 h3 h4 h5 h6 hr img ol + object p pre source summary table track video ul + ] + INLINE_INVALID_TAGS + REMOVED_INVALID_TAGS).freeze + + # Tags that need to go inside p tags + TAG_NAMES_TO_WRAP = (%w[ + a abbr acronym b big br cite code del dfn em i img ins kbd q rp rt ruby + s samp small span strike strong sub sup tt u var + ] + INLINE_INVALID_TAGS).freeze + + # Tags that can't be inside p tags + TAG_NAMES_TO_UNWRAP = %w[ + audio details dl figure h1 h2 h3 h4 h5 h6 hr ol p pre source summary table track ul video + ].freeze + + # Tags before and after which we don't want to convert linebreaks + # into br's and p's + TAG_NAMES_STRIP_WHITESPACE = (%w[ + audio blockquote br center details dl div figure figcaption h1 h2 h3 h4 h5 h6 hr ol + p pre source summary table track ul video + ] + BLOCK_INVALID_TAGS + REMOVED_INVALID_TAGS).freeze + + private + + # Traverse all nodes from the given root, yielding each node to the given + # block. Processes nodes that are on the list of TAG_NAMES_TO_SKIP, but + # doesn't process any of their children. + def traverse(node, &block) + block.call(node) + + return if TAG_NAMES_TO_SKIP.include?(node.name) + + node.children.each do |child| + traverse(child, &block) + end + end + + # Checks whether the given node is in a paragraph. This includes nodes where + # the paragraph is many layers up. + def in_paragraph?(node) + return false if node.parent.nil? + return true if node.parent.name == "p" + + in_paragraph?(node.parent) + end + + # Strip whitespace before and after tags in the TAG_NAMES_STRIP_WHITESPACE + # list. + def strip_whitespace(root) + traverse(root) do |node| + next unless node.text? || node.cdata? + + # This text node immediately follows either the closing tag of its + # previous sibling, or the opening tag of its parent if it has no + # previous sibling. If we're supposed to ignore whitespace after that + # tag, we should lstrip to get rid of it. + node.content = node.content.lstrip if TAG_NAMES_STRIP_WHITESPACE.include?(node.previous_sibling&.name || node.parent&.name) + + # This text node is immediately followed by either the opening tag of its + # next sibling, or the closing tag of its parent. If that tag is one in + # the TAG_NAMES_STRIP_WHITESPACE list, we want to rstrip this node. + node.content = node.content.rstrip if TAG_NAMES_STRIP_WHITESPACE.include?(node.next_sibling&.name || node.parent&.name) + + node.unlink if node.content.empty? + end + end + + # Split text nodes when they have newlines: + def split_text_at_newlines(root) + traverse(root) do |node| + next unless node.text? + + pieces = node.to_s.split(/([[:space:]]*\n[[:space:]]*)/) + next unless pieces.length > 1 + + pieces.each do |piece| + next if piece.empty? + + case piece.count("\n") + when 0 + # No newlines, it's just a normal piece of text: + node.add_previous_sibling(piece) + when 1 + # One newline, replace it with a
    . + node.add_previous_sibling("
    \n") + when 2 + # Two newlines, replace it with a special tag (to be processed later) + # that marks the paragraph to be split at this location. + node.add_previous_sibling("") + else + # Three or more newlines, replace it with a special tag (to be + # processed later) that marks the paragraph to be split at this + # location, with a

     

    paragraph inserted to increase the + # spacing between lines. + node.add_previous_sibling("") + end + end + + node.unlink + end + end + + # Traverse the tree in search of sequences of
    tags. We want to find the + # last
    tag in the sequence, so that we don't process the sequence more + # than once. Once we've found the
    tag that has a prior
    tag, but no + # following
    tag, we can yank out all of the
    tags in the sequence, + # counting them as we go. + def merge_br_tags(root) + traverse(root) do |node| + next unless node.name == "br" && + node.next_sibling&.name != "br" && + node.previous_sibling&.name == "br" + + break_count = 1 + while node.previous_sibling&.name == "br" + node.previous_sibling.unlink + break_count += 1 + end + + if break_count == 2 + # Replace the
    sequence with a special tag (to be processed later) + # that indicates that whatever paragraph we're in needs to be split at + # this point. This corresponds to having two
    tags in a row. + node.replace("") + else + # Replace the
    sequence with a special tag (to be processed later) + # that indicates that whatever paragraph we're in needs to be split at + # this point, and there needs to be a

     

    paragraph inserted + # into the split. This corresponds to having 3+
    tags in a row. + node.replace("") + end + end + end + + # Go through all nodes that should be inside paragraph tags, and make sure + # they're wrapped: + def wrap_all(root) + # We don't use traverse(root) here to handle the traversal because we're + # doing something much more complex than usual with our children. + return if TAG_NAMES_TO_SKIP.include?(root.name) || in_paragraph?(root) || root.name == "p" + + # Divide up the list of children into sublists based on whether the node + # needs to have a paragraph wrapped around it, or not. + chunks = root.children.chunk do |node| + node.text? || node.cdata? || TAG_NAMES_TO_WRAP.include?(node.name) + end + + chunks.each do |should_wrap, children| + if should_wrap + # Create a paragraph object, and then transfer all of the children in + # this chunk to it. + paragraph = root.document.create_element("p") + children.first.add_previous_sibling(paragraph) + children.each do |node| + paragraph.add_child(node) + end + else + # These nodes don't need to be wrapped in a paragraph node, but some of + # their children might, so we have to process them. + children.each do |node| + wrap_all(node) + end + end + end + end + + # Given a node, "split" its parent at that node and move the node upwards one + # level -- that is, split its siblings by whether they're left/right of the + # node, and split the parent into two copies, one containing the left siblings + # and one containing the right siblings. + # + # For example, if we have something like this: + #
      + #
    • First
    • + #
    • Second
    • + #
    • Third
    • + #
    + # Then calling split_parent on the second list item will produce this: + #
      + #
    • First
    • + #
    + #
  • Second
  • + #
      + #
    • Third
    • + #
    + def split_parent(node) + # The easy cases: if this node is the first or last node in its parent, then + # there's no point in a proper split, because one of the two tags would just + # be empty. Instead, we rearrange ourselves relative to our parent. + return node.parent.add_previous_sibling(node) if node.previous_sibling.nil? + return node.parent.add_next_sibling(node) if node.next_sibling.nil? + + # Create a shallow copy of the parent: + new_parent = node.parent.dup(0) + + # Copy over all of the attributes: + node.parent.attributes.each do |name, attribute| + new_parent.set_attribute(name, attribute.value) + end + + # Put the new parent in the right place: + node.parent.add_next_sibling(new_parent) + + # Move over all of the siblings: + new_parent.add_child(node.next_sibling) until node.next_sibling.nil? + + # Put the node in the right place: + node.parent.add_next_sibling(node) + end + + # Remove the given node from its containing paragraph tag, if it has one. + def extract_from_paragraph(node) + split_parent(node) while in_paragraph?(node) + end + + # Go through all nodes that shouldn't be inside paragraph tags, and remove them + # from paragraph tags. + def unwrap_all(root) + traverse(root) do |node| + extract_from_paragraph(node) if TAG_NAMES_TO_UNWRAP.include?(node.name) + end + end + + # Process the tags inserted by split_text_at_newlines and + # merge_br_tags. Either way, we use extract_from_paragraph to split its + # parents until we reach the paragraph tag that contains it. If the split is + # marked as "long," we need to insert a

     

    blank paragraph. + # Reintroduce newlines instead to preserve chunks in separate lines. + def replace_splits(root) + root.css("split").each do |node| + extract_from_paragraph(node) + + if node.attribute("long") + node.replace("\n

     

    \n") + else + node.replace("\n") + end + end + end + + # Traverse the tree and delete any paragraph nodes that have no children. + def delete_empty_paragraphs(root) + traverse(root) do |node| + node.unlink if node.name == "p" && node.children.empty? + end + end + + public + + # Process the given node to add paragraphs to it and all of its children. + def process(root) + strip_whitespace(root) + split_text_at_newlines(root) + merge_br_tags(root) + wrap_all(root) + unwrap_all(root) + replace_splits(root) + delete_empty_paragraphs(root) + end +end diff --git a/lib/redis_scanning.rb b/lib/redis_scanning.rb new file mode 100755 index 0000000..b0b85c1 --- /dev/null +++ b/lib/redis_scanning.rb @@ -0,0 +1,11 @@ +module RedisScanning + def scan_set_in_batches(redis, key, batch_size:, &block) + redis.sscan_each(key, count: batch_size).each_slice(batch_size, &block) + end + + def scan_hash_in_batches(redis, key, batch_size:, &block) + redis.hscan_each(key, count: batch_size).each_slice(batch_size) do |batch| + block.call(batch.to_h) + end + end +end diff --git a/lib/redis_test_setup.rb b/lib/redis_test_setup.rb new file mode 100755 index 0000000..0373e05 --- /dev/null +++ b/lib/redis_test_setup.rb @@ -0,0 +1,20 @@ +# RAILS_ROOT/lib/redis_test_setup.rb + +module RedisTestSetup + + def start_redis!(rails_root, env) + dir_temp = File.expand_path(File.join(rails_root, 'log')) + dir_conf = File.expand_path(File.join(rails_root, 'config')) + cwd = Dir.getwd + Dir.chdir(rails_root) + raise "unable to launch redis-server" unless system("redis-server #{dir_conf}/redis-#{env}.conf") + Dir.chdir(cwd) + at_exit do + if (pid = `cat #{dir_temp}/redis-#{env}.pid`.strip) =~ /^\d+$/ + `rm -f #{dir_temp}/redis-cucumber-#{env}.rdb` + `rm -f #{dir_temp}/redis-#{env}.pid` + Process.kill("KILL", pid.to_i) + end + end + end +end diff --git a/lib/responder.rb b/lib/responder.rb new file mode 100755 index 0000000..4c31ec6 --- /dev/null +++ b/lib/responder.rb @@ -0,0 +1,21 @@ +module Responder + def update_work_stats + work = get_work + return unless work.present? + REDIS_GENERAL.sadd('works_to_update_stats', work.id) + end + + def get_work + work = nil + if self.respond_to?(:ultimate_parent) + work = self.ultimate_parent + elsif self.respond_to?(:commentable) + work = self.commentable + elsif self.respond_to?(:bookmarkable) + work = self.bookmarkable + end + + work.is_a?(Work) ? work : nil + end +end + diff --git a/lib/searchable.rb b/lib/searchable.rb new file mode 100755 index 0000000..e9bab94 --- /dev/null +++ b/lib/searchable.rb @@ -0,0 +1,65 @@ +module Searchable + + def self.included(searchable) + searchable.class_eval do + after_save :enqueue_to_index + after_destroy :enqueue_to_index + end + searchable.extend(ClassMethods) + end + + module ClassMethods + # A class method to reindex every item in the current relation. + def reindex_all(queue = :background) + distinct.select(:id).find_in_batches do |batch| + IndexQueue.enqueue_ids(base_class, batch.map(&:id), queue) + end + end + + def successful_reindex(ids) + # override to do something in response + end + + # Given search results from Elasticsearch, retrieve the corresponding hits + # from the database, ordered the same way. (If the database items + # corresponding to the search results don't exist, don't error, just notify + # IndexSweeper so that the Elasticsearch indices can be cleaned up.) + # Override for special behavior. + def load_from_elasticsearch(hits, scopes: nil) + ids = hits.map { |item| item['_id'] } + + # Apply the desired scopes to the ActiveRecord relation: + relation = self.all + Array(scopes).each do |scope| + relation = relation.public_send(scope) + end + + # Find results with where rather than find in order to avoid + # ActiveRecord::RecordNotFound + items = relation.where(id: ids).group_by(&:id) + IndexSweeper.async_cleanup(self, ids, items.keys) + ids.flat_map { |id| items[id.to_i] }.compact + end + end + + def enqueue_to_index + IndexQueue.enqueue(self, :main) + end + + def indexers + Indexer.for_object(self) + end + + def reindex_document(options = {}) + responses = [] + self.indexers.each do |indexer| + if options[:async] + queue = options[:queue] || :main + responses << AsyncIndexer.index(indexer, [id], queue) + else + responses << indexer.new([id]).index_document(self) + end + end + responses + end +end diff --git a/lib/skin_wizard.rb b/lib/skin_wizard.rb new file mode 100755 index 0000000..4fd418c --- /dev/null +++ b/lib/skin_wizard.rb @@ -0,0 +1,367 @@ +module SkinWizard + def header_styles(color) + if color.present? + " + #header .primary, + #footer, + .autocomplete .dropdown ul li:hover, + .autocomplete .dropdown li.selected, + a.tag:hover, + .listbox .heading a.tag:visited:hover, + .splash .favorite li:nth-of-type(odd) a:hover, + .splash .favorite li:nth-of-type(odd) a:focus, + #tos_prompt .heading { + background-image: none; + background-color: #{color}; + } + + #header .heading a, + #header .user a:hover, + #header .user a:focus, + #dashboard a:hover, + .actions a:hover, + .actions button:hover, + .actions input:hover, + .actions a:focus, + .actions button:focus, + .actions input:focus, + label.action:hover, + .action:hover, + .action:focus, + a.cloud1, + a.cloud2, + a.cloud3, + a.cloud4, + a.cloud5, + a.cloud6, + a.cloud7, + a.cloud8, + a.work, + .blurb h4 a:link, + .splash .module h3, + .splash .browse li a:before { + color: #{color}; + } + + #dashboard, + #dashboard.own { + border-color: #{color}; + } + + .actions .reindex a { + border-bottom-color: #{color}; + } + " + else + "" + end + end + + def font_size_styles(percentage) + if percentage.present? + " + body { + font-size: #{percentage}%; + } + " + else + "" + end + end + + def font_styles(names) + if names.present? + " + body, + .toggled form, + .dynamic form, + .secondary, + .dropdown, + blockquote, + pre, + input, + textarea, + button, + .heading .actions, + .heading .action, + .heading span.actions, + span.unread, + .replied, + span.claimed, + .actions span.defaulted { + font-family: #{names}; + } + " + else + "" + end + end + + def background_color_styles(color) + if color.present? + " + body, + .toggled form, + .dynamic form, + .secondary, + .dropdown, + th, + tr:hover, + col.name, + div.dynamic, + fieldset fieldset, + fieldset dl dl, + form blockquote.userstuff, + form.verbose legend, + .verbose form legend, + #modal, + .own, + .draft, + .draft .wrapper, + .unread, + .child, + .unwrangled, + .unreviewed, + .thread .even, + .listbox .index, + .nomination dt, + #tos_prompt { + background: #{color}; + } + + @media only screen and (max-width: 42em) { + #outer { + background: #{color} + } + } + + a.tag:hover, + .listbox .heading a.tag:visited:hover { + color: #{color}; + } + + tbody tr, + thead td, + #footer, + #modal { + border-color: #{color}; + } + + .toggled form, + .dynamic form, + .secondary, + .wrapper { + box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.5) + } + + .listbox, + fieldset fieldset.listbox { + box-shadow: 0 0 0 1px #{color}; + } + + .listbox .index { + box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.5); + } + " + else + "" + end + end + + def foreground_color_styles(color) + if color.present? + " + body, + .toggled form, + .dynamic form, + .secondary, + .dropdown, + #header .search, + form dd.required, + .post .required .warnings, + dd.required, + .required .autocomplete, + span.series .divider, + .filters .expander, + .userstuff h2 { + color: #{color}; + } + + /* these colors should be separate, but for now... */ + a, + a:link, + a:visited, + a:hover, + #header a, + #header a:visited, + #header .primary .open a, + #header .primary .dropdown:hover a, + #header .primary .dropdown a:focus, + #header .primary .menu a, + #dashboard a, + #dashboard span, + a.tag, + .listbox > .heading, + .listbox .heading a:visited, + .filters dt a:hover { + color: #{color}; + } + + form dt, + .filters .group dt.bookmarker, + .faq .categories h3, + .splash .module h3, + .userstuff h3 { + border-color: #{color}; + } + + /* some things with unchanging background colors (e.g. caution notices) need the default text color */ + .qtip-content, + .notice:not(.required), + .comment_notice, + .kudos_notice, + ul.notes, + .caution, + .notice a { + color: #2a2a2a; + } + + .current, + a.current { + color: #111; + } + " + else + "" + end + end + + def paragraph_margin_styles(ems) + if ems.present? + " + .userstuff p { + margin: #{ems}em auto; + } + " + else + "" + end + end + + def accent_color_styles(color) + if color.present? + " + table, + thead td, + #header .actions a:hover, + #header .actions a:focus, + #header .dropdown:hover a, + #header .open a, + #header .menu, + #small_login, + fieldset, + form dl, + fieldset dl dl, + fieldset fieldset fieldset, + fieldset fieldset dl dl, + .ui-sortable li, + .ui-sortable li:hover, + dd.hideme, + form blockquote.userstuff, + dl.index dd, + .statistics .index li:nth-of-type(even), + .listbox, + fieldset fieldset.listbox, + .item dl.visibility, + .reading h4.viewed, + .comment h4.byline, + .splash .favorite li:nth-of-type(odd) a, + .splash .module div.account, + .search [role=\"tooltip\"] { + background: #{color}; + border-color: #{color}; + } + + #dashboard a:hover, + #dashboard .current, + li.relationships a { + background: #{color}; + } + + li.blurb, + fieldset, + form dl, + thead, + tfoot, + tfoot td, + th, + tr:hover, + col.name, + #dashboard ul, + .toggled form, + .dynamic form, + form.verbose legend, + .verbose form legend, + .secondary, + dl.meta, + .bookmark .user, + div.comment, + li.comment, + .comment div.icon, + .splash .news li, + .userstuff blockquote { + border-color: #{color}; + } + + fieldset, + form dl, + fieldset dl dl, + fieldset fieldset fieldset, + fieldset fieldset dl dl, + form blockquote.userstuff { + box-shadow: inset 1px 0 5px rgba(0, 0, 0, 0.5); + } + + fieldset dl, + fieldset.actions, + fieldset dl fieldset dl { + box-shadow: none; + } + + form.verbose legend, + .verbose form legend, + .ui-sortable li:hover { + box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.5); + } + + @media only screen and (max-width: 62em) { + #dashboard .secondary { + background: #{color}; + box-shadow: none; + } + } + + @media only screen and (max-width: 42em) { + .javascript { + background: #{color}; + } + } + " + else + "" + end + end + + def work_margin_styles(percentage) + if percentage.present? + " + #workskin { + margin: auto #{percentage}%; + max-width: 100%; + } + " + else + "" + end + end +end diff --git a/lib/sortable_list.rb b/lib/sortable_list.rb new file mode 100755 index 0000000..a93112b --- /dev/null +++ b/lib/sortable_list.rb @@ -0,0 +1,14 @@ +class SortableList < Array + def reorder_list(positions) + list = self + changed = {} + positions.collect!(&:to_i).each_with_index do |new_position, old_position| + if new_position != 0 && new_position <= list.length && !changed.has_key?(new_position) + changed.merge!({new_position => list[old_position]}) + end + end + list -= changed.values + changed.sort.each {|pair| pair.first > list.length ? list << pair.last : list.insert(pair.first-1, pair.last)} + list.each_with_index {|list_item, index| list_item.update_attribute(:position, index + 1)} + end +end \ No newline at end of file diff --git a/lib/string_cleaner.rb b/lib/string_cleaner.rb new file mode 100755 index 0000000..b0b76f5 --- /dev/null +++ b/lib/string_cleaner.rb @@ -0,0 +1,12 @@ +module StringCleaner + + def remove_articles_from_string(str) + str.gsub(article_removing_regex, '') + end + + def article_removing_regex + Regexp.new(/^(a|an|the|la|le|les|l'|un|une|des|die|das|il|el|las|los|der|den)\s/i) + end + +end + diff --git a/lib/tasks/admin_tasks.rake b/lib/tasks/admin_tasks.rake new file mode 100755 index 0000000..ce32205 --- /dev/null +++ b/lib/tasks/admin_tasks.rake @@ -0,0 +1,32 @@ +namespace :admin do + desc "Unsuspend suspended users who have been suspended_until up to 12 hours from now" + task(:unsuspend_users => :environment) do + User.where(["suspended_until <= ?", 12.hours.from_now]).update_all("suspended_until = NULL, suspended = false") + puts "Users unsuspended." + end + + desc "Resend sign-up notification emails after 24 hours" + task(:resend_signup_emails => :environment) do + @users = User.where(confirmed_at: nil, created_at: 48.hours.ago..24.hours.ago) + @users.each do |user| + UserMailer.signup_notification(user.id).deliver_later + end + puts "Sign-up notification emails resent" + end + + desc "Purge unvalidated accounts created more than 2 weeks ago" + task(:purge_unvalidated_users => :environment) do + users = User.where("confirmed_at IS NULL AND created_at < ?", AdminSetting.current.days_to_purge_unactivated.weeks.ago) + puts users.map(&:login).join(", ") + users.map(&:destroy) + puts "Unvalidated accounts created more than two weeks ago have been purged" + + # Purged users are allowed to reuse their invitations: + invite_ids = users.map(&:invitation_id) + Invitation.includes(:creator).where(id: invite_ids).each do |invite| + invite.update(redeemed_at: nil, invitee: nil) + end + puts "Invitations for the purged accounts have been reset" + end + +end diff --git a/lib/tasks/after_tasks.rake b/lib/tasks/after_tasks.rake new file mode 100755 index 0000000..0ed0ee8 --- /dev/null +++ b/lib/tasks/after_tasks.rake @@ -0,0 +1,583 @@ +namespace :After do + # Keep only the most recent tasks, i.e., about two years' worth. + # If you need older tasks, check GitHub. + + desc "Update the mapping for the work index" + task(update_work_mapping: :environment) do + WorkIndexer.create_mapping + end + + desc "Fix tags with extra spaces" + task(fix_tags_with_extra_spaces: :environment) do + total_tags = Tag.count + total_batches = (total_tags + 999) / 1000 + puts "Inspecting #{total_tags} tags in #{total_batches} batches" + + report_string = ["Tag ID", "Old tag name", "New tag name"].to_csv + Tag.find_in_batches.with_index do |batch, index| + batch_number = index + 1 + progress_msg = "Batch #{batch_number} of #{total_batches} complete" + + batch.each do |tag| + next unless tag.name != tag.name.squish + + old_tag_name = tag.name + new_tag_name = old_tag_name.gsub(/[[:space:]]/, "_") + + new_tag_name << "_" while Tag.find_by(name: new_tag_name) + tag.update_attribute(:name, new_tag_name) + + report_row = [tag.id, old_tag_name, new_tag_name].to_csv + report_string += report_row + end + + puts(progress_msg) && STDOUT.flush + end + puts(report_string) && STDOUT.flush + end + + desc "Fix works imported with a noncanonical Teen & Up Audiences rating tag" + task(fix_teen_and_up_imported_rating: :environment) do + borked_rating_tag = Rating.find_by!(name: "Teen & Up Audiences") + canonical_rating_tag = Rating.find_by!(name: ArchiveConfig.RATING_TEEN_TAG_NAME) + + work_ids = [] + invalid_work_ids = [] + borked_rating_tag.works.find_each do |work| + work.ratings << canonical_rating_tag + work.ratings = work.ratings - [borked_rating_tag] + if work.save + work_ids << work.id + else + invalid_work_ids << work.id + end + print(".") && STDOUT.flush + end + + unless work_ids.empty? + puts "Converted '#{borked_rating_tag.name}' rating tag on #{work_ids.size} works:" + puts work_ids.join(", ") + STDOUT.flush + end + + unless invalid_work_ids.empty? + puts "The following #{invalid_work_ids.size} works failed validations and could not be saved:" + puts invalid_work_ids.join(", ") + STDOUT.flush + end + end + + desc "Clean up multiple rating tags" + task(clean_up_multiple_ratings: :environment) do + default_rating_tag = Rating.find_by!(name: ArchiveConfig.RATING_DEFAULT_TAG_NAME) + es_results = $elasticsearch.search(index: WorkIndexer.index_name, body: { + query: { + bool: { + filter: { + script: { + script: { + source: "doc['rating_ids'].length > 1", + lang: "painless" + } + } + } + } + } + }) + invalid_works = QueryResult.new("Work", es_results) + + puts "There are #{invalid_works.size} works with multiple ratings." + + fixed_work_ids = [] + unfixed_word_ids = [] + invalid_works.each do |work| + work.ratings = [default_rating_tag] + work.rating_string = default_rating_tag.name + + if work.save + fixed_work_ids << work.id + else + unfixed_word_ids << work.id + end + print(".") && $stdout.flush + end + + unless fixed_work_ids.empty? + puts "Cleaned up having multiple ratings on #{fixed_work_ids.size} works:" + puts fixed_work_ids.join(", ") + $stdout.flush + end + + unless unfixed_word_ids.empty? + puts "The following #{unfixed_word_ids.size} works failed validations and could not be saved:" + puts unfixed_word_ids.join(", ") + $stdout.flush + end + end + + desc "Clean up noncanonical rating tags" + task(clean_up_noncanonical_ratings: :environment) do + canonical_not_rated_tag = Rating.find_by!(name: ArchiveConfig.RATING_DEFAULT_TAG_NAME) + noncanonical_ratings = Rating.where(canonical: false) + puts "There are #{noncanonical_ratings.size} noncanonical rating tags." + + next if noncanonical_ratings.empty? + + puts "The following noncanonical Ratings will be changed into Additional Tags:" + puts noncanonical_ratings.map(&:name).join("\n") + + work_ids = [] + invalid_work_ids = [] + noncanonical_ratings.find_each do |tag| + works_using_tag = tag.works + tag.update_attribute(:type, "Freeform") + + works_using_tag.find_each do |work| + next unless work.ratings.empty? + + work.ratings = [canonical_not_rated_tag] + if work.save + work_ids << work.id + else + invalid_work_ids << work.id + end + print(".") && STDOUT.flush + end + end + + unless work_ids.empty? + puts "The following #{work_ids.size} works were left without a rating and successfully received the Not Rated rating:" + puts work_ids.join(", ") + STDOUT.flush + end + + unless invalid_work_ids.empty? + puts "The following #{invalid_work_ids.size} works failed validations and could not be saved:" + puts invalid_work_ids.join(", ") + STDOUT.flush + end + end + + desc "Clean up noncanonical category tags" + task(clean_up_noncanonical_categories: :environment) do + Category.where(canonical: false).find_each do |tag| + tag.update_attribute(:type, "Freeform") + puts "Noncanonical Category tag '#{tag.name}' was changed into an Additional Tag." + end + STDOUT.flush + end + + desc "Add default rating to works missing a rating" + task(add_default_rating_to_works: :environment) do + work_count = Work.count + total_batches = (work_count + 999) / 1000 + puts("Checking #{work_count} works in #{total_batches} batches") && STDOUT.flush + updated_works = [] + + Work.find_in_batches.with_index do |batch, index| + batch_number = index + 1 + + batch.each do |work| + next unless work.ratings.empty? + + work.ratings << Rating.find_by!(name: ArchiveConfig.RATING_DEFAULT_TAG_NAME) + work.save + updated_works << work.id + end + puts("Batch #{batch_number} of #{total_batches} complete") && STDOUT.flush + end + puts("Added default rating to works: #{updated_works}") && STDOUT.flush + end + + desc "Backfill renamed_at for existing users" + task(add_renamed_at_from_log: :environment) do + total_users = User.all.size + total_batches = (total_users + 999) / 1000 + puts "Updating #{total_users} users in #{total_batches} batches" + + User.find_in_batches.with_index do |batch, index| + batch.each do |user| + renamed_at_from_log = user.log_items.where(action: ArchiveConfig.ACTION_RENAME).last&.created_at + next unless renamed_at_from_log + + user.update_column(:renamed_at, renamed_at_from_log) + end + + batch_number = index + 1 + progress_msg = "Batch #{batch_number} of #{total_batches} complete" + puts(progress_msg) && STDOUT.flush + end + puts && STDOUT.flush + end + + desc "Fix threads for comments from 2009" + task(fix_2009_comment_threads: :environment) do + def fix_comment(comment) + comment.with_lock do + if comment.reply_comment? + comment.update_column(:thread, comment.commentable.thread) + else + comment.update_column(:thread, comment.id) + end + comment.comments.each { |reply| fix_comment(reply) } + end + end + + incorrect = Comment.top_level.where("thread != id") + total = incorrect.count + + puts "Updating #{total} thread(s)" + + incorrect.find_each.with_index do |comment, index| + fix_comment(comment) + + puts "Fixed thread #{index + 1} out of #{total}" if index % 100 == 99 + end + end + + desc "Remove translation_admin role" + task(remove_translation_admin_role: :environment) do + r = Role.find_by(name: "translation_admin") + r&.destroy + end + + desc "Remove full-width and ideographic commas from tags" + task(remove_invalid_commas_from_tags: :environment) do + puts("Tags can only be renamed by an admin, who will be listed as the tag's last wrangler. Enter the admin login we should use:") + login = $stdin.gets.chomp.strip + admin = Admin.find_by(login: login) + + if admin.present? + User.current_user = admin + + [",", "、"].each do |comma| + tags = Tag.where("name LIKE ?", "%#{comma}%") + tags.each do |tag| + new_name = tag.name.gsub(/#{comma}/, "") + if tag.update(name: new_name) || tag.update(name: "#{new_name} - AO3-6626") + puts(tag.reload.name) + else + puts("Could not rename #{tag.reload.name}") + end + $stdout.flush + end + end + else + puts("Admin not found.") + end + end + + desc "Add suffix to existing Underage Sex tag in preparation for Underage warning rename" + task(add_suffix_to_underage_sex_tag: :environment) do + puts("Tags can only be renamed by an admin, who will be listed as the tag's last wrangler. Enter the admin login we should use:") + login = $stdin.gets.chomp.strip + admin = Admin.find_by(login: login) + + if admin.present? + User.current_user = admin + + tag = Tag.find_by_name("Underage Sex") + + if tag.blank? + puts("No Underage Sex tag found.") + elsif tag.is_a?(ArchiveWarning) + puts("Underage Sex is already an Archive Warning.") + else + suffixed_name = "Underage Sex - #{tag.class}" + if tag.update(name: suffixed_name) + puts("Renamed Underage Sex tag to #{tag.reload.name}.") + else + puts("Failed to rename Underage Sex tag to #{suffixed_name}.") + end + $stdout.flush + end + else + puts("Admin not found.") + end + end + + desc "Rename Underage warning to Underage Sex" + task(rename_underage_warning: :environment) do + puts("Tags can only be renamed by an admin, who will be listed as the tag's last wrangler. Enter the admin login we should use:") + login = $stdin.gets.chomp.strip + admin = Admin.find_by(login: login) + + if admin.present? + User.current_user = admin + + tag = ArchiveWarning.find_by_name("Underage") + + if tag.blank? + puts("No Underage warning tag found.") + else + new_name = "Underage Sex" + if tag.update(name: new_name) + puts("Renamed Underage warning tag to #{tag.reload.name}.") + else + puts("Failed to rename Underage warning tag to #{new_name}.") + end + $stdout.flush + end + else + puts("Admin not found.") + end + end + + desc "Migrate collection icons to ActiveStorage paths" + task(migrate_collection_icons: :environment) do + require "aws-sdk-s3" + require "open-uri" + + return unless Rails.env.staging? || Rails.env.production? + + bucket_name = ENV["S3_BUCKET"] + prefix = "collections/icons/" + s3 = Aws::S3::Resource.new( + region: ENV["S3_REGION"], + access_key_id: ENV["S3_ACCESS_KEY_ID"], + secret_access_key: ENV["S3_SECRET_ACCESS_KEY"] + ) + old_bucket = s3.bucket(bucket_name) + new_bucket = s3.bucket(ENV["TARGET_BUCKET"]) + + Collection.no_touching do + old_bucket.objects(prefix: prefix).each do |object| + # Path example: staging/icons/108621/original.png + path_parts = object.key.split("/") + next unless path_parts[-1]&.include?("original") + next if ActiveStorage::Attachment.where(record_type: "Collection", record_id: path_parts[-2]).any? + + collection_id = path_parts[-2] + old_icon = URI.open("https://s3.amazonaws.com/#{bucket_name}/#{object.key}") + checksum = OpenSSL::Digest.new("MD5").tap do |result| + while (chunk = old_icon.read(5.megabytes)) + result << chunk + end + old_icon.rewind + end.base64digest + + key = nil + ActiveRecord::Base.transaction do + blob = ActiveStorage::Blob.create_before_direct_upload!( + filename: path_parts[-1], + byte_size: old_icon.size, + checksum: checksum, + content_type: Marcel::MimeType.for(old_icon) + ) + key = blob.key + blob.attachments.create( + name: "icon", + record_type: "Collection", + record_id: collection_id + ) + end + + new_bucket.put_object(key: key, body: old_icon, acl: "bucket-owner-full-control") + puts "Finished collection #{collection_id}" + $stdout.flush + end + end + end + + desc "Migrate pseud icons to ActiveStorage paths" + task(migrate_pseud_icons: :environment) do + require "aws-sdk-s3" + require "open-uri" + + return unless Rails.env.staging? || Rails.env.production? + + bucket_name = ENV["S3_BUCKET"] + prefix = Rails.env.production? ? "icons/" : "staging/icons/" + s3 = Aws::S3::Resource.new( + region: ENV["S3_REGION"], + access_key_id: ENV["S3_ACCESS_KEY_ID"], + secret_access_key: ENV["S3_SECRET_ACCESS_KEY"] + ) + old_bucket = s3.bucket(bucket_name) + new_bucket = s3.bucket(ENV["TARGET_BUCKET"]) + + Pseud.no_touching do + old_bucket.objects(prefix: prefix).each do |object| + # Path example: staging/icons/108621/original.png + path_parts = object.key.split("/") + next unless path_parts[-1]&.include?("original") + next if ActiveStorage::Attachment.where(record_type: "Pseud", record_id: path_parts[-2]).any? + + pseud_id = path_parts[-2] + old_icon = URI.open("https://s3.amazonaws.com/#{bucket_name}/#{object.key}") + checksum = OpenSSL::Digest.new("MD5").tap do |result| + while (chunk = old_icon.read(5.megabytes)) + result << chunk + end + old_icon.rewind + end.base64digest + + key = nil + ActiveRecord::Base.transaction do + blob = ActiveStorage::Blob.create_before_direct_upload!( + filename: path_parts[-1], + byte_size: old_icon.size, + checksum: checksum, + content_type: Marcel::MimeType.for(old_icon) + ) + key = blob.key + blob.attachments.create( + name: "icon", + record_type: "Pseud", + record_id: pseud_id + ) + end + + new_bucket.put_object(key: key, body: old_icon, acl: "bucket-owner-full-control") + puts "Finished pseud #{pseud_id}" + $stdout.flush + end + end + end + + desc "Migrate skin icons to ActiveStorage paths" + task(migrate_skin_icons: :environment) do + require "aws-sdk-s3" + require "open-uri" + + return unless Rails.env.staging? || Rails.env.production? + + bucket_name = ENV["S3_BUCKET"] + prefix = "skins/icons/" + s3 = Aws::S3::Resource.new( + region: ENV["S3_REGION"], + access_key_id: ENV["S3_ACCESS_KEY_ID"], + secret_access_key: ENV["S3_SECRET_ACCESS_KEY"] + ) + old_bucket = s3.bucket(bucket_name) + new_bucket = s3.bucket(ENV["TARGET_BUCKET"]) + + Skin.no_touching do + old_bucket.objects(prefix: prefix).each do |object| + # Path example: staging/icons/108621/original.png + path_parts = object.key.split("/") + next unless path_parts[-1]&.include?("original") + next if ActiveStorage::Attachment.where(record_type: "Skin", record_id: path_parts[-2]).any? + + skin_id = path_parts[-2] + old_icon = URI.open("https://s3.amazonaws.com/#{bucket_name}/#{object.key}") + checksum = OpenSSL::Digest.new("MD5").tap do |result| + while (chunk = old_icon.read(5.megabytes)) + result << chunk + end + old_icon.rewind + end.base64digest + + key = nil + ActiveRecord::Base.transaction do + blob = ActiveStorage::Blob.create_before_direct_upload!( + filename: path_parts[-1], + byte_size: old_icon.size, + checksum: checksum, + content_type: Marcel::MimeType.for(old_icon) + ) + key = blob.key + blob.attachments.create( + name: "icon", + record_type: "Skin", + record_id: skin_id + ) + end + + new_bucket.put_object(key: key, body: old_icon, acl: "bucket-owner-full-control") + puts "Finished skin #{skin_id}" + $stdout.flush + end + end + end + + desc "Migrate pinch_request_signup to request_signup" + task(migrate_pinch_request_signup: :environment) do + count = ChallengeAssignment.where("pinch_request_signup_id IS NOT NULL AND request_signup_id IS NULL").update_all("request_signup_id = pinch_request_signup_id") + puts("Migrated pinch_request_signup for #{count} challenge assignments.") + end + + desc "Reindex tags associated with works that are hidden or unrevealed" + task(reindex_hidden_unrevealed_tags: :environment) do + hidden_count = Work.hidden.count + hidden_batches = (hidden_count + 999) / 1_000 + puts "Inspecting #{hidden_count} hidden works in #{hidden_batches} batches" + Work.hidden.find_in_batches.with_index do |batch, index| + batch.each { |work| work.taggings.each(&:update_search) } + puts "Finished batch #{index + 1} of #{hidden_batches}" + end + + unrevealed_count = Work.unrevealed.count + unrevealed_batches = (unrevealed_count + 999) / 1_000 + puts "Inspecting #{unrevealed_count} unrevealed works in #{unrevealed_batches} batches" + Work.unrevealed.find_in_batches.with_index do |batch, index| + batch.each { |work| work.taggings.each(&:update_search) } + puts "Finished batch #{index + 1} of #{unrevealed_batches}" + end + + puts "Finished reindexing tags on hidden and unrevealed works" + end + + desc "Convert user kudos from users with the official role to guest kudos" + task(convert_official_kudos: :environment) do + official_users = Role.find_by(name: "official")&.users + if official_users.blank? + puts "No official users found" + else + official_users.each do |user| + kudos = user.kudos + next if kudos.blank? + + puts "Updating #{kudos.size} kudos from #{user.login}" + user.remove_user_from_kudos + end + + puts "Finished converting kudos from official users to guest kudos" + end + end + + desc "Convert user kudos from users with the archivist role to guest kudos" + task(convert_archivist_kudos: :environment) do + archivist_users = Role.find_by(name: "archivist")&.users + if archivist_users.blank? + puts "No archivist users found" + else + archivist_users.each do |user| + kudos = user.kudos + next if kudos.blank? + + puts "Updating #{kudos.size} kudos from #{user.login}" + user.remove_user_from_kudos + end + + puts "Finished converting kudos from archivist users to guest kudos" + end + end + + desc "Create TagSetAssociations for non-canonical tags belonging to canonical fandoms in TagSets" + task(create_non_canonical_tagset_associations: :environment) do + # We want to get all set taggings where the tag is not canonical, but has a parent fandom that _is_ canonical. + # This might be possible with pure Ruby, but unfortunately the parent tag in common_taggings is polymorphic + # (even though it doesn't need to be), which makes that trickier. + non_canonicals = SetTagging + .joins("INNER JOIN `tag_sets` `tag_set` ON `tag_set`.`id` = `set_taggings`.`tag_set_id` INNER JOIN `owned_tag_sets` ON `owned_tag_sets`.`tag_set_id` = `tag_set`.`id` INNER JOIN `tags` `tag` ON `tag`.`id` = `set_taggings`.`tag_id` INNER JOIN `common_taggings` `common_tagging` ON `common_tagging`.`common_tag_id` = `tag`.`id` INNER JOIN `tags` `parent_tag` ON `common_tagging`.`filterable_id` = `parent_tag`.`id`") + .where("`tag`.`canonical` = FALSE AND `tag`.`type` IN ('Character', 'Relationship') AND `tag_set`.`id` IS NOT NULL AND `parent_tag`.`type` = 'Fandom' AND `parent_tag`.`canonical` = TRUE") + .distinct + + non_canonicals.find_in_batches.with_index do |batch, index| + puts "Creating TagSetAssociations for batch #{index + 1}" + batch.each do |set_tagging| + owned_tag_set = set_tagging.tag_set.owned_tag_set + tag = set_tagging.tag + + fandoms = tag.fandoms.joins(:set_taggings).where(canonical: true, set_taggings: { tag_set_id: set_tagging.tag_set.id }) + fandoms.find_each do |fandom| + TagSetAssociation.create!(owned_tag_set: owned_tag_set, tag: tag, parent_tag: fandom) + rescue ActiveRecord::RecordInvalid + puts "Association already exists for fandom '#{fandom.name}' and tag '#{tag.name}'" + end + end + end + end + # This is the end that you have to put new tasks above. +end diff --git a/lib/tasks/creatorships.rake b/lib/tasks/creatorships.rake new file mode 100755 index 0000000..8aff09b --- /dev/null +++ b/lib/tasks/creatorships.rake @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +namespace :creatorships do + desc "Clean up creatorships for deleted works" + task(remove_deleted_work_creatorships: :environment) do + Creatorship.joins("LEFT JOIN works ON " \ + "creatorships.creation_id = works.id"). + where(works: { id: nil }, + creatorships: { creation_type: "Work" }). + in_batches.delete_all + end + + desc "Clean up creatorships for deleted chapters" + task(remove_deleted_chapter_creatorships: :environment) do + Creatorship.joins("LEFT JOIN chapters ON " \ + "creatorships.creation_id = chapters.id"). + where(chapters: { id: nil }, + creatorships: { creation_type: "Chapter" }). + in_batches.delete_all + end + + desc "Clean up creatorships for deleted series" + task(remove_deleted_series_creatorships: :environment) do + Creatorship.joins("LEFT JOIN series ON " \ + "creatorships.creation_id = series.id"). + where(series: { id: nil }, + creatorships: { creation_type: "Series" }). + in_batches.delete_all + end + + desc "Add missing series creatorships" + task(add_missing_series_creatorships: :environment) do + SerialWork.includes(:series, work: [creatorships: [:pseud]]). + find_each(&:update_series_creatorships) + end + + desc "Remove empty series with no creators" + task(remove_orphaned_empty_series: :environment) do + Series.left_joins(:serial_works).where(serial_works: { id: nil }). + find_each do |series| + series.destroy unless series.pseuds.exists? + end + end +end diff --git a/lib/tasks/cucumber.rake b/lib/tasks/cucumber.rake new file mode 100755 index 0000000..d611351 --- /dev/null +++ b/lib/tasks/cucumber.rake @@ -0,0 +1,76 @@ +# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril. +# It is recommended to regenerate this file in the future when you upgrade to a +# newer version of cucumber-rails. Consider adding your own code to a new file +# instead of editing this one. Cucumber will automatically load all features/**/*.rb +# files. + + +unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks + +vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first +$LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil? + +begin + require 'cucumber/rake/task' + + namespace :cucumber do + Cucumber::Rake::Task.new({ok: 'test:prepare'}, 'Run features that should pass') do |t| + t.binary = vendored_cucumber_bin # If nil, the gem's binary is used. + t.fork = true # You may get faster startup if you set this to false + t.profile = 'default' + end + + Cucumber::Rake::Task.new({wip: 'test:prepare'}, 'Run features that are being worked on') do |t| + t.binary = vendored_cucumber_bin + t.fork = true # You may get faster startup if you set this to false + t.profile = 'wip' + end + + Cucumber::Rake::Task.new({rerun: 'test:prepare'}, 'Record failing features and run only them if any exist') do |t| + t.binary = vendored_cucumber_bin + t.fork = true # You may get faster startup if you set this to false + t.profile = 'rerun' + end + + desc 'Run all features' + task all: [:ok, :wip] + + task :statsetup do + require 'rails/code_statistics' + ::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features') + ::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features') + end + + task :annotations_setup do + Rails.application.configure do + if config.respond_to?(:annotations) + config.annotations.directories << 'features' + config.annotations.register_extensions('feature') { |tag| /#\s*(#{tag}):?\s*(.*)$/ } + end + end + end + end + desc 'Alias for cucumber:ok' + task cucumber: 'cucumber:ok' + + task default: :cucumber + + task features: :cucumber do + STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***" + end + + # In case we don't have the generic Rails test:prepare hook, append a no-op task that we can depend upon. + task 'test:prepare' do + end + + task stats: 'cucumber:statsetup' + + task notes: 'cucumber:annotations_setup' +rescue LoadError + desc 'cucumber rake task not available (cucumber not installed)' + task :cucumber do + abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin' + end +end + +end diff --git a/lib/tasks/database_seed.rake b/lib/tasks/database_seed.rake new file mode 100755 index 0000000..f913ce5 --- /dev/null +++ b/lib/tasks/database_seed.rake @@ -0,0 +1,21 @@ +namespace :db do + desc "Raise an error unless the environment is development or test" + task :test_environment_only do + raise "Only supported in test and development!" unless Rails.env.development? || Rails.env.test? + end + + desc "Drop the database, recreate it from schema files and run remaining migrations" + task reset_and_migrate: [ + :environment, :test_environment_only, + # We can't use: + # - db:reset, because schema files may not be up-to-date and migrations are required. + # - db:migrate:reset, because we've deleted old migrations at various points. + :drop, :create, "schema:load", :migrate + ] + + desc "Reset and seed the database with data from test/fixtures/" + task otwseed: [ + :reset_and_migrate, :seed, "fixtures:load", + "work:missing_stat_counters", "Tag:reset_filters", "Tag:reset_filter_counts" + ] +end diff --git a/lib/tasks/defaults.rake b/lib/tasks/defaults.rake new file mode 100755 index 0000000..cde2a13 --- /dev/null +++ b/lib/tasks/defaults.rake @@ -0,0 +1,8 @@ +namespace :defaults do + desc "Create default roles by name" + task(create_roles: :environment) do + %w[archivist no_resets opendoors protected_user tag_wrangler translator official].each do |role| + Role.find_or_create_by(name: role) + end + end +end diff --git a/lib/tasks/deploy_tasks.rake b/lib/tasks/deploy_tasks.rake new file mode 100755 index 0000000..95a5503 --- /dev/null +++ b/lib/tasks/deploy_tasks.rake @@ -0,0 +1,16 @@ +namespace :deploy do + + desc "Get servername" + task(:get_servername) do + @server ||= %x{hostname -s}.chomp + end + + desc "clear subscriptions on stage" + task(:clear_subscriptions => [:get_servername, :environment]) do + if @server == "stage" + Subscription.delete_all + else + puts "Don't clear subscriptions except on stage!!!" + end + end +end diff --git a/lib/tasks/language_tasks.rake b/lib/tasks/language_tasks.rake new file mode 100755 index 0000000..56e249d --- /dev/null +++ b/lib/tasks/language_tasks.rake @@ -0,0 +1,19 @@ +namespace :db do + desc "Check for duplicate language names before adding unique index migration" + task check_language_name_duplicates: :environment do + duplicates = Language.group(:name) + .having("COUNT(*) > 1") + .count + + if duplicates.any? + puts "Duplicate language names found:" + duplicates.each do |name, count| + puts "#{name} appears #{count} times" + end + + abort("Please resolve duplicate language names before running migrations.") + else + puts "No duplicate language names found." + end + end +end diff --git a/lib/tasks/load_autocomplete_data.rake b/lib/tasks/load_autocomplete_data.rake new file mode 100755 index 0000000..fdbb861 --- /dev/null +++ b/lib/tasks/load_autocomplete_data.rake @@ -0,0 +1,122 @@ +namespace :autocomplete do + # we need to delete the keys in batches to avoid stack level too deep error + KEYSLICE_SIZE = 10_000 + + desc "Clear autocomplete data" + task(clear_data: :environment) do + keys = REDIS_AUTOCOMPLETE.keys("autocomplete_*") + keys.each_slice(KEYSLICE_SIZE) { |keyslice| REDIS_AUTOCOMPLETE.del(*keyslice) } + puts "Cleared all autocomplete data" + end + + desc "Load data into Redis for autocomplete" + task(load_data: [:load_tag_data, :load_pseud_data, :load_collection_data, :load_tagset_data, :load_association_data]) do + puts "Loaded all autocomplete data" + end + + desc "Clear and reload data into Redis for autocomplete" + task(reload_data: [:clear_data, :load_data]) do + puts "Finished reloading" + end + + desc "Clear tag data" + task(clear_tag_data: :environment) do + keys = REDIS_AUTOCOMPLETE.keys("autocomplete_tag_*") + REDIS_AUTOCOMPLETE.keys("autocomplete_fandom_*") + keys.each_slice(KEYSLICE_SIZE) { |keyslice| REDIS_AUTOCOMPLETE.del(*keyslice) } + end + + desc "Clear tagset data" + task(clear_tagset_data: :environment) do + keys = REDIS_AUTOCOMPLETE.keys("autocomplete_tagset_*") + keys.each_slice(KEYSLICE_SIZE) { |keyslice| REDIS_AUTOCOMPLETE.del(*keyslice) } + end + + desc "Clear tagset association data" + task(clear_association_data: :environment) do + keys = REDIS_AUTOCOMPLETE.keys("autocomplete_association_*") + keys.each_slice(KEYSLICE_SIZE) { |keyslice| REDIS_AUTOCOMPLETE.del(*keyslice) } + end + + desc "Clear pseud data" + task(clear_pseud_data: :environment) do + keys = REDIS_AUTOCOMPLETE.keys("autocomplete_pseud_*") + keys.each_slice(KEYSLICE_SIZE) { |keyslice| REDIS_AUTOCOMPLETE.del(*keyslice) } + end + + desc "Clear collection data" + task(clear_collection_data: :environment) do + keys = REDIS_AUTOCOMPLETE.keys("autocomplete_collection_*") + keys.each_slice(KEYSLICE_SIZE) { |keyslice| REDIS_AUTOCOMPLETE.del(*keyslice) } + end + + desc "Load tag data into Redis for autocomplete" + task(load_tag_data: :environment) do + (Tag::TYPES - ['Banned']).each do |type| + query = type.constantize.canonical + query = query.includes(:parents) if type == "Character" || type == "Relationship" + query.find_each do |tag| + tag.add_to_autocomplete + end + end + end + + desc "Load pseud data into Redis for autocomplete" + task(load_pseud_data: :environment) do + Pseud.not_orphaned.includes(:user).find_each do |pseud| + pseud.add_to_autocomplete + end + end + + desc "Load collection data into Redis for autocomplete" + task(load_collection_data: :environment) do + Collection.with_item_count.includes(:collection_preference).find_each do |collection| + collection.add_to_autocomplete(collection.item_count) + end + end + + desc "Load tagsets into Redis" + task(load_tagset_data: :environment) do + # we only load tagsets used in challenge settings, not ones used in + # individual signups + OwnedTagSet.includes(tag_set: :tags).find_each do |owned_tag_set| + # this is just a check to save from the seed db missing tag sets + next if owned_tag_set.tag_set.nil? + owned_tag_set.tag_set.add_to_autocomplete + end + end + + desc "Load tag set associations into Redis" + task(load_association_data: :environment) do + # TODO: we probably only want to load associations for + # tag sets being used in challenges that are open for + # signups. + TagSetAssociation.includes(:owned_tag_set, :tag, :parent_tag).find_each do |assoc| + assoc.add_to_autocomplete + end + end + + desc "Clear and reload tag data into Redis for autocomplete" + task(reload_tag_data: [:clear_tag_data, :load_tag_data]) do + puts "Finished reloading tags" + end + + desc "Clear and reload pseud data into Redis for autocomplete" + task(reload_pseud_data: [:clear_pseud_data, :load_pseud_data]) do + puts "Finished reloading pseuds" + end + + desc "Clear and reload collection data into Redis for autocomplete" + task(reload_collection_data: [:clear_collection_data, :load_collection_data]) do + puts "Finished reloading collections" + end + + desc "Clear and reload tagset data into Redis for autocomplete" + task(reload_tagset_data: [:clear_tagset_data, :load_tagset_data]) do + puts "Finished reloading tagsets" + end + + desc "Clear and reload tag set association data into Redis for autocomplete" + task(reload_association_data: [:clear_association_data, :load_association_data]) do + puts "Finished reloading tag set associations" + end +end diff --git a/lib/tasks/memcached.rake b/lib/tasks/memcached.rake new file mode 100755 index 0000000..961b963 --- /dev/null +++ b/lib/tasks/memcached.rake @@ -0,0 +1,15 @@ +namespace :memcached do + + # For example + # WORKS="posted = 0" rake memcached:clear_work + # + desc "Clear memcached" + task :expire_work_blurbs => :environment do + works=ENV['WORKS'] || 'id=1' + Work.where(works).find_each do |work| + puts "Clear memcached #{work.id}" + Work.expire_work_blurb_version(work.id) + end + end + +end diff --git a/lib/tasks/notifications.rake b/lib/tasks/notifications.rake new file mode 100755 index 0000000..af42284 --- /dev/null +++ b/lib/tasks/notifications.rake @@ -0,0 +1,31 @@ +namespace :notifications do + + desc "Send next set of kudos notifications" + task(deliver_kudos: :environment) do + RedisMailQueue.deliver_kudos + end + + desc "Send next set of subscription notifications" + task(deliver_subscriptions: :environment) do + RedisMailQueue.deliver_subscriptions + end + + # Usage with 10473 as admin post id: rails notifications:send_tos_update[10473] + desc "Send TOS Update notification to all users" + task(:send_tos_update, [:admin_post_id] => [:environment]) do |_t, args| + total_users = User.all.size + total_batches = (total_users + 999) / 1000 + puts "Notifying #{total_users} users in #{total_batches} batches" + + User.find_in_batches.with_index do |batch, index| + batch.each do |user| + TosUpdateMailer.tos_update_notification(user, args.admin_post_id).deliver_later(queue: :tos_update) + end + + batch_number = index + 1 + progress_msg = "Batch #{batch_number} of #{total_batches} complete" + puts(progress_msg) && $stdout.flush + end + puts && $stdout.flush + end +end diff --git a/lib/tasks/opendoors.rake b/lib/tasks/opendoors.rake new file mode 100755 index 0000000..da057d2 --- /dev/null +++ b/lib/tasks/opendoors.rake @@ -0,0 +1,44 @@ +namespace :opendoors do + + class UrlUpdater + def update_work(row) + begin + work = Work.find(row["AO3 id"]) + if work&.imported_from_url.blank? || work&.imported_from_url == row["URL Imported From"] + work.imported_from_url = row["Original URL"] + work.save! + "#{work.id}\twas updated: its import url is now #{work.imported_from_url}" + else + "#{work.id}\twas not changed: its import url is #{work.imported_from_url}" + end + rescue StandardError => e + "#{row["AO3 id"]}\twas not changed: #{e}" + end + end + end + + desc "Map import urls based on spreadsheet data - required fields: 'AO3 id', 'URL Imported From', 'Original URL'" + task :import_url_mapping, [:csv] => :environment do |_t, args| + loc = if args[:csv].nil? + puts "Where is the Open Doors CSV located?" + STDIN.gets.chomp + else + args[:csv] + end + + begin + f = File.open("opendoors_result.txt", "w") + url_updater = UrlUpdater.new + + CSV.foreach(loc, headers: true) do |row| + result = url_updater.update_work(row) + puts result + f.write(result) + end + rescue TypeError => e # No or invalid CSV file + puts "Error parsing CSV file #{loc}: #{e.message}" + ensure + f.close + end + end +end diff --git a/lib/tasks/resanitize.rake b/lib/tasks/resanitize.rake new file mode 100755 index 0000000..6dc04f4 --- /dev/null +++ b/lib/tasks/resanitize.rake @@ -0,0 +1,40 @@ +namespace :resanitize do + desc "Re-run the sanitizer on all fields." + task(all: :environment) do + [ + AbuseReport, + AdminActivity, + AdminBanner, + AdminPost, + AdminSetting, + Bookmark, + Chapter, + Collection, + CollectionProfile, + Comment, + ExternalWork, + Feedback, + GiftExchange, + KnownIssue, + OwnedTagSet, + Profile, + Prompt, + PromptMeme, + Pseud, + Question::Translation, + Series, + Skin, + Work, + WranglingGuideline + ].each do |klass| + next unless klass.exists? + + puts "Enqueueing all #{klass} objects for resanitization." + + klass.find_in_batches.with_index do |batch, index| + puts "Enqueuing batch #{index + 1} of #{klass} objects." + ResanitizeBatchJob.perform_later(klass.to_s, batch.map(&:id)) + end + end + end +end diff --git a/lib/tasks/resque.rake b/lib/tasks/resque.rake new file mode 100755 index 0000000..2995ebe --- /dev/null +++ b/lib/tasks/resque.rake @@ -0,0 +1,58 @@ +# Resque tasks +require 'resque/tasks' +require 'resque/scheduler/tasks' + +namespace :resque do + task :setup do + require 'resque' + require 'resque/scheduler/tasks' + + # you probably already have this somewhere + # Resque.redis = 'localhost:6379' + + # If you want to be able to dynamically change the schedule, + # uncomment this line. A dynamic schedule can be updated via the + # Resque::Scheduler.set_schedule (and remove_schedule) methods. + # When dynamic is set to true, the scheduler process looks for + # schedule changes and applies them on the fly. + # Note: This feature is only available in >=2.0.0. + Resque::Scheduler.dynamic = true + + # The schedule doesn't need to be stored in a YAML, it just needs to + # be a hash. YAML is usually the easiest. + Resque.schedule = YAML.load_file("#{Rails.root}/config/resque_schedule.yml") + + # If your schedule already has +queue+ set for each job, you don't + # need to require your jobs. This can be an advantage since it's + # less code that resque-scheduler needs to know about. But in a small + # project, it's usually easier to just include you job classes here. + # So, something like this: + # require 'jobs' + end + + def process_job(count) + job = Resque::Failure.all(count,1) + return unless job + klass = job["payload"]["class"] + args = job["payload"]["args"] + klass.constantize.perform(*args) + Resque::Failure.remove(count) + rescue ActiveRecord::RecordNotFound + pp args + Resque::Failure.remove(count) + rescue Exception => e + puts "Job failed with error #{e.message}" + pp args + end + + desc "Run jobs in failure queue. +Removes them silently unless there are errors. +If it gets RecordNotFound prints the args to the whenever log. +If there are other exceptions prints out more information + but does not remove it from the queue. + These jobs will need to be removed manually." + task(:run_failures => :environment) do + (Resque::Failure.count-1).downto(0).each {|i| process_job(i)} + end + +end diff --git a/lib/tasks/search.rake b/lib/tasks/search.rake new file mode 100755 index 0000000..ac87459 --- /dev/null +++ b/lib/tasks/search.rake @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +namespace :search do + BATCH_SIZE = 1000 + + desc "Update all index mappings" + task(update_all_mappings: :environment) do + # If multiple indexers share an index and a mapping, we only need to call + # create_mapping on one of them. + Indexer.all.group_by(&:index_name).values.map(&:first).map(&:create_mapping) + end + + desc "Recreate tag index" + task(index_tags: :environment) do + if Rails.env.production? || Rails.env.test? + puts 'Running this task will temporarily empty some wrangling bins and affect tag search. + Have you warned the wrangling team this task is being run? + Enter YES to continue:' + + confirmation = $stdin.gets.chomp.strip.upcase + unless confirmation == "YES" + puts "Task aborted." + exit + end + end + TagIndexer.index_all + end + + desc "Recreate pseud index" + task(index_pseuds: :environment) do + PseudIndexer.index_all + end + + desc "Recreate work index" + task(index_works: :environment) do + WorkIndexer.index_all + WorkCreatorIndexer.index_from_db + end + + desc "Recreate bookmark index" + task(index_bookmarks: :environment) do + BookmarkIndexer.index_all + end + + desc "Recreate admin users index" + task(index_admin_users: :environment) do + UserIndexer.index_all + end + + desc "Reindex all works without recreating the index" + task(reindex_works: :environment) do + WorkIndexer.index_from_db + WorkCreatorIndexer.index_from_db + end + + desc "Reindex all bookmarkables without recreating the index" + task(reindex_bookmarkables: :environment) do + BookmarkedExternalWorkIndexer.index_from_db + BookmarkedSeriesIndexer.index_from_db + BookmarkedWorkIndexer.index_from_db + end + + desc "Reindex users without recreating the admin users index" + task(reindex_admin_users: :environment) do + UserIndexer.index_from_db + end + + desc "Reindex all recently-modified items" + task timed_all: %i[timed_works timed_tags timed_pseud timed_bookmarks] do + end + + desc "Reindex recent bookmarks" + task timed_bookmarks: :environment do + time = ENV["TIME_PERIOD"] || "NOW() - INTERVAL 1 DAY" + ExternalWork.where("external_works.updated_at > #{time}").select(:id).find_in_batches(batch_size: BATCH_SIZE) do |group| + AsyncIndexer.new(BookmarkedExternalWorkIndexer, :world).enqueue_ids(group.map(&:id)) + end + Series.where("series.updated_at > #{time}").select(:id).find_in_batches(batch_size: BATCH_SIZE) do |group| + AsyncIndexer.new(BookmarkedSeriesIndexer, :world).enqueue_ids(group.map(&:id)) + end + Work.where("works.revised_at > #{time}").select(:id).find_in_batches(batch_size: BATCH_SIZE) do |group| + AsyncIndexer.new(BookmarkedWorkIndexer, :world).enqueue_ids(group.map(&:id)) + end + Bookmark.where("bookmarks.updated_at > #{time}").select(:id).find_in_batches(batch_size: BATCH_SIZE) do |group| + AsyncIndexer.new(BookmarkIndexer, :world).enqueue_ids(group.map(&:id)) + end + end + + desc "Reindex recent works" + task timed_works: :environment do + time = ENV["TIME_PERIOD"] || "NOW() - INTERVAL 1 DAY" + Work.where("works.revised_at > #{time}").select(:id).find_in_batches(batch_size: BATCH_SIZE) do |group| + AsyncIndexer.new(WorkIndexer, :world).enqueue_ids(group.map(&:id)) + end + end + + desc "Reindex recent tags" + task timed_tags: :environment do + time = ENV["TIME_PERIOD"] || "NOW() - INTERVAL 1 DAY" + Tag.where("tags.updated_at > #{time}").select(:id).find_in_batches(batch_size: BATCH_SIZE) do |group| + AsyncIndexer.new(TagIndexer, :world).enqueue_ids(group.map(&:id)) + end + end + + desc "Reindex pseuds" + task timed_pseud: :environment do + time = ENV["TIME_PERIOD"] || "NOW() - INTERVAL 1 DAY" + Pseud.where("pseuds.updated_at > #{time}").select(:id).find_in_batches(batch_size: BATCH_SIZE) do |group| + AsyncIndexer.new(PseudIndexer, :world).enqueue_ids(group.map(&:id)) + end + end + + desc "Run tasks enqueued to the world queue by IndexQueue." + task run_world_index_queue: :environment do + ScheduledReindexJob::MAIN_CLASSES.each do |klass| + IndexQueue.from_class_and_label(klass, :world).run + end + end +end diff --git a/lib/tasks/skin_tasks.rake b/lib/tasks/skin_tasks.rake new file mode 100755 index 0000000..68c1b2a --- /dev/null +++ b/lib/tasks/skin_tasks.rake @@ -0,0 +1,193 @@ +namespace :skins do + + def ask(message) + print message + STDIN.gets.chomp.strip + end + + def replace_or_new(skin_content) + skin = Skin.new + if skin_content.match(/REPLACE:\s*(\d+)/) + id = $1.to_i + skin = Skin.where(:id => id).first + unless skin + puts "Couldn't find skin with id #{id} to replace" + return nil + end + end + skin + end + + def set_parents(skin, parent_names) + # clear existing ones + SkinParent.where(:child_skin_id => skin.id).delete_all + + parent_position = 1 + parents = parent_names.split(/,\s?/).map {|pn| pn.strip} + parents.each do |parent_name| + if parent_name.match(/^(\d+)$/) + parent_skin = Skin.where("title LIKE 'Archive 2.0: (#{parent_name})%'").first + elsif parent_name.blank? + puts "Empty parent name for #{skin.title}" + next + else + parent_skin = Skin.where(:title => parent_name).first + end + unless parent_skin + puts "Couldn't find parent #{parent_name} to add, skipping" + next + end + if (parent_skin.role == "site" || parent_skin.role == "override") && skin.role != "override" + skin.role = "override" + skin.save or puts "Problem updating skin #{skin.title} to be replacement skin: #{skin.errors.full_messages.join(', ')}" + next + end + p = skin.skin_parents.build(:parent_skin => parent_skin, :position => parent_position) + if p.save + parent_position += 1 + else + puts "Skipping skin parent #{parent_name}: #{p.errors.full_messages.join(', ')}" + end + end + end + + def get_user_skins + dir = Skin.site_skins_dir + 'user_skins_to_load' + default_preview_filename = "#{dir}/previews/default_preview.png" + user_skin_files = Dir.entries(dir).select {|f| f.match(/css$/)} + skins = [] + user_skin_files.each do |skin_file| + skins << File.read("#{dir}/#{skin_file}").split(/\/\*\s*END SKIN\s*\*\//) + end + skins.flatten! + end + + desc "Purge user skins parents" + task(:purge_user_skins_parents => :environment) do + get_user_skins.each do |skin_content| + skin = replace_or_new(skin_content) + if skin.new_record? && skin_content.match(/SKIN:\s*(.*)\s*\*\//) + skin = Skin.find_by_title($1.strip) + end + skin.skin_parents.delete_all + end + end + + desc "Load user skins" + task(:load_user_skins => :environment) do + replace = ask("Replace existing skins with same titles? (y/n) ") == "y" + Rake::Task['skins:purge_user_skins_parents'].invoke if replace + + author = User.find_by_login("lim") + dir = Skin.site_skins_dir + 'user_skins_to_load' + + skins = get_user_skins + skins.each do |skin_content| + next if skin_content.blank? + + # Determine if we're replacing or creating new + next unless (skin = replace_or_new(skin_content)) + + # set the title and preview + if skin_content.match(/SKIN:\s*(.*)\s*\*\//) + title = $1.strip + if (oldskin = Skin.find_by_title(title)) && oldskin.id != skin.id + if replace + skin = oldskin + else + puts "Existing skin with title #{title} - did you mean to replace? Skipping." + next + end + end + skin.title = title + preview_filename = "#{dir}/previews/#{title.gsub(/[^\w\s]+/, '')}.png" + unless File.exists?(preview_filename) + puts "No preview filename #{preview_filename} found for #{title}" + preview_filename = "#{dir}/previews/default_preview.png" + end + File.open(preview_filename, 'rb') {|preview_file| skin.icon = preview_file} + else + puts "No skin title found for skin #{skin_content}" + next + end + + # set the css and make public + skin.css = skin_content + skin.public = true + skin.official = true + skin.author = author unless skin.author + + if skin_content.match(/DESCRIPTION:\s*(.*?)\*\//m) + skin.description = "
    #{$1}
    " + end + if skin_content.match(/PARENT_ONLY/) + skin.unusable = true + end + + # make sure we have valid skin now + if skin.save + puts "Saved skin #{skin.title}" + else + puts "Problem with skin #{skin.title}: #{skin.errors.full_messages.join(', ')}" + next + end + + # recache any cached skins + if skin.cached? + skin.cache! + end + + # set parents + if skin_content.match(/PARENTS:\s*(.*)\s*\*\//) + parent_string = $1 + set_parents(skin, parent_string) + end + end + + end + + desc "Load site skins" + task(:load_site_skins => :environment) do + settings = AdminSetting.first + if settings.default_skin_id.nil? + settings.default_skin_id = Skin.default.id + settings.save(validate: false) + end + Skin.load_site_css + Skin.set_default_to_current_version + end + + desc "Cache all site skins in the skin chooser" + task(cache_chooser_skins: :environment) do + # The default skin can be changed to something other than Skin.default via + # admin settings, so we want to cache that skin, not Skin.default. + skins = Skin.where(id: AdminSetting.default_skin_id).or(Skin.in_chooser) + successes = [] + failures = [] + + skins.each do |skin| + if skin.cache! + successes << skin.title + else + failures << skin.title + end + end + puts + puts("Cached #{successes.join(',')}") if successes.any? + puts("Couldn't cache #{failures.join(',')}") if failures.any? + STDOUT.flush + end + + desc "Remove all existing skins from preferences" + task(:disable_all => :environment) do + default_id = AdminSetting.default_skin_id + Preference.update_all(:skin_id => default_id) + end + + desc "Unapprove all existing official skins" + task(:unapprove_all => :environment) do + default_id = AdminSetting.default_skin_id + Skin.where("id != ?", default_id).update_all(:official => false) + end + +end diff --git a/lib/tasks/spam_report.rake b/lib/tasks/spam_report.rake new file mode 100755 index 0000000..8165251 --- /dev/null +++ b/lib/tasks/spam_report.rake @@ -0,0 +1,7 @@ +namespace :spam do + + desc "Print list of potential spammers" + task(:print_possible => :environment) do + SpamReport.run + end +end diff --git a/lib/tasks/tag_tasks.rake b/lib/tasks/tag_tasks.rake new file mode 100755 index 0000000..1af40a8 --- /dev/null +++ b/lib/tasks/tag_tasks.rake @@ -0,0 +1,178 @@ +namespace :Tag do + desc "Reset common taggings - slow" + task(reset_common: :environment) do + Work.find_each do |w| + print "." if w.id.modulo(100) == 0; STDOUT.flush + #w.update_common_tags + end + puts "Common tags reset." + end + + desc "Reset tag count" + task(reset_count: :environment) do + Tag.find_each do |t| + t.taggings_count + end + puts "Tag count reset." + end + + desc "Reset taggings count for obviously wrong taggings_count" + task(fix_taggings_count: :environment) do + tag_scope = Tag.where("taggings_count_cache < 0") + tag_count = tag_scope.count + tag_scope.each_with_index do |tag, index| + puts "#{index} / #{tag_count}" + tag.taggings_count + end + puts "Taggings count for less-than-zero counts has been reset." + end + + desc "Update relationship has_characters" + task(update_has_characters: :environment) do + Relationship.find_each do |relationship| + relationship.update_attribute(:has_characters, true) unless relationship.characters.blank? + end + end + + desc "Delete unused tags" + task(delete_unused: :environment) do + start = Time.current + deleted_names = [] + Tag.where(canonical: false, merger_id: nil, taggings_count_cache: 0).find_in_batches do |batch| + batch.each do |t| + next unless t.taggings.count.zero? + next unless t.child_taggings.count.zero? + next unless t.set_taggings.count.zero? + + deleted_names << t.name + begin + t.destroy + print "+" + rescue ActiveRecord::LockWaitTimeout + sleep(10) + print("Retrying ", t.name) + retry + end + end + print "." + end + unless deleted_names.blank? + puts "The following unused tags were deleted:" + puts deleted_names.join(", ") + puts "Started #{start}" + puts "Ended #{Time.current}" + puts "Deleted #{deleted_names.length}" + end + end + + desc "Convert non-canonical warnings into freeforms" + task(convert_non_canonical_warnings_to_freeforms: :environment) do + default_warning = ArchiveWarning.find_by(name: ArchiveConfig.WARNING_DEFAULT_TAG_NAME) + warnings = ArchiveWarning.where(canonical: false) + puts "Total non-canonical warnings: #{warnings.count}" + + warnings.find_each do |warning| + puts("#{warning.name} (#{warning.works.count})") && STDOUT.flush + + warning.works.find_each do |work| + # If the only warning is non-canonical, add a default warning + # so the work won't be left with no warnings. + work.archive_warnings << default_warning if work.archive_warnings.count <= 1 + end + + warning.update_attribute(:type, "Freeform") + end + end + + desc "Delete unused admin post tags" + task(delete_unused_admin_post_tags: :environment) do + AdminPostTag.joins("LEFT JOIN `admin_post_taggings` ON admin_post_taggings.admin_post_tag_id = admin_post_tags.id").where("admin_post_taggings.id IS NULL").destroy_all + end + + desc "Clean up orphaned taggings" + task(clean_up_taggings: :environment) do + Tagging.find_each { |t| t.destroy if t.taggable.nil? } + CommonTagging.find_each { |t| t.destroy if t.common_tag.nil? } + end + + desc "Reset filter taggings" + task(reset_filters: :environment) do + puts "Adding jobs for work filter updates to the reindex_world queue:" + + Work.update_filters(async_update: true, + job_queue: :reindex_world, + reindex_queue: :world) do + print(".") && STDOUT.flush + end + + print("\n") && STDOUT.flush + + puts "Adding jobs for external work filter updates to the reindex_world queue:" + ExternalWork.update_filters(async_update: true, + job_queue: :reindex_world, + reindex_queue: :world) do + print(".") && STDOUT.flush + end + + print("\n") && STDOUT.flush + + puts "All jobs enqueued! Once all jobs have finished running, call rake search:run_world_index_queue." + end + + desc "Reset inherited meta taggings" + task(reset_meta_tags: :environment) do + InheritedMetaTagUpdater.update_all { print(".") && STDOUT.flush } + print("\n") && STDOUT.flush + end + + desc "Reset filter counts" + task(reset_filter_counts: :environment) do + FilterCount.set_all + end + + desc "Reset filter counts from date" + task(unsuspend_filter_counts: :environment) do + admin_settings = AdminSetting.current + if admin_settings && admin_settings.suspend_filter_counts_at + FilterTagging.update_filter_counts_since(admin_settings.suspend_filter_counts_at) + end + end + + desc "Clean up invalid CommonTaggings" + task(destroy_invalid_common_taggings: :environment) do + count = 0 + + CommonTagging.destroy_invalid do |ct, valid| + unless valid + puts "Deleting invalid CommonTagging: " \ + "#{ct.filterable.try(:name)} > #{ct.common_tag.try(:name)}" + puts ct.errors.full_messages + end + + if ((count += 1) % 1000).zero? + puts "Processed #{count} CommonTaggings." + end + end + + puts "Processed #{count} CommonTaggings." + end + + desc "Clean up invalid MetaTaggings" + task(destroy_invalid_meta_taggings: :environment) do + count = 0 + + MetaTagging.destroy_invalid do |mt, valid| + unless valid + puts "Deleting invalid MetaTagging: " \ + "#{mt.meta_tag.try(:name)} > #{mt.sub_tag.try(:name)}" + puts mt.errors.full_messages + end + + if ((count += 1) % 1000).zero? + puts "Processed #{count} MetaTaggings." + end + end + + puts "Processed #{count} MetaTaggings." + end +end diff --git a/lib/tasks/work_tasks.rake b/lib/tasks/work_tasks.rake new file mode 100755 index 0000000..954798a --- /dev/null +++ b/lib/tasks/work_tasks.rake @@ -0,0 +1,55 @@ +namespace :work do + desc "Purge drafts created more than a month ago" + task(:purge_old_drafts => :environment) do + count = 0 + Work.unposted.where('works.created_at < ?', 1.month.ago).find_each do |work| + begin + work.destroy! + count += 1 + rescue StandardError => e + puts "The following error occurred while trying to destroy draft #{work.id}:" + puts "#{e.class}: #{e.message}" + puts e.backtrace + end + end + puts "Unposted works (#{count}) created more than one month ago have been purged" + end + + desc "create missing hit counters" + task(:missing_stat_counters => :environment) do + Work.find_each do |work| + counter = work.stat_counter + unless counter + counter = StatCounter.create(:work => work, :hit_count => 1) + end + end + end + + # Usage: rake work:reset_word_counts[en] + desc "Reset word counts for works in the specified language" + task(:reset_word_counts, [:lang] => :environment) do |_t, args| + language = Language.find_by(short: args.lang) + + updated_works = "ALL" + if language.nil? + works = Work.all + else + works = Work.where(language: language) + updated_works = language.short + end + + print "Resetting word count for #{works.count} '#{updated_works}' works: " + + works.find_in_batches do |batch| + batch.each do |work| + work.chapters.each do |chapter| + chapter.content_will_change! + chapter.save + end + work.save + end + print(".") && STDOUT.flush + end + puts && STDOUT.flush + end +end diff --git a/lib/url_formatter.rb b/lib/url_formatter.rb new file mode 100755 index 0000000..c3c89e0 --- /dev/null +++ b/lib/url_formatter.rb @@ -0,0 +1,67 @@ +require 'uri' +require 'cgi' +require 'addressable/uri' + +class UrlFormatter + + attr_accessor :url + + def initialize(url) + @url = url || "" + end + + def original + url + end + + # Remove anchors and query parameters, preserve sid parameter for eFiction sites + def minimal (input = url) + uri = Addressable::URI.parse(input) + queries = CGI::parse(uri.query) unless uri.query.nil? + if queries.nil? + input.gsub(/[?#].*$/, "") + else + queries.keep_if { |k, _| ["sid"].include? k } + querystring = "?#{URI.encode_www_form(queries)}" unless queries.empty? + input.gsub(/[?#].*$/, "") << querystring.to_s + end + end + + def minimal_no_protocol_no_www + minimal.gsub(%r{^https?://(www\.)?}, "") + end + + def no_www + minimal.gsub(%r{^(https?)://www\.}, "\\1://") + end + + def with_www + minimal.gsub(%r{^(https?)://}, "\\1://www.") + end + + def with_http + minimal.gsub(%r{^https?://}, "").prepend("http://") + end + + def with_https + minimal.gsub(%r{^https?://}, "").prepend("https://") + end + + def encoded + minimal URI::Parser.new.escape(url) + end + + def decoded + URI::Parser.new.unescape(minimal) + end + + # Adds http if not present, downcases the host and hyphenates spaces + # Extracted from story parser class + # Returns a Generic::URI + def standardized + uri = URI.parse(url) + uri = URI.parse("http://#{url}") if uri.instance_of?(URI::Generic) + uri.host = uri.host.downcase.tr(" ", "-") + uri + end +end diff --git a/lib/word_counter.rb b/lib/word_counter.rb new file mode 100755 index 0000000..a247b46 --- /dev/null +++ b/lib/word_counter.rb @@ -0,0 +1,37 @@ +# encoding=utf-8 + +require 'nokogiri' + +class WordCounter + + attr_accessor :text + + def initialize(text) + @text = text + end + + # only count actual text + # scan by word boundaries after stripping hyphens and apostrophes + # so one-word and one's will be counted as one word, not two. + # -- is replaced by — (emdash) before strip so one--two will count as 2 + def count + count = 0 + # avoid blank? so we don't need to load Rails for tests + return count if @text.nil? || @text.empty? + + # Scripts such as Chinese and Japanese that do not have space between words + # are counted based on the number of characters. If a text include mixed + # languages, only characters in these languages would be counted as words, + # words in other languages are counted as usual + character_count_scripts = ArchiveConfig.CHARACTER_COUNT_SCRIPTS.map { |lang| "\\p{#{lang}}" }.join("|") + body = Nokogiri::HTML5.parse(@text).xpath("//body").first + body.traverse do |node| + if node.text? + count += node.inner_text.gsub(/--/, "—").gsub(/['’‘-]/, "") + .scan(/#{character_count_scripts}|((?!#{character_count_scripts})[[:word:]])+/).size + end + end + count + end + +end diff --git a/lib/work_chapter_count_caching.rb b/lib/work_chapter_count_caching.rb new file mode 100755 index 0000000..e26973b --- /dev/null +++ b/lib/work_chapter_count_caching.rb @@ -0,0 +1,15 @@ +# This module is included by both the work and chapter models +module WorkChapterCountCaching + def key_for_chapter_posted_counting(work) + "/v1/chapters_posted/#{work.id}" + end + + def key_for_chapter_total_counting(work) + "/v1/chapters_total/#{work.id}" + end + + def invalidate_work_chapter_count(work) + Rails.cache.delete(key_for_chapter_total_counting(work)) + Rails.cache.delete(key_for_chapter_posted_counting(work)) + end +end diff --git a/lib/works_owner.rb b/lib/works_owner.rb new file mode 100755 index 0000000..bc5681b --- /dev/null +++ b/lib/works_owner.rb @@ -0,0 +1,52 @@ +# Used to generate cache keys for any works index page +# Include in models that can "own" works, eg ...tags/TAGNAME/works or users/LOGIN/works +module WorksOwner + + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + # expire a bunch of keys without having to look up the objects in the database + def expire_ids(ids) + ids.each do |id| + klass = (self.superclass == Tag) ? 'tag' : self.to_s.underscore + REDIS_GENERAL.set("#{klass}_#{id}_windex", Time.now.to_i.to_s) + end + end + end + + # Used in works_controller to determine whether to expire the cache for this object's works index page + # The timestamp should reflect the last update that would cause the list to need refreshing + # When both a collection and a tag are given, include both in the key and use the tag's timestamp + def works_index_cache_key(tag=nil) + key = "works_index_for_#{self.class.name.underscore}_#{self.id}_" + if tag.present? + key << "tag_#{tag.id}_#{tag.works_index_timestamp}" + else + key << "#{self.works_index_timestamp}" + end + key + end + + # Set the timestamp if it doesn't yet exist + def works_index_timestamp + REDIS_GENERAL.get(redis_works_index_key) || update_works_index_timestamp! + end + + # Should be called wherever works are updated + # Making the timestamp a stringy integer mostly for ease of testing + def update_works_index_timestamp! + t = Time.now.to_i.to_s + REDIS_GENERAL.set(redis_works_index_key, t) + return t + end + + private + + def redis_works_index_key + klass = self.is_a?(Tag) ? 'tag' : self.class.to_s.underscore + "#{klass}_#{self.id}_windex" + end + +end diff --git a/lib/zoho_auth_client.rb b/lib/zoho_auth_client.rb new file mode 100755 index 0000000..a7a5b0d --- /dev/null +++ b/lib/zoho_auth_client.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +class ZohoAuthClient + ACCESS_TOKEN_REQUEST_ENDPOINT = "https://accounts.zoho.com/oauth/v2/token" + ACCESS_TOKEN_CACHE_KEY = "/v3/zoho_access_token" + + SCOPE = [ + # - Find and create contacts before submitting tickets + # - Create tickets + # - Find tickets to justify admin actions + "Desk.contacts.CREATE", + "Desk.contacts.READ", + "Desk.search.READ", + "Desk.tickets.CREATE", + "Desk.tickets.READ", + "Desk.tickets.UPDATE" + ].join(",").freeze + + def access_token + if (cached_token = Rails.cache.read(ACCESS_TOKEN_CACHE_KEY)).present? + return cached_token + end + + response = HTTParty.post(ACCESS_TOKEN_REQUEST_ENDPOINT, query: access_token_params).parsed_response + access_token = response["access_token"] + + if (expires_in = response["expires_in_sec"]).present? + # We don't want the token to expire while we're in the middle of a sequence + # of requests, so we take the stated expiration time and subtract a little. + Rails.cache.write(ACCESS_TOKEN_CACHE_KEY, access_token, + expires_in: expires_in - 1.minute) + end + + # Return the access token: + access_token + end + + private + + def access_token_params + { + client_id: ArchiveConfig.ZOHO_CLIENT_ID, + client_secret: ArchiveConfig.ZOHO_CLIENT_SECRET, + redirect_uri: ArchiveConfig.ZOHO_REDIRECT_URI, + scope: SCOPE, + grant_type: "refresh_token", + refresh_token: ArchiveConfig.ZOHO_REFRESH_TOKEN + } + end +end diff --git a/lib/zoho_resource_client.rb b/lib/zoho_resource_client.rb new file mode 100755 index 0000000..546e84d --- /dev/null +++ b/lib/zoho_resource_client.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +class ZohoResourceClient + CONTACT_SEARCH_ENDPOINT = "https://desk.zoho.com/api/v1/contacts/search" + CONTACT_CREATE_ENDPOINT = "https://desk.zoho.com/api/v1/contacts" + TICKET_SEARCH_ENDPOINT = "https://desk.zoho.com/api/v1/tickets/search" + TICKET_CREATE_ENDPOINT = "https://desk.zoho.com/api/v1/tickets" + + def initialize(access_token:, email: nil) + @access_token = access_token + @email = email + end + + def retrieve_contact_id + (find_contact || create_contact).fetch("id") + end + + def find_ticket(ticket_number) + response = HTTParty.get( + TICKET_SEARCH_ENDPOINT, + query: search_params.merge(ticketNumber: ticket_number), + headers: headers + ).parsed_response + + # Note that Zoho returns an empty 204 if the ticket is marked as spam. + return if response.blank? || response.key?("errorCode") + + response.fetch("data").first + end + + def create_ticket(ticket_attributes:) + HTTParty.post( + TICKET_CREATE_ENDPOINT, + headers: headers, + body: ticket_attributes.to_json + ).parsed_response + end + + def create_ticket_attachment(ticket_id:, attachment_attributes:) + response = HTTParty.post( + ticket_attachment_create_endpoint(ticket_id), + headers: headers, + body: attachment_attributes + ).parsed_response + raise response["message"] if response["errorCode"] + + response + end + + def find_contact + response = HTTParty.get( + CONTACT_SEARCH_ENDPOINT, + query: search_params.merge(email: @email), + headers: headers + ).parsed_response + return if response.blank? || response.key?("errorCode") + + response.fetch("data").first + end + + def create_contact + HTTParty.post( + CONTACT_CREATE_ENDPOINT, + headers: headers, + body: contact_body.to_json + ).parsed_response + end + + def search_params + { + limit: 1, + sortBy: "modifiedTime" + } + end + + def headers + { + "Content-Type" => "application/json", + "orgId" => ArchiveConfig.ZOHO_ORG_ID, + "Authorization" => "Zoho-oauthtoken #{@access_token}" + } + end + + def contact_body + { + "lastName" => @email, + "email" => @email + } + end + + private + + def ticket_attachment_create_endpoint(ticket_id) + "#{ArchiveConfig.ZOHO_URL}/api/v1/tickets/#{ticket_id}/attachments" + end +end diff --git a/multi-master.info b/multi-master.info new file mode 100755 index 0000000..e69de29 diff --git a/node.lock b/node.lock new file mode 100644 index 0000000..e69de29 diff --git a/nodes b/nodes new file mode 100644 index 0000000..5d44d03 --- /dev/null +++ b/nodes @@ -0,0 +1 @@ +written by Elasticsearch 9.1.3 to prevent a downgrade to a version prior to v8.0.0 which would result in data loss \ No newline at end of file diff --git a/public/.htaccess b/public/.htaccess new file mode 100755 index 0000000..d9d211c --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,40 @@ +# General Apache options +AddHandler fastcgi-script .fcgi +AddHandler cgi-script .cgi +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.cgi [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/403.html b/public/403.html new file mode 100755 index 0000000..1c057e3 --- /dev/null +++ b/public/403.html @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + Access Blocked | Archive of Our Own + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Error 403

    +

    Access blocked.

    +

    Your IP address has been blocked from accessing the Archive of Our Own. These blocks are generally long-term. If you believe you have been blocked by mistake, please contact us.

    +
    + +
    + + +
    + + + + + + + + + diff --git a/public/406-unsupported-browser.html b/public/406-unsupported-browser.html new file mode 100755 index 0000000..68f19a0 --- /dev/null +++ b/public/406-unsupported-browser.html @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + Archive of Our Own » Error 406 + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Your browser is not supported.

    +

    Please upgrade your browser to continue.

    +
    + +
    + + +
    + + + + + + + + + diff --git a/public/445.html b/public/445.html new file mode 100755 index 0000000..ebaad82 --- /dev/null +++ b/public/445.html @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + Archive of Our Own » Error 445 + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Error 445

    +

    The Archive is currently experiencing heavy traffic. Please wait a few minutes and try again.

    +
    + +
    + + +
    + + + + + + + + + diff --git a/public/500.html b/public/500.html new file mode 100755 index 0000000..183ea3e --- /dev/null +++ b/public/500.html @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + Archive of Our Own » internal_server_error + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Error 500

    +

    We're sorry, but something went wrong.

    +

    If you are receiving this error repeatedly, please contact Support. In the form, please include a link to the page you're trying to reach and how you're trying to reach this page.

    +
    + +
    + + +
    + + + + + + + + + diff --git a/public/502.html b/public/502.html new file mode 100755 index 0000000..d511d8d --- /dev/null +++ b/public/502.html @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + Archive Down + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Error 502

    +

    The page was responding too slowly.

    + +

    We're experiencing heavy load. The problem should be temporary; try refreshing the page.

    +

    Follow @AO3_Status on Twitter or ao3org on Tumblr for updates if this keeps happening.

    +
    + +
    + + +
    + + + + + + + + + diff --git a/public/503.html b/public/503.html new file mode 100755 index 0000000..80a5f28 --- /dev/null +++ b/public/503.html @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + Page responding too slowly. + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Error 503

    +

    The page was responding too slowly.

    + +

    Follow @AO3_Status on Twitter or ao3org on Tumblr for updates if this keeps happening.

    +
    + +
    + + +
    + + + + + + + + + diff --git a/public/507.html b/public/507.html new file mode 100755 index 0000000..24ea3f9 --- /dev/null +++ b/public/507.html @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + Exceeded maximum posting rate. + + + + + + + + + + + + + +
    + + + + +
    +
    +

    Error 507

    +

    Exceeded maximum posting rate.

    +

    To combat bots, we are currently banning IP addresses that post too many works in a short time period. If you see this page repeatedly please pause a while between posting works. If you are banned, you will be unable to access the Archive. Access will be restored 24 hours after the ban started.

    +

    Follow @AO3_Status on Twitter or ao3org on Tumblr for updates.

    +
    + +
    + + +
    + + + + + + + + + diff --git a/public/OTW_Membership_Donation_Form.pdf b/public/OTW_Membership_Donation_Form.pdf new file mode 100755 index 0000000000000000000000000000000000000000..2bdc827ef330ee90a211f6b33cda5c61fdedf559 GIT binary patch literal 89154 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 literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-114x114.png b/public/apple-touch-icon-114x114.png new file mode 100755 index 0000000000000000000000000000000000000000..cbbc686a9a75b91d165616342b97e039ec5ce4f1 GIT binary patch literal 4750 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 literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-120x120-precomposed.png b/public/apple-touch-icon-120x120-precomposed.png new file mode 100755 index 0000000000000000000000000000000000000000..3219f3093b7fe8e7f50c713ccc5da48a2c35b4af GIT binary patch literal 4928 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%0A54quAo#58 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 literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-152x152-precomposed.png b/public/apple-touch-icon-152x152-precomposed.png new file mode 100755 index 0000000000000000000000000000000000000000..e1eeeb3c2c37f8098d978d357d2547e7b8265a10 GIT binary patch literal 6459 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 R|Gpt8>dHW+dIbyE{{XoKLg)Yh literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-152x152.png b/public/apple-touch-icon-152x152.png new file mode 100755 index 0000000000000000000000000000000000000000..7bfed5fda691ec862fdc45514b33fdb67bdc6108 GIT binary patch literal 2596 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 JPDHLkV1jz>iq8N5 literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-180x180-precomposed.png b/public/apple-touch-icon-180x180-precomposed.png new file mode 100755 index 0000000000000000000000000000000000000000..64586d4ec3cf696eee60d54d91da15415a3a4121 GIT binary patch literal 8144 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 literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-180x180.png b/public/apple-touch-icon-180x180.png new file mode 100755 index 0000000000000000000000000000000000000000..d0afbe594b04964e28162688959ff9649d38defc GIT binary patch literal 3302 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 EAIaL4ng9R* literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-57x57-precomposed.png b/public/apple-touch-icon-57x57-precomposed.png new file mode 100755 index 0000000000000000000000000000000000000000..b7877ab80b7c583dd9df0959a51d800ebf511b56 GIT binary patch literal 2103 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 l5dN9KRQe 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 l5dN9KFIA3#nR|v-M?rl+B;boz0o85#1jsWy@qs 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 literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-76x76.png b/public/apple-touch-icon-76x76.png new file mode 100755 index 0000000000000000000000000000000000000000..d60caae8a6a3ce002eacc44b1b72f42e32fdfcd0 GIT binary patch literal 1442 zcmV;T1zq}yP)eD2lN+M}cS@bL5D;qcnp%z%K?kdWT3 zt+-81`0noK!ovIX^yIv}u{}MlF)`w{w)N)bswyhQZf@9~o}dyE?bFlQprFcod+N)} zn*{~6Mn>GIsIWOXrXeB7c6RB>$+JO08c# zuCC33g59dBzFl3!Y;3tuP_H*P>&?xsH8rTM6C zt~KX$y-g2n@?GyqU8>fwy-+8_@}}9LXPP|;|3?4jy+iH$1e4!4`5Vdi$dJA@3w(h$ z$ljfz6L4+Xgvs^-Oj+j!Jnsin&nth+n1JcsN`rL+SMmX=$=bWg7d`m;Q}NRb@GN{Y zpaWQtTDCsMswRygAJ8D%w9F#Dy_PSa2glXWtViy$hR%v@*jl-PpW>aOyAKB zuPxeC0r-=yH0FVlqIUt95!ToHphLwi$R~5#?M7 zL@Fdyvgl2i+S7M7Z4J@V0nkS^mjpOPrv(T^>u|~IJm`^850_lF?`jFfQw}0!@=Bu(~bC7pI>WUcl2zg_V6Sbq#vZxtaBJ>Gm_; zCCaRe&^E?tEZL$sE577Gj_ZY0zd4p0FT~2&A+ZTdlp~)fT;y#eG)rosOPC(uw2@C$ z#kNz^2}Kh}sFwHV31mM%0LC%W_64#85RWd$on}%opG}n0PZ57e4(J$_dBz5TOc1jj zYdxQ*5&5tdegJGQ-z005AjC!$wmddx{Rr$YL|!}e!cv%&H-{;$Dd-+KY?D^*lv!`p z2jif$`EJ}>M(sLanF1qQl<=yr@djYdk&LqF-#((-vCV43E)bLI>0m(ud8Z~;UYc=6 z{)uNVEL%WP8}=QmRq-|-%BD5zpe{>yR+Qk*EeF02#&&)ZQ&D;1jYv802Y-|4k+foK zL+)*5oFk8QO;`zkgq+M(P_FnGX}+Y@*f`0WRZ9%!WLc^PZ0|1y$+8#M1k#RgweoPB zHa)~J#kFkhGvh~C3l@Z*7~_a|v8a-| zQU+<2A(a+w(N1ByB?%uv~P()q`CvZaSqmI>pjl=AssI@yNYO>@wElN_}!1jXPe`oghy@zwR!4yGNC w@g9&0bvS#wBgVUv0W)9*%z*uG*gpXV0A;YXsz8P2m;e9(07*qoM6N<$f+I%ZMgRZ+ literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png new file mode 100755 index 0000000000000000000000000000000000000000..57dd4e65ee594e9e6d84c5906809373e37d11662 GIT binary patch literal 6048 zcmV;R7hmX!P)hfe6d214%= znh-$gL_t`TvVblu-&)yaU6JB~=!%QDE6WPH>n>nJq)Ar@RRIGChLV7EP?Gk9$0@d=OF zJkI-a@f<$9r!0@DJdW~shetCZPedZhcJFWxkMVeqN4Y=}2-a#ek2D^mY|E1%Yal<5 zXL+RB?s0Cb2^7m?8;>bG3d($ESroM0W8CXHRuL$XM>3DbGQZgdjd*P3@tD5^8qVWO z9))F2v!ykfZ{vVZ1RBW$QGQOD%WR9BHV%yRmO#C1Ub#R(HZJt?lt8t4d@PnnV6a3V z+qjV_fe^lZDv_4Jg-`UUF~m0#=tUk4Wv&D+0B*eGia^Lhj+Z$SxWPEmWvulC8Y4@W zz{92NRU?5)@E9g@Bk&MIZJety4+0-i8U!jN^C0jM zg>uLo2>gK%NFW3f2!RAbAb}7_AP@oxgg^ozkU$6|5D0+;LLfmHBbSvID_FTQ z($Aiy>!(f;Wn^UCiHnY=Qt|Oru6=td(X1I2tW=5e6)#RX^XBD`ok4f5UZop62bcEm zr(ZU2rk~fZrz=1Gl;!3jYUYDpd6uC4M;}qmAw$%^)x>SuL?_p*QD3j0IFThLtYF28 zRO{)dsm4=JQIXhKkKcFq`gJuI`#$)9jxAj(1TsUOqD84vw{GgGtkAi$dMefA-MFDh zgo!)0Vg+3}crfB7DrdfY)L_&os{hhUl&?eyzpiy^?OOVN>{vSe-FHGDmlMvWyi|)8 zRK0(Hs@Au!ebVpVys0KIZT4(BwrrVtGQ%A)_3KmHnKP+$%a)d1^ZxDIv}4jF+VT49 zLLhgDE?t_cJ@Ev^{pL4Ryy5?QH(X9jQ$$Mp?|;K~iL2PPD<#aCqx>6JxOL$IU1qC# z?dVbE`$Xl+Mfv$N7p`8N3RSB{Q8`@4DhEIPlr}u`jIz=~AP=lk<-|m)|Kf`dPjmXY zb98`j(%ygmlP(`P5H^#8<+#)Q`O0B-vLJWwswMg0C!eV0`Nq#bn||J+wQE!5UcIR1 zpg~l)hPnJ4*ZG>Q^u6?SA&^JEG-pm_ksAK-k5r<`|MxWBxps|G*%429_g%Vj=uk)} z27gzNq$J8y*ttFA$#1?(8%)*dlJ1C z^xw*1?!`TOD3vD-p>9lr29&2r5z3h-kMf&p{`%LHr&uw%n3AGM6>Q)JcVVl5h|7rW zuf0Yacq#UF$%W5z`rB{mI0q51zWK|Parl1mMvds^nKN`YIXQ3-E-$69ruXmMiEsjG zJi2#JP1u2tKUP+$WYebVDu0+C6ou zU-_+@r%%(71q-O`!w*w|3Kbl_htK@e=bzKg~z}DUPY17rAn!X)k=g_DdWtxZM3XoNBZ{p z=jqnPiw^z>mXwYhu^_SuB;erVi8cB>R)^bIx;G3TP8s*_JG_pxN0FK}{k}e~@d#U* zPG5XMG4<-vp6SzRK1aY-Cox01gt_vMK%}FK7pqLKK61fC)EF>8`4eaPsj|9MlCNY* zYRi$JKI+2n`leq$y7|j5mVeZ%94NrzAfuln_c;~in zr*D{)``CI0!k-M=Vk$}@D>#ha%8{BryhT2y<+N$kovngCg0lkUJ9MDDF)%ghDFHpIaM%wbc?&#jUB3E?TC=r5O%hgTNxOFR%f^iX`}@PX8V~cn>+QE` zDc{%&yLUT$59N|xn>JCSS6-nUxpQ0c`^t6b;Pl#o*|P)s8PDz5@xYqu{jl1#yb$pRb?0U_ll2>49V>!tOxh{H|Tj%TcvzZr@k3d2{Nuem%uK z{j~aj_)SX_5`tQ!jW|JB%6sq8@-AIe-O2bQwqXaj1Ba<_hP_3u{P|TF?GP!MlqUj# z>nBe-JM?ZU{oQkf9sa>jmeY8)ME2TrQ5wVh1SfFK( zK1!+o{z zwDskeLv|k`mOzL)u;i@g^&f>zrvz8Nd@75L2}dE*9T2VPlb1k&iWM`JVps)8fsMFf z$UA{NaFkIed=R2$&_?$8kOl}PB9cJJ1+{(ueN}h`c21s5>v&?#mK;cIyMO()+w3m% zIMz_-(|apXwa z&puE%AR-B*Ssr7Qbb|dJL}*u!9C3P2{<39NmbT7Fm!~(<3AR*D(N2IhIv^+#hk78n zc+F-FTfFra#Xa+k{d?QSj0p?N6WIick5^f0RJDyj?FWgp3n?k4kxiQ!Gt^Bn15*A* z@~2875mn_KndGmJTQ)jfj8yZBrGYzo;`}gwh4+k$(QXTAm=MMa@s2xT?de0gOlG83XBp@w2C^vY&{Ly9HMs0>8a+GyEOF>hm$7Dz+sR;{Q76VnLf zbdW?uLR5sYa^enju0I0{I$&HE#TXKxt_n z{XA-Ds~>yJrM?D5SR@@w>OyHaso1mTwB)b@{>Xv_PEu5F06kN;RjZsV9}<}xhYzRb zlP1|eBLE5Q@s%sX_I^YjfovL}%c-dzzXt*>NJz~}A8J{wT$#GASYZ#@)l)xgn9?K} z0j>07Tec|CmN$M8{_alf9Cw&I*Qw?PKyM8_5BAP!fDUQ9#S&M`+#2d?ze9r z6{=d57C>#cbEjADhsX-jSoj}ifMPFc;6OUEc<}?@r&cZM!j{ODHV4fTAW%p8;3EHB z*kA}h1Y?bJ>VA&^CYuhMtV z9_2jGWQf2Cf_VyfSZhr^(D3#uB;qt zPLNAzR%U6(j&758SeCE^!GD2v8``4G$b(eF${sxwd9aO0PaZ^&JO2FVh`1*aMW9j- zJ*2*(67SDGF>DG1iCjfCs69b0p$XKm-yMa^<()hGtuIFI>W8=9qDArXbZq%@l@x6_ zdbGpO?3g%F<%1#txgv=`C7L#U@bnt?Q~3g<0T7)bjCa*I0RlCUY0p3Yq5dDf4$2*s zx^|`5!Go0u-xKi~oO0B*;4d9uCtBMNrZVHxr#o0GWYANCBuC9w1i}&#W77$H6M@y z%Z1$}dh)2hgF|`r7RrpsvV{4FvhCX0Ba~~$j#++vgw4@q%9vKi?LN_r8H&JW1y{Aq z7A>k8OF_wqdY!7Dc9M~`HY-U419*UrvlEYWfHzI9vaJuKZ|!n++qQuIE;L_4cyHV-YRnUb ziaY=;T$RTkSKF7GLOBpZpDFB@Fyu-qcIl%2jfCEL!yb97f%+9{SN^v04a(fGwM0K5 z$aOc47$F2Q15*4DbO9hwKz57r6I_m+bof4%d-k+zae@Kli_Y0Pupvsr0|PNXwj$-> zfo>sDh7FHK)E+)uHJ{KDo>u2|GxFO`x!j!tC348K>5-S5CAqK%VB|S+l5j zaU9>PP?TkR!oWI(WA#M`e%Oz`}mDOG7?EaUxB^+O46ch zg%^rW_hCyQL`0gr6F1Hq{|8GII#|Ghxw_eImkN%IKpOZS`UX(&P4ruCocycuX`J)GDEH>Q6U*RR4_`ZG_N%R>uo(lFC(8?`rShXw`_8XWJVHZ6Cy zClCmrZ#S3brqLw`hazPC7hdqXI~l_36YTgNoI6*YW#&njc;s8)M>RFsKV}aA*aAT; z=1P!{Bd>e`D*4zc3z5EqKgHHEkjEsrRdn zx~OH#fT$EA&H^Dy(oYb?>}KS_6WC|x@#+W%!G zkY-r>Lhc5w zQZhSI+m(-i<_GBJ6^it|JHR@0U$cga)v4p;|IFjp{2@EaG&Pw>XkV-k?GX{KVLwdk zubAbRFg#W0ee5lHjx1bAi(9o);d3~W2SC>loLh0maMDl8^yz+EN;K9&V|BE*fe=mG z#fsV-{6#BHJB$bmgpGQ2J#acT-~^f-lP0NCk0S+eaFMUVfhgzM$wvD+qXffWU}@|0 z`R8^SE~3vQlj?t#A`nb)d&AjZu7D>Nt!)D_`B?=xkG`#~2`F+z=$#a-?jAv3!tgY< z_CWlN1R^XB>R@n`g*>hSVHzS)0FABu>ERgG1cFJ2-{bBSoI_uHK?_^7P)BWtI@45n=z;~RT5lEbaB1~I{5!Mu#}Q2+>>S7}JV*GB#!omUIhaYnU;;PyZhE@vOQcs^ z`U42owDJyeV8JY`28}@2+g0C12MkOqwkt1g+0wrIAj<;BG_lWuF8XNr+29X<@acqR z4cMB5P9NItR4n&_>KzbL0#)qV)l^=Ju3w8=w^n=J197f-I0F9Ns$RX6v;^WXY*9un z(Ay^FP(GrItky6TlYa%2T125pMgf&*%2tfF6R&&H9&~sI@`3@@c$q= z!M-xHk_S4e;j9oeEXVsae-iu0(4sh){!h@uc=e$N4N?Wgy&QJBIt(Sd0c8(pxnYIu z=?nH{;1l9Z5FCFAjW^o9z!fMG8|(0XBo~o|4uvi#qWVNa%E|9kb0%q}eLVTiZ z8?N`Yae#a!5U_|xGl|Z!6>!cu&MIH%?gu^9M8mO;=kY2@$s;QR_jW7~oFC=UK_uRY z>T#;a8$4odxq$03-&qFe%!%Uza8k=;+r1{M38dj9k5N3T*uLTbP|*`b9x`nA4)?G! z51f2+!rP0W#hn!>%_G6KZr0|3;|ELfKo8p7a<4*)J2rlvv40000wn{{8)#008E|!1LkZ-Kwg~e0-@W zD8ON1=*GtG)z$Ib+^Z}s+oh%V>+7Z=A?(o5n*;=?CMLH@NuCW2^yK8!l$5YJIindF z#B6NeudmXMj`H5#=fc9+o}TH*$kv&ezFb_@mX@Fr64{`j#cpoLb91~{Snbl%;Igu~ zPEN{ud&zluvp_)CnwsLaw#IO9y;@qYHa4+5Jl?IX%z%K}qN1c69L<7)iY zM9+qXr5+y0b#=8yM(WGUzh7UP0|Vi-w9tu(&V_~1jg77}H2?qq{rmfw0Rj2%@BRAv zpAZoC>FNLe{?wC`=*7kN?Ckyd`J4v_`0eedBqa9e===8e+^46%U|{_C__s_<^Wx&9 z8ynZ0oc#Cq`0noCu(0pg*!1J$*qxonbac#rf9J%+v_nJSv9ZsHh^sCx&1ssI27w@E}nRCwC#n)z26Nf5^wMN#lTJRo==NW9RXfX4OYFzUJ>5mXuwPdwLn z#l)DH&A-0gJu}SBF$`}v@AdrPb9$KW58c&O->ODu`JY`n0z`la5CI}U1c(3;AOb{y z2oM1xKm>>Y5g-CYfC$iU4itMG&8Y2eJ>=``9XPvaYuXvgX$2GjhxRGMsEW>(t{wn) zb=CE01LU`@nE+^6X?0ZARo^%eUG;mEMmD66f62oBk_LVGi#OH)q*vo#ni=)&tQ~gP zwzytiKTaRZFyQ@Tb!D!Fx!Z5mZkOq|+hLCfd*@|zlUSq2Kbwl4VU|K{i^#I74`3(~zin7Ee-xRa3`!JB)h$ zG?Op#nb89@@Pu@i8&1)KKNGTV%{MKp^VE?^)NA{V@+Xe)M96hz!&7IF>(vYnZ7M^D za|`e2D<$iW)uYEY*=JwymvM@lDYz-Wzp9UAuV&QmNzf_#bOAjy%fCtC)!Y;>WiNPo zUsZ5TEc}f}P02k&-T}lF-rPkGkA$IM8G!NiYNP#T8x97G(n)e5);6cYdsg&xj&IiS z&j37YAV2*5*g(yaz0@q71KyQE^HMIPY2Qapx7-&6kplmT;mQhwuF|N+Cf=1=!h9`7aE_@eY4^_ctu}W@~E~V z|M3Tm1~@)}kA;vqjczv--$6cg-^!4E&^GJPXNTe6n=@f-*FnPo-xLEc3Of^eizQkV zTOE)NEMTESZ?@Ah#;$tN9K0&HAtMfhv?&d1otN1_i1xm1v?1+fII9jQ>;gM&(`a2E z6IuiLSa%a^r-{0;X{XSd?aS}8ujpf+oRNDNKm3|!u3o?@5bBsF>cmbiiT<_AjTgqs zWQ>BkGh1GkRtb>5;i9nF{hc(C9qk_-jwwxgX=LrfpK(tX4KAvI!obVjVk1&ETN3CO|OT2`WldrMk-TPvU*fsKfZJuT%D0dGtj zpo|xEq!d={ru*cuY#`8{(*&q5jZ+7itRgt5FfuOSfV=5wTkBRdV4h&1>ofuC!Ks6^ zl653!#P^NKAGUBeHkv{mz^x0?il9EG0g!VJfNg2bsC!=qr!#(z<}!y-#|5P=<2`CK zY5)|0I!yeb*j3zT2vu~vGZ#1ck1g{uSz z<->wdbtA?x1)3>i;m8H*u^0T`cTq=6IKQkO2u}Yc?|dQtQxq3g4SsHw;B~Ce(1$VN zYFkvPY+V_U8*0HM=d(rUV%}hZ)x);+=dr{;6`d-ivM6!NRSh)5`&zEMQ$EefGCzgR ztg-EnIAs+^KfUchBnnglp$THVV(vN1#~GXvsrS5a=kXLBH9tiQ+^bC0K+q}Dbr{QZ zBX6{hF?h z44^C6&n}#E56^f8Jc@^4DK7GxSgm1YcVFov*wR2ZC>_mNLcA2`Vz<~y>@*id3g*l# zTqXdRHmbr+Lq?@x_Z3xp25CR;DK+1V(W7U!9|2;T!b4NY{u z)OAxG(0i1}a5-{zr<`N+*pr;jNO|63OCPHS$aN-=T)y+NB8_DPd#j|lnQEO=K6@++ zDF24f(_Mbf6oIk+L`L%Jzd{dQZ&eL6%-3BN{c0i?YL!oUHXn-XkD@@^98T}G>YwmP z1Ea~U4ydo-;#xNRYQ~mLEYH*6-k}Oe-(E1DK6R53d2=ocl%-SwF$Yn=-mG?Ya*c1L zMH?i6EI}Na70%UOkzr1{ zJoV%)|2Yu!AmP@jm2bx@M~0IAjQsSJ01+SpM1Tko0U|&IhyW2F0z`la5CI}U1c(3; fpx+AUUjYUHow?EZ{zO)j00000NkvXXu0mjf&Ku4! literal 0 HcmV?d00001 diff --git a/public/apple-touch-icon120x120.png b/public/apple-touch-icon120x120.png new file mode 100755 index 0000000000000000000000000000000000000000..f348170c81ded1a01b90cac110c1d264c8a36320 GIT binary patch literal 2039 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 literal 0 HcmV?d00001 diff --git a/public/dispatch.cgi b/public/dispatch.cgi new file mode 100755 index 0000000..c584d66 --- /dev/null +++ b/public/dispatch.cgi @@ -0,0 +1,10 @@ +#!c:/ruby/bin/ruby + +require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT) + +# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: +# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired +require "dispatcher" + +ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) +Dispatcher.dispatch \ No newline at end of file diff --git a/public/dispatch.fcgi b/public/dispatch.fcgi new file mode 100755 index 0000000..5d9b8ec --- /dev/null +++ b/public/dispatch.fcgi @@ -0,0 +1,24 @@ +#!c:/ruby/bin/ruby +# +# You may specify the path to the FastCGI crash log (a log of unhandled +# exceptions which forced the FastCGI instance to exit, great for debugging) +# and the number of requests to process before running garbage collection. +# +# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log +# and the GC period is nil (turned off). A reasonable number of requests +# could range from 10-100 depending on the memory footprint of your app. +# +# Example: +# # Default log path, normal GC behavior. +# RailsFCGIHandler.process! +# +# # Default log path, 50 requests between GC. +# RailsFCGIHandler.process! nil, 50 +# +# # Custom log path, normal GC behavior. +# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log' +# +require File.dirname(__FILE__) + "/../config/environment" +require 'fcgi_handler' + +RailsFCGIHandler.process! diff --git a/public/dispatch.rb b/public/dispatch.rb new file mode 100755 index 0000000..6f48fda --- /dev/null +++ b/public/dispatch.rb @@ -0,0 +1,10 @@ +#!c:/ruby/bin/ruby + +require File.dirname(__FILE__) + "/../config/environment" unless defined?(Rails.root) + +# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like: +# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired +require "dispatcher" + +ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun) +Dispatcher.dispatch \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..12aa22d490c9c4bc05e4f0f8f3f02cfb4d0e5e98 GIT binary patch literal 15406 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 bdlJam-*(8@Qs(ABMwS2b?mr`t*$Dg#U$Qg; literal 0 HcmV?d00001 diff --git a/public/help/add-collectible-to-collection.html b/public/help/add-collectible-to-collection.html new file mode 100755 index 0000000..20bdf58 --- /dev/null +++ b/public/help/add-collectible-to-collection.html @@ -0,0 +1,18 @@ +

    Adding To Collections

    + +

    + Enter collection names as a comma-separated list, and the item you are editing will be added to all the collections you specify. +

    + +

    + Note that you need to use the collection's name, which gets used in the collection's URL, and not the collection's spiffy title (because different collections can have the same title). A collection's name is the equivalent of your user login. Names will be auto-completed for you if you have JavaScript turned on. +

    + +

    + Also note: if the collection you are submitting to is moderated, and you aren't a member, your story will not be added to the collection automatically - it will have to be approved by one of the collection's moderators. If this is an anonymous and/or unrevealed collection your work will be anonymous and/or hidden as soon as you post it, including while it's waiting for approval. If your work is rejected, it will remain anonymous and/or unrevealed until you edit it to remove it from the collection or until the moderator removes it. +

    + +

    + If you change your mind about having an item in a collection, you can either edit the list of collections + when editing it, or you can manage all your collected items under the "My Collections" page in your account. +

    diff --git a/public/help/add-work-to-assignment.html b/public/help/add-work-to-assignment.html new file mode 100755 index 0000000..8bc2ae1 --- /dev/null +++ b/public/help/add-work-to-assignment.html @@ -0,0 +1,15 @@ +

    Fulfilling Assignments

    + +

    + If you have any open challenge assignments, you can choose one of them here if the story you are posting is meant to fulfill one of them. + This will automatically add your story to the challenge collection (or submit it for approval) and also mark your assignment + as fulfilled for the challenge moderators. +

    + +

    + Note: if the collection you are submitting to is moderated, and you aren't a member, your story will not be + added to the collection automatically — it will have to be approved by one of the collection's moderators. + If this is an anonymous and/or unrevealed collection your work will be anonymous and/or hidden as soon as you post it, including while it's waiting for approval. + If your work is rejected, it will remain anonymous and/or unrevealed until you edit it to remove it from the collection or until the moderator removes it. +

    + diff --git a/public/help/additional-tags-help.html b/public/help/additional-tags-help.html new file mode 100755 index 0000000..6cfdbe5 --- /dev/null +++ b/public/help/additional-tags-help.html @@ -0,0 +1,6 @@ +

    Additional Tags

    + +

    (For more information, see the Tags on the Archive FAQ.)

    + +

    Any other tags you want to give your work (for example, "Angst", "Crossover", or "Tentacles"). You may also use this field to warn for things not covered by the Archive Warnings. Please do not enter fandom, relationship, or character names in this field. Multiple tags should be separated by commas.

    + diff --git a/public/help/backdating-help.html b/public/help/backdating-help.html new file mode 100755 index 0000000..f05058b --- /dev/null +++ b/public/help/backdating-help.html @@ -0,0 +1,16 @@ +

    Publication Date Options

    + +

    + When posting a work, you have the option to set a different publication date + — in other words, to backdate the work. You can also set publication dates for + individual chapters. Please note that in both cases, this affects whether and where + your work appears on your dashboard and the works page, etc. These pages which show + the date when your work was last updated — the publication date of your work or + of one of your chapters, whichever is the most recent date. +

    + +

    + Any subsequent chapters you add will have that date pre-set on the form, though you + will still have the option of overriding that date. This means that if you don't know + or care exactly when each chapter was originally published, you can still backdate your work conveniently. +

    diff --git a/public/help/bookmark-filters-exclude-tags.html b/public/help/bookmark-filters-exclude-tags.html new file mode 100755 index 0000000..49a3f19 --- /dev/null +++ b/public/help/bookmark-filters-exclude-tags.html @@ -0,0 +1,25 @@ +

    Tag Filters: Exclude Tags

    + +

    + The filters list the ten most popular tags for each tag category. To filter by any other tags, use the "Other work tags to exclude" or "Other bookmarker's tags to exclude" fields. +

    + +

    + If the tag you want to exclude isn't in the top ten, start entering the tag you need in either the "Other work tags to exclude" or "Other bookmarker's tags to exclude" field—all tag categories are valid here, and you can add as many tags as you want. The autocomplete will help you find the canonical version of the tag. Use these to take full advantage of the wrangled tagging structure, which will exclude all works using subtags and tags with synonymous meanings. +

    + +

    + You can also enter tags that aren't in the autocomplete. If the tag you enter has been used on the Archive but is not marked canonical, then the filters will look for works that use the exact tag you've entered. If the tag you've entered has never been used on the Archive, but in that case the filters will do a simple text match and may bring up unexpected results. The "Search within results" and "Search bookmarker's tags and notes" fields will text-match more accurately, especially in the case of relationship tags and other tags with "/" or other non-text characters. +

    + +

    + Choosing any tag from a category or entering a tag in the "Other work tags to exclude" or "Other bookmarker's tags to exclude" field will do an OR search with all the tags you select. This means that if you're filtering the bookmarks tagged with the F/F category, select the Major Character Death warning, the canonical Alternate Universe tag in the Additional Tags category, and enter or select the canonical tag Drama in the "Other work tags to exclude" field, only bookmarks of works or series tagged without any of these tags will be included in the results. +

    + +

    + To look up tags and see which ones are canonical, use the Tag Search. +

    + +

    + You can find more information about tags in our Tags FAQ. To read the guidelines tag wranglers use to mark tags canonical, among other things, or to better understand the AO3-specific vocabulary for tags, read the Wrangling Guidelines. +

    diff --git a/public/help/bookmark-filters-include-tags.html b/public/help/bookmark-filters-include-tags.html new file mode 100755 index 0000000..b348b3d --- /dev/null +++ b/public/help/bookmark-filters-include-tags.html @@ -0,0 +1,29 @@ +

    Tag Filters: Include Tags

    + +

    + The filters list the ten most popular tags for each tag category. To filter by any other tags, use the "Other work tags to include" and "Other bookmarker's tags to include" fields. +

    + +

    + If the tag that interests you isn't in the top ten, start entering the tag you need in either the "Other work tags to include" or "Other bookmarker's tags to include" field—all tag categories are valid here, and you can add as many tags as you want. The autocomplete will help you find the canonical version of the tag. Use these to take full advantage of the wrangled tagging structure, which will find all works using subtags and tags with synonymous meanings. +

    + +

    + You can also enter tags that aren't in the autocomplete. If the tag you enter has been used on the Archive but is not marked canonical, then the filters will look for works that use the exact tag you've entered. If the tag you've entered has never been used on the Archive, the filters will do a simple text match and may bring up unexpected results. The "Search within results" and "Search bookmarker's tags and notes" fields will text-match more accurately, especially in the case of relationship tags and other tags with "/" or other non-text characters. +

    + +

    + Choosing any tag from a category or entering a tag in the "Other work tags to include" or "Other bookmarker's tags to include" field will do an AND search with all the tags you select. This means that if you're filtering the bookmarks tagged with the F/F category, select the Teen and Up Audiences rating, the canonical Romance tag in the Additional Tags category, and enter or select the canonical tag Drama in the "Other work tags to include" field, only bookmarks of works or series tagged with all these tags will be included in the results. +

    + +

    + To get results with Tag A OR Tag B, use the "Search within results" or "Search bookmarker's tags and notes" fields. +

    + +

    + To look up tags and see which ones are canonical, use the Tag Search. +

    + +

    + You can find more information about tags in our Tags FAQ. To read the guidelines tag wranglers use to mark tags canonical, among other things, or to better understand the AO3-specific vocabulary for tags, read the Wrangling Guidelines. +

    diff --git a/public/help/bookmark-search-bookmarker-tag.html b/public/help/bookmark-search-bookmarker-tag.html new file mode 100755 index 0000000..9dd5e39 --- /dev/null +++ b/public/help/bookmark-search-bookmarker-tag.html @@ -0,0 +1,5 @@ +

    Bookmark Search: Bookmarker's Tags

    + +

    + The "Bookmarker's tags" field searches all tags added to a bookmark. This does not include tags on the bookmarked series or work itself. Tags can be any of the following: Rating, Warning, Category, Fandom, Character, Relationship, Additional Tags. The field will suggest canonical tags as you enter search terms. +

    diff --git a/public/help/bookmark-search-date-bookmarked-help.html b/public/help/bookmark-search-date-bookmarked-help.html new file mode 100755 index 0000000..547c353 --- /dev/null +++ b/public/help/bookmark-search-date-bookmarked-help.html @@ -0,0 +1,18 @@ +

    Bookmark Search: Date Bookmarked

    + +

    Specify a range of times to find bookmarks which were created during that time frame. This may differ from the time when the bookmarked item was posted or updated.

    + +

    You can search by year, month, week, day, or hour.

    + +

    Examples:
    + +
    +
    < 3 days ago
    +
    will find bookmarks that were created within the past three days
    +
    > 3 years ago
    +
    will find bookmarks that were created more than three years ago
    +
    3-9 months ago
    +
    will find bookmarks that were created between 3 and 9 months ago
    +
    + +

    The "ago" is optional. Note that "1 day ago" is not a range, and would only find bookmarks created at this exact instant yesterday. Create a range instead.

    diff --git a/public/help/bookmark-search-date-updated-help.html b/public/help/bookmark-search-date-updated-help.html new file mode 100755 index 0000000..48eaea9 --- /dev/null +++ b/public/help/bookmark-search-date-updated-help.html @@ -0,0 +1,18 @@ +

    Bookmark Search: Date Updated

    + +

    Specify a range of times to find bookmarked items that were posted or updated during that time frame: works with new chapters, for example, or series with new works. If a work was backdated by its creator (i.e. had a different publication date set when it was uploaded to the Archive), that date will be used for this search.

    + +

    You can search by year, month, week, day, or hour.

    + +

    Examples:
    + +
    +
    < 3 days ago
    +
    will find bookmarks of works that were posted or updated within the past three days
    +
    > 3 years ago
    +
    will find bookmarks of works that were posted or updated more than three years ago
    +
    3-9 months ago
    +
    will find bookmarks of works that were posted or updated between 3 and 9 months ago
    +
    + +

    The "ago" is optional. Note that "1 day ago" is not a range, and would only find items updated at this exact instant yesterday. Create a range instead.

    diff --git a/public/help/bookmark-search-notes-help.html b/public/help/bookmark-search-notes-help.html new file mode 100755 index 0000000..72c1033 --- /dev/null +++ b/public/help/bookmark-search-notes-help.html @@ -0,0 +1,3 @@ +

    Bookmark Search: With Notes

    + +

    Select this option if you want to limit the search to bookmarks with a note added by the bookmarker.

    \ No newline at end of file diff --git a/public/help/bookmark-search-rec-help.html b/public/help/bookmark-search-rec-help.html new file mode 100755 index 0000000..f38da12 --- /dev/null +++ b/public/help/bookmark-search-rec-help.html @@ -0,0 +1,3 @@ +

    Bookmark Search: Rec

    + +

    Select this option if you want to limit the search to bookmarks which were marked as recs by the bookmarker.

    diff --git a/public/help/bookmark-search-results-help.html b/public/help/bookmark-search-results-help.html new file mode 100755 index 0000000..16ff0e5 --- /dev/null +++ b/public/help/bookmark-search-results-help.html @@ -0,0 +1,3 @@ +

    Bookmarks Search: Results

    + +

    Results are sorted by relevance. Please note that the list will include all bookmarks for a work, as each bookmark is factored into the results individually. To search for works instead of bookmarks, use the Work Search.

    diff --git a/public/help/bookmark-search-text-help.html b/public/help/bookmark-search-text-help.html new file mode 100755 index 0000000..584f577 --- /dev/null +++ b/public/help/bookmark-search-text-help.html @@ -0,0 +1,18 @@ +

    Bookmark Search: Text

    + +

    Use the following guidelines for entering search terms and search operators. "Any field" combines all text fields in the search form, including tags. "Bookmarker" lets you search for bookmarks created by a particular user. "Notes" searches for terms within all bookmarkers' notes.

    + +

    The characters ":" and "@" have special meanings. Leave them out of your search or you will get unexpected results.

    + +
    +
    *: any characters
    +
    book* will find book and books and booking.
    +
    space: a space acts like AND
    +
    Harry Potter will find Harry Potter and Harry James Potter but not Harry.
    +
    ||: OR (not exclusive)
    +
    Harry || Potter will find Harry, Harry Potter, and Potter.
    +
    "": words in exact sequence
    +
    "Harry Lockhart" will find Harry Lockhart but not Harry Potter/Gilderoy Lockhart.
    +
    -: NOT
    +
    Harry -Lockhart will find Harry Potter but not Harry Lockhart or Gilderoy Lockhart/Harry Potter.
    +
    diff --git a/public/help/bookmark-search-type-help.html b/public/help/bookmark-search-type-help.html new file mode 100755 index 0000000..0a5b5ce --- /dev/null +++ b/public/help/bookmark-search-type-help.html @@ -0,0 +1,7 @@ +

    Bookmark Search: Type

    + +

    + Select the type of bookmarked item to limit your search results to Work, + Series, or External Work. Note that selecting External Work will return any + bookmarks for works hosted off the Archive. +

    diff --git a/public/help/bookmark-search-work-tag.html b/public/help/bookmark-search-work-tag.html new file mode 100755 index 0000000..fa1ea7d --- /dev/null +++ b/public/help/bookmark-search-work-tag.html @@ -0,0 +1,5 @@ +

    Bookmark Search: Work Tags

    + +

    + The "Work tags" field searches all tags added to a bookmarked item by the item's creator. This does not include tags added by the bookmarker. Tags can be any of the following: Rating, Warning, Category, Fandom, Character, Relationship, Additional Tags. The field will suggest canonical tags as you enter search terms. +

    diff --git a/public/help/bookmark-symbols-key.html b/public/help/bookmark-symbols-key.html new file mode 100755 index 0000000..c40c329 --- /dev/null +++ b/public/help/bookmark-symbols-key.html @@ -0,0 +1,11 @@ +

    Bookmark symbols

    +
    +
    Rec
    +
    Rec
    +
    Public Bookmark
    +
    Public Bookmark
    +
    Private Bookmark
    +
    Private Bookmark
    +
    Bookmark Hidden by Admin
    +
    This bookmark has been hidden by an admin
    +
    diff --git a/public/help/categories-help.html b/public/help/categories-help.html new file mode 100755 index 0000000..a6d6c33 --- /dev/null +++ b/public/help/categories-help.html @@ -0,0 +1,21 @@ +

    Category Tags

    + +

    (For more information, see the Tags on the Archive FAQ.)

    + +

    There are 6 categories of works on the Archive. While here we have given an interpretation of the abbreviations, the exact definitions of these vary from fandom to fandom and fan to fan; use whichever you feel are applicable, or else none:

    + +
    +
    F/F
    +
    Female/Female relationships
    +
    F/NB
    +
    Female/Nonbinary relationships
    +
    NB/NB
    +
    Nonbinary/Nonbinary relationships
    +
    Multi
    +
    More than one kind of relationship, or a relationship with multiple partners
    +
    Other
    +
    Other relationships
    +
    + diff --git a/public/help/challenge-any.html b/public/help/challenge-any.html new file mode 100755 index 0000000..094963c --- /dev/null +++ b/public/help/challenge-any.html @@ -0,0 +1,28 @@ +

    Choosing Any

    + +

    + If you choose "Any" for a field when you are filling out your sign-up, that means that you will be matched + on this field NO MATTER WHAT -- so this is potentially risky! Please be sure that you really mean ANY! + Even if you also fill out the field, the "Any" option will override anything else you put in there. +

    + +
    Some examples
    + +

    Offering any:

    +
      +
    • You offer the fandom "Twin Peaks" and choose "Any" for relationships.
    • +
    • Mary Sue requests "Twin Peaks" as her fandom and the relationship "Log Lady/Llama"
    • +
    • You can match Mary Sue and will be expected to write a story about the epic love of the Llama and the Log Lady.
    • +
    + +

    Requesting any: (this is often especially confusing!)

    +
      +
    • Mary Sue offers the fandom "Twin Peaks" and the relationship "Log Lady/Llama"
    • +
    • You request the fandom "Twin Peaks" and choose "Any" for relationships.
    • +
    • Mary Sue may be assigned your request and the only thing she will write for you is an epic tale of the Log Lady and the Llama.
    • +
    + +

    + Your challenge moderator may choose to only allow the "Any" option for offers, or only for certain fields. +

    + \ No newline at end of file diff --git a/public/help/challenge-assignments.html b/public/help/challenge-assignments.html new file mode 100755 index 0000000..9555bee --- /dev/null +++ b/public/help/challenge-assignments.html @@ -0,0 +1,32 @@ +

    Challenge Assignments

    + +

    + You can review the assignments for your challenge in several different categories. +

    + +
    +
    Defaulted
    +
    The most urgent: the assigned person has defaulted and + the recipient needs a substitute (a "pinch hitter") assigned.
    + +
    Pinch Hits
    +
    You've assigned a pinch hitter.
    + +
    Open
    +
    The assigned person hasn't posted their work yet, or + you haven't approved their work (if your collection is moderated).
    + +
    Complete
    +
    The work has been posted (and approved if your collection is moderated).
    +
    + +

    + If a work is posted that does not meet your challenge standards, you can remove it from the collection under the + Manage Items page and the work will be removed from the listing, at which point you will be able to + come back to the assignments page and mark the writer as having defaulted. +

    + +

    + NOTE: if your collection is unrevealed or + anonymous, removing the work from the collection will cause it to be revealed! +

    diff --git a/public/help/challenge-category-tags.html b/public/help/challenge-category-tags.html new file mode 100755 index 0000000..5cfe736 --- /dev/null +++ b/public/help/challenge-category-tags.html @@ -0,0 +1,64 @@ +

    Categories

    + +

    + Here you can enter the number of relationships or orientations allowable per + request. Refer to the below for example types. +

    + +
    +
    + Second Square +
    +
    +

    Relationships and orientations

    +
    +
    + Femslash +
    +
    + F/F: female/female relationships +
    +
    + Het +
    +
    + F/M: male/female relationships +
    +
    + Gen +
    +
    + Gen: no romantic or sexual relationships +
    +
    + Slash +
    +
    + M/M: male/male relationships +
    +
    + Multi +
    +
    + Multi: more than one kind of the relationships listed here +
    +
    + Other +
    +
    + Other relationships +
    +
    + None +
    +
    + The work was not put in any categories +
    +
    +
    +
    diff --git a/public/help/challenge-include-optional-tags.html b/public/help/challenge-include-optional-tags.html new file mode 100755 index 0000000..4a729d9 --- /dev/null +++ b/public/help/challenge-include-optional-tags.html @@ -0,0 +1,28 @@ +

    Include Optional Tags

    + +

    + If you choose this option, then any optional tags you allowed people to set will be used to fulfill + required matches on this field. Otherwise, matches on optional tags will only be used to increase the ranking + of the match. +

    + +
    Example:
    + +

    + A challenge requires people to offer and request two fandoms, but also allows them to enter extra fandoms in the optional tags. + The moderator promises assignments will match on at least one fandom (and therefore chooses "1" as the number of required fandoms to match). +

    + +
      +
    • Jane signs up and requests Smallville and Queer As Folk UK. In her optional tags, she also lists Sesame Street.
    • + +
    • Bob signs up and offers Sesame Street and Project Runway.
    • + +
    • Sue signs up and offers Smallville and American Idol RPF. She also offers Sesame Street in her optional tags.
    • +
    + +

    + If the moderator turns on "include optional tags" for fandoms, then both Bob and Sue will be potential matches for Jane. + Otherwise, only Sue will match with Jane. + In both cases, Sue will be ranked as a better match because she also matches Jane in her optional tags. +

    diff --git a/public/help/challenge-matching-assignments.html b/public/help/challenge-matching-assignments.html new file mode 100755 index 0000000..5764b1d --- /dev/null +++ b/public/help/challenge-matching-assignments.html @@ -0,0 +1,89 @@ +

    Matching

    + +

    The matching process for gift exchanges runs in two stages:

    +
    +
    Potential Matching
    +
    All the sign-ups are compared and for each person we generate a list of potential givers (people who can give them a gift), and potential recipients (people they can give a gift to). This is the slowest part of the process and can take as much as a day for a very large challenge or one where almost all the participants match each other.
    + +
    Assignments
    +
    We try to give everyone a single assignment, starting with the people who have the fewest potential givers or recipients and working up until no one else can be assigned. This process is relatively fast; it generally completes within an hour.
    +
    + +

    You may have to decide how to fix several issues that can come up during matching.

    + +

    No Potential Recipients/No Potential Givers

    + +

    If someone has no potential recipients, that means no one wants what they are offering. There is no way to fix this unless the person agrees to + offer something else that someone has requested. If they do, you can edit their sign-up and then regenerate their potential matches.

    + +

    If someone has no potential givers, no one has offered what they want. You can try to find a pinch hitter for them if you prefer. Otherwise, + just as above, ask them to request something else, edit their sign-up, and then regenerate their potential matches.

    + +

    Regenerating Potential Matches

    + +

    Because regenerating ALL potential matches for everyone in your challenge is very slow, it is better to regenerate potential matches just for + each individual person who has no potential matches, which will most likely only take a few minutes. Just do them one at a time, please!

    + +

    If you have several people with no potential matches, once you have regenerated potential matches for them, you may want to + regenerate assignments to have the archive try to assign them along with everyone else. Note that this will very likely change the assignments for + EVERYONE.

    + + +

    Assignment Issues

    + +

    Once you have potential matches for everyone, the remaining problems will be with getting everyone assigned.

    + +

    No Giver

    + +

    These people could not be assigned a giver. You can shuffle the main assignments to free someone up, or you can write-in + a volunteer. If you click in the Giver field, you'll see a list of the people who could write for each person. + Note: the form will allow you to double-assign people, but remember to make sure they can write two assignments first! + (See "Duplicate Givers" below.) +

    + +

    No Recipient

    + +

    These people haven't been assigned a recipient. If you click in the Recipient field, you'll see a list of the + people that each one could write for. You can try shuffling the completed assignments to free up one of them, + or you can double-assign a recipient. (See "Duplicate Recipients" below.) + The newly matched people will disappear from this section after you update. +

    + +

    Duplicate Recipients

    + +

    + You will see the duplicate recipients listing appear if you assign a person as recipient to more than one + person. This is not necessarily a problem, they will just get more than one gift. +

    + +

    + You might deliberately want to keep duplicate recipients. Sometimes in a gift exchange, it may not be possible to get everyone + assigned one on one. Instead of shuffling to try and match everybody, you can instead recruit a few pinch hitters for the + people who don't have an assigned writer, and double-assign recipients for the people who don't have a request of their own. +

    + +

    + As far as the people getting the assignment are concerned, there is nothing different about getting a + double-assigned recipient. The recipient will just have two + givers, and assuming neither one defaults, will get two gifts instead of one. +

    + +

    Duplicate Givers

    + +

    + You will see the duplicate givers listing appear if you assign a person as giver to more than one person. + This is not a problem as long as the assigned givers are in fact willing to get more than one assignment. + However, for housekeeping purposes, you might only want one of these listings to be their "official" assignment. + If so, you can delete their name from the "Giver" column and move their name into the "Write-In" field + (in which case they will be listed on those other assignment as a pinch hitter). +

    + +

    Shuffling Assignments

    + +

    Finally, even if everyone has a recipient and a giver, you may still want to shuffle assignments around in order to + give people better matches. You can do so as much as you want.

    + +

    Please note that circular matches (where A is assigned to B and B is assigned to A) + will happen sometimes randomly. You can try and reshuffle by hand if you want to avoid these. +

    + diff --git a/public/help/challenge-matching.html b/public/help/challenge-matching.html new file mode 100755 index 0000000..1b9e709 --- /dev/null +++ b/public/help/challenge-matching.html @@ -0,0 +1,26 @@ +

    Matching

    + +

    The matching process for gift exchanges runs in two stages:

    +
    +
    Potential Matching
    +
    All the sign-ups are compared and for each person we generate a list of potential givers (people who can give them a gift), and potential recipients (people they can give a gift to). This is the slowest part of the process and can take as much as a day for a very large challenge or one where almost all the participants match each other.
    + +
    Assignments
    +
    We try to give everyone a single assignment, starting with the people who have the fewest potential givers or recipients and working up until no one else can be assigned. This process is relatively fast; it generally completes within an hour.
    +
    + +

    You may have to decide how to fix several issues that can come up during matching.

    + +

    Potential Match Issues

    + +

    Invalid Sign-ups

    + +

    Sometimes a challenge can end up with one or more invalid sign-ups -- duplicates, or sign-ups that have too many or too few offers/requests or ones that don't fit the rules of your challenge. Most commonly, this happens if someone clicks submit or update multiple times because their connection to the archive is slow. It can also happen if you have changed the rules of +your challenge partway through the sign-up process -- read further for details about this.

    + +

    If this happens, potential matching won't run, and you'll be quickly emailed a list of links to the invalid sign-ups so you can examine them. You can often tell easily when two sign-ups or offers/requests are duplicates, in which case you can just delete the duplicates. Sometimes you may have to contact a participant to figure out which of the sign-ups or prompts they want to use.

    + +

    If on the other hand you made the rules more strict mid-stream and you have a large number of invalid sign-ups as a result, you may only be able to fix this by easing your rules to match the lowest common denominator. For instance, if you started by requiring 2 offers and 2 requests, and then upped the requirement to 3 offers and 3 requests a day into sign-up, you may have a whole slew of sign-ups that only have 2/2 and are now therefore considered invalid. To fix this, you'll have to change your challenge settings back to only requiring 2/2, while allowing 3/3.

    + +

    After you have dealt with all the invalid sign-ups, you can then start matching again.

    + diff --git a/public/help/challenge-optional-tags-user.html b/public/help/challenge-optional-tags-user.html new file mode 100755 index 0000000..f9cc047 --- /dev/null +++ b/public/help/challenge-optional-tags-user.html @@ -0,0 +1,8 @@ +

    Optional Tags

    + +

    + Optional tags will be used by the moderator to try and improve matching, but may be discarded completely if + necessary to make a match. This is a good place to add more obscure and specific tags. + Note that the more tags you enter, the more likely it is your optional tags will have to be ignored, + and the slower matching runs, so don't go nuts! +

    diff --git a/public/help/challenge-optional-tags.html b/public/help/challenge-optional-tags.html new file mode 100755 index 0000000..ef30fa7 --- /dev/null +++ b/public/help/challenge-optional-tags.html @@ -0,0 +1,18 @@ +

    Optional Tags

    + +

    + By default, you set a number of tags (and if you want, a selection of specific tags) that people can use in their + requests -- for example, maybe you allow people to request a fandom and two characters. Optional tags add an extra + option to the sign-up page: the person signing up can put any canonical tags they want, of any kind, into the optional box. +

    + +

    + For a gift exchange, you don't want to offer too many ordinary tags, because that will make it harder to match people up, + especially if you promise an exact match on all the tags (you can of course also just promise as good a match as possible). +

    + +

    + Optional tags are useful if you want to try and let your challenge members match up on more detailed or obscure requests, + but want to ensure you can match without too much pain. The matching process will try to match + people on these optional tags, but if it can't, it will fall back to the basic tags. +

    diff --git a/public/help/challenge-pinch-hitter.html b/public/help/challenge-pinch-hitter.html new file mode 100755 index 0000000..e83626e --- /dev/null +++ b/public/help/challenge-pinch-hitter.html @@ -0,0 +1,6 @@ +

    Pinch Hitters

    + +

    + A pinch hitter does NOT need to be signed up for the challenge. Anyone with an archive account can be assigned. + You should probably make sure they are willing to write the assignment first, though! :) +

    diff --git a/public/help/challenge-requests-summary.html b/public/help/challenge-requests-summary.html new file mode 100755 index 0000000..deb4d58 --- /dev/null +++ b/public/help/challenge-requests-summary.html @@ -0,0 +1,8 @@ +

    Public Sign-up Summary

    + +

    + If you choose this option, all users will be able to view the requests that have been made for your challenge. + This can encourage people to make matching offers or write extra stories for participants, but does create + spoilers for requests. You may want to only turn this on later, after your exchange has finished, in order to let users write + unfilled requests. +

    diff --git a/public/help/chapter-title.html b/public/help/chapter-title.html new file mode 100755 index 0000000..26d3e9f --- /dev/null +++ b/public/help/chapter-title.html @@ -0,0 +1,3 @@ +

    Chapter Title

    + +

    You can add a chapter title, but it's not required.

    \ No newline at end of file diff --git a/public/help/characters-help.html b/public/help/characters-help.html new file mode 100755 index 0000000..4a57d37 --- /dev/null +++ b/public/help/characters-help.html @@ -0,0 +1,6 @@ +

    Characters Tags

    + +

    (For more information, see the Tags on the Archive FAQ.)

    + +

    The main character(s) in your work, separated by commas. Full names (personal name and family name) are preferred.

    + diff --git a/public/help/choosing-series.html b/public/help/choosing-series.html new file mode 100755 index 0000000..3add103 --- /dev/null +++ b/public/help/choosing-series.html @@ -0,0 +1,11 @@ +

    Choosing Series

    + +

    + A series is a set of related stories, each of which is complete on its own. + You can make new series or add stories to your series anytime you like + from inside your dashboard. +

    +

    + If you'd like to post a work in progress, or a story with chapters, you + probably want a chaptered story instead. +

    \ No newline at end of file diff --git a/public/help/collection-closed.html b/public/help/collection-closed.html new file mode 100755 index 0000000..bfb2988 --- /dev/null +++ b/public/help/collection-closed.html @@ -0,0 +1,7 @@ +

    Closed Collection

    + +

    +Once a collection is closed, no works or bookmarks can be added to it, except by the maintainers (owners and moderators). +If this is a gift exchange or other challenge, note that this won't be automatically triggered by any deadlines you set in your challenge settings, +but has to be manually set here. +

    diff --git a/public/help/collection-moderated.html b/public/help/collection-moderated.html new file mode 100755 index 0000000..4b7e642 --- /dev/null +++ b/public/help/collection-moderated.html @@ -0,0 +1,18 @@ +

    Moderated Collection

    + +

    + By default, collections are not moderated, which means any registered user of the Archive can add + their works to the collection. The owners/moderators of the collection can still reject stories + after they have been posted, if they are not appropriate. +

    + +

    + If you set your collection to be moderated, all registered users will still be able to post, but their + stories will not appear in the collection until they are approved by a moderator or owner. Approved + members will be able to post automatically without manual approval. +

    + +

    + Owners of a collection can edit the collection preferences and data, and also delete the collection + entirely. Moderators of a collection can approve/invite members and add/reject stories. +

    diff --git a/public/help/collection-name.html b/public/help/collection-name.html new file mode 100755 index 0000000..52bb72f --- /dev/null +++ b/public/help/collection-name.html @@ -0,0 +1,9 @@ +

    Collection Name

    + +

    + The name of the collection can be changed at a later point, but that will break links to the collection. +

    +

    + The name can consist only of ASCII letters (a-z, A-Z), numbers and underscores, and cannot contain spaces. +

    + \ No newline at end of file diff --git a/public/help/collection-preferences.html b/public/help/collection-preferences.html new file mode 100755 index 0000000..7c2b13b --- /dev/null +++ b/public/help/collection-preferences.html @@ -0,0 +1,32 @@ +

    Collections, Challenges and Gifts Preferences

    + +
    + +
    Allow others to invite my works to collections
    +
    +

    + Enabling this option will allow other AO3 users to invite your work into + their collection. Your work won't be added to the collection until you + have accepted the request. For more information on accepting collection + invitations, refer to How do I approve or reject an invitation to include my work in a collection? +

    +

    + Leaving this option disabled will prevent other users from inviting your + works into their collections at all, and you won't receive any + notifications. +

    +

    Changing this setting won't affect any existing works in collections.

    +
    + +
    Allow anyone to gift me works
    +
    If this option is disabled, users are only able to give a gift work to you if they're completing a gift exchange assignment or fulfilling a claimed prompt in a prompt meme. If you'd like to allow users to give you gift works outside of assignments and claimed prompts, enable this option. Note that you're always able to refuse gifts individually. Check out How do I refuse a gift? for instructions.
    + +
    Turn off emails from collections
    +
    Enable this option if you would prefer not to receive email alerts from collections, such as creator and work reveals. We'll still email you if your username or work is hidden after being added to a collection. Notifications will still be delivered to your Archive inbox unless you have chosen to disable them.
    + +
    Turn off inbox messages from collections
    +
    Enable this option if you would prefer not to receive notifications in your Archive inbox from collections, for example, notifying you when hidden works are revealed. Notifications will still be emailed to you unless you have chosen to disable them.
    + +
    Turn off emails about gift works
    +
    Enable this option if you would prefer not to receive email alerts when someone gifts a work to you. Notifications will still be displayed on your Gifts page.
    +
    diff --git a/public/help/comment-preferences.html b/public/help/comment-preferences.html new file mode 100755 index 0000000..62325d7 --- /dev/null +++ b/public/help/comment-preferences.html @@ -0,0 +1,14 @@ +

    Comment Preferences

    + +
    +
    Turn off emails about comments
    +
    Enable this option if you would prefer not to receive email alerts when someone comments on your work or replies to a comment you have made. Comment notifications will still be delivered to your Archive inbox unless you have chosen to disable them.
    +
    Turn off messages to your inbox about comments
    +
    Enable this option if you would prefer not to receive notifications in your Archive inbox when someone comments on your work or replies to a comment you have made. Comment notifications will still be emailed to you unless you have chosen to disable them.
    +
    Turn off copies of your own comments
    +
    Enable this option if you prefer not to receive emails for your own comments (for example, when you reply to comments on your own works).
    +
    Turn off emails about kudos
    +
    Enable this option if you would prefer not to receive email notifications when someone leaves kudos on your work.
    +
    Do not allow guests to reply to my comments on news posts or other users' works
    +
    Enable this option if you would prefer not to receive replies from users who aren't logged in to an Archive account on comments you leave on news posts or other creators' works. This setting doesn't apply to comments on your own works; for more on controlling who can interact with you on your works check out the Posting and Editing FAQ.
    +
    diff --git a/public/help/comments-moderated.html b/public/help/comments-moderated.html new file mode 100755 index 0000000..63a3e5e --- /dev/null +++ b/public/help/comments-moderated.html @@ -0,0 +1,2 @@ +

    Comments Moderated

    +

    With this feature enabled, you will have to approve all comments before they appear publicly on your work.

    diff --git a/public/help/csv-download.html b/public/help/csv-download.html new file mode 100755 index 0000000..3cefb55 --- /dev/null +++ b/public/help/csv-download.html @@ -0,0 +1 @@ +To open the file properly, you might need to tell your program that the file is TAB-separated. In Open Office and Neo Office, for example, choose the TAB separator in the File Open Wizard. In Google Docs, use "Import" instead of "Open" to be able to set the separator to TAB. diff --git a/public/help/display-preferences.html b/public/help/display-preferences.html new file mode 100755 index 0000000..621e791 --- /dev/null +++ b/public/help/display-preferences.html @@ -0,0 +1,24 @@ +

    Display Preferences

    + +
    +
    Show me adult content without checking
    +
    + When this option is enabled, you won't be asked to confirm that you wish to access works rated Mature, Explicit or Not Rated before the work is displayed. +
    +
    Show the whole work by default
    +
    + When this option is enabled, works with multiple chapters will display as a single page. +
    +
    Hide warnings (you can still choose to show them)
    +
    + When this option is enabled, Archive warning tags on works will be hidden by default. You can click 'Show Warnings' to display the warnings for any individual work. You must have JavaScript enabled to use this option. +
    +
    Hide additional tags (you can still choose to show them)
    +
    + When this option is enabled, additional tags on works will be hidden by default. You can click 'Show Additional Tags' to display the tags for any individual work. You must have JavaScript enabled to use this option. +
    +
    Hide other people's work skins
    +
    + When this option is enabled, the custom skin another user has specified for their work will not be displayed. Instead your normal site skin will be applied. +
    +
    diff --git a/public/help/encoding-help.html b/public/help/encoding-help.html new file mode 100755 index 0000000..a7b67fb --- /dev/null +++ b/public/help/encoding-help.html @@ -0,0 +1,6 @@ +

    Encoding Help

    + +

    If you find that the importer strips special characters (such as umlauts or curly quotes) from your work, or fails to import whole chunks of text, there might be a problem with the automatic detection of your work's encoding. UTF-8 is a common encoding, but there are others that you might have to manually put in to help the importer handle your work.

    + +

    If you're unsure what encoding your text is using, try ISO-8859-1 (often called Latin-1) or Windows-1252 (sometimes wrongly called ANSI), both of which + are very common in the output from Windows programs.

    \ No newline at end of file diff --git a/public/help/fandom-help.html b/public/help/fandom-help.html new file mode 100755 index 0000000..fe0df50 --- /dev/null +++ b/public/help/fandom-help.html @@ -0,0 +1,5 @@ +

    Fandom Tags

    + +

    The name(s) of the fandom(s) to which your work belongs. Full names, rather than abbreviations, are preferred. You may list multiple fandoms, separated by commas (for example, if your work is a crossover).

    + +

    For more information regarding Tags, including how to add tags not currently on the Archive, please read our Tags FAQ.

    diff --git a/public/help/fr/choosing-series.html b/public/help/fr/choosing-series.html new file mode 100755 index 0000000..2ec32db --- /dev/null +++ b/public/help/fr/choosing-series.html @@ -0,0 +1,5 @@ +

    Choix de Series

    + +

    + French version of the help goes here! +

    diff --git a/public/help/html-help.html b/public/help/html-help.html new file mode 100755 index 0000000..b11c5e6 --- /dev/null +++ b/public/help/html-help.html @@ -0,0 +1,87 @@ +

    HTML on the Archive

    + +

    Allowed HTML

    +

    + a, abbr, acronym, address, [align], [alt], [axis], b, big, blockquote, br, caption, center, cite, [class], code, + col, colgroup, dd, del, details, dfn, div, dl, dt, em, figcaption, figure, h1, h2, h3, h4, h5, h6, [height], hr, [href], i, img, + ins, kbd, li, [name], ol, p, pre, q, rp, rt, ruby, s, samp, small, span, [src], strike, strong, sub, summary, sup, table, tbody, td, + tfoot, th, thead, [title], tr, tt, u, ul, var, [width] + +

    + +

    How Do We Format Your HTML?

    + +

    + When you enter HTML into the archive, we do some cleanup on it to make sure that it is safe + (so spammers and hackers cannot upload badness) and try and do some basic formatting both for + your convenience and for accessibility reasons. Here are the formatting steps we take: +

    + +
      +
    • If you leave a blank line between two paragraphs, we will put paragraph tags in for you around the two paragraphs.
    • +
    • If you have a single carriage return between two lines of text, we will put in a break tag for you.
    • +
    • If you have two break tags in a row (<br /><br />) with nothing between them, we will turn that into paragraph tags.
    • +
    • If you have two blank lines in a row between paragraphs, we will add extra whitespace in for you (with <p>&nbsp;</p>)
    • +
    • If you have mis-nested tags like this: <em><strong>text!</em></strong> we will fix the mis-nesting + (so it would become <em><strong>text!</strong></em>).
    • +
    • If you have forgotten to close a formatting tag, it will be closed at the end of the paragraph for you.
    • +
    • If you open a formatting tag in one paragraph and close it several paragraphs later, we will reopen/close it within each paragraph.
    • +
    • If you have put in some custom HTML (eg a list of items inside a <ul>) and you don't want break tags or paragraphs inserted, + just put it all on one line (sorry, this is the inconvenient tradeoff for automatically doing the paragraph/break tags).
    • +
    • If one bit of your text shows up larger than the rest, probably our formatter couldn't figure out to put paragraph tags around it. + You can fix this by manually putting in the paragraph tags around that one bit.
    • +
    + +

    + When you edit your HTML after you first put it in, you will see the results of our formatting work, so you can + correct any mistakes our formatter might have made. Please note that the best way to get good results is to put + in good HTML -- that is how you can be sure your story will look right across various browsers, + screen readers, mobile devices, and downloads. +

    + +

    + Good HTML means HTML that labels what the text is supposed to be -- so if you have + paragraphs, they should be inside paragraph tags, not just separated with break tags. If you have emphasized + text, it should be inside em tags. If you have a list of items, each item should be inside list tags. If you + don't have a list of items, you shouldn't have list tags. :) + (We are putting together a set of more detailed helpful references about this, but this is the basic idea.) +

    + +

    + If you find yourself putting in HTML that doesn't mean the right thing, in order to get a particular visual effect, + please resist! + The work skin feature allows you to apply custom CSS to works, and that lets you make them look + just about any way you want them to (and is easier if you are starting from good HTML). +

    + +

    Some specific recommendations:

    + +
    +
    For headings, use heading tags: h1, h2, h3, h4, h5, h6
    +
    +
      +
    • <h1>Title<h1>

    • +
    • <h2>Subtitle<h2>

    • +
    • <h3>Chapter title<h3>

    • +
    • <h4>Scene title<h4>

    • +
    • <h5>Subtitle<h5>
    • +
    • <h6>Footnote title<h6>
    • +
    +
    +
    For emphasis, use emphasis tags em, strong
    +
    +
      +
    • <em>Rodney</em> McKay

    • +
    • I will <strong>never</strong> understand you!

    • +
    +
    +
    To quote poetry, phrases or titles use quote tags: blockquote, q, cite
    +
    +
      +
    • <blockquote>

      To quote a block of text

      </blockquote>
    • +
    • Use q to <q>To quote a phrase</q>

    • +
    • Try cite to cite <cite>a phrase or title</cite>

    • +
    +
    +
    + diff --git a/public/help/icon-alt-text.html b/public/help/icon-alt-text.html new file mode 100755 index 0000000..cc2a0e4 --- /dev/null +++ b/public/help/icon-alt-text.html @@ -0,0 +1,10 @@ +

    Icon Alt Text

    + +

    + The purpose of alt text is to explain the meaning of an image if the image isn't showing. This is used by people browsing with images turned off, or visually impaired people using screenreader technology. + Please do not use alt text for attribution! +

    + +

    + For example, the AO3 logo has the following alt text: "Archive of Our Own". +

    diff --git a/public/help/languages-help.html b/public/help/languages-help.html new file mode 100755 index 0000000..26c3a29 --- /dev/null +++ b/public/help/languages-help.html @@ -0,0 +1,4 @@ +

    Languages

    + +

    Your language is not on the list? Please let us know via the Support form and we'll be happy to add it! +(Not to worry, you can post your work now and still change the language later.) You are not required to select a language for an external work.

    diff --git a/public/help/locale-preferences.html b/public/help/locale-preferences.html new file mode 100755 index 0000000..64d881c --- /dev/null +++ b/public/help/locale-preferences.html @@ -0,0 +1,8 @@ +

    Locale Preferences

    + +
    +
    Set preferred locale
    +
    +This preference allows you to select your preferred language for email messages that the Archive sends to you. The templates for these messages are currently being updated and translated by our volunteers. This is a work in progress; not all messages will be available in languages other than English at this time. If the template for that email has not yet been translated to your language, it will be sent in English. +
    +
    diff --git a/public/help/misc-preferences.html b/public/help/misc-preferences.html new file mode 100755 index 0000000..48b89cc --- /dev/null +++ b/public/help/misc-preferences.html @@ -0,0 +1,13 @@ +

    Miscellaneous Preferences

    + +
    + +
    Turn on History
    +
    When enabled, History keeps a log of every work you access on the Archive while logged in. You can delete individual works from your History or clear the whole History. If you enable this option and subsequently disable it, works accessed while the option was enabled will still be saved (but you will have to enable History again to see them).
    + +
    Turn the new user help banner back on
    +
    Enabling this option will turn on the banner offering information and hints on getting started with the Archive!
    + +
    Turn off the banner showing on every page
    +
    Occasionally, Archive staff may notify users of important events or site changes by displaying a banner across all pages on the site. If you want to dismiss the banner while you're logged in, enable this option. Please note that this only hides the banner which was displaying at the time you enabled this option. If the banner is changed, the new banner will be displayed until you enable this option again.
    +
    diff --git a/public/help/parent-works-help.html b/public/help/parent-works-help.html new file mode 100755 index 0000000..bd65f95 --- /dev/null +++ b/public/help/parent-works-help.html @@ -0,0 +1,10 @@ +

    Parent Works Help

    + +

    +If you are creating a new work, you can add only one inspiration now. +If you want to add more, save your work first, then click "Edit" on your posted work and add the new inspiration like the previous one. +

    + +

    +All the works you have added as inspirations will be listed below this form under the label "Current parent works". +

    \ No newline at end of file diff --git a/public/help/people-search-all-fields.html b/public/help/people-search-all-fields.html new file mode 100755 index 0000000..04a3b3a --- /dev/null +++ b/public/help/people-search-all-fields.html @@ -0,0 +1,20 @@ +

    People Search: Search All Fields

    + +

    + Enter text in "Search all fields" to find people with usernames, pseuds, or pseud descriptions containing your search terms. +

    + +

    + The characters ":" and "@" have special meanings. Leave them out of your search or you will get unexpected results. +

    + +
    +
    *: any characters
    +
    User* will find User and Users and Username.
    +
    space: a space acts like AND
    +
    A. User will find A. User and A. Test User but not User.
    +
    |: OR (not exclusive)
    +
    A. | User will find A., A. User, and User.
    +
    ": words in exact sequence
    +
    "A. User" will find "A. User" but not A. Test User.
    +
    diff --git a/public/help/privacy-preferences.html b/public/help/privacy-preferences.html new file mode 100755 index 0000000..0848ca4 --- /dev/null +++ b/public/help/privacy-preferences.html @@ -0,0 +1,41 @@ +

    Privacy Preferences

    + +
    +
    Hide my work from search engines when possible.
    +
    + Enabling this option will tell search engines not to index your user page, your works, or your series. Please note that not all search engines respect this setting. Pages which list your works or series - for example, the main works page - may also still be indexed. If you wish to avoid your works or series being indexed under any circumstances, we recommend that you restrict them to Archive users only. +
    +
    Hide the share buttons on my work.
    +
    +

    + This preference allows you to disable the one-click share buttons which allow others to recommend your work + on external sites like Twitter and Tumblr. +

    +

    + Please note that once you have posted a work online, it is always possible for a reader to copy and paste a link to your work + anywhere they wish -- if you want to restrict access to your work here, your best bet is to lock the work to registered users of + the Archive. +

    +
    +
    Allow others to invite me to be a co-creator.
    +
    +

    + Enabling this option will allow other AO3 users to invite you to be listed + as a co-creator on a work, chapter, or series. You won't be listed as a + co-creator anywhere on the site until you have accepted the request. If + you have this option enabled, you can find any requests you receive in + your Dashboard under "Co-Creator Requests". You will also receive an email + notifying you of the request. +

    +

    + Leaving this option disabled will prevent other users from inviting you to + be listed as a co-creator on a new work, chapter or series, and you won't + receive any notifications. +

    +

    + Changing this setting won't affect any existing shared works. +

    +
    +
    + +

    For more on your preferences and what these options mean, check out our Preferences FAQ.

    diff --git a/public/help/prompt-restriction-character-and-relationship.html b/public/help/prompt-restriction-character-and-relationship.html new file mode 100755 index 0000000..8dfa75d --- /dev/null +++ b/public/help/prompt-restriction-character-and-relationship.html @@ -0,0 +1,48 @@ +
    Tag Options: Characters and Relationships
    + +

    + Very often, you will want your users to only be able to choose from the characters or relationships that + belong to the fandom that they've chosen to sign up for. Unfortunately the archive can't figure out on its own that, + for instance, the character "Zaphod Beeblebrox" is associated with the fandom "Hitchhiker's Guide To The Galaxy". + These options are intended to help you get the results you want. +

    + +
    +
    Option 1: Nothing!
    +
    + By default, your participants will get an autocomplete that lets the user choose from the + canonical versions of character and relationship tags. + This is a quick and dirty way to ensure most of your participants will sign up for the same versions of the characters + or relationships and be matchable, even if you have so many characters/relationships that you don't want to create + a tag set. Users will have to know at least enough of the tag they want to type in to get autocomplete results, + but that is usually doable. +
    + +
    Option 2: Tag Set
    +
    + If you put character or relationship tags in your tag set, users will be given a set of checkboxes with each tag as a choice. + This set of checkboxes will NOT change based on the fandom. +
    + +
    Option 3: Fandom Only
    +
    + If you check this option, participants will only be allowed to sign up for a character or relationship that + matches the fandom they have chosen in the request. The list of characters/relationships will be a combination + of the tags that have been officially wrangled into that fandom, as well as any tag associations you have set up + for that fandom in your tag set(s) if you are using any. +
    + +
    Option 4: By Tag Set Fandom Only
    +
    + If you don't want all the wrangled characters available, then check this option, and ONLY the characters you've + associated in your tag set will be allowed. +
    + +
    + +

    + Hopefully with these options, you'll be able to find a solution for your challenge! If you run into difficulties or are confused by + the options, please contact Archive Support for help (but we are often backed up so please do allow plenty of lead time before you're + about to run your challenge if you're going to need extra help). +

    + diff --git a/public/help/prompt-restriction-tag-set.html b/public/help/prompt-restriction-tag-set.html new file mode 100755 index 0000000..35e605c --- /dev/null +++ b/public/help/prompt-restriction-tag-set.html @@ -0,0 +1,26 @@ +
    Tag Options
    + +

    + If you want to limit the tags that users can choose from when signing up, you can either use an existing + tag set or make one of your own, or a combination. Once you have the tag sets you want to use ready, you + can add them to your challenge here. +

    + +

    + Note: if you are running a challenge that is specifically for one given fandom or relationship or character, + you do NOT need to use tag sets -- just set that kind of tag to 0 tags required/allowed above. + Tag options should only be used where you want users to have a choice. +

    + +

    + The same group of tag sets is used for both requests and offers, since otherwise offers and + requests can't match against each other. (People can choose different tags in their requests and offers, but they + have to choose from the same set.) +

    + +

    + You do NOT have to specify tags for every kind of tag you have allowed. For instance, you can put in five specific fandoms, + and also allow one character tag without putting in tag options. + Then the person signing up will have to choose one of the five fandoms, but can just + type in a character tag. +

    diff --git a/public/help/pseud-icon-comment.html b/public/help/pseud-icon-comment.html new file mode 100755 index 0000000..d9bb494 --- /dev/null +++ b/public/help/pseud-icon-comment.html @@ -0,0 +1 @@ +

    You can put anything extra you have about your icon here, like credit for the maker of the icon.

    \ No newline at end of file diff --git a/public/help/rating-help.html b/public/help/rating-help.html new file mode 100755 index 0000000..8744cdc --- /dev/null +++ b/public/help/rating-help.html @@ -0,0 +1,26 @@ +

    Rating Tags

    + +

    (For more information, see the Ratings and Warnings section of the AO3 Terms of Service.)

    + +
    +
    Not Rated (Adult!)
    +
    + For searching, screening, and other Archive functions, this may get treated the same way as explicit-rated content. In reality, it could be anything from porn to completely family-friendly stuff. Choose this rating if you prefer not to rate your content (because you don't like ratings, because you're trying to avoid spoilers, etc.). +
    +
    General Audiences
    +
    + This content is suitable for anyone. +
    +
    Teen And Up Audiences
    +
    + The content may be inappropriate for audiences under 13. +
    +
    Mature (Adult!)
    +
    + This is for content with adult themes (sex, violence, etc.) that isn't as graphic as explicit-rated content. +
    +
    Explicit (Adult!)
    +
    + This is for porn, graphic violence, etc. +
    +
    diff --git a/public/help/recipients.html b/public/help/recipients.html new file mode 100755 index 0000000..e908bb7 --- /dev/null +++ b/public/help/recipients.html @@ -0,0 +1,10 @@ +

    Recipients

    + +

    + Enter recipient names as a comma-separated list! +

    + +

    + If your story is a gift for someone else or in their honor, you can enter their name here, and it will be displayed on the work, right under the byline. + Recipients do not need to be registered users of the archive, although the autocomplete will offer you matching pseuds if there are any. We will notify registered users if they are selected as recipients of a work. +

    diff --git a/public/help/registered-users.html b/public/help/registered-users.html new file mode 100755 index 0000000..18db8ec --- /dev/null +++ b/public/help/registered-users.html @@ -0,0 +1,6 @@ +

    Registered Users

    + +

    +A registered user is a person with an Archive account. If you check this box +your story can only be viewed by a person who is logged in. +

    \ No newline at end of file diff --git a/public/help/relationships-help.html b/public/help/relationships-help.html new file mode 100755 index 0000000..5b1b3a3 --- /dev/null +++ b/public/help/relationships-help.html @@ -0,0 +1,11 @@ +

    Relationships Tags

    + +

    (For more information, see the Tags on the Archive FAQ.)

    + +

    + The relationships in your work. Full names are preferred (for example, "Mickey Mouse/Minnie Mouse" or + "Rodney McKay & John Sheppard") when possible. You may list more than one relationship, separated by commas. + Please note that all user-created tags must be 150 characters or less; if your work contains a large poly + relationship or multiple characters with long names, you may want to consider shortening these names to just first + names or surnames with initials to avoid going over the character limit while keeping the names recognizable. +

    diff --git a/public/help/required-field.html b/public/help/required-field.html new file mode 100755 index 0000000..784108e --- /dev/null +++ b/public/help/required-field.html @@ -0,0 +1,3 @@ +

    Required Field

    + +

    Please complete all fields marked with an asterisk (*).

    \ No newline at end of file diff --git a/public/help/rte-help.html b/public/help/rte-help.html new file mode 100755 index 0000000..4dae3c6 --- /dev/null +++ b/public/help/rte-help.html @@ -0,0 +1,48 @@ +

    Rich Text

    + +

    The exact behavior of the Rich Text Editor (RTE) depends on your device, browser, and operating system as well as the source you're pasting from. However, starting with a well-formatted document will help you get the most out of the RTE. Here are some general tips to ensure that as much of your formatting as possible will be retained:

    + +
      +
    • Press Enter once between paragraphs. Pressing Enter twice will insert a blank paragraph, creating additional, and likely unwanted, space between paragraphs when you paste into the RTE. The Archive uses top and bottom margins to create the appearance of a blank line between paragraphs; you can use the paragraph formatting options in your text editor to create a similar effect without adding extra <p> tags.

    • +
    • Use preset styles for headings, block quotations, code, and so on. The Styles option generally found in a text editor's Format menu will often translate into HTML tags when pasting into the RTE. Simply changing the font size, font name, or text indent to create a visual approximation of a heading or block quote will always fail.

    • +
    + +

    Pasting from Specific Text Editors

    + +

    Google Drive

    + +

    Google Drive uses inline CSS to change the alignment of text and to produce bold, italic, underline, and strikethrough formatting. Unfortunately, we cannot allow inline styles on the Archive, so only pure HTML formatting such as headings, lists, links, and tables is retained.

    + +

    In some browsers, the formatting may appear to be preserved upon pasting into the RTE, but it will be stripped by our HTML sanitizer upon previewing or posting your work.

    + +

    Scrivener

    + +

    Scrivener users will typically get better results by pasting into the HTML editor and then switching to the RTE to make changes. To copy HTML from Scrivener, do the following:

    + +
      +
    1. Go to the Edit menu
    2. +
    3. Choose Copy Special
    4. +
    5. Select either "Copy as HTML" or "Copy as HTML (Basic, using <p> and <span>)"
    6. +
    + +

    Pasting Specific Types of Formatting

    + +

    Underline and Strikethrough

    + +

    Underline and strikethrough are often produced with CSS. Because the Archive does not allow the use of inline CSS, these text styles are frequently lost when pasting.

    + +

    Pasting from web pages that use <u>, <del>, <strike>, or <s> tags will work.

    + +

    Alignment

    + +

    Text alignment is now generally achieved with CSS, and because the Archive does not allow inline CSS, alignment will often be lost when pasting.

    + +

    Pasting from sources that use the align attribute and <center> element will keep the formatting intact, but please note that the alignment buttons in the RTE cannot modify center alignment created with the <center> tag.

    + +

    Headings

    + +

    Text editors use many different styles for their heading presets. For example, selecting Heading 4 in OpenOffice produces italicized sans-serif text. Even when successfully pasting a heading into the RTE, this visual formatting is not preserved -- only the <h4> tag is. This is not a bug. HTML is designed to tell the browser what text means (e.g. "This is a heading") and not how it should be displayed (e.g. "This should be in Arial"). If you wish to modify the style of a heading or any other part of your work, please use a Work Skin.

    + +

    Indented Text

    + +

    Indented text is a purely visual effect with no HTML equivalent and will not be preserved. Please use a Work Skin to indent text.

    \ No newline at end of file diff --git a/public/help/skins-approval.html b/public/help/skins-approval.html new file mode 100755 index 0000000..32b6f07 --- /dev/null +++ b/public/help/skins-approval.html @@ -0,0 +1,11 @@ +

    Public Skins

    + +

    + AO3 is no longer adding new + user-created skins to the list of public skins, so you can't apply to make + your skin public at this time. This checkbox can only be used by site admins + to add new public site skins to our list. However, you can still make use of + the user-created skins in Public Site + Skins and Public Work Skins and + you can still create skins for your own personal use. +

    diff --git a/public/help/skins-basics.html b/public/help/skins-basics.html new file mode 100755 index 0000000..e52495d --- /dev/null +++ b/public/help/skins-basics.html @@ -0,0 +1,14 @@ +

    + A site skin lets you customize your browsing experience when you are logged in to your account. + Don't like the Archive fonts? You can change them! Don't like the red header? Swap it out for blue! + When you make a site skin, keep in mind that you are only changing the Archive for yourself -- other Archive users + will see the Archive in whatever skin they are using. In other words, site skins are useful for creating your own ideal + browsing experience, not for changing the way a work appears for others. +

    + +

    + A work skin lets you change the way one or more of your works appears to others. Work skins will only affect + the body of the work -- that is, you can't change what the Archive navigation or background look like for someone else. + What you can do, however, is create your own classes. For instance, you can change the color of some of your text, + or indent some paragraphs in a particular way, and so on. +

    diff --git a/public/help/skins-conditions.html b/public/help/skins-conditions.html new file mode 100755 index 0000000..0796f66 --- /dev/null +++ b/public/help/skins-conditions.html @@ -0,0 +1,92 @@ +

    Skin Conditions

    + +

    + If you want a certain chunk of CSS loaded only in particular situations, you can create a skin with a specific set of conditions. + We'll load that skin only when needed. The conditions we have available are: +

    + +
      +
    • +

      What It Does

      +
      +
      add on to the archive style
      +
      What you want 95% of the time. Will be loaded after the official archive style.
      + +
      replace the archive style
      +
      Useful for complex skins where you don't want most of the default style underlying your work. (You can use the parts you want to keep as parents.)
      +
      +
    • + +
    • +

      Parent Only

      +

      + This option is mainly to help keep the skins listing tidy. + + If you select this, neither you (nor anyone else) will be able to use this skin directly: it will only be used as a parent. + The skin (even if made public) will not be listed in the main skins listing, only in the description of skins where it is + used as a parent. This makes it much easier to make components available for people to use without cluttering up the + skins listing with skins that wouldn't actually work right if someone tried to use them alone. :) +

      +
    • + +
    • +

      Media

      +

      + You can choose more than one media. + Media stylesheets will only be loaded if whatever device you're browsing on supports that particular media type. + For instance, not all screenreaders load "speech" stylesheets. If your device doesn't load your skin, + try using "all" or "screen" instead (or drop us a Support request if you need help). +

      +
      +
      all
      +
      What you want 95% of the time. Loaded for all devices. (Some very old browsers don't understand "all" and require "screen".)
      + +
      screen
      +
      Loaded for computer screens. (And usually for any device that doesn't support other media categories.)
      + +
      handheld
      +
      Will be loaded only for mobile devices and/or small screens.
      + +
      speech
      +
      Will be loaded only for screenreaders.
      + +
      print
      +
      Will be loaded only when the page is printed.
      + +
      braille, embossed, projection, tty, tv
      +
      See the W3C media specs for details.
      + +
      only screen and (max-width: 450px)
      +
      Loaded for iPhone (it doesn't load handheld stylesheets otherwise)
      +
      +
    • + +
    • +

      IE Only

      +

      + If you leave this blank, your skin will be loaded for all browsers. If you choose one of these options, + your skin will be loaded only for Internet Explorer browsers. This lets you add IE-specific overrides. +

      +
      +
      IE
      +
      Will be loaded for any Internet Explorer browser.
      + +
      IE5, IE6, IE7, IE8, IE9
      +
      Will be loaded only for this particular version of the Internet Explorer browser.
      + +
      IE8_or_lower
      +
      Will be loaded for IE8 and below
      +
      +
    • +
    + +

    + +

    Interaction With Parents

    +

    + If you also use skin parents, you can give conditions to particular parents, and then make a skin that acts differently + for different browsers. + For instance, if you have one parent skin that holds most of your CSS, one that is IE-only, one for media "handheld" and one that uses the media "print", + then your final skin will load each parent as appropriate based on the final user's browser! +

    + diff --git a/public/help/skins-creating.html b/public/help/skins-creating.html new file mode 100755 index 0000000..fe670c9 --- /dev/null +++ b/public/help/skins-creating.html @@ -0,0 +1,204 @@ +
    +
    You can create new skins for the Archive using our wizard, or by writing your own CSS (cascading style sheets) code
    +
    +

    + Note that for security reasons, you can only use a limited set of CSS code: all other declarations and comments will be removed! +

    +
    + +
    We allow the following properties including all their variations (and shorthand values)
    +
    +

    + + background, border, column, cue, flex, font, layer-background, + layout-grid, list-style, margin, marker, outline, overflow, padding, + page-break, pause, scrollbar, text, transform, transition + +

    +
    +
    We also allow the following specific properties
    +
    +

    + + -replace, -use-link-source, accelerator, accent-color, align-content, + align-items, align-self, alignment-adjust, alignment-baseline, + appearance, azimuth, baseline-shift, behavior, binding, bookmark-label, + bookmark-level, bookmark-target, bottom, box-align, box-direction, + box-flex, box-flex-group, box-lines, box-orient, box-pack, box-shadow, + box-sizing, caption-side, clear, clip, color, color-profile, + color-scheme, content, counter-increment, counter-reset, crop, cue, + cue-after, cue-before, cursor, direction, display, dominant-baseline, + drop-initial-after-adjust, drop-initial-after-align, + drop-initial-before-adjust, drop-initial-before-align, + drop-initial-size, drop-initial-value, elevation, empty-cells, filter, + fit, fit-position, float, float-offset, font, font-effect, + font-emphasize, font-emphasize-position, font-emphasize-style, + font-family, font-size, font-size-adjust, font-smooth, font-stretch, + font-style, font-variant, font-weight, grid-columns, grid-rows, + hanging-punctuation, height, hyphenate-after, hyphenate-before, + hyphenate-character, hyphenate-lines, hyphenate-resource, hyphens, icon, + image-orientation, image-resolution, ime-mode, include-source, + inline-box-align, justify-content, layout-flow, left, letter-spacing, + line-break, line-height, line-stacking, line-stacking-ruby, + line-stacking-shift, line-stacking-strategy, mark, mark-after, + mark-before, marks, marquee-direction, marquee-play-count, + marquee-speed, marquee-style, max-height, max-width, min-height, + min-width, move-to, nav-down, nav-index, nav-left, nav-right, nav-up, + opacity, order, orphans, page, page-policy, phonemes, pitch, + pitch-range, play-during, position, presentation-level, + punctuation-trim, quotes, rendering-intent, resize, rest, rest-after, + rest-before, richness, right, rotation, rotation-point, ruby-align, + ruby-overhang, ruby-position, ruby-span, size, speak, speak-header, + speak-numeral, speak-punctuation, speech-rate, stress, string-set, + tab-side, table-layout, target, target-name, target-new, + target-position, top, unicode-bibi, unicode-bidi, user-select, + vertical-align, visibility, voice-balance, voice-duration, voice-family, + voice-pitch, voice-pitch-range, voice-rate, voice-stress, voice-volume, + volume, white-space, white-space-collapse, widows, width, word-break, + word-spacing, word-wrap, writing-mode, z-index + +

    +
    + +
    Look at other public skins for examples
    +
    +

    + All approved public skins are visible and you can read their code and copy them to edit for + your own use. +

    +
    + +
    Use only one declaration per property per ruleset
    +
    +

    + The CSS parser we use retains only one declaration for each property, meaning that rulesets like
    +

    +        .my-class {
    +          background: -moz-linear-gradient(top, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%);
    +          background: -o-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    +          background: -webkit-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%);
    +        }
    +      
    + will have all but the last background declaration removed (so your gradient would only show up in WebKit browsers). To avoid losing declarations with repeated properties, split each one into its own ruleset, like so: +
    +        .my-class { background: -moz-linear-gradient(top, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%); }
    +        .my-class { background: -o-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); }
    +        .my-class { background: -webkit-linear-gradient(top, #1e5799 0%,#2989d8 50%,#207cca 51%,#7db9e8 100%); }
    +      
    +

    +
    + +
    Font and Font Family
    +
    +

    + Unfortunately, you cannot use the font shorthand in your CSS. All font properties have to be specified separately, e.g., + font-size: 1.1em; font-weight: bold; font-family: Cambria, Constantia, Palatino, Georgia, serif; +

    +

    + In the font-family property, we allow you to specify any font with an alphanumeric name. + You can (but don't have to) specify the name with single or double quotes + around it, just make sure the quotes match. (e.g., 'Gill Sans' and "Gill Sans" are both fine; 'Gill Sans" won't work.) + Keep in mind that a font has to be installed on the user's operating system to work. It's a good idea when specifying fonts to use + fallbacks in case your first-choice font isn't available. + See a set of web-safe fonts with fallbacks. +

    +

    + We cannot allow the @font-face attribute. Sorry! If you have an uncommon font that you want to + use in a skin you would like to share, we suggest adding a comment in the skin's "Description" field with a pointer to a place for users + to download the font themselves, and using web-safe fonts as fallbacks. +

    +
    + +
    Custom Properties (Variables)
    +
    +

    + Custom property names can contain any combination of lowercase letters (a-z) in the English alphabet, numerals zero to nine (0-9), dashes (-), and underscores (_). They can't contain single (') or double (") quotation marks, or URLs. Any uppercase letters (A-Z) will be converted to lowercase. +

    +

    + All properties except font-family and content accept the var() function as a value. We don't allow fallbacks. +

    +

    + Custom properties and the var() function are only available for site skins, and won't work on work skins. +

    +
    + +
    URLs
    +
    +

    + We allow external image URLs (specified as url('https://example.com/my_awesome_image.jpg')) in JPG, GIF, and PNG formats. + Please note, however, that skins using external images will not be approved for public use. +

    +
    + +
    Keywords
    +
    +

    + We allow all standard CSS keyword values (e.g., absolute, bottom, center, underline, etc.). +

    +
    + +
    Numeric Values
    +
    +

    + You can specify numeric values up to two decimal places, either as percentages or in various units:
    + cm, em, ex, in, mm, pc, pt, px +

    +

    + PS: we highly encourage learning about and using em, which lets you set things relative to the viewer's current font size! + It will make your layouts much more flexible and responsive to different browser/font settings. +

    +
    + +
    Colors
    +
    +

    + You can specify colors using hex values (eg, #000000 is black in hex) or with RGB or RGBA values (e.g., rgb(0,0,0) and rgba(0,0,0,0) both give you black). + This may be safer since not all browsers will necessarily support all color names. However, color names are more + readable and easier to remember, so we also allow color names. (We suggest you stick to + the set of commonly-supported color names.) +

    +
    + +
    Scale
    +
    +

    + You can specify scale (for the transform property) as scale(numeric value) where the numeric value can be + specified up to two decimal places. +

    +
    + +
    Comments
    +
    +

    Comments are stripped from CSS.

    +
    + +
    If you are new to CSS, here are the basics:
    +
    +

    + A line of CSS code looks pretty much like this: selector {property: value;} +

    +

    + The selector is either the name of an HTML tag (like body or h1), + or it can be an id or class that has been set on a tag. + The property is what you want to change in the contents of that tag (for instance the font size), + and the value is what you want to set it to. +

    +

    + Examples: +

      +
    • Inside the "body" tag, set the font size slightly larger than the baseline: body {font-size: 1.1em;}
    • +
    • Inside any tags with the id "header", set the background color to purple: #header {background-color: purple}
    • +
    • Inside any tags with the class "meta", make the text blink: (we do not advise this) .meta {font-style: blink}
    • +
    +

    + +

    + Some useful CSS tutorials for more information: +

    +

    +
    + +
    diff --git a/public/help/skins-parents.html b/public/help/skins-parents.html new file mode 100755 index 0000000..b5c495b --- /dev/null +++ b/public/help/skins-parents.html @@ -0,0 +1,25 @@ +

    Skin Parents

    + +

    + You can combine and layer multiple site skins by making one the parent of + another. Parent skins are loaded in order so that the style of all the skins + can be displayed in that order. For more information on skins, please refer to + the Skins and Interface FAQ. +

    + +

    + By default, skins will be loaded after the Archive default style. If you don't + want this, you can specify in the "What it does" menu that you want your skin + to replace rather than add to the Archive default style. +

    + +

    Load Archive Skin Components

    + +

    + If you create a replacement skin, you might want to load up all the skins that + make up the current default Archive site as parents. This option is only + available when you select "replace archive skin entirely" from the "What it + does" menu. After that, you can edit your skin and delete just the ones you + don't want. This will be easier if you are using nearly all of them, since + there are a lot! +

    diff --git a/public/help/skins-wizard-accent-color.html b/public/help/skins-wizard-accent-color.html new file mode 100755 index 0000000..e1bd449 --- /dev/null +++ b/public/help/skins-wizard-accent-color.html @@ -0,0 +1,2 @@ +

    The default is: #ddd

    +

    Replace the gray used in numerous places throughout the Archive, including form backgrounds, the dropdown menus in the main navigation, and the "Fandoms" and "Recent works" sections of dashboard pages.

    diff --git a/public/help/skins-wizard-font-size.html b/public/help/skins-wizard-font-size.html new file mode 100755 index 0000000..895c3ed --- /dev/null +++ b/public/help/skins-wizard-font-size.html @@ -0,0 +1,2 @@ +

    The default is: 100%

    +

    Font sizes on the Archive are based on a percentage of your browser's default font size. Use a number smaller than 100 to make the Archive's text smaller, or use a number larger than 100 to make the text larger. Entering 100 will keep the Archive's default font sizes.

    diff --git a/public/help/skins-wizard-font.html b/public/help/skins-wizard-font.html new file mode 100755 index 0000000..03290e3 --- /dev/null +++ b/public/help/skins-wizard-font.html @@ -0,0 +1,3 @@ +

    The default is: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Helvetica, sans-serif, 'GNU Unifont'

    +

    Put any font name in here, and if it's installed on your computer, it'll work for you. If you use several different devices, specify some fall-back fonts, with commas in between the names, in case one of your devices doesn't have the first font.

    +

    You can use either single or double quotation marks around fonts with multi-word names, e.g. "Lucida Grande" or 'Lucide Sans Unicode'.

    diff --git a/public/help/skins-wizard-vertical-gap.html b/public/help/skins-wizard-vertical-gap.html new file mode 100755 index 0000000..a496fb8 --- /dev/null +++ b/public/help/skins-wizard-vertical-gap.html @@ -0,0 +1,3 @@ +

    The default is: 1.1286em

    +

    Put any number in here and it will be applied as a multiple of the work's font size. A larger number will give you bigger spacing between paragraphs.

    +

    For example, most users see works at a font size of 15 pixels. Entering 2 will create a vertical gap of 30 pixels, and entering 0.5 will create a gap of about 8 pixels.

    diff --git a/public/help/symbols-key.html b/public/help/symbols-key.html new file mode 100755 index 0000000..1649991 --- /dev/null +++ b/public/help/symbols-key.html @@ -0,0 +1,65 @@ +

    Symbols we use on the Archive

    +
    +
    First Square
    +

    Content rating

    +
    +
    G
    +
    General Audiences
    +
    T
    +
    Teen And Up Audiences
    +
    M
    +
    Mature
    +
    E
    +
    Explicit: only suitable for adults
    +
    blank square
    +
    The work was not given any rating
    +
    +
    +
    Second Square
    +

    Relationships, pairings, orientations

    +
    +
    F/F
    +
    F/F: female/female relationships
    +
    F/NB
    +
    F/NB: female/NB relationships
    +
    Gen
    +
    NB/NB: nonbinary/nonbinary relationships
    +
    Multi
    + +
    Multi: more than one kind of relationship, or a relationship with multiple partners
    +
    Other
    +
    Other relationships
    +
    blank square
    +
    The work was not put in any categories
    +
    +
    +
    Third Square
    +

    Content warnings

    +
    +
    questioned exclamation mark
    +
    The author chose not to warn for content, or Archive Warnings could apply, but the author has chosen not to specify them. +
    +
    exclamation mark
    +
    At least one of these warnings applies: graphic depictions of violence, major character death, rape/non-con, underage sex. The specific warnings are shown in the Archive Warnings tags. +
    +
    blank square
    +
    The work was not marked with any Archive Warnings. Please note that an author may have included other information about + their work in the Additional Tags (Genre, Warnings, Other Information) section.
    +
    globe
    +
    This is an external work; please consult the work itself for warnings.
    +
    +
    +
    Fourth Square
    +

    Is the work finished or the prompt fulfilled?

    +
    +
    stop sign
    +
    This is a work in progress or is incomplete/unfulfilled.
    +
    ticky
    +
    This work is completed!/This prompt is filled!
    +
    blank square
    +
    This work's status is unknown.
    +
    +
    +
    diff --git a/public/help/tag-search-results-help.html b/public/help/tag-search-results-help.html new file mode 100755 index 0000000..62d9611 --- /dev/null +++ b/public/help/tag-search-results-help.html @@ -0,0 +1,5 @@ +

    Tag Search Results

    + +

    Highlighted tags are canonical.

    +

    Very new tags will be at the top of the list. Otherwise the list is sorted alphabetically by type and then name.

    +

    If there are too many tags, try refining your search, rather than paging through the results.

    diff --git a/public/help/tag-search-text-help.html b/public/help/tag-search-text-help.html new file mode 100755 index 0000000..cbaf324 --- /dev/null +++ b/public/help/tag-search-text-help.html @@ -0,0 +1,43 @@ +

    Tag Search Text

    + +
    +
    + *: any characters +
    +
    + book* will find book and books and + booking. +
    + +
    + space: a space acts like AND +
    +
    + Harry Potter will find Harry Potter and Harry + James Potter but not Harry. +
    + +
    + ||: OR (not exclusive) +
    +
    + Harry || Potter will find Harry, Harry + Potter, and Potter. +
    + +
    + ": words in exact sequence +
    +
    + "Harry Lockhart" will find "Harry Lockhart" but not + Harry Potter/Gilderoy Lockhart. +
    + +
    + NOT: NOT +
    +
    + Harry NOT Lockhart will find Harry Potter but not + Harry Lockhart or Gilderoy Lockhart/Harry Potter. +
    +
    diff --git a/public/help/tagset-about.html b/public/help/tagset-about.html new file mode 100755 index 0000000..0013501 --- /dev/null +++ b/public/help/tagset-about.html @@ -0,0 +1,32 @@ +

    About Tag Sets

    + +

    + If you've ever wanted to run a challenge on the Archive, that's what tag sets + are for. You create a tag set to hold a list of all the tags that should be + available for sign-up, even if those tags haven't been used on the Archive + before now, and then add the tag set to your challenge. Tags in the tag set + will then automatically show up in the sign-up form. +

    + +

    + You can add as many moderators as you want to help you manage your tag set, + and they don't need to have access to the challenge settings. You can also + allow the participants in your challenge to nominate tags to be added to your + set. You and any co-owners and moderators can review those nominations, and + approve or reject them. You can add fandom associations to new tags in your + Tag Set, or you can leave them for tag wranglers to make the associations + (this may take some time). +

    + +

    + All tag sets are listed on the main tag sets page. You can browse them to get + a better idea of how they work. +

    + +

    + Some users may choose to make their tag set publicly available for others to + use in their challenges. Please note that the owners of a tag set can + delete the tag set or change it without warning, so before you use + someone else's tag set for your challenge, please be sure that you trust them + not to change it. +

    diff --git a/public/help/tagset-batch-load.html b/public/help/tagset-batch-load.html new file mode 100755 index 0000000..72c6f55 --- /dev/null +++ b/public/help/tagset-batch-load.html @@ -0,0 +1,24 @@ +

    Batch Loading

    + +
      +
    • + You can only batch load tag associations if the tags already exist. This is + to avoid mass-adding piles of wrong tags to the Archive. +
    • +
    • + If you really want to add some new tags to the Archive, you can add them to + your tag set first, and then batch load the associations here afterwards. +
    • +
    • + If two tags are already associated in the Archive or in your tag set, it + won't associate them again. +
    • +
    • + Only the associations that didn't work will remain in the form after you + select the "Submit" button. +
    • +
    • + If the batch load is taking too long and you're getting 502 errors, please + split up the number of tags you're trying to load! +
    • +
    diff --git a/public/help/tagset-fandom-for-child.html b/public/help/tagset-fandom-for-child.html new file mode 100755 index 0000000..09678d2 --- /dev/null +++ b/public/help/tagset-fandom-for-child.html @@ -0,0 +1,7 @@ +

    Specifying Fandom

    + +

    + You only need to specify the fandom if your nomination is new or not in the fandom already -- for instance, if you're + submitting a character who has just appeared in the fandom. + This information is just used to help the moderators sort out new tags. +

    diff --git a/public/help/tagset-nominated-tags.html b/public/help/tagset-nominated-tags.html new file mode 100755 index 0000000..6064694 --- /dev/null +++ b/public/help/tagset-nominated-tags.html @@ -0,0 +1,13 @@ +

    Nominated Tags

    + +

    + Some of your tags may be marked as unwrangled, meaning they currently exist in the archive but have + not been organized into our tagging system, and some may be marked as nonexistent, meaning + they don't exist in the archive at all. If you have tags marked this way, please make sure you have them typed correctly! +

    + +

    + If you see one of your tags listed with a slightly different tag afterwards in parentheses, this means that the + tag you have nominated is wrangled and has a canonical synonym on the archive. The moderators may decide to use + the canonical synonym instead of the version you used. +

    diff --git a/public/help/tagset-tag-associations.html b/public/help/tagset-tag-associations.html new file mode 100755 index 0000000..23b0247 --- /dev/null +++ b/public/help/tagset-tag-associations.html @@ -0,0 +1,18 @@ +

    Tag Set Associations

    + +

    + Tag associations let you set up associations between the fandoms, characters, and relationships in your tag set, which then + lets your participants pick from only the characters and relationships in a given fandom. +

    + +

    + Note: if the wranglers have already set up these associations, then you can just add the additional + ones that you would like -- you don't have to (and in fact aren't allowed) to create copies of canonical + associations. You can still limit your participants' choices to tags actually in your set. +

    + +

    + If you're not sure how this might work, try adding a few fandoms and characters and setting up some associations, + and then set up your challenge and try out the sign-up form! +

    + \ No newline at end of file diff --git a/public/help/translation-link.html b/public/help/translation-link.html new file mode 100755 index 0000000..1cdbfde --- /dev/null +++ b/public/help/translation-link.html @@ -0,0 +1,7 @@ +

    Translations

    + +

    +As well as citing a work that has inspired yours (e.g. if you are remixing another work) you can also state that your work is a translation of another work. +

    + +

    Just tick this box, fill in the details of the work, and make sure you select the language of your work further down the form, and the Archive will link them up.

    diff --git a/public/help/warning-help.html b/public/help/warning-help.html new file mode 100755 index 0000000..7d4057b --- /dev/null +++ b/public/help/warning-help.html @@ -0,0 +1,72 @@ +

    Warning Tags

    + +

    + The Archive of Our Own has chosen, for legal and other reasons, to mandate + that users either warn for—or explicitly choose not to warn for—a + short list of common warnings: Graphic Depictions of Violence, Major Character + Death, Rape/Non-Con, and Underage Sex. We understand that creators may wish to not + warn for some of these things, or to warn for additional content, and have + provided options for them to do so within this framework. +

    + +
    +
    + Choose Not To Use Archive Warnings: +
    +
    + Use this if you don't want to warn for anything. You may also choose this + option if you don't know what you should warn for; if you don't like warning + for certain topics or warnings in general; if you want to avoid some + spoilers, but not others; etc. +
    +
    + Graphic Depictions Of Violence: +
    +
    + This is for gory, graphic, explicitly described violence. Exactly where to + draw the line is your call. +
    +
    + Major Character Death: +
    +
    + Please use your best judgment about who counts as a major character. +
    +
    + No Archive Warnings Apply: +
    +
    + Use this if the Archive warnings don't apply to your content. (In other + words, if it contains no graphic depictions of violence, major character + death, rape/non-con, or underage sexual activity.) +
    +
    + Rape/Non-Con: +
    +
    + This is your call. If you think your content may be seen as containing + non-consensual sexual activity, but you don't feel like using this warning + or you're not sure if you should, you always have the option of using + "Choose Not to Use Archive Warnings" instead. +
    +
    + Underage Sex: +
    +
    + This is for descriptions or depictions of sexual activity involving characters + under the age of eighteen. (This doesn't include dating activity like + kissing or vague references with no actual description or depiction.) This + warning generally applies to humans; if you are creating a pornographic work + about space aliens who only live for a month or thousand-year-old vampires + with twelve-year-old bodies, please just use your best judgment. You are + always free to specify characters' ages or to use "Choose Not to Use Archive + Warnings". +
    +
    + +

    + You can also use the "Additional Tags" field to give other or more detailed + warnings. Our policies regarding warnings can be found in the Terms of Service and Terms of Service FAQ. +

    diff --git a/public/help/who-can-comment-on-this-work.html b/public/help/who-can-comment-on-this-work.html new file mode 100755 index 0000000..7d3ee9c --- /dev/null +++ b/public/help/who-can-comment-on-this-work.html @@ -0,0 +1,10 @@ +

    Who can comment on this work?

    +
    +
    Registered users and guests can comment
    +
    All users can comment on your work whether they are logged in or not.
    +
    Only registered users can comment
    +
    This is the default option. With this enabled, only logged in users will be able to comment on your work.
    +
    No one can comment
    +
    This will disable all new comments on your work.
    +
    +

    Changing these settings will not affect any existing comments. If there are comments on the work that you would like to remove, check out Can I edit or delete a comment someone else left on one of my works? to learn how.

    diff --git a/public/help/work-filters-exclude-tags.html b/public/help/work-filters-exclude-tags.html new file mode 100755 index 0000000..a2b64e6 --- /dev/null +++ b/public/help/work-filters-exclude-tags.html @@ -0,0 +1,25 @@ +

    Tag Filters: Exclude Tags

    + +

    + The filters list the ten most popular tags for each tag category. To filter by any other tags, use the "Other tags to exclude" field. +

    + +

    + If the tag you want to exclude isn't in the top ten, start entering the tag you need in the "Other tags to exclude" field—all tag categories are valid here, and you can add as many tags as you want. The autocomplete will help you find the canonical version of the tag. Use these to take full advantage of the wrangled tagging structure, which will exclude all works using subtags and tags with synonymous meanings. +

    + +

    + You can also enter tags that aren't in the autocomplete. If the tag you enter has been used on the Archive but is not marked canonical, then the filters will look for works that use the exact tag you've entered. If the tag you've entered has never been used on the Archive, the filters will do a simple text match and may bring up unexpected results. The "Search within results" field will text-match more accurately, especially in the case of relationship tags and other tags with "/" or other non-text characters. +

    + +

    + Choosing any tag from a category or entering a tag in the "Other tags to exclude" field will do an OR search with all the tags you select. This means that if you're filtering the works tagged with the F/F category, select the Major Character Death warning, the canonical Alternate Universe tag in the Additional Tags category, and enter or select the canonical tag Drama in the "Other tags to exclude" field, only works tagged without any of these tags will be included in the results. +

    + +

    + To look up tags and see which ones are canonical, use the Tag Search. +

    + +

    + You can find more information about tags in our Tags FAQ. To read the guidelines tag wranglers use to mark tags canonical, among other things, or to better understand the AO3-specific vocabulary for tags, read the Wrangling Guidelines. +

    diff --git a/public/help/work-filters-include-tags.html b/public/help/work-filters-include-tags.html new file mode 100755 index 0000000..04caaf2 --- /dev/null +++ b/public/help/work-filters-include-tags.html @@ -0,0 +1,29 @@ +

    Tag Filters: Include Tags

    + +

    + The filters list the ten most popular tags for each tag category. To filter by any other tags, use the "Other tags to include" field. +

    + +

    + If the tag that interests you isn't in the top ten, start entering the tag you need in the "Other tags to include" field—all tag categories are valid here, and you can add as many tags as you want. The autocomplete will help you find the canonical version of the tag. Use these to take full advantage of the wrangled tagging structure, which will find all works using subtags and tags with synonymous meanings. +

    + +

    + You can also enter tags that aren't in the autocomplete. If the tag you enter has been used on the Archive but is not marked canonical, then the filters will look for works that use the exact tag you've entered. If the tag you've entered has never been used on the Archive, the filters will do a simple text match and may bring up unexpected results. The "Search within results" field will text-match more accurately, especially in the case of relationship tags and other tags with "/" or other non-text characters. +

    + +

    + Choosing any tag from a category or entering a tag in the "Other tags to include" field will do an AND search with all the tags you select. This means that if you're filtering the works tagged with the F/F category, select the Teen and Up Audiences rating, the canonical Romance tag in the Additional Tags category, and enter or select the canonical tag Drama in the "Other tags to include" field, only works tagged with all these tags will be included in the results. +

    + +

    + To get results with Tag A OR Tag B, use the "Search within results" field. +

    + +

    + To look up tags and see which ones are canonical, use the Tag Search. +

    + +

    + You can find more information about tags in our Tags FAQ. To read the guidelines tag wranglers use to mark tags canonical, among other things, or to better understand the AO3-specific vocabulary for tags, read the Wrangling Guidelines. +

    diff --git a/public/help/work-import.html b/public/help/work-import.html new file mode 100755 index 0000000..06b12dc --- /dev/null +++ b/public/help/work-import.html @@ -0,0 +1,45 @@ +

    Troubleshooting Importing

    + +

    + If your text gets cut off at the point of an em dash or accented character, + you might have to manually set the encoding using the "Set custom encoding" + menu below for your work to import successfully. The type of encoding that + works can vary; you may need to try different options to find the right one. + Refer to the Encoding Help page for + more information. +

    + +

    + If you are importing a chaptered work from an e-fiction site, you need to + enter the URL for each chapter, each one on a different line. You can import a + maximum of two hundred chapters at a time. For more information on importing + works from other sites, please refer to "How do I import works from another + website?" +

    + +

    + If you are trying to transfer a work already on the Archive of Our Own from + one user account to another, you must edit the existing work to add the new + account as a co-creator, then remove the old account. You can't use the Import + tool on AO3-hosted works. +

    + +

    + Unless you check the "Override tags and notes" box, any information you enter + under Tags will only be used if the importer cannot determine tags from the + work itself. +

    + +

    + You will be able to edit and complete the standard header information after + the import has been completed. For more information on posting and editing, + please refer to the Posting and Editing + FAQ. +

    + +

    + If none of the above information is helpful to you, you might find your + problem listed on the the Known Issues + page. +

    diff --git a/public/help/work-search-crossover-help.html b/public/help/work-search-crossover-help.html new file mode 100755 index 0000000..ba307bc --- /dev/null +++ b/public/help/work-search-crossover-help.html @@ -0,0 +1,9 @@ +

    Work Search: Crossovers

    + +

    + Generally speaking, a crossover is a work with more than one fandom. For filtering purposes, a work is considered a crossover if it's tagged with two or more unrelated fandoms (we're using our tag wrangling system to make that determination). +

    + +

    + Looking for crossovers between two specific fandoms? Enter their names in the "Fandoms" field on the search form or select or enter both fandoms on the filters. +

    diff --git a/public/help/work-search-date-help.html b/public/help/work-search-date-help.html new file mode 100755 index 0000000..9c23038 --- /dev/null +++ b/public/help/work-search-date-help.html @@ -0,0 +1,27 @@ +

    Work Search: Date

    + +

    Create a range of times. If no range is given, then one will be calculated based on the time period specified.

    +

    Allowable periods: year, week, month, day, hour

    +

    +

      +
    • x days ago = 24 hour period from the beginning to the end of that day
    • +
    • x weeks ago = 7 day period from the beginning to the end of that week
    • +
    • x months ago = 1 month period from the beginning to the end of that month
    • +
    • x years ago = 1 year period from the beginning to the end of that year
    • +
    +

    + +

    Examples (taking Wednesday 25th April 2012 as the current day):

    +

    +

      +
    • 7 days ago (this will return all works posted/updated on Wednesday 18th April)
    • +
    • 1 week ago (this will return all works posted/updated in the week starting Monday 16th April and ending Sunday 22nd April)
    • +
    • 2 months ago (this will return all works posted/updated in the month of February)
    • +
    • 3 years ago (this will return all works posted/updated in 2010)
    • +
    • < 7 days (this will return all works posted/updated within the past seven days)
    • +
    • > 8 weeks (this will return all works posted/updated more than eight weeks ago)
    • +
    • 13-21 months (this will return all works posted/updated between thirteen and twenty-one months ago)
    • +
    +

    + +

    Note that the "ago" is optional.

    diff --git a/public/help/work-search-language-help.html b/public/help/work-search-language-help.html new file mode 100755 index 0000000..654e237 --- /dev/null +++ b/public/help/work-search-language-help.html @@ -0,0 +1,3 @@ +

    Work Search: Language

    + +

    Selecting a language from this drop-down will search for works in that language. Please note that this list contains all languages we are currently supporting, and not all of them will return results.

    diff --git a/public/help/work-search-numerical-help.html b/public/help/work-search-numerical-help.html new file mode 100755 index 0000000..1a0b058 --- /dev/null +++ b/public/help/work-search-numerical-help.html @@ -0,0 +1,14 @@ +

    Work Search: Numerical Values

    + +

    Use the following guidelines when looking for works with a specific amount of words, hits, kudos, comments, or bookmarks. Note that periods and commas are ignored: 1.000 = 1,000 = 1000. + +

    +
    10:
    +
    a single number will find works with that exact amount
    +
    <100:
    +
    will find works with less than that amount
    +
    >100:
    +
    will find works with more than that amount
    +
    100-1000:
    +
    will find works in the range of 100 to 1000
    +
    diff --git a/public/help/work-search-results-help.html b/public/help/work-search-results-help.html new file mode 100755 index 0000000..46225dc --- /dev/null +++ b/public/help/work-search-results-help.html @@ -0,0 +1,3 @@ +

    Work Search: Results

    + +

    Very new works that fit the criteria will be at the top of the list. Otherwise the list is sorted by relevance. If there are many works, it might be better to edit your search terms rather than page through the results.

    \ No newline at end of file diff --git a/public/help/work-search-tags-help.html b/public/help/work-search-tags-help.html new file mode 100755 index 0000000..aae099e --- /dev/null +++ b/public/help/work-search-tags-help.html @@ -0,0 +1,41 @@ +

    Work Search: Tags

    + +

    + The fields for Fandoms, Characters, Relationships, and Additional Tags suggest + tags as you enter search terms. Choosing the "canonical" or common tag, (that + is, the ones included in the autocomplete list) will return all results + containing this tag, its synonyms, and the subtags linked with the tag. For + example, picking the canonical relationship tag Erika Mustermann/Juan + Pérez will return works tagged Juan Pérez/Erika + Mustermann as well, assuming these tags have been linked by a wrangler + in the background. Refer to What is a + 'canonical' tag? for more information. +

    + +

    + If a tag doesn't appear in the autocomplete menu, it doesn't necessarily mean + that the tag doesn't exist on the Archive; it just hasn't been marked as + common by a tag wrangler. You can enter any word or phrase here. If your + phrase doesn't match a common tag exactly, it will find all tags containing + the words in your phrase. Entering People Doing Things, for + example, will also find works tagged Nice People Doing Things, + People Doing Shady Things, and People Doing Things with + Spoons. Depending on your search, results in this case will be somewhat + unpredictable. +

    + +

    + The more search terms you enter or options you pick, the more your search + results will be narrowed down. By default, all the search results are AND + search results. This means that entering two fandoms will only find works + tagged with both, not all works that are in one fandom or the other. + Entering two characters will only find works that have both. Picking + M/M and F/M will only include a work in the search + results if it has both category tags, and so on. +

    + +

    + You can find more about tagging in our Tags FAQ, and + more about tag search in the Search and + Browse FAQ. +

    diff --git a/public/help/work-search-text-help.html b/public/help/work-search-text-help.html new file mode 100755 index 0000000..608f942 --- /dev/null +++ b/public/help/work-search-text-help.html @@ -0,0 +1,36 @@ +

    Work Search: Any Field

    + +

    Searches all the fields associated with a work in the database, including summary, notes and tags, but not the full work text.

    + +

    The characters ":" and "@" have special meanings. Leave them out of your search or you will get unexpected results. Like in the Title and Creator field, you can use the following operators to combine your search terms:

    + +
    +
    *: any characters
    +
    book* will find book and books and booking.
    + +
    space: acts like AND for search terms in the same field of the work
    +
    Harry Potter will find Harry Potter and Harry James Potter in any field, but it won't find works by a creator named Harry with the character tag Sherman Potter.
    + +
    AND: searches for works which have both terms in any field
    +
    Harry AND Potter will find works by a creator named Harry with the character tag Sherman Potter.
    + +
    ||: OR (not exclusive)
    +
    Harry || Potter will find Harry, Harry Potter, and Potter.
    + +
    "": words in exact sequence
    +
    "Harry Lockhart" will find Harry Lockhart but not Harry Potter/Gilderoy Lockhart.
    + +
    -: NOT
    +
    Harry -Lockhart will find Harry Potter but not Harry Lockhart or Gilderoy Lockhart/Harry Potter.
    +
    + +
    Examples
    + +
    +
    "Fandom X" "F/F" -Explicit
    +
    will return all works from Fandom X tagged as F/F, and exclude those tagged Explicit
    +
    "Character A" OR "Character B" -"Character Death"
    +
    will return all works including Character A or Character B (or both), and no works tagged with "Character Death" in either the Warnings or the Additional tags
    +
    "Character A/Character B" "Underage Sex" (Mature OR Explicit)
    +
    will return all works for this pairing that include an Underage Sex warning and are either rated Mature or Explicit
    +
    diff --git a/public/help/work-skins.html b/public/help/work-skins.html new file mode 100755 index 0000000..77e3d57 --- /dev/null +++ b/public/help/work-skins.html @@ -0,0 +1,41 @@ +

    Work Skins

    + +

    + You can create custom stylesheets, or "skins", for your works just like you + can create skins for the Archive. The main difference is that work skins will + change the way your work appears to other users, not just + you. +

    + +

    + Work skins will only affect the body of the work they are + applied to—you can't change the Archive navigation or background with them. + What you can do, however, is create your own classes. For instance, you can + change the color of some of your text, indent some paragraphs in a particular + way, and so on. +

    + +

    + For example, let's say that you want to make a single word in your text bright + blue. Here is what you might do: +

    + +
      +
    • + Create a work skin with the + following content: .bluetext {color: blue;} +
    • +
    • + Select this skin when posting your work. +
    • +
    • + In the HTML of your text, you would then give the word this class: I + want <span class="bluetext">house</span> to be in blue +
    • +
    + +

    + Refer to Tutorial: Creating a + Work Skin and Skins and Archive + Interface FAQ for more information. +

    diff --git a/public/help/work_title_format.html b/public/help/work_title_format.html new file mode 100755 index 0000000..295d060 --- /dev/null +++ b/public/help/work_title_format.html @@ -0,0 +1,15 @@ +

    Work Title Format

    + +

    + Specify how the page title looks in your browser when you are reading a story. Some examples: +

    + +
    +
    TITLE - AUTHOR - FANDOM
    +
    This is the default format.
    +
    TITLE - AUTHOR
    +
    Don't include the fandom
    +
    FANDOM_AUTHOR_TITLE
    +
    Start with fandom, then with author, then title, with underscores instead of dashes.
    +
    + diff --git a/public/images/OTWLogo.png b/public/images/OTWLogo.png new file mode 100755 index 0000000000000000000000000000000000000000..5342117cb68c54fd677834d66cc902fd3240903e GIT binary patch literal 5747 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

    =GUn@m^fAlMpN2*A! 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 literal 0 HcmV?d00001 diff --git a/public/images/ao3_logos/logo-rails3.png b/public/images/ao3_logos/logo-rails3.png new file mode 100755 index 0000000000000000000000000000000000000000..7bf23ca1e62714fbdbff96df1edef38c18a5afbd GIT binary patch literal 8601 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 literal 0 HcmV?d00001 diff --git a/public/images/ao3_logos/logo-ruby.png b/public/images/ao3_logos/logo-ruby.png new file mode 100755 index 0000000000000000000000000000000000000000..76a4a89393f8c796757268c6b39840ac1c0d2598 GIT binary patch literal 33700 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/p8kgdnd4ICjlQ|CS0InU3OR}B7)puiZn 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 ce3AZd&!waUHx3vIVCg!0J5tE4*&oF literal 0 HcmV?d00001 diff --git a/public/images/ao3_logos/logo-stroke.png b/public/images/ao3_logos/logo-stroke.png new file mode 100755 index 0000000000000000000000000000000000000000..5c2eb4f8e10d17f48273d66cd3343b19055db741 GIT binary patch literal 5936 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≪qPe$l;oo3XVmZVu8C(7Zg*Xd-cHr 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

    3sMqTL&M5=j^5zs_MuOj@g z_%lo}=|>)0mxRU;L*(7jTV_X4&Wz(+JyLLyT@`1KBSMXFcl#{-xMvaa0!`S<3u7|G z%oD3dO-5TmIZn-N$EiszxHz>FjU(q`YD^}am5f;dNA&B1K~dpd4efN#z5MX{%Sue` zt;3stsAV=5jEVV&r9vp1X#Wz=E#P2HxF;?~I^qF^2M@y3u`5841-+-53`gP|aW%>c zr^6l4(cK;kd)Q-`gARK<{Vt_#@YDQcr>OFM>FQJVy5>Ez!w`A!dr)6 zIvE8qIzx&LnF`t-MaX~4O(7H(X) zpVNU031l2Hs&FEA8GG_XZ8=;ggM5?rctdv^j(6wvHN>x5i^-Fg(t3Mxoa^0XpvB(! z(|s&SbjS0(^KpD-7HrAz`+7O!*I&NpIXUm1{=#JR<%{NXR(g(V95!jBqsF2DWoAj} zr{YgPSAmCyG1}K{_@@#NPv2vH@i=L&5xwWtwQl&O$^;J=$ne`5UHnjMk7G;S(47pa zp`z^Fkt5q|{;w#kvz^sdTOl0XY_TuQjadK$^oWvK6GYvB9c8r$HFIZyTfcUlG?SAa z;FYM`{P-6}3`=B-EaI~jdc)DCn}i10AT-O8(WIV<3f&PHK_1tE6lUMn9iqSqFW-H{ zyT9IJ*^)9=*r7o>_@*@rztqO#&BoFAP+N+x7A0X)x|*GbDf{AJNj-KvmYoY^EHtH=w%AIDbWO!X8*=}1RPaVqB6pSl#cCT_+Vin-30 zcH&6RMw}@iq0VW*-C4V_qj(J|oGMRF*O&dL@<^YAx+p0OKOS9)!k&iwvzS14u9yCPTgWW7J@8%j`86PFxixaFgSCR>T2VW5sYjz!tvj621Hp2|2CX^ol~ zmw$SMg$LGAkf6LX8MgA#BXMxm0`#FUp&J=ydu54)TwbtzkZ_8#Mn_R&Y#ED=qy-!f zT`#Q1t*mC;OW1~cqqgH=@n+QZ8^gwBPT_Erpr|YWrXJQMPGm})OWDnMShO3r^Ecy4UL(FP>BQ#V6Ic-^>S^G)~YGM3R?s8QRS)5kX(FLLt$@xvu720(d$GU{`lMbq_7|H z^x1FhX`8CnbMgOpSr0Uj!d5A!Vzn3{X_SZ}-AHb@7ae6Q7cBi}Dm$LM#nPEG*^5S# zQM$7s6hBtc{SiFAwOkp$ZS9V|1doM2d0DF5{U2A>3B_Zl3(KBmselUvD{hh(In>i0 zWA&voGBGVY#M+a*g*@g=orHI9UvdNW>knO|R0&z!`O#m|8|%$7u}O6lS`^~3RVM|F z`k5%#9Eo*SsmRd^;oi;0s!cqHM>JxKs<8`aPw+;25&l13F%VChlJIeTGO#)YsHCeo z4}aBX;$=-5o^C2YXTB6SrdrByF4PFu-4$>y+!8bO<=M#e((=Ng(l*p3tRw>=*xgOg zI$#kVE;)w9qbBkBn@BjdCa=P+MMrRqJjm#31D)wf9@bqR7exDGtP@hSB-$3iVz?sI8u8Y0><#}$DFPzf(d%sKGA9Ky zQ~gi3QE^NXE-cxDTeJ4yYJLOmjc#K0i|a{^xIJCl$G7!sRig0Jn z9<1(Bh$&7Zus3TJ9?ac_ihvPpe9CPMagWyQzP}#DutsdC7x&Y^+oQA4JZU%^hKXd5 z&JfhT8LEdf(Pmf^<<1pqq4e{gPHaT}@E$B<*RP!C&YPD6jl~$rU9GLGum!R}v>A?O z;(Jl^zELfSyln=?Xh*|~?$uac3+u{Pac9+s-(TSEi}#pZTEvE@zmp7)TDsv@xjepF ztAtytRq=g`D^{l~^Z9pX(%{wqqY7)QrSe29%>Dt6xE82|i*_=cr@;DnoE4_HShA%S zo**-RI5>UC;{a(umcQdZadE`#nM-(9=|Gt$mTC<{gJu?LR1&e;U>FJ&dmus47b)r? zm}4~(<17dA{LRUwQ}L2C_Qi)!ctwi;+mq*r42j^*m(EFXcp>O5%ZKBy%27Z~B3`cP zkGEArxKQHlzUAnzD|!D-5mq?kp@5sg##rHI%$Bzo#Um#s)#6}TJt?aZEtnn&sXkT? zn1b~Qvk>o18(`ucE-A7F?dV8!IVB7MWoIi3fGJ!&mK7@#OQB ztT3)73OGQXp-+%5(~TI*E3jhLIcqb6zDUkoi%`b~CkYbAkwTn^bHRBZJ$%*89f$q= zq~X+boe6WnZBKpN@H0o7rx8O!@tUJymbepQhT}afu*zAJ|6VAWfZz!|J#p_yIUasK z4?li32WxXe;H@Aj^^yVOaC&kZE~IVXA=YP;>v5xCD{hQ##_6mLI5DxFy=GrCEqt@D z8s(YMYzV~hlJH<=YHA2JbHWIR2xQs!M!x+3%<@daa@RC$aL>m&n{lYLEXI0^Jj^f~ z$@5m@9AdC&)KuCpJ#MJ)Z|#rEt6Gt2Xv6Ti!PgY`1JrRVSQpb=O;`~tN4n$v@iizN z9K_*4xxErDMVjC^#gB(cb{l&+u#7}%lGoe00Mj#Kp)1CJ9NfoF;>D|%To${nxrL`Y z5M}g%l=EuaqUAN;L^pI@u`I7{J8pwuYv-c=9M8a|whfoYlbi80e7EEg2-k z*PTANT`7nA>tuMiP6>CaJ&_bF$xlZ|-TzG6-PoduQ@Gp4Q5lyb4RG08hTA?e+@ODt zg=%17h!ZCT>?IBAR|#X z5^pNw@qyx%O{06UMa`!8?XyU8TnW^{k#5Fpi3M-&=HWANV{$7FlvZM(aS#b9eXe~h z<_|38WRNYh9;h%is6Nl0(Z=LHIcP0g22a}13@?3rx3dBUIzUmr_pBUQV+-YDAiv;BQ=o&@f$mkgH(<{pnRL2q>_*2^W&*%{=B1{((~vveVE zEXT^Z$V3}^eC%x2_{816sSOS-xnT z6@e2K!|{TY_gu{!^w1K#RLWS`zZAE~DBT!KiksVxlj(IhnpTc`OShspWH>=h6~tK^ zy2@;KA5XA1VtKg zgj)0wZqoyKkx5+VEYMF{a9?bmvy2rnos9V5C_7y6QO4Ow3k=baYP%0i9)Q=Mt-yrg z-FbZ~94I6rXLE|y?#l>GRQMW7gRre+_~Fn>lx6f`<9Xt<1MFd+KYz+WY1R5lGV1Cm zQ0j?l?M&3GdV2fv6vcNR-s9C@pYYT3Kj9x_ z1#60DH_vy(gC;BP7k@wy`N^JmY@8C!(-oq6_#gNmQCJ^0w=)8YT@1IuO$Qln1}NgZ zuZW3cI22{U@WVh;9_KEe=5Yn00z{m(zI*!`A&!2e1coTo8i;!Rv8a`$pj{yg>-19) zCGSEDA&2VGd8iqkP0FCcu+NSbT#w?+rluCWdC$!{+)?rD$$RvV?#+;KdVCOlx)bOjTWS3UyNLbyA*4kOs+&* z$V6Nm--^P3QFN~cC^6`VaT?L&ovcZDl}Tw7xRS-g*&Sx2Tq2Hao1KL#?eh_4Bb|GW z9hc2b`rZBgVXUsrWor6d;IE3F_5qj}mxY64tMJXVUAUduj;ncX*j2DbqOx(fMPIW1 zJ?OcwH_X7}Jr#&|(~*WRPaOJyTxKJ*4 z+KW+MhFFz15Vg}s!^^^qdvyodM51=sTwE{N#z!p==k36fKH0Q~%3MP%6n}Vt8>&j; z@!h^9czR?BwodDZcqjFLh|!GcZ_UUsN`0{Mq>$QdAjJuS7+)zG{C(;B1p{)iwO|!b zdk?2;@014Q_Zh{{xy(orm&5IGGK}JLKSTEJ!(24+aN}qu8DCcv$H~Q+6arlC?T!lp zYPc9|tm3w8V>JRVe5i!uR~(;w7%$`tVw+WSY5jDan8~rfCdCyG9{X8MVu@ z(Wa1rcGVozkiu4~WMaKZCX!{{cv8i@$#b}aM^v+kaWMz?Z)PtWPWtn8TVMRp+7nx* zc%Y!C79z|gid!u?C5XiCe@j_KRfZ+S9eEb2xK9x3XD@kNCC_?99BjwhF^jzr;7QXb zu(Ce;C>o$Y@}cswrHeU}n5xtrl}5RwtXbHuI1Y8Pk=SIFjTlu|zR}|qbMf2Z7VKO# z4G{$S{%!#a^76*B=Wp=(%{#n${T6Rtf5i6A9ekW2gn3{Yp@Ml#fuxlBn zcGG8pEhNwJMGqaG&D!W=#OHK=q(Hl-RpRW}2HebU#$_?)Fs%{a=WfQs$-6KiIGKb* z8>7`DQR$wCg?0%Tsp>;9x&fCDR}& zasMhlJ9+?HIyYlz|DjM-5c6wQm@2cxeGpEKuE$q%_G81y>C*U)SPv{s4`#(`nVo}Q z4%c9)qb9Gb5Xj{{9I%+Yx=5~wK%fQKkL zBE~#~p2v!LhpY%W*zk08DQQ*iMWI5t9YJVaoC&nXT2p22W^(C@m3iWwP`EIE3?_*A zHz{721$i$s<*tT&MY?BQiBx_5UQF;9!n1^Q)KyTvekH;K0%6oe%@S%VX1rSC(JnD! zWHl;Fk~uSN+NIbgN(!*i(dAAgb2&pUf7F*r)8sP!!f|4L4Q`h2!S39(I8{pMXhIDS z8WRj4p9ffy12JR{>YiQCw|&}RyxKe(Pn*+mVQmH@E|GNF6l8}cAAMB&nf`O6cdvFL ze%iGhBSd0PK>Rr4ekMoykzkB-@*{SgyJ{5+mp(H>a5z11+Er=9+ zfJrx|(MgL>tNU*$?1JLVabmNUk|LZT%XEukr@Q{-U3+MuF~CY1YoV{n@ZtTtHw-0s z+B)G_3mpT7MzhrWqFr5LN8BnKgKf%L*q}24DTDG5WHH8rU_9_^XI*1IxqFfV|ZOuoOr4Nm(i;d*aZ zBx|dZ=ak3t-i5d@Z8Og1Zp4L*4LFm&2A3%2x|m9kbesE|=YJzY0#O4a>OS85h3_B! zi1jO0!_ml;&saqpS#9Ael&4B$akZt9*g>#U7@;Yd!*Hl}F+)1>Ea@r=_%hZSM+20w z#!-Onuk>sGT&>OF;LueC(RB9u*^IqQHL?8%j|Y>dHiIx)|GID0Y`sV%vljh?3K1C7f-m z$#vvc!i|w*AkRN5ALxXa9ff#V-49RK$KiF`Xv_#!<+b{o2TH8Fkn7olobbn<`PjcW zm7T=U{xNv<>}QEYi{$S9t%qE144zm{-ITnN^~ZSt_E3G-j?Ws9-;ifnZo%2)82>4!IOx%%Y;{ZqMY9a(!t z4Ab;RjY%>ZJgm`9LWNBdrn?S8q`V$m{o+0@c(`LO{`hPen#afULx~0S z@vz5}chB&WefCFA0tjoBo{|80LA^qX)5lL0OL8OmTut0-V-G`|>SctZzN%>VHe&$~ zl6S?iacwx8(}c?zn{Yn83g?S!@#Ta%oGhxxnqK2D&L(L%A2edg9?ij zEO*F4Ds6;_r;N!Wic&q16>guHjvo$IA)+hZY~9qzbgQr5zM^~mKnmM6yMf}FKmPau zlS)e{Ce@<%FymG{VVD|b#Nq1pQh1w@Ad#`^7wpP80f7oOI9uRus6OtAy4vn~XbrN! zU`++SN1;%nHrJ8ftI#hU;~f*p1Dj!}%oeL$GBCn0fCPgCT{aM_ZO3DnQZNa>F0(v( za}rPkg@(55kwn6&v%4vd^|ZkLI6IV>|EET}X|KiQ50vBE{pC2@z6d>B z$rGw{O?^|+ZCKvq8#nrrdC%k;zVWms^VMsBiKok3`Q89(Q zt$`8~oo!5+g$pYV;EVY?ae37NY%Z=qqHQ>jAGMW7<`$J;HFP?gpVgPbVzuu;X3Zbs;s+8d9yOu#o= z%8(ml%M6P94sH`&%XsnfPrM_~)4pjt_p=VRibA$!1oMH3kfH}c`4ocYYmJjoBR>kQ zq_A!Bxmd51N`^j(es52ZUxO>5#8J6X|(0X^l)V!EgYa!h1#<0u_k{fmamN9Y1>n4mJkRmzSO~fDF|AgEg2o zBAmTmoOw5t4Vi!hkHMH6OE5EgA--8o3OsHTrUYiAo1!b9<$EbFgJX@^NBMAUwocXFYr#VvZ9%^l&)F4!QdBEOb+y z2jFDkCajDs#jeD1JTBRTbE(w?FC7>m^iq+>7%O!w^w7h`?zUL#W{Fu=1hLF@5Tzj9 zlNW7HFkR^yUdXWt<9Vx#rAvm>|$koaP1xr@7m2BIgM47 zsF=SHrw$y)#QY*Y;t&(o#F&XMDrey9y&Di-~dqG0+xQDDFBF z?u%?yJ$|lHnw}VI6HE6d$}deZT&@QRl4x?UBcaxUw}KYmdyLEp{p5XVom7!v-UDlV z^D)6}F#MFP+0bQD$RG+~zHn2)EiYx9wvpjjm@N{`q~Z`^RLs>Rk1qBoh!n%Li#2~w z+YZ`)0ju7za=!fZ{%=x39{2h1+xytj)`^M*OAs0u$ORap;z_HE>};T$1;+IC`e!1c zFyap6MMWi?8`HjMVsStQZq46=ilMU*tlHl8G{cctdn|F* zU=jmia0SetA8m=V3le}mv+?`75%{@cApWRL$D=hP@TxHrhbG6ufnrH}8*|*ge~StJ z1Raqmr@eds5lr-@p;}^{2D-@O*xDSt`Md^)XA~2>mZxyT57oM2zHttr$UGk5(V?D+ z6}p4T+p8nQ*N4FMU-*;OTH+-mn_4{cnDGRD;~W1J5$#igFk_$=6l zVhkmWmXoZvc#XJ6D+NX9DM(dGLeQ3`4aCoTmZD?kFpkMA$%+<^9tR&MUueoCdJ>H; zayG55izlW#sWAK<>F0sVn>QlX)s%lH4Vog!KFbMWIb! zEO1RmnaxP9$+nZ}aQ(KCOob^|#o3`CG!r8+ELjOmkn7eTv1%S%&1J!L!14s4HL)Wg z2v-A5a64EFXCrO!*`N?Cj1FVSE{fSx`g-8-niPzU(qg66U?d<<|Ej^m*$b&DS;)#N zK;hU@jLynK>hKXr8WIm*J6E3ZE9AjN*$mOHer%}3>lY^WMAM`U2zC+;MH&B{CmHlI z!@($1?Ts;-WYFo}gJkAdFsy{0Pu#N}5+NMYvLplkI#Q|R!TksD;e$j4EhS4nVbO|Z z{~vL09ah!W^$l;jySp2uq)SRg6j2Pi8xaib?iK?so@qUVF_sNBl-}bU>VUzP|y!*ieM;H`BFc0`^TQW}X-(^F^~s z5oyXSv?!FISysRk85<3=$ox=-zOpj@di58c35P5(t1uVV)zormDn}NHwfaS9P$Foo zlEv@ICdDSsYQ>7W-v2hku36I_D0-|$Yq_95X%v4tAkTk@R-Q*5Y}&bl&GUEkD9@iu zb6~Rb^N5I5F;8y@YE5!z!ySll%+OV`1P^EKz#Xz7zs_pIzw+BSiTm5p2XJrfKC&k} zv3kfDglii!6FBNO%)T-$NUxV_b2aY?%W-_S^{~ zyxXB5Mn23LG#2M3Y~n$@VqAp@*`|x)2%^VjvzD6b;fga+4!GbU!xc9fE{dVM^!;UL zx?JRN#Y+=c!Yy!+{$^R29ZCZn5I~w&z*b>DOEFSqX09(cOv6{3r^ClcrJEr&;Hqki z+<^X=Hlz@fh8DqDL+YngG%Ogq>nm}2>pZ0R+Az}wm}!t8khEB^p(f(Bq^vC8Zn!U? zx*KaDdHOtaB4#Th7(debk)%c4c!IkjJxiin2pUJvLvz())a1{Ew~7mo$#kVN2vKq7 z)KAWh)(_-;2`8pr;@J!P!yU1fY}YD9sjEh`k~}l4Sc|WNGQRtK4*oo`6ze7z^7$Ca zX`-)h3~Uw6>2pQ8rf89Z8eB7 zR^a=K+;b;-zA}UUJZrW|I}@v%vXG+c#ddgccrqf4dlKD=t`urGIk^GHCe>rS*7R_1|a=EYd0nuYZ$nP}C{#&rEe z_7<0yS5*Dm47+O8+Hf%jaExAGG}>lkB|Y2nJ(LGdiGx&E)#5r+QDp3^qee_-jIIDfoDR{(`A8#di*P`$h7_yxB5fv^ zHI!_GrlDhSVN4rtj@pSl)j0M#ibC`=#cOapdl?;~o>YeAX@yhKF1QhFjaxp3xb3fx z>j7H06{1I))(EFUY_UJu3yu9EQ0CVYq1NV7xtY9}Y9PhXLNyif#r7JE?JHI2M5x=M zC1oy;)VMmX9S`R3z~-WPEUm3IRS_TJf-Q3j@XMaX_@Qe$CdJ#qygR8tIC?7G>~Jj3 z9lM<6vC>F}ahgOp+7i@@p*0NC@}uwdIek*>tvFem^s36CqhV0-8QT+OVo*QJxyiU zyf72bFSei}&VzrqFk>37Ozy(*j8!<6z6M7!Yw>wrEsm9~$LZ1S+|&5_$PRolcQ5J+ zXR|O$uu;Tcr<+kpcBVA_T%JAi<8%|TT00kw$~jo0n2Oc5xg?N0h%q!#Gi)?AWXvWr z#+-!o2wbgLkE`WGGvhjNW@Iy_cno2|CWLTb+Q*t;SAxhraK5(#js}p{R+j`Gho;OF zV68&PNJ9zxc5VO1oD;St4-g~Ub=92tj0C(a#3aVqc)4dGjxR4nNgq2{t4ij<2rXZ% zu`k9(?Fw|riqWc6Mq0K2Tja7x;ACN_QW&k*2sJB~amZ8D0KMrpXg#$=fr1|9S*2i& zMmpBZ(y>uB7xVO!xr!@pQ2)Arn_=tM)JIs+W>qWn7Y<>Yae$5u z4wtXu)WmCf&D_B3YEcso=dHpZ9Us;(=Bg4ylzOS*oAxR^Ik^mrs}laHU7ciUgew6? zc<3pIdj!?b_i@4MFkgPw2-?djo~fvCNkyhx54c+sGbBQAMK9egQ?y z56Q*hvFk{C>vEM%o^fA{RUd#VSrp1Ndy}>{WLs5yZUzzP3V$m!#ra@nWDiCTTvyv| zb2nFT z`cBNSyJuwK&W4%rGghVb%5hF{nPD7i46@OnTf|vI3yji`r5Q$uLIb^(ZE$>M6K>Aj zjGNV)aBI{CTrX(Em5jBxmbo4`i#ze<^!?b9w*V=Y{`4L>X5O)6GVSSQ#b(m^L?0~e zWsL+)Y2O9I&8!}a_wR_6M9lTWOT78`nk&n$oV^NdIaMzDZ(B4P7wRUUGRO?>a$%i9$H$stiNDPBGT%7NSuzpO`lV8}##0s+UOX)yITUqlL>9PhY?0j6GrC zN4NxXsA`hMAk=AQqEnd|U9kvjOmj#8Ya%Gp|G>Y^u#NTg5$3d+6^f)`bxX0HjN|oc z8K^bNBV#*&r?}m{`hc^Vp1gj-*#GUbw+QeHqYpJgqe&IdA(^i?g0qH%b0oz)3ax_{ zVP8f)j+E77XYn#LXD`O8^w}60k%C?%c?6u&CvB=ja6(C54GOB-C>dFS@4mT@l*Cwu zP$HveshphxephMHsfMOE55DTf~#4pai_Em zr?cvDf7)TJ>QjwAYG$mR1#IfsErrdx4^@2c-p#0eXuShurYN)wM3|}(3kPQdMVxG& ziERtY_;ZD$=U~Bd+#R(^it*;w;cP}7F6V8)SECN%cyR~M8?{kULYBV+do+_>W%&Bw zVsy;OWMUFpVxhAYt_54*fd|2Idl^po>0wo106$AFvgPs|hM>eT6LH!>oHQXmdwOgc z77d!n`N?|3Ok#Svo}3)VF?Uz5Ly}7z{Z5-c!;}PzJ|PYbx}OF!wYYDaj|J}bamFQI zbDRsY!{Gtm42?NK-rNWcV^a8gN80|(KNK>&cVKtwYWQe2kw=1asTG~g&nw+(}>f^l9ZhJ zOhw~@d{ZUTxYpQ7=;v5cFjl)7Bfk5LME6zZ@InOVL0NKSixCqKRpP z>FOo3ps%*1v8+i#JJNl0dGw%2lo0iqCSszPk2|zgRiU7$jG*w|JdR#y^1uH21yknD zhq}Dvz8`6+fbIPPurDD9i@i-zZl#Pk1&PUgMfb(t1vpsTfcq2o;KGPnTuoieJ%6v{ zH{)amX}^iPad7f_?pHK5Y8b}F4TFn;CFchV_~=c8PQ?VouHwQ%${e}S`!h8 z`^_6r`47YD%PVo5TG(j*Dt6d3YBdJhMbqEuk-#vAzq%8KSok8E1f)5wH9<`S=Yw2u z&t3%=O~`)t(7^FfBNQu1&Myy<*>$J^9Tk1qj_z%%hKwk0Ci)`R!MHyC08Z0Bi+%mF z=pe3+AO=n&MkYwSF=GLpg*tlBew}EZh;2*C;B6#5TZoAlCOZy8zN{x9C6UOl%svv^ zZq07g4b%O)1zDm(p9r>?=x+;zBIunrds*W><}ZMZaMBTBrI z;HDsDcZoG*)8~&T`Z^e3i(L_p7@;FMlpJ)`aA?pp=S6{Y=#8 z4aWreJ}8&Pl7#DlKzUoXyTp7|qi&d)9$|^C^9d4_B*WTB6XupC_~wVNxC@k6v&c5xd)<~6uJb0@CN+KF!#e2%W{rRb?@$FbKuStyokq@rD?1Wh`HSZ!T^Qr!q< zD9dhJOw38G8q`zDRrO86y$QQ1c)w+mMXcj95j7P?yTFsli-vs=lY?nHamJZ>p7 z&|VK;AE?DJKW(YD)EH5R(2R@X}?$$fB!4 zCjtH%cFd%r{pZ11ZFFx-&Sw>+j$#C4wsSmoRyV;z!=Cn77yWFaP~tKOOT30-qC+ef zXAjgh!I@xR{OE6wFMSD)`wAFtjVvX}ruH;c#dn+M$Oo7;U^{T(lI%r z0N1M8aWSQy1mi|r$=QZ4ChWqFoCOG0wc`D1pEv|z6;TKg z+fSuy6qy<03DQm{)1gLJ3yZXLFj8KgLp9>F2NR=T9p8a-#He2rBp1!!&sDYHWa)aY zjJi?Kimw(PLfgoN+|E=?H56z`ykFe&e2gWI$Jk(zi)6bC#!QOn1ua^yXxgqUr-B%Z z089-n#IlHT94}dqi{p0U=ETqOVCr$)9&?DVha`Y+jM|DLCF@8iSp#L5UA7&(0LZ!;{Z zGzC`!=jZ*2xmK7+Qlm*J4ei=_n4lcXwTd-!7IRGWC4uudBCY4|cZiP^%&f*E%#R^<$Ikp0`For7A75-jLhgdj~TW>O(d^FrORV_`o2_1Q9N1?k3dx4(?*j z`uE>2@bTp{2~W_+9N4-WPTJCl3ZY$u_d0{Ft)7~=5o3&-1Fg^!MjFEWzq$;JFbKo8 zjFtFyI@ws|jX0ID99JtlFu^Sy<#t1HW9mVSbxz~zoeZN$tkomQr!V3}(H zPd4`;jj7L#z zjY9|mE;chli-9tBxEoN_;G_ zFwm0Q&+ZrfokEOp+usylklpzuY5to*?l=?fj^U&T`Fo#(@<|vfK?79 z=%d;L-lop~`nMTYykdQNpNk-gz087cs-1=g^=z!y$iocXA*@9Q#`fhYU~h<#o{7{D zdKIT^3g8JkmRzkLDUc`WMGj_8bQo()>H}ZYB;yF2)}nu#b0~o<5v4r z^mCWG-H#ZWAO(y>j~y`*Tuc;y{Wn(3Ucxqokj$N92jEU!2?|^!rWH0zk)aIDfu=YX zYlIs~HrV8)!rd`k*e2CPnO{HbC?Q5!xEIX>rqa(0=(0qiFF{mqg2Y7BlkJC~(Xa$- zNb)u6mtd?$f9^P;-_5N3JdH`XtV2b=o~(gJ_s_)TCA+YJH1yc0V#M3UAk5sCiyuTs z0;#2_8q5_;kQJVW1h*)zR7&=8!0&r&@#0V&n#Pi_P?8A8NmbG~A|bzmuEn}C9Po=m zg}fz0Z*OfI3@{F0&$k<2X0#`2WE&fyGI|8(+=>n$ZR6J<*=GQUTwI8;2dMgxAaEur zZpskOolF-|QYe_pr&|LF_{okqcWbWH5g{x+4att{sU^df@rihLY%MNtUXFhLF03g7 z9KErrdKH!q9gV8KBM@j} ^6zC{E<|GuyR^?4Eef5E7#WbWwGS%|{$Y&R>cjPb;g zL_Zu2HNy#CbzJe5k~nTS%5c$6hU*@xxa6*m)5O$!`URoCKvqO!`zJRb)21KWlw#0U zKkYz#IrlJTd!{pe2`DTg0V9bfx_k_9F2)JR`t(4JhY6WFlAsmnMpH!*Y8vX0Q&NOH zF|VGQ6q*y+O4Gv9aA7pr%VRg=Zb3UErCXV8JRs~!)_UA7Y{$(>TQPG;B|Gp+WD!_y zSBMZDcc{oI;M9>LJk0##yXR8I8?i}J!~jM=HXNqXqP^F`AayqkGYy0TouP-d^Vk0o z!)7L>Hua>N%`!{G8m%-mspfIvyy%06#1tj4OIrsPI>QX%3QjI4Ys&Id86|%gInJI*pIdE_fXPk)K zVKHhEuivA!W+h9@o zmn5l!F^4Mz{E8q(T0g83UFFMYldXxk^bu{~k1@d+^nPuOkn_e|qf`=9`6yG5Cn7fI z>1(35tQ~38gDvw=K3HlOYNe`$`fM_cF{ zn?REYRZCR0bfbg*WHWv~I~!kgtw6M;j#N^op@6QTLD)qo;dF!^ZUkH6OYZ=5n0qo2 zie_zAJXcl+$?E>dvFXcIIikwNihk!LQ>DMtB`q%Cwk9VW2x3ap3dKs-T+DYMp`jnj zxyS;6e0{bvAusFXMqWuc2oHRj1S7@q!6L8M*0)26|A5&De$_| z34XT(JK%7X8_vdBVLO>08QsFkhSnAA)dN){%W?7265oY=)V{Zm2mCB8HSiKc@t2g4-gbrL8+kx#lOA)T(#sYM<(qOEzEu{CEun*?( zs?@;rS_|;8!@H>J{@a z*Eo|NPz}TF%<%o5rFgn$8ZIqP!vIrxCIWGw0|pMpFF*f*ciof4L_qua$zvq>Xfebv z=T;Wu@rFu#S2GBYTZZDBHSu_~wH)7fRG}u(0}0)8Uj!q>hBQsa|RyJ!h+U%Q0ge*a!n1xw9)MI*Yur9Q-0FP%hcVn1fgPsQ9^vudEg zU&YUbx440X*M$&6T=Z7PRcA$f;cS9qULO417QzPB^}%S1{#fFig-lrh5up_Vl|;sq zHV>RK@2)fLMd%?;tp_Lli%`OFSuad+$RuL1qczH7hK4DwMg-w(IN7mL8e~pbVy(9- zYw}N7R}<5Q;K_xJn32+h&xi}_iBVUqT#kxSr5Ku+h@#Xyj47(ZvXyJ_<&WRt)$3J!H6%L}%`qXRWKx~dX-s$y)5aOh|v$<&XYN93ievL@`=eP(HvN|@`RfzD79>tQj`%cM3`fL zm<^`6X#X=pBRw_@=Pw?^)9yjcAK(AY%4S_dGYqu#dEG0^QgLbhEW}#K{;A&;HM?Uau#8o;J~&KH1;B&}u*m%`lB;+&VhAarK(WC4TntEf=&4XR%1& z5mAl9L*vltX^tH|%u#Qpjp_DA{8^!X-pBqUhCO=psEwVR_J;vvBeWWpqm%5pt-?4~ z%0#(V0!eLSBt^z^hSQr@QtFk+`|WAxO25;;ApaqD+^)7{S(#}PwwJ9gN%#x+t znv4WAW%Ndjg5({wms5wDf(qs>UdHzlV_QTa@Qc5mBRnDi=GroJOp3>g1Jg*eR^sL6 zN<7&zk~D2Oergb*l%#1cUB?}j@m-J}ZbqA=2H9r8Ri4cpr{T*@%jebcE?RAl%p$16*U_rX<2m^4K(I8dg*dW=7LhlWfl6 zi3vD$=m;MF`X@fT``DfLC7AOa$M(d;x=(XSPMtY~wQHBsd!qOr#RCJ-x-bue{4~+m zMhU$wG?>7JRIj9GzZ7eSBMvfL_Ef^%U|Y1gn6pH-p=SxBy)PqMd!|(~Ar>JZZ85<$ z8y*T)Ojv^~dl0lWAatOQ3g;vg+V!KqapthW5Ys5Od!sbYopcTGm1m9o@SjRg7R2{XG#HGcf3&_M(*o|2jL;+^Ex?;GI- z6FJeH(i1-&ZNS*;x^&QW7e$UQRp%{Yw{23Vt4S00rI6T-rAEO4la4M=WS494S3+qh2=yl`=84T@RDS&-kYq;q#9lm~nUSImm*!Oj$G_u;FB#dwz!a zBE}h8A{^mHT6e^t{%!ve!-`jM51$jRqGP*BDVk)3tS#Hji?P5hle0BMarfnG=LLD< zDH+y()7M!OCi1w4WEFp`)=9?}Wl;}XK=02$vqnCqD)l94r}K|@P)OAb^8f^@Si#Of zAE(b9=IV}T!gi$%T{~wUOTCI@Z~XcBbo{cV9DB#dV|ITROpbTM%1nPeXvoBi%|&>; zDit5vN8$0tvADE)B*#0&{pXR^y&bBFV`T3hh_c3Tl4b_1t<*VKZBJi^*oUAYZyqiz z+>VDU58&p!ZMZ&bFH$XH84i{W4#!t}=i$i84CFynZq8t3v zcP}{+{`rTu+~W1y@4rSxK_RU4jXBj)FhW6JfBbrOBYr+xk6%tK!cW`B;LEPD@HCL@ zDnX!YdRgL5eUk=f>puH2t>H<<4(fSNASuP1HY)XmfojLR~+k6nJ z6(WdXb?AN8SnXYmVx1_4$(r3=Aw;-liKi(pM>&$6sEph03b++!h8ZT(a4gYJD%jD6 zwbH~`OFTJVhwMmSX0~9{9&8)O`A6dJrE8KJc}1e?g~Yqh=pWIE`d`01Kxl|FYw881 zgYe7A2J~}Q;No^YhSExi)a-#t*1`nI!6f-Uq^ZO-JC*LdX<}S8eH54lVQ$ZK?8#bz zI}-_#7B=BwzGy1mfODm-*ju%lnOr#OcGBlv_ff~SFoLK(4W(Ro6&WTCa^rOg#&fl` z!kJTNxfQR}8A6(?v#q_AJ<9?)1(H^NxP3l;+CLBNGn3(>DlvUubq~xj%EEk=9L&;A z$1<}#tkuh7T3=(AM-bncZS!p*is-o%iX7A50jQ$C(8 z8H~T0i}BaKg~*9;V2HHNktAB663+LgLo}A8b%c=ZGiW~70Zq~q6<_1H4M0RH+Card+^K|xw7Zr->?&;L;> zUZ!i)rcLm6a^tw3zo83UbR9{%svS8tsu4 zqLtlIX%tVyY{hk_+%8r5Qz5m~5BPL|DJ})s;6SJcCrq$5GEl^!=0!|kQ3Nr+-@gW# zVSfC(_TqUc_87=vIcHrfj7rPL*EjF7mVNp{>O=kF?~mL>{^v*Ez}d=_J?v-KjlqqL zli@*vNnc6E3HDsVM$mYYZZhi4icn`$ggouubhhTi&>Bb$Ov1I9d+@Mo53c8knY9~m zKdl)L(p$Js*1u*SLb62w+k!Rr1~^X;_-3F1c6;mco(Yfq!RdqX=Ye_HGCdtZrV5O3 z91Klx@8*5huCHHzGGE>yz{?FXC26`{MSpkva&QrTB-3sCtf5Tv0=X>L&P9j%I5cP! zW35UyT2!*IRwskIDB6oYVUa_)3E?N?Azo+6th3gZLnPh%Y@|8v5FOtTJ*MdEg-~rw zGL{Bvb?)x$^&d0rxpU{#%(aZ+PlulC(2t9F9lPzUB!7~CbdZ_^GmahJ!w>c5ja0}! zy>ucEz7;XUdW&L)(IRKEL1_ePm4~60BvX@dAv$zRvBo@~2TzI4g9~QO!Fy3#`SdZD zZJj%DhK0h&cnAD;Y$a+c1~Z|Gbiq0o19WHa@nD#NV}9c-b`_OGqP& zXU#F94GA~I1wS>^`Wi5^_g6B-=abgs^1`jSwR9J*&)tgpjOp+(bSGh>$IatJnVNt$ z5!N2)VQR&aS->SBKuQz6ad-DJ5+F;_SQf`+a;DvOsi&C*8duh#qppo4rViUP(;_l) zWzjYavyURe)nG57&^iu^QUG7rE@5_>m|mF%M+|?cWZL+YWqyws;fq*p%U+Zgr66CaXAY~;N$ln zaB#;?$OP;sfoVkRo{<%b-}X+x(?c^cBRPnX;TTyo)~gqzSv3#qFc#q)&WBI&hd8p%Nm_F{g%5c}46iqLAoQbeQGX2iiT;tFG zm{~u)k`fYHM5VmYB%&l~sFw^IXFB2bt|4fc>c{OzfBEPsoYky& zZq8VPWHg$Tps8XxqMm^kV&G%1mONne9Lo|<=g=-Tx;!1Tp_Lrdmaawm;j*M&D4sB(bU7<-l0SwPB>w!j2mIr*cIh~R3*vQ?{BID zS0za!35IPMn}%1%=3vv902Us}y?qemY>6m+OWYl`4tH`JaDLPVoSnTLvj&yHSKAV% za%$YTPOQO7T^Id=BT$-=k8RCckvC)*j77##YABwbZovQtB^H7vMy3SOMMG|FI$Mz{ zs)Su^)SY%aDAK) z(!^3)pAbZ8dPEZ&rxINh;$34AepxyUAGS@w>4in;p(gG1(k1iRll$t$OKGY)!PoGx zC=w*{uu{`tfjTza3}3cQ#k`?$WOgWGv@8@G^o!9T8-ZrUG^{6xT&x_%XIe6%SilQO zyFPi&X}b;U>R6Z$7n3N0^>N!*6%UAEZ@Ej|L>hghi3J%6(f{iMpwFB+qa_v=OmOgO zeSiGW=7S&GZ1Aww6hE|tpfW^qBCKA%nBd@ZJbUwq6P~wqZKj`Vqqocp3)R!HLA?a) zm9l7&Y1pDsg3U@L*eJ_Kqgg4uNISS%IpF7Se&dCHeExxxH0If2(48P!_~zkGa;k7C#t zLE|l(cR){38{t|Ggl=p7Gv9+P@o2;V3t3^!2cB#(}cj`06wh83@b z$jHss3Zjv>4Ss5K!~@Y=b%_j*Yt34uwL*SFL`irNoF~1zHoU5 zW3@Zt3rOLG_qlvk}Z{qTDM}%am>O5#|)G^r6R?qKjN*! z;G=H`8%zV6ual~po z7~O>%m+r-u-05`2QpMGF zA0u4w)xr%zA+?rLSZ~504?HGj{j*^Rp4O$}Nlh|PmxK@X1Ms3L34d%KLlEDT9ZZdD z*W&MYZ>5~ycdzi{k3Yjk-HZgHJtn!NkO>w-LeL8$^KYz1AFR_&L9Hwi8}&*tS2vXu zfdiXRU2R=bUc$RKJPY~Fi|2?A3S=6I&{V>nPzPM|)x>pAIo$Fhl;fj^t-Wk{uN@to zuKu?$>!+8Ig6yRaG3D{q?)a+R0N>Wh@ZCHap0v25b+j4m$Y2g~(8YK6AMitqe1~U` zo*=eo2*+#_lmfBTI0toV*=SVG=Dx05M1{UVA@_OmbPvQ|gdpB?5%CM2Adpdz$_IUF zO+F6I8!pY7(I%U;uM2Jxr1;KT1sB3B&{tIohy2)*g{Rv}IlwP$zoY&-xJ5S2@kmFM zsK~g%b_2oTtJAk*u6G_%w1TiSW)yBr+l>ST(ThhH9tx!4RNXLG-IIRb3&Zq+kZ2Og z?QNp;0}yHGjQ~SO*b)pCX?6@{#9)(|J7 z^fBMvh@rHmqEzE6_ILk^skpge8EdEnBL0(gl{nHiAC*~&3?YRU+&Oe69^|#)tHRB= zk=~A**#uKFH{#N;^*EopmP_G|Pi;YpkK|!Dr)SUVYmJu4nV6s37sG?B5l)Cli`S=( zRoM%1XX!CqAK#8_W2w+R)UGFvRyE`2MaNKT6+_G^+ToaCM`mO-oib@rq(Tl|HWbHpH18@|+@Bs4MOJnl) zI1wnjyPNSS;D33F-ZurcNpk<61YTOOEc6p4C8h-2?jc40N z<4I=~ZZ1s6ttFZGqoWkhHss;2h7owyQHGO?in_Z{(tQq}z}vsy;N=G?cD{7{9G<&W zsW|{G#H^j9T(%K1Y?Kk*8W&)SP6E+_6?93Ej42((vG$j*o=C1?qJ1%_TQrmJZ|aYO z(>gHHXCP;)g|MJi!MTCnnC))N^qd?O*7)Dbte;+K10q(7174V6fbY5@ad)LA?ky(< zu2sbkUEZkfBW08LIO-90zbbVNr04(kr{Cb)qZf}o2qc?ilulo)B&OYTs^0L^#m;aGw)cjsIO14UD-PzY#>K)8+{@X9^Mjjkxo`un%-VvSka&iu z;(q?!gr6x0fCx-zsOh9B7F%jyp|>*z>1)BNJ6T*+WML7yxUp?56HKC<5pGZH!0qxa zIG5f+#JvgkrtiYm;^m0e>&g9>M2e!iOcQp-F7S5m#jvTYk0ZX=G#+2Ij>OA@bMfN9 z0(`%H2__7WgL!wZv93&Fq|zQv_&h$4op1L7jM<5_HO7^5ZH0zC7;B1)e#Fe)dbmhG zukYn3C8#LLA;e6Xnf}uttgcxFSXnN4F>6N-z|RMp5Me6E4nGZI*nmJU4#616=^@XMF!Uec8cOMefL+N=$YqT|MR^hxkF>3%`@1KNoOACK3StUZ_n&*3HMJhJpzYY}eMk3}y% zNno{fNF6$VfAxsl>TX)s&TVh<^!suGP_tYbS~N4U#w-IlYNEhiv>r0Suh3m}M5WOlKa3<`4h3FzcsRh_mTM zanS3^oblb(2;8gJ!-E>KCu`L3b5|%P#&=Kgrj7V)_g0oR!eRF2?{`QaHjLndn5&|V z5%R&9PWXShdl{09z4$$CHT7JT^FicY(z|~B@dplZc<9Kmduj%-b1oh?S7UO57XmEh z;7nS^n+~q6svjP8O~H%yGW<|SOl={@40_DZ7`K8=&=F+Fp^*YzLI#s}<6LPwPnEkh zbR)hi*^jG4aKp7+83qc+)I=+FY>RZo?qFM-jdsMv5K~+Zr7O-JpT)V8WVG&%@yYSX z385_}mJY{>4a=D@#@dG9_UKj|O<#knW47{)(?XX45N&si6!hTl<%f+OoABhfC%oQ~ z6_w1en`UI;+2>1eu_hf`Dgv>&G!)B{dm_!tlJ`eI(oZ(C5LhCwb{rv)RTfI9^)Nt@ zg)(cNVhduz{;t?eFuBpq5YgsCa@{Kzip<|6ddm4vTY z`v4uOYDcW`%#?n3vT+n1v`s{ui)fZ0!=l>NcuB1K+si+=3*?^7J9uz&s%0EjI2B@% z?l4T$=}&v^#vw~fB_p)dHZy&T&J`RQBIP`J$?@&?b2Z#k~{zm;Ld%R^7|JE3XkE)^a>sor=G=R^!k1QTSye{eSla{JFUbFT1MnY+WvXZ7fGW zTPb#V)Yk~tg3YixSQ>s*X&Qp>r+<#K=}kCK_SS=}PTVi=M5>_=OW{%U%!kO{yB%(h z8$RmXi0zcCBF?)h<7$L8c0}0|Oq04ah@9hoI$<2T5_{3Ld;)ehPG`+E+94D-#j+joy*P8jKo^~qlrOYT{K)!8g#^?YWS~}MFg6-wVU=7W)@h7Djg@GI zZbFQyMCM5Yx{6mJHM&3dloHP(vX#b@fIc2!gR}nnI3H?`1HGLw!$pTp7aWd zeKsC#pN(nJ=B&-iNvmEN;DpmL#$>ZAu%JyMW%AwD8MxUo8p$F0Y`?E;ZQ_>oe?EW2 z@K($z)+HekV;X=$$3(=)dy>G>ApxR-h?YMD8D4_DjKK%`s=S4F))RbJt9?I zacEQ>5AZ&j-GHlU8*!zm3nyo6L_^hFgxPzEb9g&X@ zGMrk_1248k;Fon)xHwN054S{MWwkweIZK|w#6H3J{`&`b^7m7cV(;(|Z#nU%pM(0O%UafC$U>ng)TZZkG{eaFf_;YCj(3pZ(^(lC? zdN6*k8;qYRSJMBrD0%&|B?pAT=Wc?i$aIiJ#q+qs+YWyKcM z1r@Ml9-*a(J^p66?yZV1J!H5?&wkZK4%dUF^u0!RU8E>|stY5sO=TFUDl%jhInJNv z$?A7&QgMk`c`sWdp3kaJ8u>)~OteoK$_!mQY9M~tx0o~=+5KWFdhTF;f3$5+oL{~J z{_+m6*LB8~OZTN1Ik(z=k01a1340IkLfOb{XwtsSEJ?y|pVi>l!aR8EN^AObSrQ6~ zGw{T8r*y2eB0JEm5Y2koSg$?|9Y&dGHO;|7(_}IyOc0@Jj|F{3v9=XL%f(C=26X>H z)>=3m=Yh*UI=Jqsf&H%P$XAgxXb%!#Q-^utQPUW_Y^%nlnsUTxN=YF*NzjV)ze{u- z>u-TlW9baHPD{r(`{rVhp9VV*_kI33Yu2YP9&-}=HiF1P!`jK2avG+&oCyXejzDvJ z$3OYu@7}&3H24bFFJD2JR{%E?NO6e7$+05TwE+jym*aeCGwzJpiSy&SP!*ZMdE7d3 zT2B@(Tp03ygjxUZujGEAEy5=8F_dA_U}KzG>WN==gyQS1LAbN6KM_VA;{A153VXO% zNyhn#&X|Yu@FIA4Qp#Tt?${JS9nbZ!J{Wn5fl)`Gh2I*fVi`2 zB0hGO;jd+}cwIXje>Y|V8`AKuArWXw!##KC7R_L{=G@K(IZVlP&CY&2i+wXWaivv|Sgl>&5#Q`1-5+us1e^ zkAV$Fhm7EC9Vfah*|t-GpQRy&_VK{-sVO+wG8LQWmEh6A zTHaeX`g;#kHS|={LTAYw+@3=MZBR95@5BVg;D>*G%au4UU;W9K5Ip;~cd*$qIyn%} zkFLOkKGqD~mF1M^dE~n*UFhDb3f$&KWMqZQJTX)~966fd$WZn}vZ@z?dD6WRrt}?! zJnw-#TgQp6Ndq$w?ILBZt#h#?0c?*uK{lA9AbHBGVy$pt>2SQ+F&d9n3vaovg< zhPL`7Y}H73Z0+2S7a#tX2FDPieth)=A3wgtuC1N$w6NnAuj743;KJx;Tq3$Unz0D? z#%#j9$y?E!HUpvBPTUTuhok4Y0|yRh{~u@8Pp{g=i~CsVYkm}xRK#O*d(lQE5uBp0 z{j5kr5+Rw%OSaRtT|2qu<6ke{@cfddb@g!6Ga&-iLWWZ;&kc?D4Z-g}eUF##UT`wK zVBY&TzJ-^aFE?n5FjU32ZKLphTN$3N&Bn{xbUd#eNDP|hA6zsB^;3(a3FBH)vvoIXd)&W$iwWQ@N#ZB3 zUg57duUX6H=jO3TdRAfu9xnbIo0I0FK7JC`kC=`zfyoHeG-g5h$6rfDU3e6kDWBplSc?c{O6gK%$VC(h-q!IiOXDDg>R;Zu;3!L52k7lk*( zxS}=Cw_o2wFHak|lUDs@%QSS2?$4biWbzt3xlhnVkclcnb!Gn)mP?~h$&}j`e=e*q`j)ayX&Cnid$_^jlEk8Q93g?^VGRi0&nk-tU@JN`~ zAD{F3=8d1iy}berJxS>3p_f}Qet%5D>iuiHdo2c+zs96VqoJvyz|O$pn8CQVa2sw- z>%^t%M%`6m25 zeb`yjlceJI8HsqjVFKQDR^wHB0e-6|Dce#S zwqaAb^S$V+(~vtCtA~u^=MiEkwn@; zlQoDS#8WM^5JQ?=K|u=j1crv-#S4k3xs>PKf0dywNeaD=;&5md4`Qo~1~meGqo>j8uR8d7%ySO8QHXxx0*RaA*%KsLEl&6YzDz&?$H* zT8d__!;Rt=oEzJMp_aj1#4x6~93S4iWoZ2SlP4^EimD2k(Z5+g8vkk-%R)vJgKNm7 zRz49rDp(cgkHay(*y?VCIi`w8lat!txX7fzUjABM*gv`*x2NyNwJ{s9ZNOA~Hhdn= zm(}6sv>h1VbEq`cPg51wh#^mr?J1Cva3t*=+ZP{pP9U==4bO=lW+XcEeW$o+VPBjZ zF2`8mNUS}E=*sh1W!k9YkKOCAwz`0yd)b^>d@v#`^Fg#cCFGYJ(U*jT5h{Bmqo2AD z=Y;nU>cgd^;%^`Q`5W{Nv^nQklv?V_OM4ft?~K_)$}q$^igU@$WTr1h#13k^a^;HB z|1^*Ozg~kvLx1Y2Zj1$k%FviL6W41FV`NAU55?WFd6!f>`}R4WKK>np!{T_Nnh5c< z=$4^Lxflzy(#Vc6=f1j^E=qaDFNEadQ3quEKK>PHDFb*;tkBxSUDU9-A|7|v7USCu zWZQne1mmNv*hZ=8X@~3nRt$?rXi9cVL)=Idn#VE3( z)LdH0tHD7|596XUQRJ0KKT}7lb|BX2ixGoqJfONlEuIcUk%`=!?8(W)1GqzjNTg6B z8+!Y$PJD6y8tz>`i;E`?;TWNdy19!nvA7a3k-d4a)6B3!d^zPa92s7R+XY>?ozaRb zDRsD*Q;%x|r4|mJBtbHI9$!}*799KLR^SE+2U{Uzh=GSh+TrZx$@uobT-<4#fHYSf zSQ4tq?A;U3_bX zEx0nG30JdPadl)nj#f3GkD(VA&{yP?;n`nO1Ma6{L`z2l3<##T=Y-?WuKBQ16;m6? zj4*M8yPOUSLyismJK;*GEtd=)iZ(~Bj|s-u>a%CthdV_mVZL7`?u_4xniPQ?b^ zi%Yo;xH!545h^aM2x>^XUQTevbO&vABK4*7{i-!I3C$CS?-5m2BQnAn} z12Hm3POO^tb?Yli3`Blw$0VKSk#td%sdVB&)G|7o85|9ypc zMqc9irzvxBd&VwYo!o`pqu27BQV%Onb~K3s=fB>(#JY9sIVLM+udXuAK)q@<*2yxl zO}iY^`(l%JJ~|ZgvBGRLLFEWyR&8jLge?hjM2538KuT9m_K)4B-wkQC zy9=N{^*q*)lQM?dhR($O%5AuiQO`}sMSbV>l2%-w*p9Ki2C+tSva!R#eLK<7u$tlJ zq>L0K2S@|4Q=@xfdPORVGeeLZ>mrTO=>FX0qjK@$n}`n&=TRR%x(;Z`Uxb?#TX8L|1DDe~ajRq(PUqA2W47S*=r#<{^x=kX z1H%U3`o+84t>L>Lzl4viCUV_1@XM~1@UhclcP)WYvw^YClKNWAJCiCasPQ0Oj0n4A<-7Y?XWvT5(HDZ{(twU{x&kLjm; zR3V;_q4vl7r`*a#%uc)SW)+M4{-@vJZ0SM=L(s@zAUce4u}UQkwQAXD(a*(dyKMB+@gkyAV$MC75mAEqaTT~-u?_dLJ2}1XVp=n&k=t;0)LvXD*nr!Uc4AprF)^$L zGL(F=+8`5a3<{B_m_+wHf2E+x2#u{ndC5<%RP0Q`u-iK1rrxsVDc6=(g16E~6V0!*wteKvSEz|O_abgzwSg4aFmZcbH zA?}v##062Vm`lQ$wi!1jZO82X>CDg6udgp|-o4HxZ|)9O{ERk=TCkK+=$#QOeSe~g zHIWzPexl<@4vuQF*t@C(v3)gQ*4vrlBBzP*fw8zSe>d_-Da0A__qT50#-$5T5tUqq z&gd#%%f{+TW;;&Dx8QQ-Hk?cEz$v=7D@E&WA)2#QY!8zV+j8kQ^`=7|?O7vPr- zv3TB@iKqK#R*zu-~Wca zh80hqBCzwX$~96>EmSZPrEyQ-DHhp)!qm& zm1f8r)~y`&x%KmZyxNbB^Q}l~} z$N>I@*B@STwocH<{PgW_IK2A^8dj`j&nC{~_V}ovCqfsi-PL>NhRS1VPyw!#ZO6IP zEx1o#bXdkNqaI3zt%xa6Z2cTa&6WLd_2&%>ytut_XdV%^1Fi%DB?? zoayhTWJ(Vd;#ShufvQ$vD*G1PSE#Qx4;c)Oxtd+M|!1FD{&yTJk#&zk#A4fs@tY zaf=r8Jfn#~p;2Uv?WGqtF zjuS`q&WboY*aY1nrtEda&mCHjjwjnn@vwRbeyAOXC!Ga&(_Ms*2j}2c`wSF~aOI4; zsGmN6`joV==hbWO))6qbqNI`$Sc*!2)M{s8izJ0nm6!#)KxYgyc$le};PiznphyjW z{rn@$#rz&E39c@&#!njz@l&%SjxBeG8^LlLQ^nU}eCy}d(|=!%MpnOht68HxcNufE zo=K_0^+{b=7hB1RlG!sRN=LK5e2uq%y+V+MFL_rZOf?*ZX3Z3|s3l>RYBX)8&cEX} z%z8b?r?W&IJzK1A=;lUX;ay*n!ajTdj_Z|QKKsaLM5Rd?Y-J}|s?jD|V0VBzq75Q<;s~%QK^&RI1;V-OR;0Za?Bo?0)KNWX>Dw80ll?Q7I91>FQo?+eZ*oz`%-MT zZ)qVmO-<&wZnj%2?oZxFFx#*!JI2LUg z3sILa6(=We!OgPWxL@)GzMrul8-`c%u|du98Wuuvwy4HyD9f`~cNDG1xAgt1;~H>_ zJZQO>l%ML%nZvZAubAbdcJ(S!G)0E%<9)~ASjk3QD{sShv%bL1Nn1ItzEs&v2Dugo zau=a6Y&6W2HUF)?5_@)W>vGi3O66;7Fd3XKhLIs&YoCXF?Fdp>1y))Ck9WIU;p;#< zeBI9&$3?eOUnP7M>B#v8K{S6nYanXn`6;GNkgj)1K{y1$9&L!64Tt+i)%-D-~vw;*l z>EiT>BLEYDzr}YCex$fT7m<=aSY@1pdWu_{wDS=qapbbI#^T|)(pZf8!U0HfS4CgN zPvvw9kdSA|E6Al-_*WL>HxxVxc8d2Dca)Zu6HJsagTk>$S8NNn#VC1c%qS8m{jB_u zJ0KB7fn%{^Tq)KjRH7+;E_Uax#?kScaC&MpuFfToJC)$q^sP8Hz78=4LG-)Ht6KQu zZuMbYo7{!VQ%GQE?!@&a2XJ}8P8^%I8J!cBA}M4b_rQvZB}GLE^YZHcZ}H@(0s;X` z2Yc({zsp_GpL+Uf-d4lkK-iUAYT&Kbx0!Bg%GrV;+5s?C)yKnc@3K)7O5~<$f%4!KbfqrgTGq>nqQ$S3 z+x`{}E@p-5-qyuqQJ+1L^5&k|e-sw_CUmcguw}9_9rTqmL7289qKsTIK-cPDLUr@r zKMiF6SMkTjNh#R2viM(PD~yN@8H_Z&0a$30iX7z-KFayThdkNV2%G(Eu`ARGJHs7N zKa>o*iXaX!z{!a%*b~1DC2m8}nX?dIk8j7(F*Q7XWpPk88|ZjFWqd)N`ee8ja`mKV ztV>6D;YQSW??;!l=$6wepe}AuspMR`}1ee$Q;ZdV0?yOP6 zgGL{Wah4XjT)cQu?{n*`L|abfWw4$zzOHDYIHLhq61L!SPB#waZ(%0%n9$*P@tlNC zoLiBXU9@l+ZKMv;<-*ZyT#h6;XMkj7m?7*e?dfcQ~^m0lwZcW&O=9DFL-x?SE+{mA)T(UsiPIL z%F^fQqb&nhih=!fHQ}$S0(U|!ZiaFg9%6&Jh0$0(Ar6x>h9cV68vZ(@uoKg6yCcpqRw`-Wdsfs)N-cQn(NQi zurqE6t``z2D(u3cf(C>d`?1leFqXsqC?{+RwnId3;!2=2F)d!5jERGT6Y`5D;3rZr zaB2T*Jbw8nb6*Q(J%0EEYz?fqQYpo1AXd0#qDCtjtumqoR7$karIL#V$rx-fNk%_8 zdp={nb?pW|e0+l!FaAJ!d^j7gomGDLezP6!t&repnu&i<~zAHS42bD)qJGzSFfY}pf5N!R3w=bUXS!BNeL13+oIr<4`P|QM` zd;vDoLd;MfO&g`cN>vfC9@UUS9{@$?$FOD_h;OczD2OGmoR@$wirKEsW%a&qH z^jH?EI7=mT4t2uSNDG2kI_NZ&cGpa$_d;C><{C?|*i3>&q%6xxsAiJ2og^}Z5@}Pn zNcoExNQ}r36;XY9m0VvUrFwCY7;@ZdAraiM`doFTBT?qkHIZ!=%!~a=zy17QrulsTSQ=hTURcF*W)@}j z!7sa~HP z?8J`5V$%z2_9fjxePtp*Mabwh0*Jw93y)757c z7vexyyJ-KyhY!!l2)@MYcTZViUy0Ef^ti{5or0~EE63s^O#+Z@I|yS9f-&AW8f#V3 z&?TRZcDY1;w-6#+uako~jc{g0+}pjK>(|8fc5dIq3COAh3;bt`GyYp6!5?cSxV_dI z{cTB}%nbg&54rmP^X1}beO(A#QJ;R8={XonJjbCUat1C_jF{vy1g7L!4(>g~F#nC{ zZ+-igp_UT~{|fySv@7LdGc7=aQaaDZEH$L~MqZC$q$qMowAI9fKzmFKwMTu$2y`#W zN7}$3n8-=FfW-Ni7)fcNq>3CT1I)Bjz*cB#j z`Q~8i$ccz_=+A_4qVmU`1T0k69chMxF~w#K*19KSItgQx#0Gu@;f41WTuHWC%IskU zo1~cj-P2Tw(`&QgKtdI)Z-ZlV+L--NK<3~7d?dsQe=x-e@YgSYAaz_K{Z3UBI>qAl z%)>a9x`masM`V>NJ5UiC$7O&AcOT^8WI}0g-Mt4H@@)N0eQ>d?8@E!(Gl}F8{oKWj zR@|7i59I;zTvE5Udno;&@Sso4(;`lgU!G((t#_M~bX zPS0w==}DV#wwRu$v>Ojg_uy{vPMj@hMydT6@|dQ`?-!4gb6c?@ERUdX5Hbt{c-WcX zv)1YT-LnY^9FKBDoSAgA%Dr=!ICp}N&++`lFBGaip|ufJXK%^7eneMCCoGLk$&ktr zno=XgB+DM&g3*}@8FOzwxoDD)#a87sj%7Ef6`(|KEIXbhGpq3C{WH!1oH=&{CWJ=D z_{iYr7H|A_jRZfhl;GKRPvj3$g+A@|>C>lmKAXZ?t0{7(?o+9kfSMvM>u+oY9XUDJ z*jVB3r%yg-3;}((n)wMRTX*2DAHzW8t``oG_vpYjDDiKMMo8Z3NlR4Hi$gzIC}~5?Uhh& zua0s%ElhRQ$8=XMEb%r#Ykx-^kMzXXA$B-3&;jd)yYa?FYnb8MqHXwY^(pksqqueP zZiLI&A%Ng#o>ma5^u}SmO%Ybx5(I97RdvLKAhY4{#$7EeCTYQ`nNn z757;lVS>NU)F3%fIv6V>bPO3P9gK_~PRLYD?0(N@*6X%xgoCR+c}h7xlZ`U;#*vB! zTrHBaSKLZnk8diQk?a-$Q)PXeI&zBV9ld(}mZ4g4VG6I?yvTe!m`h$Ze>1KnZ@{_4 zM)XYBfjxO^2$HJ7#mbrmk25gzPECpDpZmRgF2(9eyrx=`|JBR-X|2WEx%a7Vt*UAn)D+cw6LZqu>NHC^tR3Tv^+iz_WT-@8mNLo|!ceb49#%1f z985ME)ruG)3eTT8A{H;-JSC^}7JvTpUkr*2fTgMgH#RupmyNP`utb92+HA2d*NP3= zy6VMQpG8?W*VXxm)~u;kW;iq=6g2_HnB}QKFi@5UE(?X~8`6iXNB(;Dgdy6ahd=$)cr5O^kzqsyqwVr>W*<5^1*BrFXN%Mt>UO zEDq~M)Avku39gX>_xKxOhO;sY!a|>sxIUu`krEF~^iD>1<|5ieRT2&z%yWyw0;2>} zDh$Ioi7UlnQszP-JPBH~Ie}K>!M(7+RD%_GsCj=x=z1|+bECDpwPz_dPDx{9BfO`& zj23R*{07fny~Niyt|M$<2o%UFYsiU$eLoDdH)F*p=`#%XXOl3GTZIQXn{jt?JA$+v z;A-KBNB6#!5+1w~(DprU^qgSUdMi@)a_^D2Sg`@$&Dx4n84Wm*MUc9(6Dj5c2oB1l zVN)&V8Q%Q;JBEh(!&O6qzjiK1Yknl(ql&2DQk8Nui6m2~kuBo%e37gXfKf_beB2RA zUelGJs~r!Hwm_H7}I8)SwOL=XitQ&B* zqzh-qQhc7$jyqEi@loLfw`huc6?tuk(0xp`l*bBZO)Paa#1ao`Jc`?9W?|3uVoGoFL8u zuZixONxN}%$w72ZSqWbQGY;ZKJUC+bXx@Z3Z=?+Ff)D!Jhd;p6-WdI@6mVr#As*G_ zpl8uo94re$N0Ku($J$~`q9bZXTcT=^E-FKfSkc6^xXVtOcoblYIX22%=el`V8I}zk zPjF6;8>y#;B_h$npS+?HCn%igo~=nh&AE_WI^VRruMxhY^*A)ZfI3{S z$S@j29$1A9NJT; zCEW4S8as=RaxTR;;&MqFf(@L|*VT;__5m~S3peuWm*8^Qrwsj8v(>epUyB47|$di;(0aKL1xfO7eBpFRI1=yrfg84e}geuK2 z$i+v>j`I2y(;6*aJcrk2YlRkmtkuEw$50q%*c^V)^uY> zLtSvuMG5CTS$a(pcwWVhn{xbA#cN(Vc;s)uOoAf*Y#dUKb))ByLaD((K^xiR<*zL6K%7e$ymjp}b3N={J%eM~PaMShy=WlF zQV;vrSK-OA4fwXH2wlalI9HR1{i`RlmyObN#NO=Hcvx`&*C+2mfQ}>FY;5tvg9p-9 zO)^{unzl=8h+Qnuyl^}+`nzz}T)^9KRXePSo`^k3iwW{?M|M;^Zc{(`o3kb?;SU(FQ)=Mc`@Kw6(g*q^O1tc>!nKEus|ak8+0kWQOQDsd@eRA=V6hi z$OfB`VjJS?xjV7ICxa?+xcrWab+K zU!km7dh*yEPO?UObJI&5w`iZf3AV%m`g4u3l)9%tBF!?3h5#|Wpv+Ml(ayHCwlXl$ zGlBxio`OWm3~8^eg38zkbWKaenpA(RPW8c>w7%GoF#xq$!!W{7ofD7A5_{BWC!kI# z2`x(5XqGL&I;C99HBRP+{4f{6$Ne`c>l@}D797Vqg06JDImuTb?$?{+L9-*i?TnzX zfRK)<y~2wg8(_iY)>k|faoSZC*F&r^Rat7y_ifvb_k!mY(j>?)zx@hz zSs79UJ#040;|!eWhVUZGdm^t956ADt`LtGCNNvWQ+*aHq*mgd44ZfYa8*K@T5G-fQ z!rI^37JV)4*u&N})N?tRpr(Xq$9wZ9f;~)mB<1amWk5qdUM-8kt4#&mcJ;Ek7|&Y@ z@Y|L&JgOUqCoSo?vUD65I*cY5do5TOcLFuB(nX6EcD83MPR!~?u!$%9wH>e{Wiig@ z)Z>S${kT%qfquG{tgNdn)NsMy0vA2CamrZ{Ux(_U#aCMNE|5rx#22-OX_%xI&3&Ij zF)ipGXT%O*h%6K&m}2bd3C_6OUWuPCG~sB&OjL~>fCxi5R$}qqQ(b~ZS<)(^NMjFt zk+KGN=O4ykQ$INCTj1uk%iJCG;Lcr`D9gZ|jKRfqmH7K;9e&!m0*7a1Vp6axE5aux z3MUzL4Dk(wp_&f7t@|J`JPIzP00-BVp=o|@Zy|^h{MBvYAfv{Lx*?R5)Io=jPy}rB zCvTHyFbd1HGqFXj5M3H1*ajl8WW&cX*GgOPWx^^hMv1Wt!%r)}Lb>s9k`qBJV1xOd zxp*|^C@xRjj<)#u7-!mtuPdlr7n;$&3^c^8KrLMG(!hyOYpnD!AUH0KUq4MMa8_4C zsJkZu>}(NYrYWu27EoSJ3G(uakjN-NR!$k3N}8M$`$XI>&SzBw9Zqk(xA=Sj$)%X_ zvqEDWHmhf%K_MN@3VE!sYn8Jx*))-!OCK@eLpX+g_Dq@}+*r4PjoR!{M!2|q08T9N z#(~9NxY`@EIBx9dNVFwHxuumi$_WNn#wx@)wo+{3}s^P{!TU4k>lMxqBpXJQ( z+cz)plwzZ|q*~g_3S3{h*|r#SWJlBAb&%{i9N*9W66Z#)$JeP%xR~02Gs)}7+O`lR z-i4Ln#mpfrl(mln8G_Xd;AvtET@_WFId_s__lxKMaJ}uXKi_6=mFTU3|1?+P`TAU- zwF2L*EyUKmP;4A&hqE(=;n&t8{JJ?EZ`-qQZT<+p-y{<`Tq8y6@m1ub0l^8CZxF;q z61ygEz@G7I@pWkjt|f2Ax8rwWWuFv|O*3>PxY5rBcOB$$$6XWWJ+*MKpBd8BrI}MF zdd8KyW6Ap@VHGK@==u=nlKP|+f|v#x`>PjV6WIzHXJVxt-<0rKMW#o zzi6B{LG0-`uxb*jGKO<~9mOY^XMoPRfNg*052{IPR1hKM?G!Me}OAh1Y_$_3>%t@JiaI&fe zcUK=k`}j5JoUoo}7;TQ4hKaUA*-#3Dk|O52ddlNUxDGD#k>F~u7WVoXAxlY`e-QGJ z9d3s}D;4ex5^N>^P$=;5hhK2##x?BjZpMb1YPh(#@aPROmsUd0=VkAXqCv?>a28}-uBD3gkIl@ioTGSMQ*N1b*7iVb7vds-;Y$l(mJ zAX^Ylsim!zm7d#5Y0n0e^9ogwCOsY1#PDdz$Iqg$Lq`qmNTl={yD8N5%$c%RBM&%!9aFK;COI z#jaJm(3M|}5jLS*9w-)6c%ruaVfdkInY2hjOBMGX-sF7h^OrBUKXd2q9Z(fKQYoHX zeDP;z6A3W}ug6CTbaCz<+7PwS%WnAd50DC}$zl$s0a@ZDZ z&dt)P$^^qEw&Q$pBQEANa!u{mnH{)X-i-{cK78Qc8f1qXz8bjiKwjNW4n4v4m~5@X z*EFNpG+1JVMy*t|$)up(FpKM@^=PxjG0&8-k@)FI3u+f+BWp|_1X;`c+xqq?d#TNR zrM*={;%s#MX#9R=E!GxhX_ZpC(EllvnqkW6vXe`YYi0rQ5-Wq2%fIV!y z@b;nhI2mS)9YOk>5w~YySE7B=hnRRMvdtuK@^-;&62y0BTl>WO==KMao_=1ewpIay6 z%&IIdkWf{WLrY5=heceK&ozgyQC+hfs!Fn~)S~~_RZAZS%WLsHA(K;ib@(cGJ$5B7 z!Q!AyjMEUabk(?pFha=<%k|^Xq?F0YrX5NZq_A12RnJ1MK@<-H+qj~J5uR{Jf=y&g zQwy(QKQeG*$;m`Wl*#a`VW5l&t%tJ6Rebm?3Y(gqx=IMk7lDSj=c9-ljuIYof5TrJ z(^RF(b>P4OR@OIfUoh2+nCh0Am_RU01Jgvqx@kVe8s0n%cbKFvRs|Ph+o(#c4@pCu znm=>C>T&0Zw2ElXSbsd;U4>IC(xf%JCc3zM?JV=~hzam-C{Ug?cL7s#){YOt%j1i% zBtC$xo!I1TTTM*!G3WYX;Ux}E8He{EWukGQJElN34kdXtDQZ z*WjD74qS=di0{(3AV)9c;-7ca4>qjgj;hKHUtf3D2RCM)gMq5H2c z7>GYk*I-w50soAGXhc_4LR3^gE`uB8ZG<0>G@^5UI&2iBN+pU2Hi8_S;^HD6qtCdzosXOtws{eRbwdJ+20ALy=8I9 zUlCpY<`~**RP|_GqTNUtL&jihMGfMt!?+z!Q&8aOJJGe|8H)e!*?Pg%TV$+(HQvV9 zOGf{^m_F|!hns%JIO1oHWCiIS`jf|MC>hC#p;x4=PwEo!diNw0M%wYc_6zXFhY#=Y z_g}x^<%=hH`sxYxAKV8eIaxSanqW|XBOAFC%|P6pxCb|KT5&tO4UdX;<5ocjZcp8c zjTGDW({v@7&>+L)jv6wyElQ%u}(*y%2+yd|{((@p&L|)%58(!ozNI)WmfkHQaQT;GU}lkNRq$ z!AyGaJZJ7qye4H8JULvnPnK_I_b%Ezb>zr|V}o%a7HGwCme`Fvt!M~v=7G8Dw3%Yg zjXeo~Hp9vsFKs+(ufT5yCSggwH?unES{UKnrHh<_76tOJ-vVP|;$T4nd1lElJlQo7 z0eaG;#U{bB7jA@}AvS1mRcB!tY$(Cw)@k^=X&Oe`Y4h>UHi|(7Eox7Hd(6{T;Gdl} zBp){?@50UG7Tg-$fNx8?uxeBZA2Ccbrt3!e;k>UdUwd7EF<(b0M6_cdkC%v)*wH4Z zp^jqqIaY-P`TEdvSzxebAbERj#M$?OlbR}zvlPl=DN)2og+3^@9!|eQh5lOsRysN? zkTw!2pRn-4nS=cC&zGC9JaGVLag};wx#5;-__=cx&elxgX#_H4+++nSf}#Sm11k4^ z&!rc+i0g{1X^58zij(@GBF-N_?b(2MXG7_vYYtZb~>CVu|*CE}Xp=8T(9U4cu8*h^L)pc(y46Pu7pYleN)!(v*hd z%M+yrQco5)@84vv_tz6?vh&!n^Q0syFr*l_uBr&p4kmODs#r%5{91WCE@m{~VoDQw z^15* zYgbm&-Y8L6I0UsC8K_gu!fNGIc20u{SvgCL-h38??QCiB6%c5mniw`^hm)RiINwJO z_XpWvTZjV-)WFC=c=_%HdDb^vAT3t!uiu~0zv+`T_Qn$ZRMhKbaF1z`RuqQG_8}-? zhiGMAlp2gex$PJ}?(rdyeSc#K{@GTBd)vk%*j7r(p+-V{^vFrhioSRuJ=O^h8URxg z&U=li_@%u7eRQN2{PbW`9_@G4PC_w}CF1qvSgB4-8--W9=V47&lym}`z98+gWa75n zUgjL5Mi{!{Qh5g+WN*VaW9x7ye+ybNW^%$qj0jxoZih`CCYY!ttxFaHyI@!r4$f>O z@2){YtbrMtkyvP)NZ!exl+F&hu5mcMxSQZy7nWvB@b|-b3xH6<_if1evMuzKDM6)s&f<3S4kOO8fLIlG-Za4P>Cbztn*P! zdncZKH0?_dLDd@+SKlNfeV-s~jkh)zFocnjIass;-^|#F1@37WEa!-pl112p41JrB=XittCx zNW5)~!@IiCz@~9{*_?)-yC!f)lsGw9y}p_`u!X`3nfUV1IVdaY@Okv+X({NMoXUIe zKuWtgeh#kB*pBm=O*kG`hjaOzI6+?bdg%@v&aOv@x+guWA(kp9pi30>g3{^OqLPIT6bna_1L|+&`0Zy=Sn+bz zQpOmv*axHgW7lvO)CTHeo|7uFtfef8)(&p?&(FW$)ti@iONuL?v9LlpV{=KU4Uw-I zg$Dg>Y*tLhChc@Im}H~YJQwvAg=jR$!94vKX3k3vaKVdRv+;XN0X9z5=U5{ z_@9QUn_=~kESxW?#ZQY5W6S6&&Y(JzXSAb@w33)$g!UkuDsRTkr8`kFIF^(}nU9U^ zB<4sWg>LkifWh+4d~Lzt-xU>zSVIklkJFT+u)r*pJeDqdMnTFJ8{&?Vk-l)Hdp)yd zB2LoV%ivQ}yF7hvhd>>74h=F)H979~6paElaacjuDvN*5l?ND!;gPC$sJdajfPmBt=8>o!i-txFYVZo(=MwqH4g}N0XadeYEj~rv{eWC}E0~5+;}{BUw}0xFL*R7=5oP(+_Xk zCIB5Jc(o-1@7mJwd}9oruN{Fm8^)3X$Ke^tM^S%EzVG?7=Hm66=Xm>8+F*X|@(qsf zg)v$ht?f^&~9Tk0v9g zk6}K2k9{_U9pLSBNkE`-CmSSb%W-d_SZG1VVL>;iM4Q~Wp^1-m-n@IvqbS9YptE0{ zBM2uN%N==`bEB-NAW1}rLKYgu&}aI4t86;f=q7TJ!4L;?Jl6 zN4ocLq1y&0mfC^Y-#M#JbQ5EC?yYoQQm6^cl?eJZW$duC6hhasRi*A{d$*+cu_ zOv@Y`s3T8fE`_;bl%q54!x*Co4Ak;ruUO}6i)wUWZuu)= zS6>~z|It?caJy^=Zp1co-Sf%(2J9_a&8VS_jLV_^W;hXQh5TNbap`?#fpmgNQOhG8 zaIwCG_I@_rbXVf;{Aiq>5{Y{&6Y;966o1tw08IpqHzwn+_DNVya9-TgqL~Z0rs>)9 zfAId*JM>(-#zh}OnP)~?;_q#6-L8oue1>6GZ5cB`iZ>id%S!5nu)~k-MI@p9SiP6s@6$j8SaoF z4@=HyhS^Xi>??>%UjNw?cFMH!N*&23`W4}w^iUxV(Updx#59R4whiJU6L^f@$M=HP z5tEUjWGG_=^7!`!{5HDI> zSzeGyUSmn^A{JeQJZeNT%f?rF4_CVoEEh?3|)hNwvd5BCrCz?TDEaByS@ z#u`h{Z*3N5N=04tkw8;cTEPpIDkG92^4L|n7F*I6pbxiu=^@!J z3SZCKhWk^u;r93rJesl>r&2cIV%auS51m2Z(dDA|L8d-9T+x90E5GEqw3CKp!(PUK z4UTSaZEcz)1nX=IFvVsxJ+m~%E+Tk)DaaCMgRBv+Ctc%GNf5>USy*8nPqDETXV68q z*^v}_W_}!OG?h7?WrdZ9`LUL$uuFg!K~munyZy}Z#QMD`Jc$op%sFsO3#dOpg z<)Tm{j1)>tayLcWj0T*W*NtJS?wmYhPoq5sD@{|$X!g>$(!0t|2R9>}aotS;H+)DD z`x$dKH&n#~w@SM4Fry0>;~R0IuocHDn-L{v%o+HuVSUgM=EQ{#BPbNvIynZ1%ZH+8 zb_{;sT!cTjRp7UMRXDmj8`*)z%w#FhOgOE@iiAG+qk9q_uZ_dwnpiyBJ{c=g0(tKj z%&y|0R?pu&W6yW<>UBm9qMS0tpP=}*srX?>C6YZAdb_biZ>};T)ErUlH5?lgreI52 z6($EI(3Q5;`mTgM=Yzj*nBB!n-&rQzb?P9RZC6S;$@&-qYy2!c@)@_;>x9w($Z(D>6oMw zO`EUV%VDcR-p&$}?GjOGJe(F&1zGXQcup$&Sj5WW=;--t_&YknieT}!Rpq$UwSswu zgyj~+;G(=uRKp0E+n+xFabpI-taSXdb{t-BpN_&%Cl;fu&~hEP%_? zC!;uMTyJ%bHV+y;l2DEN=}ovXb^~rFHQ{Pv3wp}-V8!66^gRPEXB0C{yYs5CIc5&s zgB=N-4i8E)QP5_kj;5G!qg6f@8^)0$8E||h*cgt4S>cj{3a*DbVw|2dk(Da(#9IAK zRIA0K%5WT)MQV^S5uQc7y|k_2Z|2HMD-wTc1b63HB=8;yuiEXRj;lj#QSKnEl^#l- zeX(u^#aTtzET4l~LOdCY!JO=y7E^*t%eK>+8?#`Gp47>DL$TOCnf^{OA;Wwb_LwWp zRq<7jDYrL%5$Vd;9nbeHSDNVST--b(*w<490g@DDY`+H!=$Ur{t9%(4S zZ(l6N>yApiYs$ydO{sX&U53`OaQG@p4TC^$DJIHnxCERPBnQ|&0e`QdICl3;%Im?;AhP<)Q}Oc1e2S?D@S62CazKQpD_vKRoGWviXMjZT zSgX>0sGwMP0BWprk*_|K`HA}nN8sa=xA^$%6?09C?jOOnI5D%3wysxnlC!6jr=O4j;Zl#5&WAN1|RQ6AkiYttFY*q)~=xT8TVC zJJ8DqzyI{D^jz%C8|HNt$~AA!A`)nI43hQ1YTZ0^sMEs{=HIN8z;SK8VhZZDvap7r z$V{0*n5i%XOEuz9W1NWvI^#(AEfC=7i3h)a#{?%rWoZp@_~0qFw8K12@NoB1+-jMC zvH= zrViLQy#|97ow@G0&?W}olyAk?DGm5Kp%yn&Hlrt_4L$iCxIc3@b{DL|2OMg<@JlHg~rSrm$dzYd+>!Cy*hr)|>#R}y#ETedGw60+DS4FU@J#syVHf!ggQf)9Fz2!v4;>5Bx&SV=(L%v;x?a|asb)j?7-yxg zI}VY;iZk8eDR53Vv>xf&u!{Z1=o{EAZkiDbmLmeENU!_%RM2tRzzEo@t}}@!`vLxK%SzS~;g` zftB_tSV1yXMhGTF;!cLKFLEhFS*1*|t3?`0O`~|yp1!g^&Yi!)T?8MVi2oxO{_#D& z{q83+2wJqC)@Tq+DvE+lB^x`m%CTBMm6YEUUY2$@KdZ8e*Rf;AtVCa^pewC2%tD=V zu5{z&3b0Z;4I@2ql9-sAO?*LeHtqe!fApKNMeDxX`$OMKaLY|u_bjY13> zl~d5JD*9#9(Ir=iPW1wGXyntiQ?W@UonS^55+!~3fO~W6CcGqd{pam-DN)-~Fxj;@ zvdHw;!%tt#!*5?L#sh*)4_hknYa2nS&WU*0R)BZ)arn4#4A2mdrwzFj&o1G)vLgAk zFT@hJ0(J3KfDzB>u^?}X z5)+*wx&PCIJdqy#>>yhoH07EZNI0u z@SdXrPKVgA7ZVCQNR;tuC1Jf*9v17QBGWvIeohOe?s2$N^A$R>7tnW&7@7skxniSp z5y5C*MikKmDbMyZ#}#*FoC-8Usgg9KEt>C($QTMkAdF!K39SPuv9wZCx3kOsL2ypt)-|$rgo4kAKDcH&3y>aT6bnjWBU1 zFRH}G_wcM@beE;EaU4#Da*Gi;8%Z463=6PUGZnQ)g{aZUK$A{3mg}&)@nfS}wm(tSPnbWE`7A}6#np!v`bF&! zT^YsdgV1C&o)4L8Whn;L&cuAvu_Qn`q&$k~?%d8=DpKtft5ZDt27mti2r(i3NdPo4 zO2!S#En`V(<54R~Lc638TP5SsDN{;|Nw7^mgFF7)WYW;3nTI*5Be^y;e#97tBu`%c z!*nVipMStlcOSyT(uk+R$NH$_^twF!x_v7C++2!ZRwv_WT{>RZCF0}SXnd?0f)BOB z@SoMg@cWLrDDc+f7;l4*F)sOQ;#hz_E36H9t%kAF&{N)ptK>-q9nQVHZhSXsH**@d zrq08puyN?8Db2VFB^jonE={D!s$u_{fQjMe`sLx?n&XIe2&LFn zi|*9~V^juWwQC6(HdhwRWFuKz2(`d9X9;eF=%CtMnt#wIL9`}VEqZwaND;*uqhQzA zKE4iZB}=*TC)Io~PR!Yg45wj8cNmVX`J3>~{F68yUxT})t++R9Cw8YU$9%60Om&RI zkQ2b_9*Pqc8*#3v4%a7c#j1cDHb9f?3~(yS4$IA@9(u|+PrTSY4Np5u zadc4vE34>lJrnJPuUzP!>3zpe7FR>;5wD}dHN;;|8;aLo&PREq9n1(hnVXv7yPyB) ztuKGUCkN?6#_`crnZsBV=nkaoD#1fhh1Ok;)>Vy1NQy}g9VBDTvJ}h9r=nUyD9@@4 zv-HLyOkzdGKpxdq3t4^z4U~Al7SsI5MO^y&oHUO>zoXimm%>-{?zM{$7#Lqu!LHW-P`rlkarvpEjfBFSfKwM9lc0eh=#7AbBD zYV|Y7<2aF*)xwE`hZz2ReD;Q0#KbQ+ck&3#wWZ~K0Td%`DjbBz9pve^&&IRnLj18l z0Z-SB!&~yMPwGbDX?HIEIBPP0`aSgeIZ0osVrkmJP5s-cr`cg8;4EZUB{ zW!rJ3q!BCplaXuKmjz7xobVP26l+a(HAUy}e#lT$Bt=lit~qt68j!=W(g0G34RKSk zDrOccgNv}Kpa!vKeHo5#39`j0Uu|3v)nh?===3sVr5AA7S#&m$0L|8n!c?6o?tT%& zrA|$1MpMds7|ZDJk%K3B>`L=Q%(BTMfwN}smu*FcE64!fkf*xiBa5w`s(f8r6%CAV z^rr79!Ar&hqm0AQLf-J+hKraQkxm{~g(+|DFF%92?1e~li$a#mIPA#SfIG$AxEi;C zP(}m3DcOaqWqa{({%M>nY$YRPLWV<=g?&-KbX=Rz#1rqg$IWL0ltyv+#VBj+3e;dv zpE%G0e{@yi&rP|wRGrQ1nIbrhhq&PQ07IM&(7~NZPi%2A;YzDO3KK4^$-}o>XTV2S znrMrUkLQY`7q6a68$#ZF;B#a_Njt+d9m`EJQKmdZ+UiFkRiVN_3I{UKN;1_Z_{HeY z26a+2(?aAa52kxCW@?-H6_dHl_U(&z(rze0$UsQ(@!Kcx^>bij+K;^G1g$Wv*G)r{ zQWn-KBxAO5JWn?q;2d)9bL;8wP6Gc z^x&p%kD~{VFk8G(+7GYZu~+=(yT36hZ6aq*MU_*sQV13qrlDR~EA>)zDHpJJ?T`p% zP3PmE7X2d3)QjV4lyKKTy!hvtlmSmna2Jb9n!D?ZHYf@LHyLT!-zXbhG-M6It-4Y? zJ2)SI?VgKYX~TctHWkbvRjdF4zP;VSO+`B!kF{HI83}@_+=g#Of4x${|SI z26vYo#<>YwacR*(3{!RB4E4@1CtT>Of(uTfFo6V3Tj~ibhGbyQfIKecbR?y;=e5$t zqKF*aT-lA0My@;oP`n3;WRiU<(zQh~y(PoxOiN9i3Dn0ef|a-2B{&ggfe=y%M_EmL zIk5&uifhoCwE*S*DTud-Ms@mPjB*L%YOSN0n{gtq6<%_dTv{k7a-wuRajU!qw^Qoy zAg6;zc%IB?#i^oB>`164!)3$CDUrvhkC=*EMO_r*x8SSHRct6?R3*4Fz!-;oq-VNA z+_ms)Ln&U@=iz1hRFt`^aPlff)ILW#Vtud$GW3<$JB$6v9bkbM7q(zltPf|z^^_Iy z`>(%o3GD0FFPTk~LN>Zrb&CB1P-9qzYULc%=@ntQW)kX+veBWLiw?OAbcre^#cVWC zs4+)B1w&N&k)bhyHlZpp#qK4Z(fcJ{J(Y56e|#eChR@GQ=7g3QSnVT`b`On}_r_A4 z1Z=P?K&)O6_f4;!y*&GK>*)XK)yK@eM^uH(G#P`9^5d{iB_BIj!Ln(wN|2-&&hf07 zwmupg8(CrBzUcLc^zhIBe24ngwS3fJPVWJ<;nQ_vutY5$Yc$hPNAX0hRwnAzvrw;; zj@9x>Sgx0fF%lnU49pmpA-$GRSaA+V|9eHN+jI9O0z-#DSwWMPRuo>ilAsQD?t0pNmL0?hMXHDP95mir7W~i}~RtM?Gs3EtHh&RQ|6~%w!wLE)utnstN zk>P!Dp5B+j1kbKMdc4)~jk^)LETqRA@owQbHm?Pt^7hQCk>)fAcc<;avDkIEPO;ut zWf%6aP5m5j+FKP@{nW9$pB=+O0U0}rR^j}DUFaUa9>v4bQ5>0sEh%&G&C(rM9F@xV z?4%^Rnp81X#T~QV;%N=t$aCuQ{g2Uhv=P2vYNcost20Np*aYvlh1(?8hK|Pg-j!Ys5H$# zaDk+_kr9JfHcC`Rph3SJtK~AWmSFFCg;a_)Q?Z4-;1<;sY@!fjvGzEWstjQRr$f%g z!O{~44;&FwVDT8w@z+}^GyYxaKTbnbwn#kQPvQNJ_-%PczmX( zt^1A7t(*UsuRR@mjEp22-0!)HJYTbXGDFyQNgg&xa%*B5*AubP6nl=*?9Tv zcWGxuZ+W3$3cUaAEsTg5z@%8hx_b~T8Liq6`KF^W!DK8JSf^o~MJ873CZpamAB!Eb z;4AOSV>6~?RgmVt#hZ_>Xo;UQ;rJ)^&XecA!R*O%5$xs(a}`+__HHzHu}CCLm1?0! zf<&>E@Mx8Gx;Pu{hMC&E<0j?h*b{_Fq%4b#Hd;8=-xj9_JL71i2iga^BF{`7!^xYc z)4y+XRmFcpEO61=1S906Emu2om*L#RHZ%^Ngr15HTp}UAoU$2@Chx)=7ipdCY(Gbw z8)T33;dUr6lX{svlm56iXD9YgsK=Cnnef$gKwfYRZm-ybtptVb$p8%0az+io?EVVQ zTC}wK!Q{fj$)Kh|!kq?d^E+_5&xIUcY+A%6k5* z;}jBU!(G-8%iMCY-jEyzdDe{-O0BoZ#Y(db%r%a|1mnRNC~Lz5&%}v`wSqAgRW1_>;VNVOA1np2aa?cYkY~4Ku>UP-E=yHbS|ol(to5vQ-6R z#kARlpIbNoZ(sAK&&v?PGFsw+)kZ03R87TZxpXwC7hw^>gh2|{3}5VeSqugQSm4B0 zds$&cx6KRkiBI1DNellB7tbC=Ojs1Wj9uxw;%Gsind(IRF_>bKaTGHrNxTs);{`WG z2WXI>>Cl3gBxK_6e|~4?K{3no$s6*vQq~mFp4%IPyv2pn$FXkpN~~U0jrzJR*th2p z@6g)mlUZ@*yP9*Ak)T5L=!Ib;$pf!)GsMZE-ncT<1IGf)vE54#)72$>o+y$=ek#&z zX(0(@K!wz0F(GHPclD@s@;}dU| z`0t?J&ypO1;HGE86>H1v)o?J%1Bv#hZ8su&6fWilpY2$wHg$WHIodoUTA7`FWQ&%ZD*Focbbv#bt=%D5m+ z#vi$I{z#GZ;X-`T_9%vE3l3y6MGbg3Iia$AJpTUmSGw41e0cr}FW$Vx%lGf`L0tRI z2Yhv4ANpFG@V$>D8E*475rOnpn8oJO_(PBnMTk^6ZW*8ni6ki@bDlMiE z=d-V$;@OMGJcL+G&HjMr=v86XV5VYyD-Eni`v}^6XW9;2 zPj92RuMIuvojjfGTk>%61VcTTpiCMQ#migbK;k0Y$lr!*6esRWm_x!w5L?L#0VX0* zWJCg|iHV-6xVGpJHk0R@KYSu)4=%)^33a$nO8B6%8{2c1k>V@yamt!NW1Jb`idt7a zR+3?+KIHXV(UaeXt7)ycKluP|Ec_CYWEh2~=p5mN4Q?tJFDK4{|0g^ZUPQ$3w!QJ2 zFj^_}E+h0(NycCrg&9=_a+swpMIC;a;_Y!nkbG_blb9G#O! zD+|kTV+k(S`QfK_YdmUmMC%k!o&?TZM&wa45{IC5%Q`&& z=l@{uy`!?qo^8<$eB_*S20=v-K?DI6446?t$vFo>MMTUwiy}yrphz@p8#>vxZO)ie zYX`N>2}!1TYpsoa&L4M-JKlNsJx~A6Z}<2HG=6;Sux8b)T2-^2^P$1$8p*+|C&Sb8 zr!R2t=52hldk6M?vmK4QYH{S$j~F#>BvD&wgj)c-Q`tXgDjCY{TnTHfr!A?%nzoy*1T&x!le{-SO=pThu$MqlT>Lo{@Ga z?WKtM1_JN>WPoJUIn+T5m8rh?ZR-@Y@6Exp9dnQ}s0UwwrB3oV=BbL4F6!9ZN1qof zu-{qf5s52Px8qXMcCN(V99Dv>DOET;wE{~u@M+Y-L!Dj%Mi70 zMp$L9j)k@=m~JMEBtvN=naCrdSKAI(LN^Yn_RLx?6G&&hiTk6#sd?l8xj)ByYcr?@W#l#_98i>1h&+`rL_6 zA3oz_OB>f!I`!kvu-3HX)RuJ{=?XGfv1l3gA3T8F+iJ0MTOEG-6SoEUwxR zbLp*s)5Gl%qawCH&PWT-`Pw-Ae{=-+jbF$V+xw^(inBp!p&wgng5Rrj(Y%2!GG7f( zD|+Jh5@&49P~#$1x?M44-<~}%VdO-tU0#6GCz|o>;VX2xOS+dI34df)J4FlF_VPL0 z9URE=5%si;MxJIAvXuP!U}ziiDz4gQh!2Rs){0s@dGJ(B9FSdR&Glch)vUyffqBl< zOzt%nn9AYU_&#VH)*bnStdY@MAHIqrwPOp-hhnZ}qpWdox*wj@Wa7p4bo^Nngx~Xg z@u4XN2WAIwFT}jcu@QDS(nB6M$Sc>_sq^Uqyi>?K7PoVD;7U{_E`*9hp0-Wigq)#i z_-0xWZm!sc^OGxZCT0@{?D>$bxRJ0Km*;Foq}xEgfck5zaE~=wvllLH_!bG4!^!ih z5QWtxP?)1RXB*D4iF0ucXwKb_Mg1ZPh!V~USb1PxuQ=SCydM`Ln{a+o1FlZoj{7rz zMzU)t2X}#`JWdeJJJHtw$NL)L>_8J-7+{EVPAa(EM*}xKOwjCRfRlYRd9%c={-(Iu z$ABvuHj^j+$;X(hN1h#Ih|5DvaMI5RhldzrldU{v%ZT21qk}qD`TF4{HYnpq*yUIWC9jVnS%B6mtuDf8Lo3z_%mbWhpioN(DC6NFTQ6#`|kT6(M`*Y zK1&C2dcK(KFq$X$Qlk>k`B^mBpCPJ4u)GG}SAF*hY_p=XYhuE&V@EM1GZj7qJi0oU zBydtU;*26gPX#B(x#MRt+!uQZ{MFo33fC#*x!}_csrvGqZH(;SxAJS_@4s|ROGyuB z7tQ$ms<{4mwtF;g7ir?^1_fMRDd6F1DLh#xk0+ZAaj(t^dsjLmVVE3`PxQL1DH}3n zuB8aq?sfS!YJYAN_d`o=#4%r-ih3U{9p!h%uz?f3o;} ziPr9!m53{))A6J!8}Ay@@vI^YubPqwxRGeD3B#lOacF7ELA0@$d{|FH#bQ8>M<7E1=l!B3+X$|B~A(xK5cI2GB5({bd{v$msV z;(Tljor&F33h-#zF9g;)G)FYxVn{7+gp&c8vKzwUrpod#BF5j}QL zCB~qSYkjqGr;j#nIBDTL(byZ_hB)J@O$%8QhaGirpob=^tRz@yN`}c$z#0k{RuC<& z=p~CC-ugH?syogR)&9=a5QluMv5o-E4CTV~G<*>de&6wdgOLI31KUmbAm$%hSyGYc z*4uY2c+U+jA8LZ)jb*f6RC$PyDDlP`;}GPSj^o>CZdQ)`mtVbpikA0p$$!%KpBdok z>+^P0Z`y`QVEeD_?T$A)9PzkJ4!^Dt@cSA8 zcUBAdb)z(XuQ0$vqRO{QEO2725f+BAeoyiw-34gKi@loCbR!=;d4ZM>pC}&vgpDiK z@$$wfbzfAev#fLsHcE$Kg<241+xTOgu@lTyRUt1Y1t~!s@u5JUAt4Y8@(PgC)q;&J zJt*^T^l!>glTrSgmf4!9V#Kh%ShF+>wzS|Ph`zOalaEIwNqAKmg;%xVc-9b$P|}xRXb}H>Dh>DK@?wS&#D(jRbh|qEVZ0ZB7%unYRTK?MGmwd~Y0K6-X(SxD-)> zyUC3>Flia5%0ubgj}NxQPi{KAyM~>sQ&*h2)JzpyTr9BBSsx|d7FbBkfr-xb?|P3z z*ZWz_Zr^oo?EfvgXs#c|`88qJS8x_r_YT)DB4}2z5D}nW|&Sz-< z#HJa16eme^wDL|Fa0>exm#<#IV4q>UslP944$&HiLcM6LRtV%HF8k3vbWittx;#(JL&9HD!1bKVa)nXwaB=YNOk-Ntg( zG?UiEh5i<3wwK3k9|P>@r;c!QQO3x_sprA3jko`6hgYv&Oe>QVcfbB zGF36eBxq{VR9 z$qv1Nk7?&c65|gLQ?Ky#ad)BqG)4d08y*uqh@v)}?%3TZ)q9C3J%f_x9 z7=+VPi*aLm6D}t=@M-E7qH1tFU>#1SZo))MKVl_XdQDEr%9^o&N^DgEJu>&!4j4RYk#Q|jvKFjbJ@EFp&2Q>n8KHu`kupOx$%fR<++_|)=|kJ^0t@j2e` z>FA&T9`ePW`t@_?v1dy?LPi8|y(u;+k+G5-m2udh7J~|W_!Do)il@;?34RcvJ;3qOv8nZsrY_v8WzTmp$BHb zYeD7Z39z*2Wt61R6(n)$&5m2QZott@6C;eJ@U(F;o{%SP-!&iU?izftGR6PN8lv}M zUM0m%A6Lt!;|;y%mjwYB)z!~BiERZ8w8qcwQaJA^jg!N=Aze-c!~_#p9GT0;C|2Nf zS`{uPSD`ts8rNs;K&Epr_f*WYHn^GL9L3h(_g2I{X8}hCD&mZ{27YkU#$qxGU%a7@ ziUqR!2B9HrInHO*;c8|*?h+-wzvv)&Vjp59%5<(87_Hn3S27xKDSiu1WK<$d!!8i|%|Q_-<~ zHafS>LR(V?-qt1K{oa{4x;744^xXSZAfMpnjjm}ndD*pemJ#t7ZXIQK)bZWPKjQcy0R#G6JcWus7G zkcJ?^1G;3KHdSol&-L3qJ7KCL3vC%OiIw0r5@#utxH)GV&PP_`R6rTuYC9iJtRt+7 zvyNM7O}M}80P51_^XEO;)CAG`YNB4Ws_=AXYHak^#@7F*M`2;1xrdia6VZszjQ6{% z(PFd}5a%W!XD9{t^flIj7Py_*``C+OilWK$G1AeCKd5I9?upwn1lZh!DO^e>%VY#L zs)V9KD*-XmUR-3XGAkV|=eFU^k9l~ze?DICnT;DIai~ujgvFyB5!Bs;@2P1K1!SrO zvI^qs%&F5|+XSC@HiFGh_2^;E!T8sv>0!HT!~lTuSCnig?QJLhF4`Fc$FWBcN+rG zS~v!;Hw;JT=1}~yaEv%_wzngmKNG8lc5H7zPa6~7$Er>Dz{OJic|80QG@e;aQVsz?2nU8;?YhN(ib|BQagp zk9P_6Rn|r1AU9c91o1Wn*6Mn-m|kR%PHt zSv)P~*_h=kZeK9*?FRB-=le)-y}uI0g9e;VGtkZ*lZ0baYjHkz2Nn!Z;2>wojtWO3 zoE+(ZlAbD@l789yWQnajO9@U4G{=v04$U4KIO3{}gKmb{Xex`z3SuAd7iExsQid3A z>54_c891@L4p$cJ#OdfQxR$jWtHxyV_b#D(bYf^Xtm$dQ|9`fZB3|ssBxVtTN2M|N zt9~{fZeNIF`Qg|y%?HbZ-LNTj1a4PMp%{KT-j;>pL)k>UFY(8R^6~gw6M@5XM#GSv zt8?$ZxJ`_OW$9Vn@2xvG5g8E-1!)N}9c6mHnvkdGqCx;xk%-`Ay9aEmq?^otjJ9O4 za1S|FCTfnwO5;(foQP8SRFuo5qD%-wm3$~Fb)v}lIPsi7c}W!yqxK)#1w9Ib(uNt~ zk8Q!o_7d-fxdZy!w?xaioxT3(x1L8%Fn&lc+1zo$k;WPNSi z{I@&SFJ150O)$gmv=TI@H{j;%-56!*0VT3iQY}t+ZdcAQ4B4bGl~S2v}jIi1TCYagJ#EX(wfz>7$CXUOM=0pdP9R8)4lbD`c4I z^7r=YqRoBC^Q<12h$}O;;dFK#hG_NV2B6klf{R0}k*F&caWtg$<(cru#ldK6%*OW2 zahPN-^>-Z0C_S%cB7p788o?!ZI?D;Lr4#UK{b-;*8I7qv;#7e#0dzwh5gr8rl;97poAaCmhFN)kpQZ9sR}$%}?) zm|%nzilNvjpTf&v8`USHST-2z)ci3?=!WiOq#A0P&`OW=;^nijP^bG(&+E~)zPP)! zC!z<*@^kZbaXdfB$@Ld2O@n*px(4^`tZXhjI5-^k^YblRuplRtsjPf$T>Q5^LdFEG zVa?S?rdFdlxrWDbW34>tLCWCITerKqh~FcB(Q;m@7q8=oGOa|E3*khG5-669!2;D` zNHK7Sr>cPnSU~}Cy~f}~dNqE_*^BeZ)i^q%0-i>;+>(b6^MH+(9F*mx(cbosJZu}E z9?url@zbXuPjq&ugC1V~xEQ-~yf~d=(lfi=%yGS+5w6?Iq1nqA>wT=nq>7Dz_U#n= z75Jg0Y$TplM-ZKyk5mtPzD>ZYpN{&P;zEBtY_?V9zhk3lfXSnixGWCK{%)|9!$m)H z9O$ou;ZkCC(Z(oG-etrZ@xRR;1{Z1Z=cCDUY;@7XcLTcN=l-TR=Sx)GT^T1`WN@LM z3alj8G;Ap$>^+(L|a)9UKfX-!c=ot_36rr0Pafg+uQou(N~Wwi)IGB8n=!L$G${8TU#4|fs$-noRl_&hwU znTjXhFXw8BEHgb#Z6u17lIi&;p;l=M@+6_eJVMFf8Ngb>5Esu~;WoJW>{*zo$zY75 zfO}2W_`S&ln`ZQcA>G3jIhkKibLpRcSZSNKkJfR{yl`SybuAy8FjmqRg&OgwlS;*QAp?~{B+5;qkZm-W7ML__3DnESPsPdHMl{FP z;aW%)uElRbW6*p~u~=+Ww=5H*dmHiXqgAU`a4*o={!DBpc;5z7V~Tm1L}y7d-u$!* zk^S^IElpM>(0bVN3Yhxd8XUyz=if{lfY#bXe5{^`k5%LGk|-ie%KTcl0-?6rd@Ex~ zHzhRt8t_SM{kn{b4o|2ESZpA{xsmqxjy&aLMe#GI_;ttQ+F2YtuZx1wQa>5{mV{z7 z8H;XRo{m*irO*P*rSod)Ess-fnz-*{f}`C8obRVaAU482FMEV2OL2g)Ji#b)2cATk zsHuQc!>zHkhZH{tPZN1O0BS&$zuJ8{5zAuUH`}9=~`5Q*#~2urV5z z2K+gU?=cXSQ}f`WVb8Zqn6YJ4c)FiGzF!i7ziMXS-QERwcxWN!jO)eEGg-|CJr2=$QQeyu4kZzQHu?1ets#Acjq z{`=Sd{&zjh6g3cOISAM1Zo{#Vb+|EaCsKUE2~3LkX4if(n@EiH*DH6?%fOCknH37O z61YM|gOG`hQZal_t`8R=Q$|Tp4$jRY>X*`hbKzTYY+@g4B@S<^BJj2@6;J9iu{C25lF5@!Fc-I3z9gPl z!}m;0B@{RrVE;gCTy!_aMQ0tH9@Yaf(&FDU5~MhAlg-s|XqYAD>4WV${(ZT#hCh=VNSf{@|-or_4GPIMqzRfu>fM@cpHEvrdEyPNw*53$vP|>?$L)8 zs^L>tOC@721)EACMfbr_RSMZ5qu`^hjbSoYyjS?AsWr&)h~|wB?7pjafj89EoX%?m z5{5YQb9WPzFyFu*<;tuPJ&9h)C{<5Dy4i3pB|F-4?BAtKC%*fEytfpRJXP>?YY*Jb zm&V;1F9bP@xs$KG?*EZTNkN_~yU~liV{vQ7cAN_xB#%@n_>H9==r?jwh92_-kVv-Z##{-Sv^Uoga=r zi{tQ|Xy@A>^6+5)a-6D4!~WGFC{7)WW#ilss3zg{yDYIaiOn7|VeNIsIMZL30Bp(s z9y2m5A(m;WjBh45A-YSg@Kiw-UR6*`S{;su6q|+`h&8}FhdAJfs|K#PDWlm{5hsV+ zBHUDk1E?{s4?4;7w^XO&epMEn^aVa%Wz*&|zL)y3O$2Qx8C(-fQ$Ff(h?5x(ZJ3Rb zWLUffO&m?D#L1+sxW4cZ@`7i=UeS;%MC!}Pa-(L;DZMIPmo~CAhhU>o1j=P2QAf|d zh6w@cCSjtw3q30dmd#u#ZsOA4t0~#Qw+RNbVz^g_5Y7M zR?J-xY)m(LU-&xQPu+}!a#HH@0&<7Pz`Zmy2P+bx-B*)ipNATbNy`KOZ41>KFgC0q&8Q=!U?XpQaJ;!_sruJS8umY zM`ztEJSt4U;q2j<>8rzOGv7O=-`(n}hNB~GQQ6m=%fB)zKix(Z{a-+ z+IQ2(=l5^W!6ue>l^Ir6l=ET=29z{^58U0i5uRL@R>HfDj;2)MhmZ}pH)|($Ml2(v z!n%_*5h!DWIayV(Bz?G8J8}=({$6A{&3CWETtk}WWpg$M%`us`k9%5Tb zkAM3W6NY+;%JKA&vxeE?^tu$h+&UMpYG>m4j#+#ZVn_W<4w#pWJ?_0riV&J7Y9^SFQSjxN{QiB6_ROCHamr=7?$=suTa2jh>uYcNDt z+_G5_kcsm-4LB27hD#F*d6WO<_&lx)?MG{1t^RmaswSgWlEG>44oMn?LdmEk@48tv z0dqA*^79|+-kTOlJ38LI;j?qYCb{#^|7D#6?w9KGve=ikwpcP=d@ctL95DIH%m1Hu zq@-ldVPawj(>CFL&H>!XXy7GvJEj-%EUK!a0^br~M{7$PS6~kuIf@Hr#c6q>Qa=>S zWk+%4gaK-9I6bQg*QPh(R`xbr%x=JZFE-zY37BcYmA<;rBL8`H0^ZigayP&U@|>xbq7h*Y*jW?3(Y`GgZ&~cS zB?>nRBeKE;CBJnLvL7$D1HESv=u*r@8`%(=68PmZDWtthI@2O!a_rS%NP5EqG}US~xct`Zy`<$xFs zF+o*3r9ZGg8-K0yLub`^v{VG5b?am_7i94LUJGqi#D)a&`^jS1Z64-mc2~!qUUH(! zVtgbXJb#5@exvzyFmUI`d*XCqG+yjqgwA6d@Mzx>{CRLaZXGDW?QhHQ+krKxo;3zu zW}>%JlanAbJ)1nL7(aG&$p-xO;02t!yFpD}tX}dVHgTT~JlnPa;dTmL$t4Bsj9P=6 z=}qE9g{XR*Nvy+<8Rc-6(j=p#g_V*3G|8lsXHDd>>lOlUsahK1)coll>R_;|hZxRu zzUJ+Chraz0Mnt(|Tm?LAbjFqSY=osIo@{ePL~kbK_V1+Af9c51o)ybf-1}>)|J^0R zVyt+gVv*`%%$b%R$y1H3Z5>_f{}ZNV<%13gd9H#Lisy)1HfU>+@N( z6NMgFqUw)LCP`fBz8fu$vAu0^tau7al1A_uwO&GRl-N(hWSPOVfR*5C+XL6mT;dDw zIsMJnuI7VJY*;ld!{7eAi;YG3NJ>gTa&jW#eC(VZEsM%p_qHZ)FGz$gW|^*O^Ntnwhw0jQRHPW zjkLj)uBm({2((8Bb;A@5acgJ$w2^p4@pyY_I6BLM@fUgMhmARyGQyrS0$+DGeEigo z*)yhaF|kS7O8CLQH>PQbt%Q3Ien)5fkq_f8&)A z6wgmUR^$luH`n3Mh8eB#W4+O^rH+ODJm2%Gqa80gUh@&8i4l=x1Y~$s5$_*07jSR) zeB7;=1%EO`?0k&rIVM~Cb-A5tTqAp%JIDWBUIjni*0+EI^f&g`?*FGa~f<;(EE0_2-(yDQT&a`(R}Wb zo%#5YhrG04+wivY3B8A`{ijy?{w)`wW+HJ_*TYFKZJZryf%<-yyb_Ah)O!`#Xem!Y zTTwV(=LeCuU5th~L7ciXb;!*Xm0Yjr$*ULWZecCPp98vcI_+j-g}CW^|)NuG>@2X~?UeG8|)Od9k(lOCnJ&`HK> z{_I&WA_M6mZH~znqv>1~Fvds`ua0fT(e=6L&&n6+`FTrh$S{!?9XK8LW*^4Im?r!j zSd5zszd^iv00CVM+0y=~RiAFvJc5I3 zcXT8AeQ8a1ye-zo-9-W(lp5iORXyQmNJeI)`+={$_W!YmlbS3d=;j_6(;Ghxu;e9w z=ex_`xTg*R6vc$dPuq8k8Asw-A6rGLdiGQ^)TNkAiV>1EhoQ(i5$gz`#j0W0q8*1C zwOC##&cxwL3&XKVEgt2PI9{V#tQ&z0r2%~WB^!e= zJ$DXXe)ysbB~mUn#q34vQ@nfsnm1m*c=?)QrjLBlu&I5YJ}}jc4zZ;2BiFvc?Q6FX zG=3uYNQ};}Te=qQtsExkATWP!eUIzE9OuC3O(4Bkn2xu*mZC0W1f09}PnovxbUR(l zbd-?e@b=;$g1{eZTX=Q#Pp0W_9v#KNp8SUzhyD%P*S@dLZ?@X8h7U1yg< zekXzTCBHwPiBYfyxtR;+K~sv&sI|Z}t?^i6k%j@pdOW36v17%2#0~T1>>*jv1-beo z(MvGqlM!;<<8X3T1MV$5fL(E`DD2TDpqpc@(j+u0B%)d-9OcG|2vq3DpU+?)U*7lH z+5VnuUo%nhox8X2t)=7u6Fh0~#gh%H_PFI7$*Gbe@c#nkz#oqv7%S{xdEVBcXrEsR;{H0_}% zGmXM#r4XV`6S0k~F&k&OO(_*+GV$0biQ$v-%CzE9Xq1UO^djFf$_^kM7?RrQSYway?}BUk4A`K5<}nwtOO5*vdt{+FrcI zsUMGH@r=3fbaH{cxfRbw%S*{ZSxyOaX3gbTe%AJqdn2wd_O=cAi{`?dfH~Ay8dt04 z-0bLRC(qd4!54k&yVs&V7OOI2y@yOZF2?R4m|~WC0I`=?R2oi0g5b?PD%%gY;6ib_ zSgkq+rTP&_)Mnv{9{r9c#w$A^tNU0!UxBc4`U#;&CZb+GMzqrM2`D9ivcX7u6jOL#WsPh+ zHqrlYQH?=`RvH$ng(FbPgAYq)i4h)aJNCiS1xv7t;=W_&F5r**xAE}KEnGWwk-X6{ zESg6E_4I_Aiar5U35rC4SyGCXN zdRZyr=YnZ?eIO4n4=l#c+`&loRK@fmI{0qxFtqNRiMIMVXlY!86Zr|4JE<3}6hxVx z@qR<`^zk#Xc!9D5Kv41`UL)oHC@OWFXM_3?1r??+^Tdwl`g6NqlgT=xN#T z?02m%@aWY`yng=yZ$Gr*6@mH9^A>z02ix(9`&Igl5BUE3Z((L)PDV}%g9K|V(wl%< z74nKgBsR%Kp-?jdsZw4BHY#!0tPqQQ)o3iy3PPY@LqKLyvC8CGbrB)B zVwFZ1s`XQlryGtSC0E`}{@})C)0apzmvCQc*3HfK5^n1mti|p$l}Au*fbNQPxbgL6diuuqk?mTo+l5 z7N#oS3SwDR1KxEa#Q`bPwZ*{zZYn2WxSKtEJbUrN0roR3i9~!4n=*IyEXB9vr8@Y| z58B>~G4b@A3{Icfb|8x1G5-l^2PfS>uuEO);Q?n5|`> zKO-|q+>&BNmhU^bw$aDWEqMF(F@h(KgG8DEm8ovXLRuo8FKcrf;^B>o$|4*+{sZpc zxl7)volDVv;3+e4*g`x1O!1yG$Na~`r}+8Eal{0M(e=yHIV;k=QN#rGK3HZPfO3^c zG$|*cL?#G@O2Nq2B=8z0p+Y$twF(rrkfCHrqzZaIRT{C_s2746ii41>F$h`4W3j z@#!Ni8@BJlx_F45ed)Knc;*sKcnll^2c(7XpxTN$Ed(p>q1 zd8A7hu5^ixb@CFvx9uW>s4gkOC~sH3)xx}{shR*+ieLNoGJvbC8VtJYW$%}jm4zUy06|7VhC~|H8sc6mV*)Zn$sN1f zA~-MrsZ&!if5l?tZOBLU<{H%R*oLjO^(b7i0oh5@(a*t)u1lRyBp4uP&NY*iiH&Fy zu$VeXyoN8b6-J=Kl+C1#MVV|Awn*Z{>4aoFo9Jr;eXSHi#96^?X0Q$c*gP3)%px#Z z*AISjEKw*=&p`@vrc5D_w(~H8W#Kz01o_b3!6|V@a3;M^A3^kNiu4o7C=kQa2*(Qj zF&Lv}%?+!Wj`oAEz1IIFj?&UnYu3b`%v2zTbjRtw^0-Q%y<#okTpvBujdZ~X10}w2 zvr^NzcV(-bZIZWlzT??iCe-$+?K8^PmBYcp0ZcEM#Y7_nD`ct+#(dQYDAY|vsZJ6$ z>PDkLJA!{L(NCi9ld(c27IWk$B9`ddAd0^%2&k-ShF$fw+$Ay(%i#K!RS2;d_vs^4SCwPxlnnU#41}4fA$0XLpr$Sl6;)YS zSeatPh!MzJz77v=KH{E+0hW*X(3dF^03b6CbMO zY-ot3nehl4?eVt(VBSc!s}f9yK*)sKbqR z17mD1uY#q95$~?@p!+{w=z(dH!N}8#MxJT}inU_+{j1WAMTKq@iVdQO@`hr)ek47E zG02ee#Yn-941o%-5uOw<7C#(4z{xkevX^h3^6y!Ki>WSdq-Sm{7}9gI!&;p6%nAFLz$T*Iw)YGDp-9uTqvd%rPVH>T8B;Jr!`%MiuA#b;Hb_ z`n-PCh^VI$Eu7@IRGvur&?SD^`MHDBx6Y0h-ir6vqX&G^40j*Q#k<&85jI(y>G-+| zX7G};fTye}+}U(@!Gw<+>`CCZrqBP5 z%hq9xOE>7V8e0kp=H<>1iw-(E&`Q_RO6X(P_MQccbggYqU*hro-|+aid$@n|5^gjf z#~*huq2<*hK5~M2>9+QdXzMCmVB1fd>nosVpvq%ab&88KhM3^MibQ^mzLu^yGQS>P zf-z50CHVKly@N$KLUHq)iSAt3n|b$v#@)I0FEe^^1iVbyzL>8u0Si=vv066<#m4a{ z(F(x=!?7G({XD(+`QE&63l&8baJKBpl?p8g^sGd*2i3;KTuknAmqnnoSob8X+_cg|8cWYdv*sst~lj|HY zP)yYA2WP>8yqyNz?L2Vo=QA9*Y-^(9!&}}O_on3$E%Z)qe_y|gcG6$OmebpdFWT9h* zuwVk)wq3Y-_ddT|HdL7>ti@dboaa=lPz4RoM znI)2u?a8zKixw>n{o3pMU+!pXD(S&!C>uajHNp#1tPOe1>_DQYS!(?$Hi^Urok#>z z{KzJ@83;z0o4Xvp|Nf`Q1)28VyT^RA1Iu8(@A$H}2(hM@fc@gtOWeEj0M{T_dYzvHSiLvnI_48-AbK@qiG+)K_<{S9y?gRdQQQwrcyLa-MZg$_>T0ii-5-$;L z6Ys@ek6&QL(mbN?@_cM&uEubbYlZUU))x6#I>%s?7$hKBXE>i*JE)h}_g{N$|H~dp z(GxRSjjgw;qS$aw7C2L-KgxANP$w6SdWCotX+kvUhYTi*s+Ueh=&q=+o&Ce62%a#)Cl30(45`pGf z^|%mLiEHt7IGR}jZ$)#S{BgIH#r?Xec(H2+Qv3`#$UU?z;2<%hg)a{_(z9^UdYn0Y z2KR6OCW5xDlMjda(3P=e9`)tRmpFIqC~Av~;p6Da<3^@t-&0AKd(wVN0xoTsj5h}g zF?IY9{&xl|TH)NREjXW0g67Oh6!=f4^OkTUY$|&&%4Ers8pNT%AOzupBY|3n03r(mS!G0p1!H;PYBU_$$(8zEzj{HK{4&9g zC1gHxg?R?tmX3G0bNf0DZf`=-ilqn+97U8(1}Z8NE zlwYhLfC8mp6sbpItwuPKg@FhV91thlA8}gVe7d|N#Z+fzRpHv?Ew~s^j;k?s_&%YC z$IqIA4D3_{+$)YldtDL-h`SW)z|lZ4R?Jtz6BL! z=!w%Ar8pH^h_k5`I5n#YUefj)?5se;$6SKOC84;yV=>BeBDh!f6s)m9C5FJ7j3%i> zG!PxGCg2vR$0A(GlVVRLq{pU;RaFGYWh<7$$;ks*Gv=eXYBLTU{sF)L_7GnRs@`>q zRodKjzW+~5=red0xU;Lej1O?7(BSC7{g{;y&sm5Z85etLV=Ofcz-Fx&R4T`zL@E+B zib*JtkHAWOR)%WBJ$}*3qH$k)J^zn5qC=vW%MoCENvx2mGz8TK@hFiCLWOK7c4{P1 zoH7noGJ)7?9EZ6&V-Tr6fG=`GS~v`B0_){8kzn)y8-$MQi?ryGm>M65$uR*)iSpZangk_5slM#`{Bxx5E7{#EF zta^nKQ9{jRqUy;gHc3ae`groVx|re;j*Bzua3-P{S3)=AR_addj$23nrb8f9=HBn% z^bu&^HWiN>W+L0Y8v$JrNtzRoZ<@%PwqsO=VyK)m(LNmxCKe;I$@LlpP#N+t0-JQN zV8+3gpga((v?tPeMPQNnL;}Ae{4_Ojyl4*ZxLFnEBnq|DVox#m#oakgI2BWb!(oMJ z&fSMxw-nA+Y-DwLHknnJjk7f7S?=!iJBf+|P^q5AWm#&a2&_^Os8Wi=D!m}?U6tuQ zXU?4BwbPewUxorPBncS@MS33cd?chI`dK?6VpI^OP08X~T6^oa;l#nixcJi<+-tsr zTNiKO{OL0|efnqY-&cq7b@MSZVGgW@<|Qu$8)+#Flrh12b$?U|6jv+6qEI#l zMQU+8$KXe-$C3=))VRz!Uwa+@k2+?|n47M|M>MD-Uc(3Zx?!kNjzXVkWzPBJSvN0ZvatHPjFlVTMiX>J1 zTBrm{}6-Y<9y^6T+QBrm1CyTIq0H?q&qJH2y@cH&8A$uJY0m;p`&^7 zBtl^{DpZotAfJQ^W(c&Sv5btsa^3OBk@v+kqmdYG)*nVP+FUBsO|3ifx+kDqBMzID z$ivY6nW67b9$o>#HuiXSau15;Pl5qaV|6((xiq=k5ZqzS{?U~<6|or?r|d>e=sLPb zI`C5KiFA{}#2A=5g&sx=W|$*47{$aSs+5vZDV>DPQVFP{`(B_GfHVzH&Ti5Z6L~Fl zd*@5coI3*&DY0pQHCtp4BhWbwLx1v$Y_PHxy_AV%=#mjKlhJ{htP!j=tYNHYik{u9 z`LqZ&c7+*IQOij{h(tg^cTH>?>VyOXHQp4FCfK3YFc$d)+D-KA7Z^rjn9zrZF41En z)_v{u`#)w6L;V4;LDqw%dtkj@6iS5%UL{o{pNwj?7^Dl{6gwFq zFJLiFrZwSgObyONSL4ErMugf8r_a8Ji^5TT{EIB`-h4HB1Dhz3urxVDvh+XJC zL$!6_AkP)-(T6C#DO3D6?uTph8gXP&5w65-!{xNy*cV+wUQCBPvnlc{!?1~k99jw3 zq?3Xstt3=RQ3xP}qgpYQt~mx}nlZ@L8v;A}JR1!|G+(^LQ@O2g9&@k`=wpQJN&R_T zzhKBXTv^kEb2B$#fAShsCN4ydUlihc`y;&jNKCRCj-h6r(3DccP{xH-GPqx2gg5)?D8Gzg}1*5e+#rmR9tict(&v2G1?$Qw=#Hpk`qICv|HTXF}p^U<8K376%YTDw*?V!7z8;%h2QNKKc*qF&ai}ZKc$nb0mljU;SI6Z(TDaCr5x08_ zINx2sRS#3-YbtQbo$=cCh_@R-e?ym*C4Nep7&q^0uhoAaT}NJizQ41*^Cdl6h|c5* zqGi0WNH-X3P06zwrlLSU4JqV>ndVVNsv!Z<1ozeoxR)o3J9!dZTP5Jy3ITUl%HsZd zP4cXkc)G(Kr}KJX!8i#|t~kgFs0*8e=2<(iGqH%`CNsG8^u&{wZ}8~@MY8Q}`0clQ zaJK4B^i~m3^8HYx6V8)j+f-w*LT)U@qFR_>^}?UC51Mc!4FyqGYFmrZV!WKgUgkFARFMERl!bVIo0O;24b zJpBDP-dR(=CLc_Qy+3*NWx7FFryPWQiuEgv#5g!tehfBfMPQRIeFk~TAi6)SyD2|x zHm*&t=acU4X6(TJ;C1}GM+mkk(+Qz)gJM*H&Os&>^>Xx;j8d6YI0_UavBoG0Bl$KC zdAONb_|*CSO9vusG?ma@S-`hzUGZ?oXv`lW#Y2&#e*U<%WT%*fi`|5?p=CH9T!phi z)!fS;PAq}DoF*5DJK=1KTecG1q;Tab0rZZIG=8;{=878^deF;77eD*CW2mAO(RgXj zHcVBGo~>B8!tZOZ(SINRn`7Og<*^>t&bM_0If_>l;2@Y_oPjqodj`_NRmLzQ0l)5! z!1G2|Jg+dqGX~5mD?F(+!;`I6cv;&A52^=Z-vVbW3N?kBz94EJX$i2FQzo$1qM2yy zjf_3W=^jThmp0a{EEGk}SrzNYcJAHmj4a99DPoH1V3eqZ5WvEbF9{&8X3Isyyp*gF zY&V2}&<*zF*(M1+k*^hmdL=e4Gn#v^dYw#EX(sXFgG!eDmIRYm4I-Ky$?KfAke4ga z3`4YBf1-OT&{H$ScRwB#8*1LR@M4O^Su^;3@L>DWM&nVU8Ho)9`ZD!oifz+Sp%72N zkH9wN$yg{IK`-0e6=-ff!WM2fvt5G?J2jk>X2)Hju=a567OC>6$G z3o)9ddZF-^vV$6V`M^m5c=YA@l=x* zEURT@8BRw{qGS^^u_{Uio04Tw9j}7DGt5w(p^W@!DP+-tnqb4gDHbc(>MLQxy2V4L zW~HZU69B)Z#d9aN7T2O0aWt_OeHEObuV{pa4}RlK?Cq=sl8zH6Ps2n>kHDykXu%cv z+My^hiA9cS07ghV@~s_5qQ`bbOCuC~uvTj#DiuSyazdjF6BJ|ZXK`F#mvs#>D!fHH zoa^o~vFvj71gy~t<2|4@WB}CU)zR?HH{6-M>kviGSR+JR>ub!MlEEhlI1^2sqU?ua zgCyk1Mj@YoS}UK3I_Wqx(%&mpji*@8o*R^@Cc{wRnSgl9AwcG2*C*p> zi#cP&QqP3Al*OL*1MXXpQR%B-hnZfn_%5{q7qWNZ`rL!Kx_l2t8(DKrVLs?Da zd8Oj_tlc;jT8#5q^+fB^2-vb1iH1XwXAy-w z0@^B#2rQGGhzgBJR4Rv{LMaSe)d`d`(Y(d4n!r#e&yrVKw2rr0dG5>s`-opetPJtZ-9sYHwV2S1Oe0+gEM8DB{V>w_Ls_#D6f~Hp+`p!GlU0+*mEa!~fOZbpTa$ZS4b>Cc>p( zZjs*Z1>_<~6Of`n6s#0Ql#ac}U^jLR5(|hFK}AHwLNrFBCK_W!V>e<&#TMhUpomKG zegEG3l9!qPmHFTNF-(&4&75K64)<)&-s`Nj_Fmt&D%>zSm}6e|@#DuG=`)@-eDX}G zk%)Lkb=V5b5M<EYMx~eis`a-r; z<6ewQh~;zDKNHTJIip#)qfnBwF2{NK@~psR3l;?DE?wGrVTGtn2%p);R5{EpaVXV7-3GwU& zhUv%=r(u$QBz!mv)^WjF%LH53ZTyEo`0F-h$;I>MF)upIn?v0eFVwEmL2a%cu9kL1 zm>mZzlYdqzoV#f55FZb(6CzE67V5D(5sy#F9rUP;b;xV`>C$$zLk-o-L4G)E-on@q zzj}E5Vc_Q~za%H&^{J^PxHxY(L%B==nHgt{VK++M-q=TZqO zXIR3H{C?n|kWK&TndfEYg{KTjS`Zl&Rv8r(R2AjtT@~HU=Zl1}(2Y})hs@oydR33# zY5IBm(J(e8VX+l?(-#ezhN~Y};$%!du8#Nu*XHfRq@D?kawanr;l__OOz()QDN>ch zM!apKwE@NJH=$S0NOZQ4Grp-6S@cTc?RpSnjON@hl0Ns&y0-Vc^7xZt*REaW^w=ocIs}(zSK-u{4LCNn9OK;kv9OGKEL!L6=`6#oo2RHM z6B7b!dH)VCiBY|$qGe2^w*}S5j$`qsi!mu>JbHPA!o|df7^NY(Oo&m4VZ%uwH?T$T zZejR%oiyvd>UNIR-+hDPx`Nq>Kir341ML zcy;Q6SpOI-88Z*-vWsx5u9g+;Q~oLS?jSFLx38YEJfO6A4J1Mi_9V9~9dC?B8=P?a za~<4Uu7j8BZSnmgJ1C4v7^@UtZtpqe@h6AU#Hj5K8=m9Mo7XBKwB{B(`}qmZT{w^9N2_sU_X&0# zJ9-M2uU}`ZAW9~q@+ZuTk-w$#C)D7|x0b=DvoYJy8Pb)*sp3eS$nS@49XNywC8%Dx z2YHE$;Gu2HyziiXQTVauBJ=c(HNS-8Eya@iXzJ^t}7t zG7h)1gm|zn2$MtA84tIpD3?DQbU`sGNTO5Dt=sZ>s#i*=w=b6 z08;CI|E?9pPH_GDP4tTR2x2XcwG=5F!r@M_0(E6wQC$=Ue;wKmQh@W*%5iq`HtZi& zjCk8nM$NMn+hg{;EVhdc)rK~nKd)!^LJ!?ElkJ_ zDk?FaK6!>AvGGjxgH||Aj}YN;MIT&QDa7qu4v$DUTwkU{{s;woHW7i|yW4v%dHh9S zXXp9@J(PDRA>SmK5c~b@aox)RHxwK$E3|Of*BWDNO;{BVy{5z`;_=NZs&XHyTHMmY zsC@M2`^E;eHom~SchqQJpsBtQEsagACv6MbjF{FQylzI_&6`My>jM$-pd#X-LM%8O zn$rm{O6~CDV&cV0T~PFi6C7#BJwqvOF4%$N35B>kdIwHS+Ja?K)0uLhkmSuCwn}U( ztwdu(+dZJ788$bzFfuqLhBuHGME$#FJb%}O`nT^Hc^`B`>9vY%{*JtKUe>?C7n{C> zr=^myh1|4k*g0q)BMzrO^FiGPYn=Ivc89aa-WgI@k^I`)-1xgPK)3c(hK8OU3T+c2Y^o(42O0zu~w(tqN!3H{i$gowzme8yrh1#dzEPj2J-A zqum{yP`0iJ_wLj%g^JeJR;H2ECWZWK%Mn%7tcvVOIDh-W4eZ=gMe@)t%yTQqOCXl( zf~AfrNYe3OoXFE7EUG+};6AR_++=dGJJ(lWTG~j6w5ZOo zI;%Yn=j51Y8jBp`B;*?=vHrZ>IU|MI6k?*yhilI<&p#j>lgV$nD>ZS*L4Ye>R;Uj5MYM@7qvl0vxU#;bN=gW4;^VqZ zwxtu32&Kgp`b<2Gsx(kT>TJqkPLdVA&vM7z;?8(h=7>jmLOjUUz`ZOD+|4z@z0JOu z5vP)R4e086jE;@?LM@TD-YdDT2xTLe;>N@;aV35uj>Tl->?b9toUjz`#4|>a@H*XA z2ca6Oe3<@!tPOM!?CXWz;bG_%+ykM0-66M8z(iokBu!~MjR4LP3EF;`qZ5M?!?CQs zxQI)_dhJB4H5!UVqDTx-7sHFB4N5T;Nhhhnn3##}J!d@r;)v)SRBF~nqTb;x#HkPo zPIT>vqpoVW>?OoSCw=U+HD#pgAkG{MEr(&5c`D|b#9+K(7*a$b7$yovytWV0jYE-S z(i5qY2#mMshd{0){7D#jaZ7(ZDRV+y7Kfi!aj0Fwp>7d}X9YHRToHoIk5uGypUyTX zYHMo^ei>VSe*OS8O3^d1#i6k!xHe%cs#9}taaIYUr7mzKpDnc4!*>JRP!(d0JWmlO z*y|&_BMFt&Roq|7AC@tazb*oV&KPDIgo!2}VZJyHtIbkT)`6B!j=?r=95!>qu~sky zxrT9AB8x?`$e)Z$oe8KfnmZ+~J?DuBkAGlz%AjnzsA*H^8MZ=v6Y4;`tpQGveD*3a zgq5NWtc7E;FaXQN=~&${19=7`vBofiEbe4h*;FDPg#wdw5; z#b%S|9foXr%s)qM!dJ5o&tMD z=b?7yRvaCj#b}1TNKSktuoLSDcvhi-3!a8J*IkDFzDC#=D#gw)JCuiZCb=nxkBH}= zDTzX%BpvGwhNDC`75Rb$ln7E7sh*0jRp?}3jqxzdlJrLp{VuGpk%NWf&8n&@MSIK( z4<7#(%a(mU)Jk9f1=SWBNQv8WZT!&N4tv6#S-;kvB#fLP8i-Z;X~e@d5APe+9oZJn5iLfxSlO>#r(;c_OLOY2k?-U0uobxilUGieNL-OxC3U%C7YT-P23DA}( z$Gke=V6Z(BC>flD>r0IKpja@Bj5!$y-V71|EdC&t^!kmP$D(gX?=SR`YE{z%4jSxXlE29on_ zR!c^ufOuG9u;m&gywps^dbK!|87ECf9t~Kt=#q&n03L@vIy5GO$)N=`yT$E0sDS@=eq9{M8$e?j4%hJ=yNV z<7WpSZ$H=>yL;D{*Mc#M#)er2LBYwh-4CW1_Fw#V{0-mVjZr2{m5WS7IxYt!&FfK` zoU&$epZmO*9Ba(vx@0C>tl89aTx4~^4k3Oik3&~E#ILqZSgCjY(pmqF)v4DGz4%`i zQ(gY9v}{A6wP$~^jYpiNdt#e@?VJKDhrU-1-XXwaF?yD3p40HmxN}tCe)Y^p4m*TS zGKpHJ%~>NJcEUp=XV$q}1!pe4Z$B6lK52e1Z-(L;UfuUS9w!! zdIP-li}CjRlA@ol3VkL6x5`|$OTCm-{jv9b1d+0T4iJvp0y z0zblc@7aI3mNnJ#w350y->FW%m)q7)zw|R^!P+;w*0=tAyUyriXubOK%Yy&@S=-B* yCx&?@COTC2Ol0Smv#I#-;9xT`jN|Nw|1*?SibNj$_3}3Z5O})!xvXuEi$r}ea+*3)`gPwQztt*7<0p4QWPT2Jd~fB*L3!w01k z)%(V-n74RiVpQVyk&{AiPZ&A;k4gRmp2bY^yE#2I_?vCZ=H(qM%8L8&@P+=@KHi?z z)Bf$+>9eOjX3d?usc&ERd#ciE&=u67DM&#}5MV~#mAW@|C+e2edv(8VASMo1E6exG z=FD3A;^D)83V7eVsn;IW+X( z?O%Sd`%fO1qm7P9 zg8>1xub_$vf)z3phGLCUAaeBMQDmNuG{F-dgrBwc=D6T%hD&`Vamhyx7krfQpuZVz z5rD7z_rhLhRctd+La?|1qBLkJsjxFujt+Ha zJrSGt6;zO9?1yxX!C0X+23dL$$W#eOj&eNmHIuPTH4N+3#$mO_I7}7uMUv1T!-d`i zZe;?y043_d0VAH4?kPz8XPwuc*3M$gxav-24s`y~JS^x^v!%(dn zk8+7fl!-;6LMa&;f)9Mi&{tY$;i{J=?%4{s=Oo~!jez?W0v=GmV@=&n9+$k$v2UO^ zXJkW3b*KvR@b~e%b?43<^Z$|KDlX1k>f>VGqQ<1Qw16mY0ozl1;c7(`MrsS_Pwc;; zcQlHO6HzQ5j&dOwhsBa`K$wO-!W8Thi^Cqdci2t#;jyD6p4bbxM6dts zYk>?kMUd`9LBc9Tx&)AXm4SQjK9BC-zpwY-J1!=FNBDYP*Ax@6^TKfgPOmb?i*i@I z-R*|w)gFkk65vAbP0{qnYK0Kw2oVI*SR4|PP$5i4x%f2dN!TewVYd*CauLW(t)lEukfx$RyM~~K;Sx?* zYZQrmnK0~=P9P(XM5PdqGAWXl#ID5(G00K~MV@{vmKu!a#vN~>iPOXT;PL<+-0si1 z7JhM8#svo{{7S5Q*INyRjv5$9pAC_*#?{3KaBcMw%fGzus`aoQ6+xPlx`fn+2$YeXSRuz@FiZ>y6kZnzlXk%K;N4(g3EcVmoH z5I|l8?iMERemr%`>nmKAp4QX;?`_%QdCL{aFpb64FhQq3)*8nmS0Mq_5|fFYNCJzc zpiG*KpI$3bi9(5PG*)ViMvU43_{v&CpQN*mq$GxGh+!D9(s(lT8D;{qJhX6ns0GEf znz%F487Zdnu%i8}_l(D{GmheFVij&LID{F#Az(6hu#3-aVpD~G9M|cyr(OD(%6&AT z_vQx(c(Z3H{>(GOi|xvIu~iIDHVJsPO+dq*J~%bof^U0-x-;hW4o8Oe1gut{faMzF zF;h1P(+z^KP(Ki>bOMpB9gaM+M9edtL`p(H5cSjj^>EEr8ISrX;fAFot~+bsM~c4} zYfEtn-&;u$)dvpr3`+I1uiH}MLkrkoi=l*Q6gSm$0Jaez^Tgw^Pihv*NKWRcOvV=7 z1gzGah-uROFhY%mroIw=(SMc^`T-64d#?k|oJ+ z2SFBt1Otqdbix>2Z`jdymRl<0tgj(16IdVhQNR;hN!+5?`#DMcoBhnN%}SfgW@8oU zwu?6}ntt6Y*3*|J(k&&iOtm;Pwc|N}{ULNwrt|=y5B90W~vC<#} z>-FLhAq;_upaE?$b-1~>WBrCzxN`0c(AI=5(yy)5o6w1N>g+!~5p{ab-hcMT6O>mJ zBX~j}qyQxOvfPmOuhqmU=V6CRE6<-=#(AL$7=GG?aEgYyV&7Ekhsi66!62UKKL`= zm;?6pE_)nXVvLc!MAI%T=AMx_2|s;XjW_RpMMK+1er(K9v^RC4si7IQtqrK{s6#_X z4eDDzprzw88oH00I~V%Gm1MbOpC~5asH-vVd1~Q?IRTbHd&^k?X9rp% z*@#${-e>c_xjS-WzV>zOY5yk8-b&+7b2$O07V4p<+??V;G5ofLVz%wtcu_ePLu}-^ zyi^e+FfV=z-u(U>w{b?CUm7_a(boP6_4QxykJi=IMfTrD@3f%4rJaKootRzEM|h@2^qM*U=JRq?!$@jtppqy47V4@yFJ73BF_ZR zD}0ali~V4_3gd-L81HT>{TG3V60vz^h6pY)aIIk}NTpvK*>1ix?ib z@i&spBr-*9V=Mhh#*R7;mZs(}XsG>!n$Pd?`O8~+zXr8mn(+B^69*^za#ve3JrJA; zD0NM(98V0;OXjYG62+046i+6)j>nC~Cr}l=mIKq@MZo*x!|~G^V~j8p_|%WNfgDaA zucB>{9Pgy>Re$Ut8%*p^;yT=}zA|;?NB|uqIz>)7xikOOQ{YyHP$fO!eZ_)uwsr<(=*u~i&(m7d5CS0;%{ zOkyO3A20p@#*Hnl?PzRl=4{wb*8I!GpRs!R5_tBuqc~KYJ}*TEEe8)l3j+i__zLX&ivb1;78pvs zKgHngbX>M{99DuZ0Z$vUf+qX|!;rbN5-(r;N!x5gS8F5M+Zxf))y@acKD5^&X<9rF z3s|hZBWx+o&E1c4F*|V~vJ`hR_8~;qn->~<_uY36U;DcDwEqp;(_enk-oHCPaO2tq zb5_ny-LNz@dFzanv~4q{rEgiideNN9%Az5JE9w8YZJ25)e{t3k@VLMUue0RwWW9iQ zrRMlfz7ExGb7>c>t6A-RC9A1)6B)K)YBk^^3j#NM!KGc1{(4j+VKQdV6myY|(zay}g;dWdlo)dVt4M`?2%VJh~ z`r7|08|Z0&gO-z1k}%eP>{%OqeVC8|8+ON2Osbhvti>{f6o~D#WVB(bVGVyT|5Ixg zE}Y5A;{M}y_Ei>)VxNujAo*MEh~EjUuW~eSC*K*i>Y_Q!Z>slDfJda$)ry9$CLY#h zX63`t%!z<1gJFUa=E}KXgT^G}=%yh{X$o@Hrem9SJXY(5Vw%P%Oi>$&6aKr-nVaV2wM4m`=zuX5*M7LB$+kBuHGCy2McX~k1s_X|@Y^~8A9s5o z$y3f*~Y9Jp~=~qdt&iXu2=}Md~rg6M}f6eWi3f%2boFUOODo+CyMQ;MXEY6Et`z z8sEL6ee(bkoh@B>{pV*q|Kk;bwSfd`BaR$Ag+4}op-w<{qV3Pu2}GtwBr24nQ6|Q! zauTU0W4BlgDkLINAQg=qX?m0mMX6#0%H<oJf1aN3baO;Qj-2oXT*Z{oa~hh6f3SxD}U)%d-kFSlbbXDth>j z*X_XGvN6f=0mt2JRX$m03ecA$Co3z8!}UqU7%0%+O5||070}PosU|KcdS6jNR^->Q zvYz&zZi~}Xms`jSt)_H=2T`9#7yXc%F)j|W!j*vrxaFgb2acM!)xS4#`rDEu6tL1K z0#7#ofE#m<;r!$ZWDQQkFmW@Uj;Bd|(~7kT<3_q4Gm#+{UFVKx+m-OHNEZj@TftO< z#f$1_VW&@$prI?mt8^%cFCt>nRF<9 z#+saj22xZ9lQbR33&m~eyK|(6BVR2ZxdhfC$rO}|r=n0M8QE%ySf&$7zt0NV1VV@2 z_PG1>0UtzaZ)EXglZfpok}fVPAgLfnzeOA26291|N}yDoj1qysDiw=D@kkU3F{l(z zJJsnOv+S*!>o-~=>lfiVS@wmI78dsvTaeu)+B)JB|P|gJB&R%!P z%F3B;X{6D>(mXAd1@x8|FveQIw7~)v1PE9iEUGd}9V#HqQ@~Kme`J3NJSEduLKCCC zM|@XaP})<{_jhP#kDj%)H!yq1E}|zfUWTm_j{2G6roRbpJIdjqtpsk9CNxBqst51!>2 zeE(NlI2r#bKv-1S)0Xuv;pT zSMFpgh9g37<6xcdKLrn#9K@>)Cy^VqgaE5WfHc8Iy=Y_;Bj<_{D~lzgQg$lxS;`}^ z?Pl{NjFtD``|4{;GX2qSqFA+^&Al|EvY?QTPYR~w0KyfAk(4D?m!3?3Oh&bkgi7WF z=va#65|AUom^2o96;eTNB=$E})`cbgrrmLCac6Ql?#!;nmWZX$7gvXa zz8)VObI=kHKU5MGbItI0moHxKcEg7~ebIE-ozAxfUR9am)j=oxeqbc_F7SZ|8x2>t zM3{Dec+jyq(f*C;TJ@4LYFUz=vFYj4r`liJE_>SlLtBu(Xr2xqQI+J$=yQ!VaekaT zzHyPoSz7^joCu)y05Kcb58z@*5w3(6<81hLoQd9n z8*>if+M**kGI<*rg9HIfz<1e!cv0nx;v_lrB6$`xb{JaPT2bFDnxG8yVyTFV2$b-^ za;+F-DJP>;g2~@#RIw5}Vy%417;IIEz%sotB!zVmDCL9;^LFFs*j$_m+l=c=cO%tu zB*}GkOwkBHAxYzEWr{Nu!wG>jp+-Jd`yhoR1c(fEmu<5N5C ze0zyvLBiCiK|Bx12sj2%lHc1fq9P$LD~bYrkcbrja?Ou}~A z5EQD$Bik?@6NKIbL=8-~7>ASb`8YSb68XUkN#bg7hF_r_hb+xhWNRjoTo0ufTc77M z=d8}=B;U^Gox4z3T0zoT1<^MCxI3c~_cE$5cX%9U$Ub5M<_{NeIm;EV4|w6_PGdaH zl*5yCl6baO8uyoonOLHo4A*ljqBl7Wx zK)cv=ERTf~hN|J!$rOaxi&E?^UAn+WX&V~buxj=az7|rbm@5Gwj^fiqV$~Fi4U;KG zjKf~3$tac}W>tv6I;}9wH3}f6l0%GAKir&Igl43mi0hKl7vkWXzi_CS#3h9Kyuxd6vx-V;S7=HpMkF3EcJ6 z$Io7RIP9f^G9O*6a#q4rdo_$U)8<)09*QQIJtPLR2gG2(&;+cSI1PJeY{%ItMYuC- zAAVbS95jOO2)Fx(yWjdf`3>cr1KT_mQ3Eh-bSPk{~OMB$*= z6q26_Br{`BPQb}libb||BDNaEW2sRPNpf{0==$Nty#2TxT7jE^#dw&u2j3=S6CezU z-Lx@|WFPxYY()r9L6%rk4wD3D?9@%7_>({=7K$C3Q50iZLW@8!z}bfnFolY_AWuIY zIg+6$Cq`z4^yT7VD3hFod})fS)uJ&?=ub{d9L{1=2(dKdHL+}Mr)aAY@K&&;zm<{c zk%ZUtkK*Tv+wooKR@_{%8%Y*^n>d9R07l_d|H6t-kV=R479sTVF;Q8x! zXy|I>{qWHv6i-WH>ZnL8o)FC)V4|xcYW9r4#}aeADYC??Vh23m>47I@KDd?Vg`36R zxRmdRo4XwGV80!HKiVHxvWJm#VN2SmVy$U1@?;WFC6$JqQb}|S5h#`-d9M+VE#wsA zWPM2Ss6$I!3+YocGQYOX{@b<*-lGp0kx`D9>WfXnZWfxfBgG{D^s8WR`K`3?S{Ib;yRj8{A^7Ohi#bWY&`eT^5EmDm}AuD)3 zLc9m_q-PqmuW!g>zXt|NB73Wh?Og8?M zy$IiKU4lMRO2mj(SSLFkyX096N>0Ei5mQXZz>JJjhJJ^ktS0963Bd~8AZ*kR!#14= zl#qNaQ;R{K{6u8R2O?7^5`o0nY>MmXmJGZ(QGlW;A>0}DQDBuds&pQ8aXu~+zo+iT zwWwm8Cs}-DaVf&JJow1(JdIEksw9%*n1l)fN};UCd4x&%@btsgo44}1pXSbb)O`7j z!2^dtNm33*3Ua*u_UGI*JlZ)D`)4R1GfV<$ZUP2s2yjypU?nNQn!*k{sKY=qRkK)wPLpV^i4>?~@P1p19dZxb8n%j=K< zYe19srz9r9GAq~wEj*m<@aDruo+_AIRK^!X^CO1at{aX_nLw1vlk}8HM79`#NhuB~ zBs=X1d=|VYU5rmBnez-IB?7uE_M~jUlPQOBYr;<4OWB8SCl|t5(SpwtGuAu4Dh9Qu zx8eBG7&u5t5YUa0rwl3^0s)QJw z2PtuKswR?%46uMIJy#=eYEajb5@4Vxz*1WRR{D~#)|Y{ui3)mYO2J%R0>+A>Y9r<_ z)%m!BI>Hovuta+ja`fZK8AYI!tw$vpkKN+&$P>b_MJ@t4Ht85es>GUNY@<__t_nJLKB6N~gG zAVC;Fv6==s6}Ezf99+z8Fu=zbUi}ARu>WX`96JfahK_)ztt)p9mel)_k%tJbSZp4R zIBg$3n3gs`4w?$IB(;I19B?F-}P|TAs6R9njoJC#wS=|9B5)CpQAE06Drg>MA7l zJ$qsFq>&IjV|xV@iAy{00t09|KeVyRC^m zCrP+qzS<~a_(<$z>rYV#uwR1Wcj*Ldkq*JSK1moV>p;It2BvDd4L|&FPxouv^S^Y< z-@VsIiHvQCV1pgxO>-0oq|&jdCU06u5-49Y9_dPc#9}I3>W=dpj8ljAqO-fkw4tL5 zEv$}{By30B7qmBg=5?lZ4fSa1=)jk@R@An#aw@Q++63bL5#1Xp^a5WOJNNF6!o^qHozylw@&Bn*d z*=RVt92o(9I4D?BfV;c}uFo#Rji?;lP1}XTF_{D~9WL8Xt{scEAD7|ak}$3o%q7L) zVQ4|$73a0D!|a@~cagb**S?_^aB#yZo;ct*xzi`uGVpEL?%HUc-oWrO9#0 zAV}FAt92%#QXvu5LNqGKHVQ~h#OMtp+fb%smEgZuPuqlf2KldT*Z;E3Ov~!GUQC8* z5u+-`p;$bU1BCS)rAVZ!jwA+Afq{$$wrtvrrp7P)qIa}3^YSrvof$CEN!GzuRp@9% zS7$q#+B*4r^<)5VKYl<>%_p?AHj6&TCMDX*TDlrJ8#mY2@?vvdc|!)2Fd?2N48-dC zA(x~tk6FoJ*;1xO(vjS$Y)}s)Hqzm@;wVlUj`{-&@Tx2sFZRwyu!AyZQI@*6esCP_ zW$ePQGpdj~Y!){@Z)0`5JhA|{isCT9KnjKgRzrDtzHs-D0sT;1kd1eLJmE-aZu%nn z9dy|5>)W`1Xsm7KbF(6+MMh4)q3+8kWN+FEQ&l69`3jJgli-px!N~x1`*+}O{%njk zk>W-j(Ps$m&8fhpkWAd2bqodLSCKN1fsTYYm+QV3O4yX>hebhy2)y$28+()EOea~I zfK0^@lH8_TN&IsDXYMq+*fG_#a|zSc+0w0ax_E*Vs{{U6SI4ixr<#vwX|Dfk=?$Jh z)ha5kumALkmmD&u+QmImCq907hwS`3IM~?n;~Pfd$r8EIWETWhop4MSbLE3}>>4cY zV~z}GE53-jm!tEYuWi@=k}W+ZX{`kr#5C2xC|0C6Nh|~)rJlhU3<_0cvn|Q(;;gzoQiIZoLHhDUHhxozMs~`H>Il;lQ4;-y* z;coAYf&B(y#PHErzH%A9|KZ!e)^BNRXLYP~{JEQ1AM_%?F4P^1GTCVC5~9d~#1mL! z_y9<`Ts*3^red+&NHQ3CJ|H%Is2QH_orAjL3vsJ370#O7EAUI{;o!9GxU+O0W?K&B zac=RP2)sG51A}x$17s4!Y%;{GJJxT(yEh;IT2`jLmXtwL2U=R%co)^twsI%aQeVSM z>R9$sV{-#9mS-S&arZuEB_~55SuP_XP%JHAb?6v;{;?V(ELAwW`}gw3?Tl*NNG`?2 zd3)in>L_9->V*mY@vLYH8c(gkpGUXzaRSC*d73HYxZ+Vl&T78KFanSSk|rn8IqyJI zdzVPz(#3fF<{gSkiV+eLg5iGt@N{;Eb8kC1S=+$b&JG^#&geJL2SY{$U}I)BuH3vM zS`~wZFdYrNw2u|lw|6v?a}vqtN54M7f~j+P1{gb*2>pQwqS)T0d%CaOLLFD!OmKdX zC1#k5afL8%PTIz=ZQuV=ZSSeQ)=FfkV@V2UX#}BMJOl>_5c$$U$kGeLR7GFd5NK5C z0)6-01(2hr3)w}IsXGQ@RMXMLpWnat7@1*_n2udsJ$}y{MV@PGOWl~Z zWzc;O87($AB(4E-btBA~G6R1+e$30tUOayaSA7fk(C61`jYFA6G%B?cuw5?}8w_Hw zS~UoZBt~M1)JQDS3q*+35K-L9*wI|T_Zz}d`~5bY%3BCyY0)50V!sLaepxBp3Ecfu z#PLJna`>6cbC9sX8g*?G96oSd6yCM7y#FrFI$h1(@|SgD(@v85tn5vcqS(&U1Uoue zsb4FX`kg%YxQ&1Ir=P!rp1vk8U@#CTqh3B8i=xNz!8JRzUbwP!FK!WN|01`VLl!dOh$mNX!Jc;(F3_^NysG`%I*%ZN^>l|t_Tkg4?2=AG?JP*ckU`i z`%i$jlop+1H9Gh5T-uxPYamaKSCt%_3S9#^9&hUN`}i7~M_!vqwVD&Wt7Qj&Vz$;O9L17RsFqIU**ZHE!Z2TZECEat+Tu$1=GbY`KoBc8V{A$Q zZEF_=bHCkrjM0MvpdqG42Bb@@s7fBUHx|kJVTAT%8byQ zoDIuFk|X1hk&=fr0gr)$uO)1)iJdDmurMlwgVIn!4lx7A(sMD4@wCM-cQZbf#0F>_ zU0m_gg=>FF%eLk&(fUu+|9Jladk-E#@PzT`=U{_AMmn&uvWA0;I|d9Nf%z+z;^a36 z@c#WD{}3N&s_!=N_Eyx@f5wEs0A5RLp(KvbVLs4Ql!v97Aueq{jAR>s9@E;9fuCL( zji$3(@t}GMO6N_0y@F_^|4D)cw&+EpNOd~)X)oegRjgFclFqdmZRgjAPcXoDC_jJt zeDF&T{`8&MvV*ZoIRKlrgRqU_UUpBPY@I0NYEej`Ng;*OIHZgFkjyou{b=xOphk}i z=B>bs*YCJ2ZfK}OYjYb1EAvH+iGR6#1={KwT$!ZyvA}hI2VA!haNSD4eJ24=TxD?7 zMWlKL_p^EUwe9?0q8&MML`RSjU?i`Kc?P3+ZY#^qVK-=6ryGNz1UhvBLe{peT;?@U zyvo4(kxLEn(nfPh zTPiD>-z<=!SX3qvdFrWHq!Wo)ol&qO>CM*fWp|@viRTmK-7s3P;^k%xn3lRG=-=NL z5h0<-NGGDh&-4 zNj}xX_SH*Q7VB3n!JAjFdD&fS3vq9oD3)Y{KT}fUxPwrmeX@NUs_9^Yy$@$rPdy!+ z%2|yYB@3`U)(eArN%CB34Fa)^lmcd&4#!N{;g}^if%-%&kPXBp$0WE)n34LCqhpYQ z2A#M5f;nPjy|Kz52sygZC{>Ka9)&nm%EzHtf|!}ud6!rW_K7F*Ud6^Kl%i2+7>{M- zT*ruckP@;cr=|rf4J+*1wdb!`x0SRuJ10zKHIf85efC?JYwL1Q?sn9}4Odm%b(6+@ z2LTTWy!ZNPVV0q&qN{kv=BTf2?|=I?X3X&2O60+{Wke@6P~Hl26o+D+K?LG81Bkt} zkTN;~U3Cp2E!5S9FBIRfi1pHq8yL~wpUc`|B&X-e4@H(i6n5CBVzy2o78*{(O3fe? zsKoFZF!yD9eCE2N=JG8sD*V|hGQp)j2oJry|$Nyyet#u~L?B&!T2;2M&%P$nSA z@yeXoF|pXWtsKAIf7UI4)rJr%`5GD+(=eGT5!v$9iBroqmQhF3I^i0VB zWU9oWLM|C)LJW#!6R=e=0#hXhAx7}PI$2_M#mOiVr?^=v99h~iSZEeZjB3QQikv;X zvGc$I4#tjdz1h;#$_J)e+8Xh>uAYxXzptrBZDR``d||-jL1>3)%IN!Vk0CZb3Su%6 z1QanyNXkN1N*S|f&F9OmG>VM9NkUA5tzbcnEia1o*c23Fe<=d1K;6dK8gVHUw`cA^b$KO9^72qvn2)UN zZJ0lM1_Fi*V)d?2An>y>fiVgWSgzoY3YAEd3Spc{D<$H2F~UwUQSNoI7=e=&Nk}B4 zM0N^FWKwv_VTE)wfjEedz?aG=@Ot5;YGdF-Qkj)PMvMwV?S~rf5!)I>Xl-QWhICP; zC&qKzSMwc;p4zCDdo$DY1#_dbj(MR1BRs_}*#eO_K&DDtDx6qg<^d(tr zOkg)hsQLhkH`OUF(kJihimhs4DA10^9Q6QrQ@q-{dybLaiEg=G2p^r!Qwc`A+F+Q` z`^vQa1vBR2?aSwU-ms3G`v*4X$p(X1AVm=F?5yWtXliKui)LAoc_*9i?f6I_d4sNw zPi&T$FL8SQ`Xxjq#F3GUlf;$AxgUO{FEsPzVE(bF+r_I_VCP`LnR2A10xqsg#FvU$ z=%`M?$C4<#s>;ArPhFmd$<7nM_bWNREh$6r$G02t^7I<4j`HAxTwb=eXsrFj53RXd z0kG#!o;*S?OA~S&0v|;d6O(|FqzvrLEHNc12?zF9^R=sffBWZOQ=@!kMaFP!kdGWo zD>U+REXcn+diXDDlCxIrC;@d~Lh`+qO}I zyuY!c_~_~;OT5Zf#Pe+eKJT^1F9iYUtxn9MC&#O0n1Ow+`N9q6)AJ9o*X#`ol4G$_ zp2#yGc9ffh9NCGOqcR3=1lExR;$w5m@zbmd?2q4u{t8a?d3A&ePFP_%k-)0Ur#RMy zjYh_ZK?Ho3)zb?(Wf@rZk0@63mG$*j}%MGC?F;w9e3~k#s{jJ zYU_BBe0Ks8g&^QdxPJKf1+9(rdi@vFe0WReqM4WU^CeN~JiYw%5odomkG`hP6yB(j zlXSpZ%}`Wmh!`|qDjr4JlQCOtFkK64Oce%Tt?VT1Qeic^krdlbB$katp=>;gmFYD# z0<>Bj3REMp(I^4~CG7cHQyJ;AxeMuRW{#W`S4S&fcR6ixBxlhgdo|o3&|Y?w!v#Be zTy{0asS(~J;ROuz^*Q;q?f!4uG!%upfffQjRypCtW&uyOvE@aTv1_#h)QK^ILWc0z z?!}k)+;D2in1cMn2yD6tlIqWMW%K39i_3;0TRjBh1s6WbSnM|+PZu7+<>WG4n@wO! z&&3!mH~O9ehUwe$(OMsMX?!`Ji;HWgaHjH=*T;gsqbO#QK+L=kdsEM!Lv|{EgE`!ZU2H(t{il&OG=*o^j!^UxFt(uJEbBAz7Ws7!K z`cE#buQ1BXnSfu5k+O8yuax)>yGiA$6webbdtM-<{gq&9*$@_Eu zj`(?q1x^nz!NGnu*yLr)iw%sm)LwsWyZ>9ZbH|UHtIG+99xUM1&R%%7LBQL50e@B- zBYY6WL>*%iV6fnbwR&+VR7{|lCmiLHp(xOaM3AH#?1&xr zja`A8Nu{_JQ-pJ2nY@^~EMzgUtR|n1VFn!IZGqO4n{at`6#5c4oYl2>l?+=BbnW6b z-8rspJTakzWlxdOp8n<-!h%Ng0T?zYoG zveZ|s$iS0FkNNi4+-TO)MI2PKt@Kea*psh_p-1Q8_doC9*@N3KRgvL<&Ydy}pLY?n z7Dl3Ndm!q!k4NL7*_hE^nM=Dxo@O{dKo3_<$;nv>xb2~as^QLjdlPj8yxBb+jk~Af z&ejCZI@*d#=%jf1#cvNV)V3EdQi!#nxUiQ7tmwUqKVIU1ZD4mLU`Z%VO?(iIo%fgT zUf{y{Z}82bYLsSYq9`vL$G$m^%fH^@49g_)mk%HKJp>xNM1yeb<*6y@biL#;l){q? zjQ}h$45fHfmroJp&P&6x=n!(2(!|6D$TSGYcGYoMt1=eB0;?18~m! z(f+k<|8Ln=EuK1!8S3hI1AN%$gx@v_sM#uoKl2@6L;x~1*TiRHR>o>g6eGTV`38oP z`aIidF|lcZav~~aQ+W+&1;sj*YO$CmH-sm?FR%~CgQZ7tDJ&OHW6N+iI2(T~*pI1w zClFvoDS1mn2c!1rN_@L`9A6qnOGcW@&{2a&iWbaf$qJ1vd=c&1&o!8mlFWh1nAFEe zz>dj-@#N4l)c(8;AJ1;aryn+=;oL^le!m7c3sR69?}O2%N_=0vP4#f}=wTwzc34VD z^U=%`o>n+Fz!58S<@xCNC_itkT{@c&{EW4i#pCiB_)r*w=7M0f76svRVKCkun1K)* zk@Vd(z#6{}Gs0s6>kEq2uF&g8hWFuy8K}q>KA(a2c`<0(J0B}XIq^)Zq^Jn^_I2Xl zkJS)xc9I+7$T2#~i{n121~!2653oJ{^**+4-Hz0hBnB%Arcoxql6uaElES@?V+7t05^ zaVIm)cnA{p`w`fb_?lNCS_84nB^Gn+!uU0JqEKhP!g#FH3rCEG2TW<3X%l1lwQ8f? zzN>5I^YUz-TB|$xgXKT_6N{%9_QtlrD1^E7hpwywU5lf(U)%owc5QOp=D*9qeTd924IWV{#2(6S8FezzF~Nv?=@5HN{YF4axI z!eKJlH`^7jtEZy<)EYd>oPq4{A$-b#&1FW6o5aC6izM5Pp*FbSV~$fp>=3CYTAs#0 zLNw5}F>wICoLGvFIiYCDoq)#NvG|xb9yJH2VN0kb2i$ORw(5pDu6k+Wrnfq-54Xg6 zM@^ohH`iGVwbj#5Qy7ifvdQ>k_j1@1+naT#Cr-E4!~p{LPre3Nu1*exm}h5k5my1P zUp&WxIWu8pq|N2Nu9#@LZLppcCRyuZjI}mAjpSiYfLEvAAx-aVD$_pGlkw`eC*xbWz1ilKSte=Akrh82>%}l`QBzmh>WvMZU4P zwsarv&D)3j%Z^~x=-Kq19s=pQW}3!hrP)Nf&c@vN{(9vuR|a+MqJgm`OO{cnA_KoZ zo+yf2h^mOiI5#aDkGCDeEWa>PMiLb6lsJEF`~Taul$d~027nVAz3{5S2KU!fEL&lL zZ6OjoDPY@%obG9eMtu2L3ug^WGDa1w)*X*rt!QM42ct-cK$Tb`_OUrV@hB8%CGi-^ zTF^m??Ib*v<|a48}WR~GKWBoki_*eE{-e7Up(8G(k-5f@EmM1@4~1ay|7 z+t?zC+vYBs$wyH&sV@t#!@FI}@Zrz~O!d&>>q{|XV*@^p-J`YawTu9Y2`lEJt|ARM zG!Iuc#luHMRI|(EaFLfj${i(;Odviu(hBGO95Is>b9Xz1r7?r>=GZD=-%NC5jt6ok zqCIOY>WhN$W>+dwz104ypz$XVPEe6XoP|EG5oS_%&(waXt4_u9O#x`$Hv?z3CBaTY z6!$K(RK>vn2OJw)CO5u`3;~ zizf5_pdbN1tq;QS`J=Ht(i5Hu>_id|cU@&RNupKze+< zJtj+vDoc_m-u&6S7p@O-##}wo!eb1Gp>$klrVmF`$#j6g(pi>>hO!vEEl}Jzg3qU*w&OmcwIgVjg?c-P??C@;&6P)4@G@xENW@HUyd$9!;!V9 zJGKLV9N30+aRD5(EVeJmE9B{ejB45R78_}wH!}lbf&xF+v2MzEdnkjP+B8hGk>b-= z?A}311440Q!!i66wgdO0N^mQ<08eJ`CpkNd&WREovkmffqOn0C3@c5dDHc|RzJwC$ z-qsRWMfcyWd-o9*+9v2DNe*e|E?f;M#;r-a@GRq7gqaPd5JjQkRR}Xm)Pjvq<{%LZ+E%w1QaNQ^V(Pj z)K=)!^Q&+*r3Ckjx(*5aBEmE zTy@pKH8*YC^f$vA6A@D`9P5gP>M3}=eGD28EZkrBgDN$@} zt7wP|ODb_OJ|8zD3-N1IAufk)#jndMF;K^voRJikN(@4!LKIIY-Jp|z(F*O4sGb71K zF~XY?1KcNu{jJm)ZWIrxD++&2)W7}x1zfBgDTdL&cHL-HNXBv*T+SxeRpPKn(Vq-Z zhJ#^DZ&Qr6(}OiJw_*2fI#`@DPR||tqSoP$C8u#LdK(`I>Thq1l_`@ro2x6y;OzMy z`I;1b`hpnY>HYg~w6lf*G2)%fQXpJf?f5&8nw4KTnrQ-|PHQ6kz7PDk7BB(#;qqO~jvb;S{= zD@(wW>;#O^7Xf}YJ)RlU7yEsBAw)`)i_Go;lu57O_Or%XYaM_&c^Y?~jG0%5q~r4BV%&``!S#?LT&KrpD~@1AzetL^ zrFhI*rXGR)V$sMGf{~-1gvt67VJv7NXv74xHn*UyL3EE@U(bPjk-Ae;GI1@n6u-oj z!Y}*S7t?Wjjz^?Z!NMVt)beDlPH4SQWPm`@&Y1jKM?^9qgW^P0jf3 zz+vb~Dq)C(C3b2g;((BVBf<=RD~uxgJ4CSNOqH1)j1NawPx3E#LLgdNTKGUoV?!Nx6ss34=JIfgzbl$3 z4t%{i?G%uDdDXf|nvrxho>qOak)= zywPm1iG8-4dHswfu_a~z0ci^A$|Ldnj*)m(7KuN1%|uN1GNIEn1)TNO#5sx;V|A1{ zP+3VD1KBKcj%Nm#;>Z9KgwXzblT0sIFo7iRRJ4^$LdW(1pl~AEwhRFdOvUUGy}7K9 zqt6wZOW>4;CN`Uieg_-O`gUy?8ZQ)J+88(PEUPOE(b)8b-;0QaH_ut)7ux9WaUWma8Kvt>*@ocDlLIe&lhpn23 z#hRn(eMJnia6}i&G;0+V&W8ua@Y{#%joO6k>6N%NtrGiFw)2%S2K##L`P#Psw{1=) z+BNP3swc$`_;s5a&TV&w3wdW3b5+s8OC(FPR<7q2Ghyo9s8C6y3zmSx1lVGF%u`Lk z7{Q2p>~HcHq2}mHeBL`5^`~aw{fSw)S~?92g1um;r9_~RBxBXUF!RAsl2C+Y@sX7;-I!p)V_a@kpl;C_C35J4Yj4oXe%0z4|$`|`OO?GA7#!NiQRR) z)JYwA1k&}yR+H64*+Npo@veq|^JDFh?QY81DbA!X_Ril5 z2TcqKU`{H@-dc}<+QLVRYwGLRy}Yn|Y#v5&d)#m@J_wcW6o7NH zD{v*P3is!p#D632EugEqwzlCDcXxMBAS6VI2NFUcNZj3xBtQsGaECxbAnt-Y6f5rT zw6vwSEiEnX*5{jR?eyO9jo;;c`N#Or=pKb|a?ajs&1cSM&NXF!Ryzu9S=N#^F(@M+jE?|awR}m`*OvSL&%O>G>{nU6bWwCsR>91S#Edl&5#zfR7(AL)z@dHy)KI1<0?n1S#5XXD}CI$kms>*obcNg1fiDe^N!IkH&N zB%CgT9Prb34>^_k{8G@+XO16%j*=LsYKIr+;B#v+ur?B(HcY_t_0jlaLmtX(Bze?z z$N)Y3hqjJU7hz9%C|-7z;rWIbyzMDLg|8I{Y>%xJP6V4`qNNUh?|i!n_*eBl>>x`p zLE4^MPPYN-o2#dSl`eYN8fc0mzD79bt&6kH3b;5_373eLUJM~>J;W601NV?0L@ed- z8q7^}4C zP=^t=@=zw<_};^t-#LoCMVJl_8saXI~vpoxZaj`QWPK?HCh~w?s*Br2uvnJ8+s-RSRG+ERPbVy~O zk^C4I9d4IT#cH)UM9X*(0Mxj)W|Yl|X!TIC)Gh={NBT1hgfLnxD-p`tG^GP=xpNS2@53XagNRkIGga15JC9LFLrLryqKvZv+BoedhZ7Fcxa&z^ zcC$jHm=GyW9Hhp5N@l6+y$o<=gf04Q)j3!lMPg_VsluJ9+i|jLBSMvpIIt5n#W}6N zWG8{MK315mEx|3Z7p>3jRpb}Zp^OYvUtHkz^By1-{v689fb$bL(+9zX9JAHRI&;oj5*iGfq`DV~SG% z-)Kf_*G-9nH3@|>(J9`1i~gIOR>5EIgqy4QwkVY7=qG6(={ju7!Z z>~vJaDL*r;8KTRnHv{XckrVN-avv_lY{c!74zy30Olz*d0bXONK(t#QXIVNIb6@QyCqp0j_W9h&AwP12Zsp&u< zWQ>{`JXK{8YGi^73wrR~+&#EAaTBg*b>MnVCobo7;bdwXjwaXRa#<5@EojH8m~6Nx zEAtIzMcxKRs=WIj+vuvS$vjF}q7#IAN4yb^nN>?8l?Ax~%*s!#sr(cs5_J>tdWgN^hsTtk^xa*X#HjBodELQiiU zw29*RXi4Jxj>UMoZ5keT=HTNd5}qysWM2tB_Lt&^rc9hz9D%K6-q>2?iPl(0Qb;3k zZB8^EH%!E*eM`}r6~L|1Br9E<3A9CvkrEgBY>y~hn6U}RbJpXV;x%MR^>_frS|p9O zu<3ZR=qxUmY{i+<&FG9-in1Y5@Y68lQB_7uClV9c>8io0@+mJ}9CA0nIs;j3aW=;7 z5JzkotP6jUV0ovr%%NF3aW1I^_j3AhsjwN>7xrWB*gT=bK3$E@+BoT>iQ^uM*ym?~ z>H2aUgltb&PjJHHeo{=^W}zk97p@Y*JX1)-*Rv2_}rHRs~ynjBb= zl@9gw<2`*oKKsG}%QB5O?cT+^Y_LuvB4Ry?bcK5i;=QJB^{l|pz18@ue=7d!EyPb7 zQ*do@BDR!A!C6_76pSq9$&bNCnN)1l%0sfqm;8S{bhd9164OX#7A;>5Nm2meRz5=8 zSQbBsGr^@*K6p^?iie%v_@OTlr`CJmV2vm0%T16QN(#qV$N{h*w`OKp?yRqktN)T$ zu&478wjj}Tb(@h;276$UlR2kzWe%Y@Gr0@LlQ-aW{6>76xE_}ax^ZjbX56pZigT3> z=*_7{ZRQ;Ko4P=e6?aPrEmQs}V4Gc9MKnnqW%|R>pqkDL&^L+l(W_E`X=9cYC%n4qoEp!}Y{Wf3W&;mT+Zvm{*)R->APTz@gUSEPsf_*GOnzc-@MLQm*}k-j@!wRUu%Lo za|NFF%s`#zqld>^rjYfl#DS?1$hMZ?&oOA=c`JQ&@UeFaUaX79m*y-ys40Lw0nyub z=)c==yngiphmRk^r0ErqR*-}^t(_!Y3i49W(^i6op*k$J^+50AvMCdJw+xo|?QbZHoeM|c$=(Tg z)@6^M*U01AQW37u^dHC|LNTaom&G4}t; zi`GTj(oFLa^Mfk%lyT7A3J=^2aMx7_yWLIs;lB?FVSCzqT&voQ)446UJAV(3Ox%e2 z&~lVmh9O+dp0^lbGe^}$s!)(qhF`EhR<2$lWI28LfHjMkkRVGUQN<0l%84AXz3N4L zg1IMYRu=h-jf}$fy*u&z~Bq&kD!fbx`MNj5r+$4n8Iz%;K?#ucwSa4+jqb^B;gR-!PN}qrgBO)q_ni z(^eB@7D^ba@}KvyY^H3wzKyU)D}4_GS(ub2PEKjU<&+J$ncj{QMQtc^O(NiEBhD%W z7iRV2M8sW^Hd|Xzg^g)u5y-3t1&;L0Pl7f|TG^F}FlZ zOdPg~x`?q1M6O0CR%??RBqLO5tf78*l%QUv?&%ubDv3vsA~qVOF^BqJ_)WB3xuu{+^mxt1rd1Z?4A}TwcBtZOQYI zY8MP=DP01nBsA$#A;C!wi$=%FCR{jp77uQGk5_-a;(&Vd<`wU2v}JoARKykFC2o$5 zhM8#B$|M@(!rPu2h|BUu+pHJw>kprK(mqS9;h*topu-YxM=x|)c+VPb4~&O+`LEw$ zDW{Gxa`Lzk;DD>H>NrGJj>>Q+p_1a>Xr$ItbeorO|Q327r>GbE7x~!e19J&aY z-#Dq^s=p~Ndzs-PQPS(4+PLAXOBPQ9y^gY2Wg@~9T7#psCfA1RVU~p&w-%L_LHKS` zAMPb~;$~zAZlrC(<r>T;Z)+J~E^eYlXY5w~)?c`o#=;&ya|PQgUS zXzZ9&hs`;2$dbx%rLczlyUyW`+#)h7U+Ovd9{7B2Ys`aRyheakz8oWFJ+MHPiGw$$ZHKt@&oo+(jyCoK`;+(g(k-4(Ysc;IoD zGk)Hnjq3|U_*ab-?k^VMQN0d+?Qq5MjUx~`Fm}|#(e>ij#@zqym$SL{cT6MCHdV%@ z5l*<_sE9iR*1JPQIA=#1dWanM2iU-yG^LTa97daa@(vN~m_%Pj4*6;6xP0*vp8WZo zXwv(EhGze6L(BW{vfu%WEH5 z%66d2K7qie#f#|U)CS{F);ioM-GqaYH3ZgvoJz07aFGF7Lk)VLB{ruo#n$Y3+&a1` zD8f%pLhz66{cvt>56)yYkcDo#n zZ$o$C5@HidT&a|4i*U$88E1z`;^Hu6^ttPB!1|FN`K+TH&(}rb53;6D8q)Esy#!A> z%W!{HG?olk!f+MA!dr-hbK(R`MJyO(;dwek0V=@sHOWH0l1%Jrpj(#I0#?B#LUNdlK_ zMY!W4j>~QeI2B}xx?$F^l@*feS-Vg#TW9oc+=$QbUU4n>Pk*6zyn)IGy!cyaruFLO zd;I+CQ~dO=$GCm_Hh%y8cZ{D9OP?c$AWI)kp9kw$;o7Nl{H*r*>sNUFMF?iFZl2%W zet=08Wdh|IpjAvmYKsdcZtSRmMTONRgvg+$ya+pkZBRBqVOgr+aQfL2SAA>_U|`k9 zNiStw^iaVy#v4ShyW$ z$qFA%>c9wM7n*!HmLAeg#^6rP5rkU|BY%y}osmV-;9#7pZo>rv=H;w*TqWyzKAFCU z{NLln>(LTF9UHQ$v8$pU_sV;4HDNt2CAN{j+=P2%X%A$rK#-Icr~mWKC_qpoP!0tj`+`zJ|4$MtLoW0z@>{-DdPNubPc2dI8QFhow3a~HG8i&2i z(dT2s^S2!ao8rr-zxh!Q+w=GDNG3=a-n{-uRNr;ME({E?5jJQqru8r4K2q z>4TFIq%w#Dxn|J{JbLsie){nNzgSA-(?5S>XLMZ3J`XfnXR!=?d4>}^x{x^18xADH z>)B&aHCf%8x0-Qlntxss_`uYr;lM|Ia<0dz`*D4*yTR zic3pN*aK#2$>LCu18xk}#0>)K6`~C%$%>r!RKqS;ZB)@hu#MFuP>dKAjBVSt4D^-# z#M`a>{`?gOE9)!!?9B@tJ97f9?Jby?osWRQUa--$hk=9vbcnh+D4Rlu1W1|yDrDW1sn zx56kJ4OpoPR$xnzDOTAlaRaG z1AeT_z~w#Q2eK=St^)dfmI1Xl&=e~i_4s$iJB`D=We0IOb0cnKx8ra7k-aJH+93K`$<+w&7|;KRU-xN2H7y`MhHMbD8qkA2Sm_mUQB3dKWGyb>d2F zGrpg=8M|_8>3xdaKd!M?!g*4{-#RN`uB|?Q&iP?R_`W3veK~`XWh#J_DVQ)?yCO45 ztQlsB1ChQs5jF&iRfLqx1%@J?tu;?iSl@ZeX7NVp5Sn@L2=70CW<#)^zI=g~Z$EIR z#ly>FJs&=Kg1n;1JnhhkO%9OIges%)I%crdG~vqJOj-v+^=uL8H5{ueXJThd2TmV5 zGtfcgHCc$K!Wq+-kGOO1E=o%C;cTwO_kMzv2nQCp;8dLthN}w+F|jg(u+}gQHM;32 zR1M>UtS#kCem~H2!02n^@qhPq^5jV+4NaB5*}-t*5ihsQ!=x}9Zb{mlq;Y(#3s*AQB+$XC78phw z^H1d0Vc;4x@c$v)3Q8eS*&G$7KA34e5{sN7QEf90b8N?9s`V(0l`;8u_EVgZ68vOX z7X%qJ7p=ki_&Ml~osTO;?YK0#3oBwPxo}jHk9>|LF}N#WuZK2Q1}tj4vt%vy71i?Y z{0Zj6kmC}DLvtGO!u0MKz};@{h&c(b@}369d??y8D>nHSA-LuD(D=d$%6_kvO2RcACG_ejnkU9?>_J&7Iv=s<;xfH zE#F~b#VUB2_;8S#(r1Q@gu8C6@9orc?a%Q?8N<9X1&8N%p{rswVjcat_BP;P*GG&^IDy!J z)=>xD5p#ItJl$o2kS3@r!u?@txMWO9&`%fTmb&~LG1klz(Ryy=4@&V2C>z>?9LFHE zXRtt#3W8*v(N$85_TnY*SF(nej5+26WZ+6gCoYyXAy~?gE2f!-ir7zzY1;&6Opp|; z;*Q+KxLDealSGMcmu$h6oL(GFYQclWN0DeWl+)XKx-UlU4+I*bi2OdDfknW}F;~J$ zcT?;Q8HDqrhTw#k37U;$Q6w!ymDyVA4Jf)2s`Z{{_sHzTGoDi~lNs>eV z?WdF(h@)qWJyv_0@S_Aqb=ua~@gAwTGZ(dTX=qW*MxA&9+U3)EzUW4S42)JB!XwJ8i8b$H|KSzyX2>+|lI3f7 zMA1o23O8G);$iP}q`DblkmNsScS3PD3x2ewyW!KODR^EJjTfzXXqg<&t!TA2(fP4X zSm0#ApDj&u8161UjH87uI6u7?=NENjX+#04N0#8^oNc%|btf(s_2FE8FHWYn;cQ|H zPNg>EP(cHtbiBB)kZ*LAvdD zet!*Ca=786gv)kBABU=<-PeKNk1-d1MWl&bvA{Tzz%368X$3f{oA8k$Y((T8`kbD; zd6?=KgB4*VI91hy`-=}?xnDL{28jydI2&e%LrxMn9im4j(zXNSCv zNY@P}i)ezX;7n3-wY)$efv&xNdN}ARhoeK~aL`*F`+YTWEW`*$BL<<-e-QHZHMqk5 zhlzL*Kt`Ah;+Bf}<5SUA0^-@8gJ1GAK4 zFivDoGNAxNNp(bw3MXIpUz{4Vqdx{(Ca(`4e2+21!+1S4JDHfOHy+IjnY?#$y<`T~ zDyQ@DBdlev4((%k`LyX@8=wD+SK@@&T9$xcr4fx9!#t!b`4jC>;2SfVXj~|Pg)M$9 zQCv1|@Z*QSS=~8b1m1Cg7JA0SX?(ncAzdM2&X}X0hz_k>^vKiV66IjMXxmha(V&=v zcFjC&lukgaSRz)dCXfK>lh%{urCO{51)r+^iFGkN0!>vlo}JP@I~~7msYbTde+Cd| z=}2Ljw-u%g)#nO^{p@gMB)+s4<5OQLwpK?9Z9&OjIX2n>b?(+Yp+8k=2(DIb#p(1W zT$|X1DTBw*`((NQQf!`p`xX0fbo6?hN@&Jq^8e07HQ+(%R&0q~$kY9_2LeD7#NF`S zqJzjDI-Zn<8WvBOggEOkm`WO;U}PFjSNGx4{B2kmRV8$U&?46&KojR|ML6y#gFV3x z+^;p@)LI|Qw3D#XAc?4+6pym1vf;)qqj7)TSxmA>q&?A~wNfPus6iHVD7F->L$ual zZtd1O8{v|#E-sS$a>-knSd3s{XN4x=+UzYjU)F;y8Ow-DDiVk^z~=PsDPBuTEQBlL z<#zHo6<~r3!*p@nTN6jg1?nfiHcKS5p0VdjMGBD?zNj8vh(p!As2ZEgm1YcGeZHpX zA7+GBN}f= zV3UTOiaxF$J;i&wvRT7yVgpkQ&whQ1qSzdgS6TX8bF9@#MI)O^Af1gysSLEqku_Hu z#~aq`%Nf4hylb=7*T(4o^fHpueB&)L#ZuK|G|1;-y>2dMYmY^^NGN<}8Z&2Xv@m>$ z_rCpSIPXW^=s7z*gC1Uq1jh(d3H0mrim^dHhtFJT5JjO$E|$-L%@uhgPBauLV&0gq zLx9!E$4uD>qJ_%Hj7jG8u`B@b`5o&D@fL1w9(+T`4HDtEeY3H-GMZZrro}tlRq&0E zHckfU<4lM#YV2jWP-Qx6;eG2wd}`0b$z?I{A+63R{-!`XbO$^0452t_L!2t9$F=kZ zTrX)SU(STLM>V2nh}HDR!%2JaV|qV+E8m6NscpC(S&utO4Y*Uj-`%5vcEk*nlW*X;|gW`9L$AvzNdbCpjDn zapd=7M82etyff--iclgRz+DMedBl1!ADGvHWr+(21gvDw5((mdsfN%arNpda;fE3)xLR4yu$4aF%G|3duXV4;wrJzG50gYtDObEDdQg{=%Ye-Nh3{-#>lEH>xVH>m|lxv3dkq1x8z?(NbQD0)H>=`-G@EBS_nW=&%&;3B;-J=a2YI)^&PW zIrnp1$rt;ns~Ar#KhC6}Jbin@_ zZeW7C=wckoUyD0rP1l7m0oUb&q0EUwCpm<{QbrL$CRR8~ltT(SA@{~fb-Y^k! z6-Ll=>yh9{aAmW=N)hLWsodg(}l=1S(@bW5z|w8ow?-gj-ep z7@;|o2eek`WMYj3n}U#r0>uDWkq|S$R*{9f=%a%(jv}1#RzZi45%(*FN$aYl6v)bp zeCaa`=-I4sXW0RM^wgZa62lFJ89mI;bP`iVvY|Itx#i(pS_6J4-;6u?-MF6JjT4FW z_%^c!S1Vd^I;$4nE!c@%=dpZ0X4Chd575I!cP*^b6R7x{Xcu6|6uhn*hxZN9_}G?; zM{DBnuBRM-b{FHXzDanqX$GG6SK;lE1?Z>@fenGyN?j3W4t>kP^y=*=VFbw=AZJ`Q zDMD3DQVd7CN&%Lp!_sd0@qx zXz&t^v1rv#$1J(Am?##4LQwz#V>nhQN2A^}1#>JW&?ZV^w1EyD?r+EK{uOX#eVGWr znv!IVjEwQaPu~gSAy`t5@=0eU2C#+Hy@_$!F6ya{g7F>#M#Pvj? zyAykHa%wk5soL?w^cZVZjMV#2UU7x%7#ynVA|MQ*ziS}UAb|W?eR>8JvW8-abMeRZ zrP~oEvVpJ20<$&a(50A4R}$vxj;D1JT9+o#_n!~a$8is3)VP~)Iy#1|z(TWlq-gta z1*pxMrH`J7!$q~2?Gl5*QhIbxN<5<8sF;pM`BW?+1!*$S>uL!*19g+faXSKTxCL@` zg@gbTTHhcUSIjZZ#a!D0VoQc_QL#c#>H_5JhjPWk0Bx;cOcqWTsUh(=w4@*Zntc%W zlgO$jbmF_D4t{=nF|(Q6hz%$)8-a1+cGy6yWMkGs9yiEfu>%iv-1XGP0T-b?te=hu zf3)S|Lt`x7Z-~azbp+P_8Ms?pi0TpA$Rj_#)ItI?hALz86mLBFb`iR(lDI$bKhznI zA3x?U*xR>)9^c%wlb%Nj$%-DRRZT^!LM~@>^JSv3QYH!=nptR+OyrZ}8{`U6C!L3S z$t*M(mLOTypMF;rmfBXhe&@S^gq|<-xv%({ZF^4}$(l6Ai(Ii@I|psj>3qg*y<8$z znkFM$#f}Hcb~m;=epSHEoHTPHvlJE5qtK|p#suc@F@Y^wg(#69Nt>yHh4UA2fWH6u zgxt$#JhSBP_3LodwB${@3v|M<&OQ%mA~&)i+N1?FxF9g0c4Zo!v|FylND@p{I1tcI zH&4ftt<_jQ&XF&I0{NJOoNV#^!|#OQZp5_N^s?m037if$OdN+Ny`^~6n27INvyf~h zfHPW2gh{q)7$+_GS)=4c*jqY`50iSgJ^?Rk;_z|n4D6{K$0=X7t~Ab(AKPrG%>O>o zHwh1>ZO4t6jkpurj%!(6Xik~SL6s*jkAovT$UnA0kCQe}Ib@*sP_rkHT98lYiUm&j z2$i=Zz)Et;mF*did)51B9fpyWw8d1tcr?qCdmxHKqhSt`#hm$PvmnzhCskYuw8l(J zLw@g(r1a+7Cc;a`lAc)(Dzqo5!SQfX(Bo^QB_YNGFJU4ptTV~R268i&tH!`n!i1NW zZFH2wWnWdCc9BP)i>ffTf`6_9mKo+@KK;%pNp~m^lhIdKCE&{Q%9ucrHJYN9pwu^w zr-tg1zcxZ|D89{IkE_Y`xDmG=*JEmNBdHNLi`!8XQbfwlqTCp_Gi|WWNO?HygJf| zf?*~+!n}D)7csg|eBKfR?xj;VVJWMLKq(WfGKt4D+2M5mY{H=e$(S0FiA8klYyzKET&y$-UCPPm zlZeK8!VKJRw6|f;b!F%lpT=V4Pv015t&-ZLp%)(ObRN8c7IB419 z^0nK%s)j{xKNBtf`{M`9D6QgtS(-u+R@mgBR6U#)O&e}xamu}uF(<4HB_8ZE%xOWD zNqATxwLGU?opX}#X3KP3UKGzM8#@zov@^wTZ0zADo?ynQQ1qBloT?pJQ-D9aa`9)w z1ibFg#FeFy7^nW97NIPeJ=K9Ia!roVy0dE{-n10q_w@yM*ft$oE8}^DHkB;fMSnB& zS*dbijwL$xV8%||jNXU`@#LfC^^-3>>fW|B4Xb=)FY-Aw0^?+ygxc6|StDbrlgY%$~228V8{~@)d*8s*!;;DzPN= zdfdV_SxNA=GOXbmD`aruG+Pgg)uOS{sE~l`&XX?`2BOcVM9=4irsGQWc6`737-kJG zBKogNR!Dg)l9`nY9yJP{_gIQyRZYmFnC(3z{kSJk+D_Oz$yK$wGUAu65S|1umm%^L0A_Jeg zqzK_oYIxQ=4G-%J;cFny1;}NPIez{5!M`VOzyJIN$?@a(x$l{}Lj2X4gpVCjcvdq8 zpWBM?ylE!3XN^LAv;$5oipC$?r{lNnb8)?K8rG$RV5F9CK5HZr&S=@6%ZVo53f9C{ zdr7YSN7;tq%A_5*5!;IEksEOxp7*F`$Jk)@Hjv)zb ztjH6~t@Dtm>CTTj3~4>egYs~GX^3Gs?d>jiQ{Kw;pszKr{t1>8dPlwPNyTq1=@=v@9KD?yX^)#8ia6mc z!f~STW8?(aqdM9Vzn`u{ke5(}^V5TyJY|uc9=w0~8so=DLPc5u!?bOL8eU(0JUvm5 z0}IQzwVps0cP+VQ>%`)DiC&8+nk;T2dWqilsAr)z~ zclX>FyxEk6KUW3-ElK!$T^e536yi(QY!ZYDyxuh(KlGD7l^+N{seuS5T_ecSM3T_Q zsglo2^tsDf1=rkJg^Hpu_V)pEf3gq`m>TcHQccg z;Xd;XeTdrY3*~7(^!&4o6OpOwPaCVn%h_hdOvJo|0)gg}ph}7{jjX_}(Ri|OQ&gfb z*DMXOQcm2;#@iUeQ&)*U;}~rRxQiK(A0^J$BiK>}H~W@g--0xF6EmoY^M;MKB=_mr zQBeX>?p2mabRQPny6thb#tyPn47@|=ev&2qu*fWv6pu6gU5VEevp&9+f$2CmXA90$ zbRkZ9DBZg<39t;0l4jYC;{SGK&NiH#){eTce2kYi;GfCvmjNwU+6v9di+Iw>*_<{` zm4BGhhYVXkzV556HE_(^2p0)(OO%DrctZgp{-_pCrHnf>+jO;rC7DxYJdQ za5W{asOFm{VKp&CR$JYqlY&O&I5dmJp6ska=PLO9zI{_mVzJVvKq~H zoFS@tmp1iMaxIU>UYOK}a6KPxHQk94-ru(dnIl~})w3}-#vi}`hL3Mw5olQ_iMJ@q zh~rjyZAKtI^q1l_Yj|B32Q+5k<+2pKuFb{E);v6D&PV)<)8Bg*P z1JrS9s0_Xj(8mwnnz-RWK6Ici0tisnq(zU+Ai)fugnZi&>?vG{yHj>xm1`Cko(MLB z)XxBSoTYKaT7*mVdCl$`9L#RyPnMfUqs)9f0Y;sln}#?!!&RF!v$8lQhI{gsq5o78 zu_OxzTAwI2AEcQE6X<0H-&9OcV2%pfd|g}Yae(-VnWMrf6~5wwI7pRPx~YmKx+>S<#+rRNJAVs; z6kO>UHHa$PpiIplqvag=nPrZ7B+f3`k96lToVqe!c(S@877-X`8yImm;IAM*vZ1wK}I+dUa? zdrHwiGYW&HSYIt;%yUY?G?O^wtBypfsxOK)LWtd@pOaynFmjf>^lMr1qFmFN?_|4ADkXO2-kfqam865d)zH}vBVHV!>eBfupKLFd|9%6 zh|(aeQp@E2YrALy8g=4Hs~W*X#}e1B-sUv;^QU+8K<{vF|8btl6fbf^oo+fBC1TJd zmyBu3@w7Qsq>0tgFscII&)$u*nN7HqwjLMb*Wr3x8!jYw;>48A@RzsdR%Kqvc+4$K z7A&lV74F=<&r77_C$C>-!yIFg1Yvy)Lu<_&yV7iV7XZ?+EevmXyIf~<3vH&b1$~G=S$pe$kqDiQQ zz>tzi09SR=2;A+fMNzO5#`#$Ap9{V(^WP-+&?g2=H3ZuXUIm z_IjG(dY~f?1bcA{%>s}ZLs)gwyPg#S*9hcV6$Ate{6hayu| zuKZSpnFB}Hp}9O-Xs<)c>`<^ZPI{^1>=;YT7_7mSO%4J0^|xzKogBc|==8yTLW8## zA9$_i!nupMYhXYM_wcF`yy}{apX#y^Y9q$iK2*+}N9h^sVY%G4v^EZ;h(bv=tK>(c zK{*L)brb11Enur{i9a7c=6#O8y!#|n6utk9aUQN*QT2FR;N&0;T(*$H4Qpwf39!Ie zVrnMRVqa$zNbQ0pflO1ynfam4t{6=kd1z5fM!iE8(Jnn$nmgmklQ+WfsMpUqV5jAj zk(O1ahmYWWcN!&9&?1?EX4xXl6pJRyqs`lqR{162*tAA`SJjLAd7ZeK(u=Ffy|@5s zK$X9i*U!&8nb29Oh$C~tDDK1RYv|*_5C3AlyzuD#Q(oV=cjq>!$x3iRzrHF1pL+}N zTitlP*;<5$o2R0#C8cG`%&VPCFfSz>R-`~`Cr08#LnUU9bwHGr48KNLqMrxPu|yog(H^TMl1id2WGN9kL?bKT~>Y{4*@c zS{u{PBze6syV$=m1<5R%DLoU*$YQ>5lHPEvQ_Vz!Y#LS@Ctw6AX?9}3&c|5=&sJ9p zT=X@2G4a>!L!b3_-pF|Qj9`EM}~a*;Ao+@W(gLctXPv zGY6h5utF;pt&-Vj5@Vg(bI?O{x?QaZg-T&$nV4TD1#cxYOm>LCHyJfJO&ffvbQ5k( z*@_3N_94S#Bo|UmX$d|`Lsvx;4}ba zvnmM*b^=hD_O7s##)%Ooxaca6%g%B*=b?^f8z~+r_-Ei0tB4t@YK&1vJ{TfrDHObu zRUKpL0#5}~1nD|sZd3(<*??15c2vNqrXkNS7Li{hi*J3jaFZ--o3#x889TnJG>t^C zh|Rl|;uay*T^m2`TmxTIbq-ACXU&Uo!*6?*(eOc|dLGZ6ovkvRA;?Zu*O`N9aQKr2G@&wa3!u0cd|QhGO-T#rffskgjobcF(fKU z;FOOl&U;CsE6{|G9?8-c;o-VGJnx){n>A_hQ55!%eV)qzW9cr5#G}3v{Iq!@Vtn+V zO7!}t@9zmd=Cf!21}p<+oR22{b!-i0#CdXsF0dFm#Or#aCvv_}yiv9pHzxPv&XQdy zACbX>P3a;hY&6bAoJJU}lLopPTX-rYYlHsh+vhw0yBc+5dFvj}W&-O~@o{nzRN-7WLrVjGef;@Br3j&Ek#9 ziXFz{%Cg<~W_~YEf^a9rH9_QzA~83li0sKa=#zpH=N4g-r34Q9X<N@Hfe630l;CA!I^MOU;m7sKm=~ymJleNaqs@sqrQ>CLE}pg( z;#NxqOvvx`@ps3cFP`v(eV$Ci<{`~q!j;kNi~wv|md&46@ac81l3cL|Gq&MwQ7J!?El-9GF^1d#i~Mva*X!vXHMA$IJ2ZQj%$%Ul35=;`z%bJV(ANJ)H;I z8ip9)+)zzivlQW;1u>^#s;F{Q<@>&2@#66RcEHxpn>SKVQUX(AgRpf$Fq(?>&^yTi z>k3_Yb1i#oeZ2bPkx&r)Jpk?|4e^w^2s)(sWj({q~I`xYQmWEM9cS9AVj|@h}sF5g+Pk^zM z7!P(Zt;ZHJL0S?ESo@kFbM9N-a8t&`U<<4;R^UKp7ImbqHR@7l;M&~1xG-%uCi`ZP zGBUy_(O?|PZN-+-bv&sfOneZ|%-({<5tRf=9gHRoyv8;itvZQl(2U0{-B{XWYYteZ z%qmEb`oaez#mSg&T%dvjyyfgT3t$xWXR?ru<)ffS&*SCb$*HWFiUK^1wE6o@2B=@| zAS3Lbo`dU6GjX=D6u%!^jE?ycMAeBE*ctP|T@0{2z5TpEyCJ*;-!IsPNb>-0Y5nLv zu5?x*JKT0)f*;+VCRs9nN9D)M$f#X7>eM%#Jg(%J(&r}*Z?ZmbKRf+U?_ zGz3=S^3*X<`-W#74R;k?oR?SSp?thZ;{YF3IH z9&Zc9&l@%Ql)2w`j>B-eK^r|){Cwwz&^PDP6a4bv2KiO8@D#H{lNJMP8oDHM&?=tF zM`|o4u)6Y8H}V2;8NFSgNdjQ1jf-xUynEqEM+w{@zhaw*A+oe&x&JhrXisfm zCQ`dIN`35n1!?^FdY3c^lr_3jop^9j73s&n# zp-CzZ8`xpHViwkFq@Y+dlq`o}fqcndPIk57N`w_xn@H<%8XD_qiGS@~g-CmOc-z?F z{>`7^?(PnKc_s9fFG73LRLt^@M3%)cx(^8+BuXc0ylq7R`qyQ`owT?Kt;6+i4{>Y4 zGQM{1+r^K1<`2uE=h=#@v$kTYXC(jb(bg)s*)s==qpdL~!T`70%JBNo2JBs0jKnd{ zke3#GV+Kwg0zjg#6&flMI8E2&R8$L%`WaX$A4vkL&K2SYMC zniBjhoBPOC4#*xh7G2}2aAj&cTx3o87!7{{!htCpFm|vXS4i93RB^^f4K41b9Iz{b zt?}i+ay;+O#rwW2eCjF0hpv3`Yt!+2b2Oec5r|t;@K^72c?tAg^j?Q`cED zgI9k)MR-Ig_sg{urMN-xq5ayQ(txXFeZ1@B)d>x_8P$R-iJiDo*oT|d+tHCW55vUt zN!iPxO4=XmbmB2hhsmlw{OsNE`t2*c|15O7V3at0bU3ea>UK55c{g%{Y{l`wN(@&C zyp?9Md@Z`_mVcc>07Y@pm-JvYJZiJTPfJ9&wOE87+8hz%LfVV8{RJjGUs$65Q+#*x zB7ur^i?>I!COZbo;*-XB9ic)J`M`t8FHu11NKf2sF301}GCb;>hNs&X;jeEN;NkxH zs4W`PGjP23)CgboW?UfJZ#nSm6sBf-5fCpzs#imxeY7Fjtn?hdd> zd4IujL^%6!mt~s=QORHjM&VR-IIgdY#ofj< zJlQiJdlzK!=bBNNIpB&3k=xJYW1hHh1SXb7JWwYsC4tdHf^d57c062oj4S5L#T~pX z^3lwrxHWkvc4gLKx>qVGCf1Z)842X-tXGLevsyA1>ays*E?o3&@QnG#OhJD5gg2i) zV6?v%f97owzBoaO=7O6hDKG_G^s`19%hVDVy~5G|LEKx1Wto2M!Vlfu-Q7qiEeLjC zfpjYf0(M|`fe8YFbl9zI$d__oZq_E&CGA_jyLB)$2(gaC1SOY&vEao zn^08Lg}0n1s`T=(MV5z6is@V+-DsAJ!DO+5RVk+ID95wUmf_DWlksEwEZlEffR=eF zi1pXw1c?e=QT{$SLyG$3#cS@GAOiqC8UqNgKHN1CG}+yYf07O0JKLRF|e zHikK1g|7*wx@w`HvPAqX;OaELkvLu2jLXICIFnk7%c+}iE4u^d(%W%q+-~g4+=%@X z>MK+mO=Aam=V8niu4yimK!5$KxCsD51P*2?IF>e@1apfRigvE@(=a#UnH>rdQ*^ z*e$p_X)EeSO-7Km8FUHeMUbF8`QuMM%zyFxJ>I?kgp)^3@TBqi!FjkpZ9l$9-+;># zH)CgBHDWZ~80yZX+PM<5<9!$r z2&g^IX$Zya){JE4d70tFAU`zw>tmFrL;)ieO{k#{g#{&={V>z09}09r2^|!r;{e5qi$UxjW{av?izIM+4VCILKW`%GI*KE z!B$IDh!K1bkLKaf+js6@wnTB{vVGfbCLvc;m%=DtD+lJpo*J5hb;GA%#h?k85t)k| z_aPWy7J>i;2TqWB3g#2VzF4m#DxWg>R6`I2gb5Gp;)4%wpMip8F3`Ai=Q3Q}EO`%8 zZFI4~%@7UV#yA<_g(Cw(n77MDTlV9>qO9V}-^=dHU~?HBtarcu9dWh7M#yX1mDsr^YYu1+oum7M$5)1%;;mOOl-2b?_s*Z)OpOToC=7uV5**`N~ zd}UHL(YxysR@_#^a{6{?Em?t!^S9%|_zs-OY`~?AW}Hjf$i*AyayH|Ov=*GrX~FSv zn>aaPP6Fsl9>I=0h9OyA6Z*FyVF9zZR&>giz6_)H%}&MrZA)RSCLI+8X*hEwR3AkpRP_zR z947+~M5S^ zF~L3fwQWJJXz?)Rx?ATi1+kJ7Wru=AK^+6soiRT;3rFWRV2oFP3^NTv&Cuz%TF{Bx zIi2`s{7&2`>BQA3J8-_Z1Ai5o;kD$jtq$n=>3Y_2I1<`UC4`0 zgDxr8-`QPp-=Z2xD5f-ljbdtAuXqOy^tPq{r|%;TWvEQ>z^h|xku$`Lk68BXYT@S* zWtIZgIXU$l#}`TKabx;URHiSb_cuj)>KMErEd2VtL`*iX ztc>UJv<#ht2gN&aC8ZJ9(_3&Orvs;o8W3UPNrJ0@;{1F(eL`#bnrz`KNnzWoE9w4K zkr_G^oAT$d66X7u;kV=UNE*}~O8iWEOdin7!U0i+MlARqETlG=rrRHDY_hP_CLIN4 z@rYIRBX4EGeWL=VPac+!#v%%Hk|v|QbUlXHL^5k+j+ZN%`nq6Ov1X!$g9hy_F<| z6zD;)C@RvWr=<=jGc8OX8HLqZamWlbMK4oQCNiA9Ol~hFJBOPDVXk!oYE+ZaEa+t9 zQc-P`i9G!{uK%7pZZ6(G|AbFZ-!Ylg;+YF6?w7}^5o6JwJPDKUXz8di=G-I`{D}`1%CW zgX&|M{wTB(v|x)R%O|Ljjz+C)OjGO0wYX8r)`+w8g|Ci1w~INN*x~xc+k&QvtH3^z z!oGU@Qx}&psqWL?aN_6zEGnDMn=_QIy@R5$BEXfER#;gFZ6j=%u^QXQmg9J7BW}&x zk0m{e2v%ux59t6MKU^o6c`9{1mir{4#4-YT7Gap;G5{OGaCa%)|L9Tkx3} z8kX0JtLcrnl-q(MC2fQjf}o>jfG@9J5r6|PUc5l^&|zGZu`9J4-xTh`%@k7Bq(<`4 zRrqGkZVYpd;qIQNPoMH@L}!aAN~0JC{kw-S{Yh)VGF+M4NrER4(CuG684VSa_?%M| zUTE{6F-4xu>ZGKPB-a@7O2aT&e<()FN1!*eRhV;4v^M{}B6}|>d{E*xJ(0XKqdl-7 zgDRk|fY{;~Nbo_8C$BU~RmKXq)twzO~STm z!!dhgcZBOHa$-+ph8uO$(Mj@JBTK{zgCvYJ5KNc4*j(Ky`3g~P@cb`i4$0tI$A^p8 z*jz*-k)`v;inqMuuEWma$9?l?NWf#8*X7d{FB!_D zrtZmVQK+`dM6y~4*U$=zoNzlYbhq_}kC8DR9%?{IUsv?^x5lE08E9TxihcEEXqlCd ziTy$lALM}EewG;GXN4iYW=QBkRye?xv$8JM4)|v-;(KZQ!IPg}l5%LFmq9mNoUXjsl)BuR-8;&i*M(ChE+qSK#lIBeoGSLir5nIfHGf}!$FI&^*Wa*K{7f`%RFTr2 zBTu`khZBP2C3I6(Sd5QPKjQJ%zhUgyDUg?!hpv*836JsCLDRex{C;RD-W;3{99)ch z)sry9(~@LK4)c@;p;cuJ8kNRit?3v<6Iw7N#XS4j=TdTuw(8=kYcNr_K!m9u&Jnyn zm$Dugvl?)spb>R>t6;C@3@2y*6aT8Rim$@l;RU7y`zmsE@cULj+$321?Itbknr{Fd zTCCih42gS^wC(D#b6n^iE3-v~bqcD~M={K3k)?HAWW^|6$WadE@rw2arnq_YIy1M4 zn*QgK-jfVJ!<5oo1Y6s4yds1rIm{NT$Mi$zoGf^2OEGJ+iw>^z@yB9!3qBhQpv~Wz zw-nckI&m(m9Vfajx%Z;0enJ`wI{q3EU<0tYMdL}&aw9Cgmt7$?bw^V9Mi&*p(m$^ zgp?6@{q8v~ojJn_ljhtXx2NvMrKDCS0vAetA$L7l{x&3f$1&UFci-Qmk9k5i;t5{- z{v%?7BKfr)S&MO*p!0+LtvH&zhVEAn1H2t@q-H#aJa%1B-{7ARMv4oCBCCnsS!E@P zcXg2!m5h~X^RO|08TL)7$L(c@acALv++Ds8_bNZb-m>-ZQ?#J>FvR@fQ*nO6W`4$< z@aJq05k0tZy12yTj2=*cst~ zPFH2?_?r)NUH6O7+6|xx?{t-x}l(2xDIC znW}@)q)~`k83RucmFqjr5JUlupKR z+8$*3C6jy@d|J7t!{^`DSN^inlRfHAF~HUJUihv`AK$H_ShmIq{p_Xb)wj={CU5Zp zFMjv|9y%7xx?W;7h`ekXnq*1Xtdz~wPAy8A%tI^+u8rkX@!-;R$veN0(62b{I&fqc zyqru~P&{a{t1@G8tFj2cbxg#wEhTumdkWg7#!19rbnTAt!G*YPn5`kjS4nPR%%*=X zvmO^lH{*KA7Mvp?ez5QmCPyXl>nhwVa4yyxXZ?(EE7%ejgUxU>(gqVuC8h%*lu(9R^| zr;3_*^8B9MDlF+W1p)G|%%wXZt`C0s;gQrH_WC_$=M-_NoJ_v6H^Jg2jTUTUofCYI2k=XR1TPl`z8BHfHvc+lHIse(u&O)^RaLKM#OkV zL4l0Tqn{p=!oDV(`V=cyETOeEM26ciT$#EB7qaT4Q5~h5(M#Wp4dji^X-M{#JeyEj zGntg=5#L*MDXfm1l$a8VlogkXs&T7uX7wJl7Oq5^M?ZAeut$J~8OHY;fmJyZ=ymc; z8)`$IYgcLoz8b#`mkOKsxaAsM_s4JM>ni>1#*{W(p4N=ZGum-@MjgEMZTa)FN$K{4 z+Tvh;dn9W~#$^7ynUWWL`KRO7@Af@Fy>xgI{nr9^9?1ASt(a7BL;dS3`j( z1Nf4sU#yvm4Juiv(oIFFb}!D5&ze<6>-C1O-=6-0eo;M{f~GNJ4(=2;;o`_O+;-VA zVjjtd9(srN>-e|z^q;Rq^C$Ha36|MI)bUGO1Rj=a;FmflY{;_Y4P07QNFZNib6;U@ z=|tu+>Z|CBO5 z@o>u`Jl#cC`$Rn1l!IR?hvUcUVfbz5I85uQ%}{odr8X|~bi$EfbEN1=5UM;nk09X= z68d$xOz=?5SiLf?nTHn(r5041rz6~P(_I≪qPe$l;oo3XVmZVu8C(7Zg*Xd-cHr z=PU%voJcs-`Ak(ntn(XkNg;;t_i;TVV5w)qt!m?gQgCzjemt0T2v@VV;7WQsuIFsQ z^{lP9U9=lFChoz2b%P6>k?B5-l(Zk!$8jH5YKXdFHVLkt2)v6K*KWKV{KVsckM zJbLs!56C|B`2lE>()i1} zO9rTNI@*^NpkZDbR!ts;S)+R+fxKL}lLovERR}pK)9Z|p*=;aq*ag>@U=gunxU7iW z?gLTWE0KPtg+4kyIFzxDv*2fkufDafL#FOG&l(D!&~!vg>g^Z3AwM??9>3 z06y0i+3D?W#<&vgj79EBQe_*(t`EQa7Qg=T6Dz9-(m(Q;(NB2uK_XK7;g6?CO3D)P zB`h>F;AdhAFIB-RqJo|>cTChAg=*bGtX4`vg+&sVCyF}q&kpV5&_j$Uy?pIF8>UeX zp=?O*j%mitoJ}}Cv6&#cIBQmWy?5_ky?QzdxS|=AJ27S2re^gi!-v24q^)I}6 z`<(Um%k$^pXk`GAmEJb1AD$nWiC=fj$FT(|xU@1IKQ)fS>&{XEcqD3m*IG zBxAPB9*QI7Suj#2Sl+S;m#$of zr<13|7O&xg=8WY8`#P9ePzdAQjCLN%d?{rkdy`wUI#AMM2pgwisUsN4ZExL73aN-W z!;5gCVjpHiWN`hiaTgRHpP7JZDG}2DlV=wV+)jD~-84-8Deq*@*9Bvx*D0ZF(o8mt zch1~|yMY6HgN^+c;`-Q~d>(y0y#Z$u>u_WGZWIQNU=OsSpf|p3or)7p3vsM@CHB_L z#lG4(*uQZGjyBE2l|9RGY5P1}Zk>h)yDBiq-I_h1IDZxizI^p)ta2EQ2_{JhA*B$l zdhJDPu`_!mPK~L>gNb`^Gphr4(n#=A8*!05{OQ~loFVw%*k=}w5<@&f^Y%Snym^gxZ$JGr%5?GU zWgH&(s##MAGz_b(vr(@<9?dEfu~C+bI)i)^8^n>JRz>lUM2gRzb0w8{zhQmjIcZki zZwkJdxErU3R^d{?W{mYq5|lE3Et;_)_21Ud|KnF|VBm2f9P2YpajPZ_k9Uqh%`|^5 zFi*=&#Oqg2ndyH@Q6YI=btK6mv085&%H?xWVOqe$icAO&AKvyQ-t!T|3w-$N6(0Wj z2w{-{ya5f<67lxLa$Hz368Rp=oVgTTHJN5I?4QsVPd87&@3o`wc6$-pCJ$nz66av8 zA;!4a+Zu}vr6kfYt8iQ|YQ?RTO}Ls~hZ9L_a3Oyq_K&IHSWUcdnT8S$d70sMFB_cl zQ^x6T+Suc&h9jiN^R2Y`{7)!%l72Ay>jaWAs51<#$c)6#2iNhGyzq$bJdgC{%a@on zX(~5_i){0P0j2nQ;XaB*t8p#02G>Sa;||@&mGo*{DXv3Z+BCSC+dxL|aqz_F*tKgH zDVRJmBL||du^YqDP%9%O#s=^dz=;{XasTi-^!1QBe}u)iQBgo38M(nx4(Jp?gvnRE7bZbSj@&maVl)`A;pP3+k&q}22AQI5A@@sNXs zyfj1Au*(35OZR_?XI*KHJ#@%0lEK` zkzw8&>w-%`X6SI#;(c+@R78xqA$(NjI3y9q&p=ff`I+gs|Mgu#w#$U`pTw-;_tMd` zm=kPBir1a)XN7SV+LVgWDl0&X!dR>}$sv#HLaAebB|QK}nVWwqE}KevL`bEHze^;+Z}!Bp9(en3Np|YfB|4(9geq zaF;FGPv8Cwe=A>tM1~lx-xt+J`B(wK}AW1F}-Z@ z?T*FRzhpE9n#pm-Fo9ym0&P(TEWzC=1eKq*Ou(NtY51^fB32Bt;Y86Odj0WGU7UZPgRqfKO3?x~G~vCg;}=Z5Qk zMz|7egSiHOx8Nxu%%&TRRkT@IX2$vB@zyG??RB&=!N-@+yQZSO$M(&g(9$p_0XM+n z{>8M(6r+tJ4@QvnW?Bt@{>I_cxuS~4P$6$mFCl0Qei6|TT zd{Wqx^%HSxUj<@pqNY5INi4rdiMxI>hS(38J&iO(Q7{7UF1Gr?TTMAYb}ahK0>s~pY+coS?~ zkTL}m2Bjm$${js4Z4s(sjW}&LObJZJ#j;)4lV8JL%#2$X)iAAB7D{3>*t@QFQpNFb zJ$xQ!gvAchxXg;eA^5&yK29%5#_F*l$n0+k0|hCrcK5Qxq2v1*B7b`Gjt4!91_3eT zIc-!b%;k&`uNI72U5UxR!L*ROuq-H)%g@N=5arX0=j@p?60^xjX=Cl^Ik>)L3$|y@ z$C`u*+^(0NlGXNa>*W9OD{n;FGEY;7H@0$m=wi#?(Cs0p%WuPCyxw+N2@UO5U+tA^q2)~QJLvgV_Jg=Fs9;b7vad-ND94%?Uq}XJ5D5|jn2=eeDB8g$7j9tz; zI2me(&jtr$vbQZmP9tS4rd$;Yo91SQUw1bmr&lnH>DiC%-O0-O^y$ysTz~N78R%-7 zGZW#e!NoXNT8*Pmk6i zIlzRKcU6)Ho*gSk$zV^;)@J$`;!$Tge%V!tl}Vup)sYO;P-g|4SUnccK3|0u8R1;i zA<7O#C^Ig0ATC#I#g%#6ak97>Cq~!ddTBe3r>(}Nu^X{FZw0pyhWmu!m!EzoMEG19 z;lMS!pYZa<~a}2(@U5q1e zAAkFS9E=T9vCbx$thLNUfpRpTC0lA+;JcrGU*) zZM#B_(W6tA{mZKPzkiL%%b9JWru9bjNA}WmLF>>m+@87_x29~tf&A6zoW2Y_Y#lkp zFGqhe%QYO zWpVZ_d?U!K?hiG?`9LkE6geJe$K5(&1Gg6i<9+97{J3HuUN#otQNtouP*G6P5^jyd zaSoVmCiSWI(euVPOOK-}dK&ky_A~Oq$;mA^S=NRTevzzz(sVc($BchBP7CiIu1QMl zY7G}1Ew1qJ7;>Yy~`%zO8WxjL|gH_Bu3id$?5f|D~{m%>TM~*Z`;c7 z;H7T8ei?MKtiZ985gxW!A(D^sYEAPnPCbt6u8q2sRCMJmHdVwfe;phO(Zb;{ z1MCfRK(U$_V8F*7Z9IrPd;g5BR_}Em0S6gReVQLQv#w#gc=HywD(!TmARgQdmhyA;@(f!I{ zpq4B0Yq@cZFf^f8b&czLKf zE=3sPIzeyIEPXQ83O#Azd!KM2O?DF$yrw0E+v+ZG30op zrK+-YoFU%x^M!f1-(JDr2l+TLYIrReF+RM-%UAC>(X+LwkttV(n{>yK{5sqzJ%q*q zi@EmLRacoavh#)n;>FQ5m^ajs->Z7+DExF{4ML2h&puc=6Zbn8pn7a?Sd-WAvDH9c ze=o$iYB2RlfW0wJZ- zOT80tXHo}lWNyUc;+;5C)Qlc_9(>I9WuPhU1sS0wz?Eyqi@VA2YkM|6R3!sz6Y*DN z0zOub#G94zcvGE?KX%N))r!DfBl#g@GU*+CmwO|hMxTJfz!xJ$c2%TK6_bFlWXH>jVoVWXGMPhr*xdNqHHEx z;faI8@%-d^3^bK0UDkx#;&O-~&e}-X+txr`PA2stkMnfBS&k!E$Vswz?fM)bVi-7pbv4mYB=l@=^?HBsN*hR08Sqv!v? z)58U|$cyJsF?Gy%{@g{wOY!CW9fSmI*n7_&84V}e=vgCz@%(5xdK*Yh0#`aKv3c19 zRyr#!83soB^Jfa!EHcB2UEhlkLX(V_0U42QCTi&8VvMZbLHxSjRyugFV*`FUS&0V+ z7vR?3r8wQT7`5}pA-zvDY*jQ^n9cZ-gOR)W&qHgG>#N5e+>X|0y;mW|%SCeal2Fu9bbs|;TKJMs!=+$D zoN<%kswX|8n19<%mFt3s)8}_1Lr^z(E-n|g;#A@~+%0J5S+za1oH>W^1u5&5Kt0q3 zx^RKa>~Iad=p2I&8&mLl)et;gKN!!eN073P!jtt0__-zpKXy#PFbZu%;>^R^3Ew?< zOt$9(kChZ*OH)fDt)&w56!f7^#wOUK2No?{hU<54^Kp)7j2B2_`mEVd(^i2Rp_o~@ z_PE*YwSIDhp2Gi9AJeoDT8H_>iBXegS43*+l? zb4&})XEx)@)J^!RXgdxjtw3)LM^>_olu`KkkDnx7CyHI4P@sP9{AJ`P6_JAKOQYpU zK!=z|z+KS_-2!|_s3}HxBbDWe4BpVVI2N9z8U66h?mE~Uq=#d{S~wS?i@pB(SY#^_P|AD+;HYPW zA?`g6oe+hXTzAW*QU%DGDTl zJq$2rurIFE&%|dlGqGSmILFjtqb#&d5fv1HysT`rw$QMLq(BGF zd(kJX57!g>=-OlTh-r8*VIQs(Hc8cBE}HoB^J?<2=KPuA=KjbriYA1j#4xtNRso$9 zdy1K~rzo~Q>r9I0L7p{CoB5A+69P(6lH%AYjze*0+CH4m+Jtk-8*n9SBRPd?1gcsx zls?tn2={tgVwr~-cgU<7WR2$?WAW>%c)YJq$A_(@__Mtjzfnl=dfQ|??aasbO=EC$ zQ6^LDh_$M(u46fU`|c&jvsZ3jg{he}bmjFBY3R>ID5hM{ql;zpm*JP6|G=vk5`Aym z=56qBH-!n^Zz6g3YwO(beXS{Ot&rhCl?*?3I%EG_CqCjd_QzziwvIBgeeq|I{y%E)TFmoT8(wD$j(T004m(QM$k00MNMb)2gUUJrVZDlR2 zG_A?n>XY|!$0V(OSYnopWzIRAN)K~&!>_+T6y3nQ5Wl~A4sSnKjti#_3dGYb6Y)!Z zF0$MuBD3BU$7Z^jqo;ua!{mH#W&F8$CZ4v=!pv^EyxA$_?e+v);6jKME_b)W$tXw6 zu~p$Dl6#l18xiyoMf~&nkH!6UpQCZeG_vY~SlR|fwgXUZpN4XaG)y%fh7oEZeC8@j zERDP3+kVc<*tt9t-yT|z&5QDoALYpkA}$}Y&_k?yV5n6n7Y&FiF9Ex|yZB(?jQOmz zlL|_hSzi!#`)VlRhaF2%p5)4~d(*s;`1Okl%t{Vquc@V|!hONoU7sy#XG`cAR}w_7 zCj+%H#sYpy5-cA_vD^$j3MbU1HZT9K=hgpT6xxkEL$;3!3WGH;v9C3z4YtDiEC)Q^ zKLZ*4oS;Dhy|KNSVBkl*rx2xe($PW2F~FdBPBgu%y!40H@;|a4F6WXG3jqJK7nS$;+PT<%~`;!V?^oc;1dM z%wuihaI16|&L=kDPF5SPr&Qycu`M{9xfp)Rx`-vieX5%wu95Pu@HS#}QXcP!=Q}6k z_u3S^Y%WB5ZZyWx=j2A%pt!Fij;u_lproW)b5 zBqq>3>!8ef7*<%MB26h09x_p&qJgMxVNxyeN9ip0o3HL8ZD0(ei%1I@POtUH&ke@- zZlw%AuF=H9HMY1@6^UVP(%P?Bx;Xj&nz9}{cFfRFP6d7>7=j&NEc$f&ezZBHuw!;` zmrG;PJb0?vaQBBe&k{}L@9979@PR8zaE(!5J0{{~%V>OCHv!{AY}hOOT@IHKXoNd!v+!

    3sMqTL&M5=j^5zs_MuOj@g z_%lo}=|>)0mxRU;L*(7jTV_X4&Wz(+JyLLyT@`1KBSMXFcl#{-xMvaa0!`S<3u7|G z%oD3dO-5TmIZn-N$EiszxHz>FjU(q`YD^}am5f;dNA&B1K~dpd4efN#z5MX{%Sue` zt;3stsAV=5jEVV&r9vp1X#Wz=E#P2HxF;?~I^qF^2M@y3u`5841-+-53`gP|aW%>c zr^6l4(cK;kd)Q-`gARK<{Vt_#@YDQcr>OFM>FQJVy5>Ez!w`A!dr)6 zIvE8qIzx&LnF`t-MaX~4O(7H(X) zpVNU031l2Hs&FEA8GG_XZ8=;ggM5?rctdv^j(6wvHN>x5i^-Fg(t3Mxoa^0XpvB(! z(|s&SbjS0(^KpD-7HrAz`+7O!*I&NpIXUm1{=#JR<%{NXR(g(V95!jBqsF2DWoAj} zr{YgPSAmCyG1}K{_@@#NPv2vH@i=L&5xwWtwQl&O$^;J=$ne`5UHnjMk7G;S(47pa zp`z^Fkt5q|{;w#kvz^sdTOl0XY_TuQjadK$^oWvK6GYvB9c8r$HFIZyTfcUlG?SAa z;FYM`{P-6}3`=B-EaI~jdc)DCn}i10AT-O8(WIV<3f&PHK_1tE6lUMn9iqSqFW-H{ zyT9IJ*^)9=*r7o>_@*@rztqO#&BoFAP+N+x7A0X)x|*GbDf{AJNj-KvmYoY^EHtH=w%AIDbWO!X8*=}1RPaVqB6pSl#cCT_+Vin-30 zcH&6RMw}@iq0VW*-C4V_qj(J|oGMRF*O&dL@<^YAx+p0OKOS9)!k&iwvzS14u9yCPTgWW7J@8%j`86PFxixaFgSCR>T2VW5sYjz!tvj621Hp2|2CX^ol~ zmw$SMg$LGAkf6LX8MgA#BXMxm0`#FUp&J=ydu54)TwbtzkZ_8#Mn_R&Y#ED=qy-!f zT`#Q1t*mC;OW1~cqqgH=@n+QZ8^gwBPT_Erpr|YWrXJQMPGm})OWDnMShO3r^Ecy4UL(FP>BQ#V6Ic-^>S^G)~YGM3R?s8QRS)5kX(FLLt$@xvu720(d$GU{`lMbq_7|H z^x1FhX`8CnbMgOpSr0Uj!d5A!Vzn3{X_SZ}-AHb@7ae6Q7cBi}Dm$LM#nPEG*^5S# zQM$7s6hBtc{SiFAwOkp$ZS9V|1doM2d0DF5{U2A>3B_Zl3(KBmselUvD{hh(In>i0 zWA&voGBGVY#M+a*g*@g=orHI9UvdNW>knO|R0&z!`O#m|8|%$7u}O6lS`^~3RVM|F z`k5%#9Eo*SsmRd^;oi;0s!cqHM>JxKs<8`aPw+;25&l13F%VChlJIeTGO#)YsHCeo z4}aBX;$=-5o^C2YXTB6SrdrByF4PFu-4$>y+!8bO<=M#e((=Ng(l*p3tRw>=*xgOg zI$#kVE;)w9qbBkBn@BjdCa=P+MMrRqJjm#31D)wf9@bqR7exDGtP@hSB-$3iVz?sI8u8Y0><#}$DFPzf(d%sKGA9Ky zQ~gi3QE^NXE-cxDTeJ4yYJLOmjc#K0i|a{^xIJCl$G7!sRig0Jn z9<1(Bh$&7Zus3TJ9?ac_ihvPpe9CPMagWyQzP}#DutsdC7x&Y^+oQA4JZU%^hKXd5 z&JfhT8LEdf(Pmf^<<1pqq4e{gPHaT}@E$B<*RP!C&YPD6jl~$rU9GLGum!R}v>A?O z;(Jl^zELfSyln=?Xh*|~?$uac3+u{Pac9+s-(TSEi}#pZTEvE@zmp7)TDsv@xjepF ztAtytRq=g`D^{l~^Z9pX(%{wqqY7)QrSe29%>Dt6xE82|i*_=cr@;DnoE4_HShA%S zo**-RI5>UC;{a(umcQdZadE`#nM-(9=|Gt$mTC<{gJu?LR1&e;U>FJ&dmus47b)r? zm}4~(<17dA{LRUwQ}L2C_Qi)!ctwi;+mq*r42j^*m(EFXcp>O5%ZKBy%27Z~B3`cP zkGEArxKQHlzUAnzD|!D-5mq?kp@5sg##rHI%$Bzo#Um#s)#6}TJt?aZEtnn&sXkT? zn1b~Qvk>o18(`ucE-A7F?dV8!IVB7MWoIi3fGJ!&mK7@#OQB ztT3)73OGQXp-+%5(~TI*E3jhLIcqb6zDUkoi%`b~CkYbAkwTn^bHRBZJ$%*89f$q= zq~X+boe6WnZBKpN@H0o7rx8O!@tUJymbepQhT}afu*zAJ|6VAWfZz!|J#p_yIUasK z4?li32WxXe;H@Aj^^yVOaC&kZE~IVXA=YP;>v5xCD{hQ##_6mLI5DxFy=GrCEqt@D z8s(YMYzV~hlJH<=YHA2JbHWIR2xQs!M!x+3%<@daa@RC$aL>m&n{lYLEXI0^Jj^f~ z$@5m@9AdC&)KuCpJ#MJ)Z|#rEt6Gt2Xv6Ti!PgY`1JrRVSQpb=O;`~tN4n$v@iizN z9K_*4xxErDMVjC^#gB(cb{l&+u#7}%lGoe00Mj#Kp)1CJ9NfoF;>D|%To${nxrL`Y z5M}g%l=EuaqUAN;L^pI@u`I7{J8pwuYv-c=9M8a|whfoYlbi80e7EEg2-k z*PTANT`7nA>tuMiP6>CaJ&_bF$xlZ|-TzG6-PoduQ@Gp4Q5lyb4RG08hTA?e+@ODt zg=%17h!ZCT>?IBAR|#X z5^pNw@qyx%O{06UMa`!8?XyU8TnW^{k#5Fpi3M-&=HWANV{$7FlvZM(aS#b9eXe~h z<_|38WRNYh9;h%is6Nl0(Z=LHIcP0g22a}13@?3rx3dBUIzUmr_pBUQV+-YDAiv;BQ=o&@f$mkgH(<{pnRL2q>_*2^W&*%{=B1{((~vveVE zEXT^Z$V3}^eC%x2_{816sSOS-xnT z6@e2K!|{TY_gu{!^w1K#RLWS`zZAE~DBT!KiksVxlj(IhnpTc`OShspWH>=h6~tK^ zy2@;KA5XA1VtKg zgj)0wZqoyKkx5+VEYMF{a9?bmvy2rnos9V5C_7y6QO4Ow3k=baYP%0i9)Q=Mt-yrg z-FbZ~94I6rXLE|y?#l>GRQMW7gRre+_~Fn>lx6f`<9Xt<1MFd+KYz+WY1R5lGV1Cm zQ0j?l?M&3GdV2fv6vcNR-s9C@pYYT3Kj9x_ z1#60DH_vy(gC;BP7k@wy`N^JmY@8C!(-oq6_#gNmQCJ^0w=)8YT@1IuO$Qln1}NgZ zuZW3cI22{U@WVh;9_KEe=5Yn00z{m(zI*!`A&!2e1coTo8i;!Rv8a`$pj{yg>-19) zCGSEDA&2VGd8iqkP0FCcu+NSbT#w?+rluCWdC$!{+)?rD$$RvV?#+;KdVCOlx)bOjTWS3UyNLbyA*4kOs+&* z$V6Nm--^P3QFN~cC^6`VaT?L&ovcZDl}Tw7xRS-g*&Sx2Tq2Hao1KL#?eh_4Bb|GW z9hc2b`rZBgVXUsrWor6d;IE3F_5qj}mxY64tMJXVUAUduj;ncX*j2DbqOx(fMPIW1 zJ?OcwH_X7}Jr#&|(~*WRPaOJyTxKJ*4 z+KW+MhFFz15Vg}s!^^^qdvyodM51=sTwE{N#z!p==k36fKH0Q~%3MP%6n}Vt8>&j; z@!h^9czR?BwodDZcqjFLh|!GcZ_UUsN`0{Mq>$QdAjJuS7+)zG{C(;B1p{)iwO|!b zdk?2;@014Q_Zh{{xy(orm&5IGGK}JLKSTEJ!(24+aN}qu8DCcv$H~Q+6arlC?T!lp zYPc9|tm3w8V>JRVe5i!uR~(;w7%$`tVw+WSY5jDan8~rfCdCyG9{X8MVu@ z(Wa1rcGVozkiu4~WMaKZCX!{{cv8i@$#b}aM^v+kaWMz?Z)PtWPWtn8TVMRp+7nx* zc%Y!C79z|gid!u?C5XiCe@j_KRfZ+S9eEb2xK9x3XD@kNCC_?99BjwhF^jzr;7QXb zu(Ce;C>o$Y@}cswrHeU}n5xtrl}5RwtXbHuI1Y8Pk=SIFjTlu|zR}|qbMf2Z7VKO# z4G{$S{%!#a^76*B=Wp=(%{#n${T6Rtf5i6A9ekW2gn3{Yp@Ml#fuxlBn zcGG8pEhNwJMGqaG&D!W=#OHK=q(Hl-RpRW}2HebU#$_?)Fs%{a=WfQs$-6KiIGKb* z8>7`DQR$wCg?0%Tsp>;9x&fCDR}& zasMhlJ9+?HIyYlz|DjM-5c6wQm@2cxeGpEKuE$q%_G81y>C*U)SPv{s4`#(`nVo}Q z4%c9)qb9Gb5Xj{{9I%+Yx=5~wK%fQKkL zBE~#~p2v!LhpY%W*zk08DQQ*iMWI5t9YJVaoC&nXT2p22W^(C@m3iWwP`EIE3?_*A zHz{721$i$s<*tT&MY?BQiBx_5UQF;9!n1^Q)KyTvekH;K0%6oe%@S%VX1rSC(JnD! zWHl;Fk~uSN+NIbgN(!*i(dAAgb2&pUf7F*r)8sP!!f|4L4Q`h2!S39(I8{pMXhIDS z8WRj4p9ffy12JR{>YiQCw|&}RyxKe(Pn*+mVQmH@E|GNF6l8}cAAMB&nf`O6cdvFL ze%iGhBSd0PK>Rr4ekMoykzkB-@*{SgyJ{5+mp(H>a5z11+Er=9+ zfJrx|(MgL>tNU*$?1JLVabmNUk|LZT%XEukr@Q{-U3+MuF~CY1YoV{n@ZtTtHw-0s z+B)G_3mpT7MzhrWqFr5LN8BnKgKf%L*q}24DTDG5WHH8rU_9_^XI*1IxqFfV|ZOuoOr4Nm(i;d*aZ zBx|dZ=ak3t-i5d@Z8Og1Zp4L*4LFm&2A3%2x|m9kbesE|=YJzY0#O4a>OS85h3_B! zi1jO0!_ml;&saqpS#9Ael&4B$akZt9*g>#U7@;Yd!*Hl}F+)1>Ea@r=_%hZSM+20w z#!-Onuk>sGT&>OF;LueC(RB9u*^IqQHL?8%j|Y>dHiIx)|GID0Y`sV%vljh?3K1C7f-m z$#vvc!i|w*AkRN5ALxXa9ff#V-49RK$KiF`Xv_#!<+b{o2TH8Fkn7olobbn<`PjcW zm7T=U{xNv<>}QEYi{$S9t%qE144zm{-ITnN^~ZSt_E3G-j?Ws9-;ifnZo%2)82>4!IOx%%Y;{ZqMY9a(!t z4Ab;RjY%>ZJgm`9LWNBdrn?S8q`V$m{o+0@c(`LO{`hPen#afULx~0S z@vz5}chB&WefCFA0tjoBo{|80LA^qX)5lL0OL8OmTut0-V-G`|>SctZzN%>VHe&$~ zl6S?iacwx8(}c?zn{Yn83g?S!@#Ta%oGhxxnqK2D&L(L%A2edg9?ij zEO*F4Ds6;_r;N!Wic&q16>guHjvo$IA)+hZY~9qzbgQr5zM^~mKnmM6yMf}FKmPau zlS)e{Ce@<%FymG{VVD|b#Nq1pQh1w@Ad#`^7wpP80f7oOI9uRus6OtAy4vn~XbrN! zU`++SN1;%nHrJ8ftI#hU;~f*p1Dj!}%oeL$GBCn0fCPgCT{aM_ZO3DnQZNa>F0(v( za}rPkg@(55kwn6&v%4vd^|ZkLI6IV>|EET}X|KiQ50vBE{pC2@z6d>B z$rGw{O?^|+ZCKvq8#nrrdC%k;zVWms^VMsBiKok3`Q89(Q zt$`8~oo!5+g$pYV;EVY?ae37NY%Z=qqHQ>jAGMW7<`$J;HFP?gpVgPbVzuu;X3Zbs;s+8d9yOu#o= z%8(ml%M6P94sH`&%XsnfPrM_~)4pjt_p=VRibA$!1oMH3kfH}c`4ocYYmJjoBR>kQ zq_A!Bxmd51N`^j(es52ZUxO>5#8J6X|(0X^l)V!EgYa!h1#<0u_k{fmamN9Y1>n4mJkRmzSO~fDF|AgEg2o zBAmTmoOw5t4Vi!hkHMH6OE5EgA--8o3OsHTrUYiAo1!b9<$EbFgJX@^NBMAUwocXFYr#VvZ9%^l&)F4!QdBEOb+y z2jFDkCajDs#jeD1JTBRTbE(w?FC7>m^iq+>7%O!w^w7h`?zUL#W{Fu=1hLF@5Tzj9 zlNW7HFkR^yUdXWt<9Vx#rAvm>|$koaP1xr@7m2BIgM47 zsF=SHrw$y)#QY*Y;t&(o#F&XMDrey9y&Di-~dqG0+xQDDFBF z?u%?yJ$|lHnw}VI6HE6d$}deZT&@QRl4x?UBcaxUw}KYmdyLEp{p5XVom7!v-UDlV z^D)6}F#MFP+0bQD$RG+~zHn2)EiYx9wvpjjm@N{`q~Z`^RLs>Rk1qBoh!n%Li#2~w z+YZ`)0ju7za=!fZ{%=x39{2h1+xytj)`^M*OAs0u$ORap;z_HE>};T$1;+IC`e!1c zFyap6MMWi?8`HjMVsStQZq46=ilMU*tlHl8G{cctdn|F* zU=jmia0SetA8m=V3le}mv+?`75%{@cApWRL$D=hP@TxHrhbG6ufnrH}8*|*ge~StJ z1Raqmr@eds5lr-@p;}^{2D-@O*xDSt`Md^)XA~2>mZxyT57oM2zHttr$UGk5(V?D+ z6}p4T+p8nQ*N4FMU-*;OTH+-mn_4{cnDGRD;~W1J5$#igFk_$=6l zVhkmWmXoZvc#XJ6D+NX9DM(dGLeQ3`4aCoTmZD?kFpkMA$%+<^9tR&MUueoCdJ>H; zayG55izlW#sWAK<>F0sVn>QlX)s%lH4Vog!KFbMWIb! zEO1RmnaxP9$+nZ}aQ(KCOob^|#o3`CG!r8+ELjOmkn7eTv1%S%&1J!L!14s4HL)Wg z2v-A5a64EFXCrO!*`N?Cj1FVSE{fSx`g-8-niPzU(qg66U?d<<|Ej^m*$b&DS;)#N zK;hU@jLynK>hKXr8WIm*J6E3ZE9AjN*$mOHer%}3>lY^WMAM`U2zC+;MH&B{CmHlI z!@($1?Ts;-WYFo}gJkAdFsy{0Pu#N}5+NMYvLplkI#Q|R!TksD;e$j4EhS4nVbO|Z z{~vL09ah!W^$l;jySp2uq)SRg6j2Pi8xaib?iK?so@qUVF_sNBl-}bU>VUzP|y!*ieM;H`BFc0`^TQW}X-(^F^~s z5oyXSv?!FISysRk85<3=$ox=-zOpj@di58c35P5(t1uVV)zormDn}NHwfaS9P$Foo zlEv@ICdDSsYQ>7W-v2hku36I_D0-|$Yq_95X%v4tAkTk@R-Q*5Y}&bl&GUEkD9@iu zb6~Rb^N5I5F;8y@YE5!z!ySll%+OV`1P^EKz#Xz7zs_pIzw+BSiTm5p2XJrfKC&k} zv3kfDglii!6FBNO%)T-$NUxV_b2aY?%W-_S^{~ zyxXB5Mn23LG#2M3Y~n$@VqAp@*`|x)2%^VjvzD6b;fga+4!GbU!xc9fE{dVM^!;UL zx?JRN#Y+=c!Yy!+{$^R29ZCZn5I~w&z*b>DOEFSqX09(cOv6{3r^ClcrJEr&;Hqki z+<^X=Hlz@fh8DqDL+YngG%Ogq>nm}2>pZ0R+Az}wm}!t8khEB^p(f(Bq^vC8Zn!U? zx*KaDdHOtaB4#Th7(debk)%c4c!IkjJxiin2pUJvLvz())a1{Ew~7mo$#kVN2vKq7 z)KAWh)(_-;2`8pr;@J!P!yU1fY}YD9sjEh`k~}l4Sc|WNGQRtK4*oo`6ze7z^7$Ca zX`-)h3~Uw6>2pQ8rf89Z8eB7 zR^a=K+;b;-zA}UUJZrW|I}@v%vXG+c#ddgccrqf4dlKD=t`urGIk^GHCe>rS*7R_1|a=EYd0nuYZ$nP}C{#&rEe z_7<0yS5*Dm47+O8+Hf%jaExAGG}>lkB|Y2nJ(LGdiGx&E)#5r+QDp3^qee_-jIIDfoDR{(`A8#di*P`$h7_yxB5fv^ zHI!_GrlDhSVN4rtj@pSl)j0M#ibC`=#cOapdl?;~o>YeAX@yhKF1QhFjaxp3xb3fx z>j7H06{1I))(EFUY_UJu3yu9EQ0CVYq1NV7xtY9}Y9PhXLNyif#r7JE?JHI2M5x=M zC1oy;)VMmX9S`R3z~-WPEUm3IRS_TJf-Q3j@XMaX_@Qe$CdJ#qygR8tIC?7G>~Jj3 z9lM<6vC>F}ahgOp+7i@@p*0NC@}uwdIek*>tvFem^s36CqhV0-8QT+OVo*QJxyiU zyf72bFSei}&VzrqFk>37Ozy(*j8!<6z6M7!Yw>wrEsm9~$LZ1S+|&5_$PRolcQ5J+ zXR|O$uu;Tcr<+kpcBVA_T%JAi<8%|TT00kw$~jo0n2Oc5xg?N0h%q!#Gi)?AWXvWr z#+-!o2wbgLkE`WGGvhjNW@Iy_cno2|CWLTb+Q*t;SAxhraK5(#js}p{R+j`Gho;OF zV68&PNJ9zxc5VO1oD;St4-g~Ub=92tj0C(a#3aVqc)4dGjxR4nNgq2{t4ij<2rXZ% zu`k9(?Fw|riqWc6Mq0K2Tja7x;ACN_QW&k*2sJB~amZ8D0KMrpXg#$=fr1|9S*2i& zMmpBZ(y>uB7xVO!xr!@pQ2)Arn_=tM)JIs+W>qWn7Y<>Yae$5u z4wtXu)WmCf&D_B3YEcso=dHpZ9Us;(=Bg4ylzOS*oAxR^Ik^mrs}laHU7ciUgew6? zc<3pIdj!?b_i@4MFkgPw2-?djo~fvCNkyhx54c+sGbBQAMK9egQ?y z56Q*hvFk{C>vEM%o^fA{RUd#VSrp1Ndy}>{WLs5yZUzzP3V$m!#ra@nWDiCTTvyv| zb2nFT z`cBNSyJuwK&W4%rGghVb%5hF{nPD7i46@OnTf|vI3yji`r5Q$uLIb^(ZE$>M6K>Aj zjGNV)aBI{CTrX(Em5jBxmbo4`i#ze<^!?b9w*V=Y{`4L>X5O)6GVSSQ#b(m^L?0~e zWsL+)Y2O9I&8!}a_wR_6M9lTWOT78`nk&n$oV^NdIaMzDZ(B4P7wRUUGRO?>a$%i9$H$stiNDPBGT%7NSuzpO`lV8}##0s+UOX)yITUqlL>9PhY?0j6GrC zN4NxXsA`hMAk=AQqEnd|U9kvjOmj#8Ya%Gp|G>Y^u#NTg5$3d+6^f)`bxX0HjN|oc z8K^bNBV#*&r?}m{`hc^Vp1gj-*#GUbw+QeHqYpJgqe&IdA(^i?g0qH%b0oz)3ax_{ zVP8f)j+E77XYn#LXD`O8^w}60k%C?%c?6u&CvB=ja6(C54GOB-C>dFS@4mT@l*Cwu zP$HveshphxephMHsfMOE55DTf~#4pai_Em zr?cvDf7)TJ>QjwAYG$mR1#IfsErrdx4^@2c-p#0eXuShurYN)wM3|}(3kPQdMVxG& ziERtY_;ZD$=U~Bd+#R(^it*;w;cP}7F6V8)SECN%cyR~M8?{kULYBV+do+_>W%&Bw zVsy;OWMUFpVxhAYt_54*fd|2Idl^po>0wo106$AFvgPs|hM>eT6LH!>oHQXmdwOgc z77d!n`N?|3Ok#Svo}3)VF?Uz5Ly}7z{Z5-c!;}PzJ|PYbx}OF!wYYDaj|J}bamFQI zbDRsY!{Gtm42?NK-rNWcV^a8gN80|(KNK>&cVKtwYWQe2kw=1asTG~g&nw+(}>f^l9ZhJ zOhw~@d{ZUTxYpQ7=;v5cFjl)7Bfk5LME6zZ@InOVL0NKSixCqKRpP z>FOo3ps%*1v8+i#JJNl0dGw%2lo0iqCSszPk2|zgRiU7$jG*w|JdR#y^1uH21yknD zhq}Dvz8`6+fbIPPurDD9i@i-zZl#Pk1&PUgMfb(t1vpsTfcq2o;KGPnTuoieJ%6v{ zH{)amX}^iPad7f_?pHK5Y8b}F4TFn;CFchV_~=c8PQ?VouHwQ%${e}S`!h8 z`^_6r`47YD%PVo5TG(j*Dt6d3YBdJhMbqEuk-#vAzq%8KSok8E1f)5wH9<`S=Yw2u z&t3%=O~`)t(7^FfBNQu1&Myy<*>$J^9Tk1qj_z%%hKwk0Ci)`R!MHyC08Z0Bi+%mF z=pe3+AO=n&MkYwSF=GLpg*tlBew}EZh;2*C;B6#5TZoAlCOZy8zN{x9C6UOl%svv^ zZq07g4b%O)1zDm(p9r>?=x+;zBIunrds*W><}ZMZaMBTBrI z;HDsDcZoG*)8~&T`Z^e3i(L_p7@;FMlpJ)`aA?pp=S6{Y=#8 z4aWreJ}8&Pl7#DlKzUoXyTp7|qi&d)9$|^C^9d4_B*WTB6XupC_~wVNxC@k6v&c5xd)<~6uJb0@CN+KF!#e2%W{rRb?@$FbKuStyokq@rD?1Wh`HSZ!T^Qr!q< zD9dhJOw38G8q`zDRrO86y$QQ1c)w+mMXcj95j7P?yTFsli-vs=lY?nHamJZ>p7 z&|VK;AE?DJKW(YD)EH5R(2R@X}?$$fB!4 zCjtH%cFd%r{pZ11ZFFx-&Sw>+j$#C4wsSmoRyV;z!=Cn77yWFaP~tKOOT30-qC+ef zXAjgh!I@xR{OE6wFMSD)`wAFtjVvX}ruH;c#dn+M$Oo7;U^{T(lI%r z0N1M8aWSQy1mi|r$=QZ4ChWqFoCOG0wc`D1pEv|z6;TKg z+fSuy6qy<03DQm{)1gLJ3yZXLFj8KgLp9>F2NR=T9p8a-#He2rBp1!!&sDYHWa)aY zjJi?Kimw(PLfgoN+|E=?H56z`ykFe&e2gWI$Jk(zi)6bC#!QOn1ua^yXxgqUr-B%Z z089-n#IlHT94}dqi{p0U=ETqOVCr$)9&?DVha`Y+jM|DLCF@8iSp#L5UA7&(0LZ!;{Z zGzC`!=jZ*2xmK7+Qlm*J4ei=_n4lcXwTd-!7IRGWC4uudBCY4|cZiP^%&f*E%#R^<$Ikp0`For7A75-jLhgdj~TW>O(d^FrORV_`o2_1Q9N1?k3dx4(?*j z`uE>2@bTp{2~W_+9N4-WPTJCl3ZY$u_d0{Ft)7~=5o3&-1Fg^!MjFEWzq$;JFbKo8 zjFtFyI@ws|jX0ID99JtlFu^Sy<#t1HW9mVSbxz~zoeZN$tkomQr!V3}(H zPd4`;jj7L#z zjY9|mE;chli-9tBxEoN_;G_ zFwm0Q&+ZrfokEOp+usylklpzuY5to*?l=?fj^U&T`Fo#(@<|vfK?79 z=%d;L-lop~`nMTYykdQNpNk-gz087cs-1=g^=z!y$iocXA*@9Q#`fhYU~h<#o{7{D zdKIT^3g8JkmRzkLDUc`WMGj_8bQo()>H}ZYB;yF2)}nu#b0~o<5v4r z^mCWG-H#ZWAO(y>j~y`*Tuc;y{Wn(3Ucxqokj$N92jEU!2?|^!rWH0zk)aIDfu=YX zYlIs~HrV8)!rd`k*e2CPnO{HbC?Q5!xEIX>rqa(0=(0qiFF{mqg2Y7BlkJC~(Xa$- zNb)u6mtd?$f9^P;-_5N3JdH`XtV2b=o~(gJ_s_)TCA+YJH1yc0V#M3UAk5sCiyuTs z0;#2_8q5_;kQJVW1h*)zR7&=8!0&r&@#0V&n#Pi_P?8A8NmbG~A|bzmuEn}C9Po=m zg}fz0Z*OfI3@{F0&$k<2X0#`2WE&fyGI|8(+=>n$ZR6J<*=GQUTwI8;2dMgxAaEur zZpskOolF-|QYe_pr&|LF_{okqcWbWH5g{x+4att{sU^df@rihLY%MNtUXFhLF03g7 z9KErrdKH!q9gV8KBM@j} ^6zC{E<|GuyR^?4Eef5E7#WbWwGS%|{$Y&R>cjPb;g zL_Zu2HNy#CbzJe5k~nTS%5c$6hU*@xxa6*m)5O$!`URoCKvqO!`zJRb)21KWlw#0U zKkYz#IrlJTd!{pe2`DTg0V9bfx_k_9F2)JR`t(4JhY6WFlAsmnMpH!*Y8vX0Q&NOH zF|VGQ6q*y+O4Gv9aA7pr%VRg=Zb3UErCXV8JRs~!)_UA7Y{$(>TQPG;B|Gp+WD!_y zSBMZDcc{oI;M9>LJk0##yXR8I8?i}J!~jM=HXNqXqP^F`AayqkGYy0TouP-d^Vk0o z!)7L>Hua>N%`!{G8m%-mspfIvyy%06#1tj4OIrsPI>QX%3QjI4Ys&Id86|%gInJI*pIdE_fXPk)K zVKHhEuivA!W+h9@o zmn5l!F^4Mz{E8q(T0g83UFFMYldXxk^bu{~k1@d+^nPuOkn_e|qf`=9`6yG5Cn7fI z>1(35tQ~38gDvw=K3HlOYNe`$`fM_cF{ zn?REYRZCR0bfbg*WHWv~I~!kgtw6M;j#N^op@6QTLD)qo;dF!^ZUkH6OYZ=5n0qo2 zie_zAJXcl+$?E>dvFXcIIikwNihk!LQ>DMtB`q%Cwk9VW2x3ap3dKs-T+DYMp`jnj zxyS;6e0{bvAusFXMqWuc2oHRj1S7@q!6L8M*0)26|A5&De$_| z34XT(JK%7X8_vdBVLO>08QsFkhSnAA)dN){%W?7265oY=)V{Zm2mCB8HSiKc@t2g4-gbrL8+kx#lOA)T(#sYM<(qOEzEu{CEun*?( zs?@;rS_|;8!@H>J{@a z*Eo|NPz}TF%<%o5rFgn$8ZIqP!vIrxCIWGw0|pMpFF*f*ciof4L_qua$zvq>Xfebv z=T;Wu@rFu#S2GBYTZZDBHSu_~wH)7fRG}u(0}0)8Uj!q>hBQsa|RyJ!h+U%Q0ge*a!n1xw9)MI*Yur9Q-0FP%hcVn1fgPsQ9^vudEg zU&YUbx440X*M$&6T=Z7PRcA$f;cS9qULO417QzPB^}%S1{#fFig-lrh5up_Vl|;sq zHV>RK@2)fLMd%?;tp_Lli%`OFSuad+$RuL1qczH7hK4DwMg-w(IN7mL8e~pbVy(9- zYw}N7R}<5Q;K_xJn32+h&xi}_iBVUqT#kxSr5Ku+h@#Xyj47(ZvXyJ_<&WRt)$3J!H6%L}%`qXRWKx~dX-s$y)5aOh|v$<&XYN93ievL@`=eP(HvN|@`RfzD79>tQj`%cM3`fL zm<^`6X#X=pBRw_@=Pw?^)9yjcAK(AY%4S_dGYqu#dEG0^QgLbhEW}#K{;A&;HM?Uau#8o;J~&KH1;B&}u*m%`lB;+&VhAarK(WC4TntEf=&4XR%1& z5mAl9L*vltX^tH|%u#Qpjp_DA{8^!X-pBqUhCO=psEwVR_J;vvBeWWpqm%5pt-?4~ z%0#(V0!eLSBt^z^hSQr@QtFk+`|WAxO25;;ApaqD+^)7{S(#}PwwJ9gN%#x+t znv4WAW%Ndjg5({wms5wDf(qs>UdHzlV_QTa@Qc5mBRnDi=GroJOp3>g1Jg*eR^sL6 zN<7&zk~D2Oergb*l%#1cUB?}j@m-J}ZbqA=2H9r8Ri4cpr{T*@%jebcE?RAl%p$16*U_rX<2m^4K(I8dg*dW=7LhlWfl6 zi3vD$=m;MF`X@fT``DfLC7AOa$M(d;x=(XSPMtY~wQHBsd!qOr#RCJ-x-bue{4~+m zMhU$wG?>7JRIj9GzZ7eSBMvfL_Ef^%U|Y1gn6pH-p=SxBy)PqMd!|(~Ar>JZZ85<$ z8y*T)Ojv^~dl0lWAatOQ3g;vg+V!KqapthW5Ys5Od!sbYopcTGm1m9o@SjRg7R2{XG#HGcf3&_M(*o|2jL;+^Ex?;GI- z6FJeH(i1-&ZNS*;x^&QW7e$UQRp%{Yw{23Vt4S00rI6T-rAEO4la4M=WS494S3+qh2=yl`=84T@RDS&-kYq;q#9lm~nUSImm*!Oj$G_u;FB#dwz!a zBE}h8A{^mHT6e^t{%!ve!-`jM51$jRqGP*BDVk)3tS#Hji?P5hle0BMarfnG=LLD< zDH+y()7M!OCi1w4WEFp`)=9?}Wl;}XK=02$vqnCqD)l94r}K|@P)OAb^8f^@Si#Of zAE(b9=IV}T!gi$%T{~wUOTCI@Z~XcBbo{cV9DB#dV|ITROpbTM%1nPeXvoBi%|&>; zDit5vN8$0tvADE)B*#0&{pXR^y&bBFV`T3hh_c3Tl4b_1t<*VKZBJi^*oUAYZyqiz z+>VDU58&p!ZMZ&bFH$XH84i{W4#!t}=i$i84CFynZq8t3v zcP}{+{`rTu+~W1y@4rSxK_RU4jXBj)FhW6JfBbrOBYr+xk6%tK!cW`B;LEPD@HCL@ zDnX!YdRgL5eUk=f>puH2t>H<<4(fSNASuP1HY)XmfojLR~+k6nJ z6(WdXb?AN8SnXYmVx1_4$(r3=Aw;-liKi(pM>&$6sEph03b++!h8ZT(a4gYJD%jD6 zwbH~`OFTJVhwMmSX0~9{9&8)O`A6dJrE8KJc}1e?g~Yqh=pWIE`d`01Kxl|FYw881 zgYe7A2J~}Q;No^YhSExi)a-#t*1`nI!6f-Uq^ZO-JC*LdX<}S8eH54lVQ$ZK?8#bz zI}-_#7B=BwzGy1mfODm-*ju%lnOr#OcGBlv_ff~SFoLK(4W(Ro6&WTCa^rOg#&fl` z!kJTNxfQR}8A6(?v#q_AJ<9?)1(H^NxP3l;+CLBNGn3(>DlvUubq~xj%EEk=9L&;A z$1<}#tkuh7T3=(AM-bncZS!p*is-o%iX7A50jQ$C(8 z8H~T0i}BaKg~*9;V2HHNktAB663+LgLo}A8b%c=ZGiW~70Zq~q6<_1H4M0RH+Card+^K|xw7Zr->?&;L;> zUZ!i)rcLm6a^tw3zo83UbR9{%svS8tsu4 zqLtlIX%tVyY{hk_+%8r5Qz5m~5BPL|DJ})s;6SJcCrq$5GEl^!=0!|kQ3Nr+-@gW# zVSfC(_TqUc_87=vIcHrfj7rPL*EjF7mVNp{>O=kF?~mL>{^v*Ez}d=_J?v-KjlqqL zli@*vNnc6E3HDsVM$mYYZZhi4icn`$ggouubhhTi&>Bb$Ov1I9d+@Mo53c8knY9~m zKdl)L(p$Js*1u*SLb62w+k!Rr1~^X;_-3F1c6;mco(Yfq!RdqX=Ye_HGCdtZrV5O3 z91Klx@8*5huCHHzGGE>yz{?FXC26`{MSpkva&QrTB-3sCtf5Tv0=X>L&P9j%I5cP! zW35UyT2!*IRwskIDB6oYVUa_)3E?N?Azo+6th3gZLnPh%Y@|8v5FOtTJ*MdEg-~rw zGL{Bvb?)x$^&d0rxpU{#%(aZ+PlulC(2t9F9lPzUB!7~CbdZ_^GmahJ!w>c5ja0}! zy>ucEz7;XUdW&L)(IRKEL1_ePm4~60BvX@dAv$zRvBo@~2TzI4g9~QO!Fy3#`SdZD zZJj%DhK0h&cnAD;Y$a+c1~Z|Gbiq0o19WHa@nD#NV}9c-b`_OGqP& zXU#F94GA~I1wS>^`Wi5^_g6B-=abgs^1`jSwR9J*&)tgpjOp+(bSGh>$IatJnVNt$ z5!N2)VQR&aS->SBKuQz6ad-DJ5+F;_SQf`+a;DvOsi&C*8duh#qppo4rViUP(;_l) zWzjYavyURe)nG57&^iu^QUG7rE@5_>m|mF%M+|?cWZL+YWqyws;fq*p%U+Zgr66CaXAY~;N$ln zaB#;?$OP;sfoVkRo{<%b-}X+x(?c^cBRPnX;TTyo)~gqzSv3#qFc#q)&WBI&hd8p%Nm_F{g%5c}46iqLAoQbeQGX2iiT;tFG zm{~u)k`fYHM5VmYB%&l~sFw^IXFB2bt|4fc>c{OzfBEPsoYky& zZq8VPWHg$Tps8XxqMm^kV&G%1mONne9Lo|<=g=-Tx;!1Tp_Lrdmaawm;j*M&D4sB(bU7<-l0SwPB>w!j2mIr*cIh~R3*vQ?{BID zS0za!35IPMn}%1%=3vv902Us}y?qemY>6m+OWYl`4tH`JaDLPVoSnTLvj&yHSKAV% za%$YTPOQO7T^Id=BT$-=k8RCckvC)*j77##YABwbZovQtB^H7vMy3SOMMG|FI$Mz{ zs)Su^)SY%aDAK) z(!^3)pAbZ8dPEZ&rxINh;$34AepxyUAGS@w>4in;p(gG1(k1iRll$t$OKGY)!PoGx zC=w*{uu{`tfjTza3}3cQ#k`?$WOgWGv@8@G^o!9T8-ZrUG^{6xT&x_%XIe6%SilQO zyFPi&X}b;U>R6Z$7n3N0^>N!*6%UAEZ@Ej|L>hghi3J%6(f{iMpwFB+qa_v=OmOgO zeSiGW=7S&GZ1Aww6hE|tpfW^qBCKA%nBd@ZJbUwq6P~wqZKj`Vqqocp3)R!HLA?a) zm9l7&Y1pDsg3U@L*eJ_Kqgg4uNISS%IpF7Se&dCHeExxxH0If2(48P!_~zkGa;k7C#t zLE|l(cR){38{t|Ggl=p7Gv9+P@o2;V3t3^!2cB#(}cj`06wh83@b z$jHss3Zjv>4Ss5K!~@Y=b%_j*Yt34uwL*SFL`irNoF~1zHoU5 zW3@Zt3rOLG_qlvk}Z{qTDM}%am>O5#|)G^r6R?qKjN*! z;G=H`8%zV6ual~po z7~O>%m+r-u-05`2QpMGF zA0u4w)xr%zA+?rLSZ~504?HGj{j*^Rp4O$}Nlh|PmxK@X1Ms3L34d%KLlEDT9ZZdD z*W&MYZ>5~ycdzi{k3Yjk-HZgHJtn!NkO>w-LeL8$^KYz1AFR_&L9Hwi8}&*tS2vXu zfdiXRU2R=bUc$RKJPY~Fi|2?A3S=6I&{V>nPzPM|)x>pAIo$Fhl;fj^t-Wk{uN@to zuKu?$>!+8Ig6yRaG3D{q?)a+R0N>Wh@ZCHap0v25b+j4m$Y2g~(8YK6AMitqe1~U` zo*=eo2*+#_lmfBTI0toV*=SVG=Dx05M1{UVA@_OmbPvQ|gdpB?5%CM2Adpdz$_IUF zO+F6I8!pY7(I%U;uM2Jxr1;KT1sB3B&{tIohy2)*g{Rv}IlwP$zoY&-xJ5S2@kmFM zsK~g%b_2oTtJAk*u6G_%w1TiSW)yBr+l>ST(ThhH9tx!4RNXLG-IIRb3&Zq+kZ2Og z?QNp;0}yHGjQ~SO*b)pCX?6@{#9)(|J7 z^fBMvh@rHmqEzE6_ILk^skpge8EdEnBL0(gl{nHiAC*~&3?YRU+&Oe69^|#)tHRB= zk=~A**#uKFH{#N;^*EopmP_G|Pi;YpkK|!Dr)SUVYmJu4nV6s37sG?B5l)Cli`S=( zRoM%1XX!CqAK#8_W2w+R)UGFvRyE`2MaNKT6+_G^+ToaCM`mO-oib@rq(Tl|HWbHpH18@|+@Bs4MOJnl) zI1wnjyPNSS;D33F-ZurcNpk<61YTOOEc6p4C8h-2?jc40N z<4I=~ZZ1s6ttFZGqoWkhHss;2h7owyQHGO?in_Z{(tQq}z}vsy;N=G?cD{7{9G<&W zsW|{G#H^j9T(%K1Y?Kk*8W&)SP6E+_6?93Ej42((vG$j*o=C1?qJ1%_TQrmJZ|aYO z(>gHHXCP;)g|MJi!MTCnnC))N^qd?O*7)Dbte;+K10q(7174V6fbY5@ad)LA?ky(< zu2sbkUEZkfBW08LIO-90zbbVNr04(kr{Cb)qZf}o2qc?ilulo)B&OYTs^0L^#m;aGw)cjsIO14UD-PzY#>K)8+{@X9^Mjjkxo`un%-VvSka&iu z;(q?!gr6x0fCx-zsOh9B7F%jyp|>*z>1)BNJ6T*+WML7yxUp?56HKC<5pGZH!0qxa zIG5f+#JvgkrtiYm;^m0e>&g9>M2e!iOcQp-F7S5m#jvTYk0ZX=G#+2Ij>OA@bMfN9 z0(`%H2__7WgL!wZv93&Fq|zQv_&h$4op1L7jM<5_HO7^5ZH0zC7;B1)e#Fe)dbmhG zukYn3C8#LLA;e6Xnf}uttgcxFSXnN4F>6N-z|RMp5Me6E4nGZI*nmJU4#616=^@XMF!Uec8cOMefL+N=$YqT|MR^hxkF>3%`@1KNoOACK3StUZ_n&*3HMJhJpzYY}eMk3}y% zNno{fNF6$VfAxsl>TX)s&TVh<^!suGP_tYbS~N4U#w-IlYNEhiv>r0Suh3m}M5WOlKa3<`4h3FzcsRh_mTM zanS3^oblb(2;8gJ!-E>KCu`L3b5|%P#&=Kgrj7V)_g0oR!eRF2?{`QaHjLndn5&|V z5%R&9PWXShdl{09z4$$CHT7JT^FicY(z|~B@dplZc<9Kmduj%-b1oh?S7UO57XmEh z;7nS^n+~q6svjP8O~H%yGW<|SOl={@40_DZ7`K8=&=F+Fp^*YzLI#s}<6LPwPnEkh zbR)hi*^jG4aKp7+83qc+)I=+FY>RZo?qFM-jdsMv5K~+Zr7O-JpT)V8WVG&%@yYSX z385_}mJY{>4a=D@#@dG9_UKj|O<#knW47{)(?XX45N&si6!hTl<%f+OoABhfC%oQ~ z6_w1en`UI;+2>1eu_hf`Dgv>&G!)B{dm_!tlJ`eI(oZ(C5LhCwb{rv)RTfI9^)Nt@ zg)(cNVhduz{;t?eFuBpq5YgsCa@{Kzip<|6ddm4vTY z`v4uOYDcW`%#?n3vT+n1v`s{ui)fZ0!=l>NcuB1K+si+=3*?^7J9uz&s%0EjI2B@% z?l4T$=}&v^#vw~fB_p)dHZy&T&J`RQBIP`J$?@&?b2Z#k~{zm;Ld%R^7|JE3XkE)^a>sor=G=R^!k1QTSye{eSla{JFUbFT1MnY+WvXZ7fGW zTPb#V)Yk~tg3YixSQ>s*X&Qp>r+<#K=}kCK_SS=}PTVi=M5>_=OW{%U%!kO{yB%(h z8$RmXi0zcCBF?)h<7$L8c0}0|Oq04ah@9hoI$<2T5_{3Ld;)ehPG`+E+94D-#j+joy*P8jKo^~qlrOYT{K)!8g#^?YWS~}MFg6-wVU=7W)@h7Djg@GI zZbFQyMCM5Yx{6mJHM&3dloHP(vX#b@fIc2!gR}nnI3H?`1HGLw!$pTp7aWd zeKsC#pN(nJ=B&-iNvmEN;DpmL#$>ZAu%JyMW%AwD8MxUo8p$F0Y`?E;ZQ_>oe?EW2 z@K($z)+HekV;X=$$3(=)dy>G>ApxR-h?YMD8D4_DjKK%`s=S4F))RbJt9?I zacEQ>5AZ&j-GHlU8*!zm3nyo6L_^hFgxPzEb9g&X@ zGMrk_1248k;Fon)xHwN054S{MWwkweIZK|w#6H3J{`&`b^7m7cV(;(|Z#nU%pM(0O%UafC$U>ng)TZZkG{eaFf_;YCj(3pZ(^(lC? zdN6*k8;qYRSJMBrD0%&|B?pAT=Wc?i$aIiJ#q+qs+YWyKcM z1r@Ml9-*a(J^p66?yZV1J!H5?&wkZK4%dUF^u0!RU8E>|stY5sO=TFUDl%jhInJNv z$?A7&QgMk`c`sWdp3kaJ8u>)~OteoK$_!mQY9M~tx0o~=+5KWFdhTF;f3$5+oL{~J z{_+m6*LB8~OZTN1Ik(z=k01a1340IkLfOb{XwtsSEJ?y|pVi>l!aR8EN^AObSrQ6~ zGw{T8r*y2eB0JEm5Y2koSg$?|9Y&dGHO;|7(_}IyOc0@Jj|F{3v9=XL%f(C=26X>H z)>=3m=Yh*UI=Jqsf&H%P$XAgxXb%!#Q-^utQPUW_Y^%nlnsUTxN=YF*NzjV)ze{u- z>u-TlW9baHPD{r(`{rVhp9VV*_kI33Yu2YP9&-}=HiF1P!`jK2avG+&oCyXejzDvJ z$3OYu@7}&3H24bFFJD2JR{%E?NO6e7$+05TwE+jym*aeCGwzJpiSy&SP!*ZMdE7d3 zT2B@(Tp03ygjxUZujGEAEy5=8F_dA_U}KzG>WN==gyQS1LAbN6KM_VA;{A153VXO% zNyhn#&X|Yu@FIA4Qp#Tt?${JS9nbZ!J{Wn5fl)`Gh2I*fVi`2 zB0hGO;jd+}cwIXje>Y|V8`AKuArWXw!##KC7R_L{=G@K(IZVlP&CY&2i+wXWaivv|Sgl>&5#Q`1-5+us1e^ zkAV$Fhm7EC9Vfah*|t-GpQRy&_VK{-sVO+wG8LQWmEh6A zTHaeX`g;#kHS|={LTAYw+@3=MZBR95@5BVg;D>*G%au4UU;W9K5Ip;~cd*$qIyn%} zkFLOkKGqD~mF1M^dE~n*UFhDb3f$&KWMqZQJTX)~966fd$WZn}vZ@z?dD6WRrt}?! zJnw-#TgQp6Ndq$w?ILBZt#h#?0c?*uK{lA9AbHBGVy$pt>2SQ+F&d9n3vaovg< zhPL`7Y}H73Z0+2S7a#tX2FDPieth)=A3wgtuC1N$w6NnAuj743;KJx;Tq3$Unz0D? z#%#j9$y?E!HUpvBPTUTuhok4Y0|yRh{~u@8Pp{g=i~CsVYkm}xRK#O*d(lQE5uBp0 z{j5kr5+Rw%OSaRtT|2qu<6ke{@cfddb@g!6Ga&-iLWWZ;&kc?D4Z-g}eUF##UT`wK zVBY&TzJ-^aFE?n5FjU32ZKLphTN$3N&Bn{xbUd#eNDP|hA6zsB^;3(a3FBH)vvoIXd)&W$iwWQ@N#ZB3 zUg57duUX6H=jO3TdRAfu9xnbIo0I0FK7JC`kC=`zfyoHeG-g5h$6rfDU3e6kDWBplSc?c{O6gK%$VC(h-q!IiOXDDg>R;Zu;3!L52k7lk*( zxS}=Cw_o2wFHak|lUDs@%QSS2?$4biWbzt3xlhnVkclcnb!Gn)mP?~h$&}j`e=e*q`j)ayX&Cnid$_^jlEk8Q93g?^VGRi0&nk-tU@JN`~ zAD{F3=8d1iy}berJxS>3p_f}Qet%5D>iuiHdo2c+zs96VqoJvyz|O$pn8CQVa2sw- z>%^t%M%`6m25 zeb`yjlceJI8HsqjVFKQDR^wHB0e-6|Dce#S zwqaAb^S$V+(~vtCtA~u^=MiEkwn@; zlQoDS#8WM^5JQ?=K|u=j1crv-#S4k3xs>PKf0dywNeaD=;&5md4`Qo~1~meGqo>j8uR8d7%ySO8QHXxx0*RaA*%KsLEl&6YzDz&?$H* zT8d__!;Rt=oEzJMp_aj1#4x6~93S4iWoZ2SlP4^EimD2k(Z5+g8vkk-%R)vJgKNm7 zRz49rDp(cgkHay(*y?VCIi`w8lat!txX7fzUjABM*gv`*x2NyNwJ{s9ZNOA~Hhdn= zm(}6sv>h1VbEq`cPg51wh#^mr?J1Cva3t*=+ZP{pP9U==4bO=lW+XcEeW$o+VPBjZ zF2`8mNUS}E=*sh1W!k9YkKOCAwz`0yd)b^>d@v#`^Fg#cCFGYJ(U*jT5h{Bmqo2AD z=Y;nU>cgd^;%^`Q`5W{Nv^nQklv?V_OM4ft?~K_)$}q$^igU@$WTr1h#13k^a^;HB z|1^*Ozg~kvLx1Y2Zj1$k%FviL6W41FV`NAU55?WFd6!f>`}R4WKK>np!{T_Nnh5c< z=$4^Lxflzy(#Vc6=f1j^E=qaDFNEadQ3quEKK>PHDFb*;tkBxSUDU9-A|7|v7USCu zWZQne1mmNv*hZ=8X@~3nRt$?rXi9cVL)=Idn#VE3( z)LdH0tHD7|596XUQRJ0KKT}7lb|BX2ixGoqJfONlEuIcUk%`=!?8(W)1GqzjNTg6B z8+!Y$PJD6y8tz>`i;E`?;TWNdy19!nvA7a3k-d4a)6B3!d^zPa92s7R+XY>?ozaRb zDRsD*Q;%x|r4|mJBtbHI9$!}*799KLR^SE+2U{Uzh=GSh+TrZx$@uobT-<4#fHYSf zSQ4tq?A;U3_bX zEx0nG30JdPadl)nj#f3GkD(VA&{yP?;n`nO1Ma6{L`z2l3<##T=Y-?WuKBQ16;m6? zj4*M8yPOUSLyismJK;*GEtd=)iZ(~Bj|s-u>a%CthdV_mVZL7`?u_4xniPQ?b^ zi%Yo;xH!545h^aM2x>^XUQTevbO&vABK4*7{i-!I3C$CS?-5m2BQnAn} z12Hm3POO^tb?Yli3`Blw$0VKSk#td%sdVB&)G|7o85|9ypc zMqc9irzvxBd&VwYo!o`pqu27BQV%Onb~K3s=fB>(#JY9sIVLM+udXuAK)q@<*2yxl zO}iY^`(l%JJ~|ZgvBGRLLFEWyR&8jLge?hjM2538KuT9m_K)4B-wkQC zy9=N{^*q*)lQM?dhR($O%5AuiQO`}sMSbV>l2%-w*p9Ki2C+tSva!R#eLK<7u$tlJ zq>L0K2S@|4Q=@xfdPORVGeeLZ>mrTO=>FX0qjK@$n}`n&=TRR%x(;Z`Uxb?#TX8L|1DDe~ajRq(PUqA2W47S*=r#<{^x=kX z1H%U3`o+84t>L>Lzl4viCUV_1@XM~1@UhclcP)WYvw^YClKNWAJCiCasPQ0Oj0n4A<-7Y?XWvT5(HDZ{(twU{x&kLjm; zR3V;_q4vl7r`*a#%uc)SW)+M4{-@vJZ0SM=L(s@zAUce4u}UQkwQAXD(a*(dyKMB+@gkyAV$MC75mAEqaTT~-u?_dLJ2}1XVp=n&k=t;0)LvXD*nr!Uc4AprF)^$L zGL(F=+8`5a3<{B_m_+wHf2E+x2#u{ndC5<%RP0Q`u-iK1rrxsVDc6=(g16E~6V0!*wteKvSEz|O_abgzwSg4aFmZcbH zA?}v##062Vm`lQ$wi!1jZO82X>CDg6udgp|-o4HxZ|)9O{ERk=TCkK+=$#QOeSe~g zHIWzPexl<@4vuQF*t@C(v3)gQ*4vrlBBzP*fw8zSe>d_-Da0A__qT50#-$5T5tUqq z&gd#%%f{+TW;;&Dx8QQ-Hk?cEz$v=7D@E&WA)2#QY!8zV+j8kQ^`=7|?O7vPr- zv3TB@iKqK#R*zu-~Wca zh80hqBCzwX$~96>EmSZPrEyQ-DHhp)!qm& zm1f8r)~y`&x%KmZyxNbB^Q}l~} z$N>I@*B@STwocH<{PgW_IK2A^8dj`j&nC{~_V}ovCqfsi-PL>NhRS1VPyw!#ZO6IP zEx1o#bXdkNqaI3zt%xa6Z2cTa&6WLd_2&%>ytut_XdV%^1Fi%DB?? zoayhTWJ(Vd;#ShufvQ$vD*G1PSE#Qx4;c)Oxtd+M|!1FD{&yTJk#&zk#A4fs@tY zaf=r8Jfn#~p;2Uv?WGqtF zjuS`q&WboY*aY1nrtEda&mCHjjwjnn@vwRbeyAOXC!Ga&(_Ms*2j}2c`wSF~aOI4; zsGmN6`joV==hbWO))6qbqNI`$Sc*!2)M{s8izJ0nm6!#)KxYgyc$le};PiznphyjW z{rn@$#rz&E39c@&#!njz@l&%SjxBeG8^LlLQ^nU}eCy}d(|=!%MpnOht68HxcNufE zo=K_0^+{b=7hB1RlG!sRN=LK5e2uq%y+V+MFL_rZOf?*ZX3Z3|s3l>RYBX)8&cEX} z%z8b?r?W&IJzK1A=;lUX;ay*n!ajTdj_Z|QKKsaLM5Rd?Y-J}|s?jD|V0VBzq75Q<;s~%QK^&RI1;V-OR;0Za?Bo?0)KNWX>Dw80ll?Q7I91>FQo?+eZ*oz`%-MT zZ)qVmO-<&wZnj%2?oZxFFx#*!JI2LUg z3sILa6(=We!OgPWxL@)GzMrul8-`c%u|du98Wuuvwy4HyD9f`~cNDG1xAgt1;~H>_ zJZQO>l%ML%nZvZAubAbdcJ(S!G)0E%<9)~ASjk3QD{sShv%bL1Nn1ItzEs&v2Dugo zau=a6Y&6W2HUF)?5_@)W>vGi3O66;7Fd3XKhLIs&YoCXF?Fdp>1y))Ck9WIU;p;#< zeBI9&$3?eOUnP7M>B#v8K{S6nYanXn`6;GNkgj)1K{y1$9&L!64Tt+i)%-D-~vw;*l z>EiT>BLEYDzr}YCex$fT7m<=aSY@1pdWu_{wDS=qapbbI#^T|)(pZf8!U0HfS4CgN zPvvw9kdSA|E6Al-_*WL>HxxVxc8d2Dca)Zu6HJsagTk>$S8NNn#VC1c%qS8m{jB_u zJ0KB7fn%{^Tq)KjRH7+;E_Uax#?kScaC&MpuFfToJC)$q^sP8Hz78=4LG-)Ht6KQu zZuMbYo7{!VQ%GQE?!@&a2XJ}8P8^%I8J!cBA}M4b_rQvZB}GLE^YZHcZ}H@(0s;X` z2Yc({zsp_GpL+Uf-d4lkK-iUAYT&Kbx0!Bg%GrV;+5s?C)yKnc@3K)7O5~<$f%4!KbfqrgTGq>nqQ$S3 z+x`{}E@p-5-qyuqQJ+1L^5&k|e-sw_CUmcguw}9_9rTqmL7289qKsTIK-cPDLUr@r zKMiF6SMkTjNh#R2viM(PD~yN@8H_Z&0a$30iX7z-KFayThdkNV2%G(Eu`ARGJHs7N zKa>o*iXaX!z{!a%*b~1DC2m8}nX?dIk8j7(F*Q7XWpPk88|ZjFWqd)N`ee8ja`mKV ztV>6D;YQSW??;!l=$6wepe}AuspMR`}1ee$Q;ZdV0?yOP6 zgGL{Wah4XjT)cQu?{n*`L|abfWw4$zzOHDYIHLhq61L!SPB#waZ(%0%n9$*P@tlNC zoLiBXU9@l+ZKMv;<-*ZyT#h6;XMkj7m?7*e?dfcQ~^m0lwZcW&O=9DFL-x?SE+{mA)T(UsiPIL z%F^fQqb&nhih=!fHQ}$S0(U|!ZiaFg9%6&Jh0$0(Ar6x>h9cV68vZ(@uoKg6yCcpqRw`-Wdsfs)N-cQn(NQi zurqE6t``z2D(u3cf(C>d`?1leFqXsqC?{+RwnId3;!2=2F)d!5jERGT6Y`5D;3rZr zaB2T*Jbw8nb6*Q(J%0EEYz?fqQYpo1AXd0#qDCtjtumqoR7$karIL#V$rx-fNk%_8 zdp={nb?pW|e0+l!FaAJ!d^j7gomGDLezP6!t&repnu&i<~zAHS42bD)qJGzSFfY}pf5N!R3w=bUXS!BNeL13+oIr<4`P|QM` zd;vDoLd;MfO&g`cN>vfC9@UUS9{@$?$FOD_h;OczD2OGmoR@$wirKEsW%a&qH z^jH?EI7=mT4t2uSNDG2kI_NZ&cGpa$_d;C><{C?|*i3>&q%6xxsAiJ2og^}Z5@}Pn zNcoExNQ}r36;XY9m0VvUrFwCY7;@ZdAraiM`doFTBT?qkHIZ!=%!~a=zy17QrulsTSQ=hTURcF*W)@}j z!7sa~HP z?8J`5V$%z2_9fjxePtp*Mabwh0*Jw93y)757c z7vexyyJ-KyhY!!l2)@MYcTZViUy0Ef^ti{5or0~EE63s^O#+Z@I|yS9f-&AW8f#V3 z&?TRZcDY1;w-6#+uako~jc{g0+}pjK>(|8fc5dIq3COAh3;bt`GyYp6!5?cSxV_dI z{cTB}%nbg&54rmP^X1}beO(A#QJ;R8={XonJjbCUat1C_jF{vy1g7L!4(>g~F#nC{ zZ+-igp_UT~{|fySv@7LdGc7=aQaaDZEH$L~MqZC$q$qMowAI9fKzmFKwMTu$2y`#W zN7}$3n8-=FfW-Ni7)fcNq>3CT1I)Bjz*cB#j z`Q~8i$ccz_=+A_4qVmU`1T0k69chMxF~w#K*19KSItgQx#0Gu@;f41WTuHWC%IskU zo1~cj-P2Tw(`&QgKtdI)Z-ZlV+L--NK<3~7d?dsQe=x-e@YgSYAaz_K{Z3UBI>qAl z%)>a9x`masM`V>NJ5UiC$7O&AcOT^8WI}0g-Mt4H@@)N0eQ>d?8@E!(Gl}F8{oKWj zR@|7i59I;zTvE5Udno;&@Sso4(;`lgU!G((t#_M~bX zPS0w==}DV#wwRu$v>Ojg_uy{vPMj@hMydT6@|dQ`?-!4gb6c?@ERUdX5Hbt{c-WcX zv)1YT-LnY^9FKBDoSAgA%Dr=!ICp}N&++`lFBGaip|ufJXK%^7eneMCCoGLk$&ktr zno=XgB+DM&g3*}@8FOzwxoDD)#a87sj%7Ef6`(|KEIXbhGpq3C{WH!1oH=&{CWJ=D z_{iYr7H|A_jRZfhl;GKRPvj3$g+A@|>C>lmKAXZ?t0{7(?o+9kfSMvM>u+oY9XUDJ z*jVB3r%yg-3;}((n)wMRTX*2DAHzW8t``oG_vpYjDDiKMMo8Z3NlR4Hi$gzIC}~5?Uhh& zua0s%ElhRQ$8=XMEb%r#Ykx-^kMzXXA$B-3&;jd)yYa?FYnb8MqHXwY^(pksqqueP zZiLI&A%Ng#o>ma5^u}SmO%Ybx5(I97RdvLKAhY4{#$7EeCTYQ`nNn z757;lVS>NU)F3%fIv6V>bPO3P9gK_~PRLYD?0(N@*6X%xgoCR+c}h7xlZ`U;#*vB! zTrHBaSKLZnk8diQk?a-$Q)PXeI&zBV9ld(}mZ4g4VG6I?yvTe!m`h$Ze>1KnZ@{_4 zM)XYBfjxO^2$HJ7#mbrmk25gzPECpDpZmRgF2(9eyrx=`|JBR-X|2WEx%a7Vt*UAn)D+cw6LZqu>NHC^tR3Tv^+iz_WT-@8mNLo|!ceb49#%1f z985ME)ruG)3eTT8A{H;-JSC^}7JvTpUkr*2fTgMgH#RupmyNP`utb92+HA2d*NP3= zy6VMQpG8?W*VXxm)~u;kW;iq=6g2_HnB}QKFi@5UE(?X~8`6iXNB(;Dgdy6ahd=$)cr5O^kzqsyqwVr>W*<5^1*BrFXN%Mt>UO zEDq~M)Avku39gX>_xKxOhO;sY!a|>sxIUu`krEF~^iD>1<|5ieRT2&z%yWyw0;2>} zDh$Ioi7UlnQszP-JPBH~Ie}K>!M(7+RD%_GsCj=x=z1|+bECDpwPz_dPDx{9BfO`& zj23R*{07fny~Niyt|M$<2o%UFYsiU$eLoDdH)F*p=`#%XXOl3GTZIQXn{jt?JA$+v z;A-KBNB6#!5+1w~(DprU^qgSUdMi@)a_^D2Sg`@$&Dx4n84Wm*MUc9(6Dj5c2oB1l zVN)&V8Q%Q;JBEh(!&O6qzjiK1Yknl(ql&2DQk8Nui6m2~kuBo%e37gXfKf_beB2RA zUelGJs~r!Hwm_H7}I8)SwOL=XitQ&B* zqzh-qQhc7$jyqEi@loLfw`huc6?tuk(0xp`l*bBZO)Paa#1ao`Jc`?9W?|3uVoGoFL8u zuZixONxN}%$w72ZSqWbQGY;ZKJUC+bXx@Z3Z=?+Ff)D!Jhd;p6-WdI@6mVr#As*G_ zpl8uo94re$N0Ku($J$~`q9bZXTcT=^E-FKfSkc6^xXVtOcoblYIX22%=el`V8I}zk zPjF6;8>y#;B_h$npS+?HCn%igo~=nh&AE_WI^VRruMxhY^*A)ZfI3{S z$S@j29$1A9NJT; zCEW4S8as=RaxTR;;&MqFf(@L|*VT;__5m~S3peuWm*8^Qrwsj8v(>epUyB47|$di;(0aKL1xfO7eBpFRI1=yrfg84e}geuK2 z$i+v>j`I2y(;6*aJcrk2YlRkmtkuEw$50q%*c^V)^uY> zLtSvuMG5CTS$a(pcwWVhn{xbA#cN(Vc;s)uOoAf*Y#dUKb))ByLaD((K^xiR<*zL6K%7e$ymjp}b3N={J%eM~PaMShy=WlF zQV;vrSK-OA4fwXH2wlalI9HR1{i`RlmyObN#NO=Hcvx`&*C+2mfQ}>FY;5tvg9p-9 zO)^{unzl=8h+Qnuyl^}+`nzz}T)^9KRXePSo`^k3iwW{?M|M;^Zc{(`o3kb?;SU(FQ)=Mc`@Kw6(g*q^O1tc>!nKEus|ak8+0kWQOQDsd@eRA=V6hi z$OfB`VjJS?xjV7ICxa?+xcrWab+K zU!km7dh*yEPO?UObJI&5w`iZf3AV%m`g4u3l)9%tBF!?3h5#|Wpv+Ml(ayHCwlXl$ zGlBxio`OWm3~8^eg38zkbWKaenpA(RPW8c>w7%GoF#xq$!!W{7ofD7A5_{BWC!kI# z2`x(5XqGL&I;C99HBRP+{4f{6$Ne`c>l@}D797Vqg06JDImuTb?$?{+L9-*i?TnzX zfRK)<y~2wg8(_iY)>k|faoSZC*F&r^Rat7y_ifvb_k!mY(j>?)zx@hz zSs79UJ#040;|!eWhVUZGdm^t956ADt`LtGCNNvWQ+*aHq*mgd44ZfYa8*K@T5G-fQ z!rI^37JV)4*u&N})N?tRpr(Xq$9wZ9f;~)mB<1amWk5qdUM-8kt4#&mcJ;Ek7|&Y@ z@Y|L&JgOUqCoSo?vUD65I*cY5do5TOcLFuB(nX6EcD83MPR!~?u!$%9wH>e{Wiig@ z)Z>S${kT%qfquG{tgNdn)NsMy0vA2CamrZ{Ux(_U#aCMNE|5rx#22-OX_%xI&3&Ij zF)ipGXT%O*h%6K&m}2bd3C_6OUWuPCG~sB&OjL~>fCxi5R$}qqQ(b~ZS<)(^NMjFt zk+KGN=O4ykQ$INCTj1uk%iJCG;Lcr`D9gZ|jKRfqmH7K;9e&!m0*7a1Vp6axE5aux z3MUzL4Dk(wp_&f7t@|J`JPIzP00-BVp=o|@Zy|^h{MBvYAfv{Lx*?R5)Io=jPy}rB zCvTHyFbd1HGqFXj5M3H1*ajl8WW&cX*GgOPWx^^hMv1Wt!%r)}Lb>s9k`qBJV1xOd zxp*|^C@xRjj<)#u7-!mtuPdlr7n;$&3^c^8KrLMG(!hyOYpnD!AUH0KUq4MMa8_4C zsJkZu>}(NYrYWu27EoSJ3G(uakjN-NR!$k3N}8M$`$XI>&SzBw9Zqk(xA=Sj$)%X_ zvqEDWHmhf%K_MN@3VE!sYn8Jx*))-!OCK@eLpX+g_Dq@}+*r4PjoR!{M!2|q08T9N z#(~9NxY`@EIBx9dNVFwHxuumi$_WNn#wx@)wo+{3}s^P{!TU4k>lMxqBpXJQ( z+cz)plwzZ|q*~g_3S3{h*|r#SWJlBAb&%{i9N*9W66Z#)$JeP%xR~02Gs)}7+O`lR z-i4Ln#mpfrl(mln8G_Xd;AvtET@_WFId_s__lxKMaJ}uXKi_6=mFTU3|1?+P`TAU- zwF2L*EyUKmP;4A&hqE(=;n&t8{JJ?EZ`-qQZT<+p-y{<`Tq8y6@m1ub0l^8CZxF;q z61ygEz@G7I@pWkjt|f2Ax8rwWWuFv|O*3>PxY5rBcOB$$$6XWWJ+*MKpBd8BrI}MF zdd8KyW6Ap@VHGK@==u=nlKP|+f|v#x`>PjV6WIzHXJVxt-<0rKMW#o zzi6B{LG0-`uxb*jGKO<~9mOY^XMoPRfNg*052{IPR1hKM?G!Me}OAh1Y_$_3>%t@JiaI&fe zcUK=k`}j5JoUoo}7;TQ4hKaUA*-#3Dk|O52ddlNUxDGD#k>F~u7WVoXAxlY`e-QGJ z9d3s}D;4ex5^N>^P$=;5hhK2##x?BjZpMb1YPh(#@aPROmsUd0=VkAXqCv?>a28}-uBD3gkIl@ioTGSMQ*N1b*7iVb7vds-;Y$l(mJ zAX^Ylsim!zm7d#5Y0n0e^9ogwCOsY1#PDdz$Iqg$Lq`qmNTl={yD8N5%$c%RBM&%!9aFK;COI z#jaJm(3M|}5jLS*9w-)6c%ruaVfdkInY2hjOBMGX-sF7h^OrBUKXd2q9Z(fKQYoHX zeDP;z6A3W}ug6CTbaCz<+7PwS%WnAd50DC}$zl$s0a@ZDZ z&dt)P$^^qEw&Q$pBQEANa!u{mnH{)X-i-{cK78Qc8f1qXz8bjiKwjNW4n4v4m~5@X z*EFNpG+1JVMy*t|$)up(FpKM@^=PxjG0&8-k@)FI3u+f+BWp|_1X;`c+xqq?d#TNR zrM*={;%s#MX#9R=E!GxhX_ZpC(EllvnqkW6vXe`YYi0rQ5-Wq2%fIV!y z@b;nhI2mS)9YOk>5w~YySE7B=hnRRMvdtuK@^-;&62y0BTl>WO==KMao_=1ewpIay6 z%&IIdkWf{WLrY5=heceK&ozgyQC+hfs!Fn~)S~~_RZAZS%WLsHA(K;ib@(cGJ$5B7 z!Q!AyjMEUabk(?pFha=<%k|^Xq?F0YrX5NZq_A12RnJ1MK@<-H+qj~J5uR{Jf=y&g zQwy(QKQeG*$;m`Wl*#a`VW5l&t%tJ6Rebm?3Y(gqx=IMk7lDSj=c9-ljuIYof5TrJ z(^RF(b>P4OR@OIfUoh2+nCh0Am_RU01Jgvqx@kVe8s0n%cbKFvRs|Ph+o(#c4@pCu znm=>C>T&0Zw2ElXSbsd;U4>IC(xf%JCc3zM?JV=~hzam-C{Ug?cL7s#){YOt%j1i% zBtC$xo!I1TTTM*!G3WYX;Ux}E8He{EWukGQJElN34kdXtDQZ z*WjD74qS=di0{(3AV)9c;-7ca4>qjgj;hKHUtf3D2RCM)gMq5H2c z7>GYk*I-w50soAGXhc_4LR3^gE`uB8ZG<0>G@^5UI&2iBN+pU2Hi8_S;^HD6qtCdzosXOtws{eRbwdJ+20ALy=8I9 zUlCpY<`~**RP|_GqTNUtL&jihMGfMt!?+z!Q&8aOJJGe|8H)e!*?Pg%TV$+(HQvV9 zOGf{^m_F|!hns%JIO1oHWCiIS`jf|MC>hC#p;x4=PwEo!diNw0M%wYc_6zXFhY#=Y z_g}x^<%=hH`sxYxAKV8eIaxSanqW|XBOAFC%|P6pxCb|KT5&tO4UdX;<5ocjZcp8c zjTGDW({v@7&>+L)jv6wyElQ%u}(*y%2+yd|{((@p&L|)%58(!ozNI)WmfkHQaQT;GU}lkNRq$ z!AyGaJZJ7qye4H8JULvnPnK_I_b%Ezb>zr|V}o%a7HGwCme`Fvt!M~v=7G8Dw3%Yg zjXeo~Hp9vsFKs+(ufT5yCSggwH?unES{UKnrHh<_76tOJ-vVP|;$T4nd1lElJlQo7 z0eaG;#U{bB7jA@}AvS1mRcB!tY$(Cw)@k^=X&Oe`Y4h>UHi|(7Eox7Hd(6{T;Gdl} zBp){?@50UG7Tg-$fNx8?uxeBZA2Ccbrt3!e;k>UdUwd7EF<(b0M6_cdkC%v)*wH4Z zp^jqqIaY-P`TEdvSzxebAbERj#M$?OlbR}zvlPl=DN)2og+3^@9!|eQh5lOsRysN? zkTw!2pRn-4nS=cC&zGC9JaGVLag};wx#5;-__=cx&elxgX#_H4+++nSf}#Sm11k4^ z&!rc+i0g{1X^58zij(@GBF-N_?b(2MXG7_vYYtZb~>CVu|*CE}Xp=8T(9U4cu8*h^L)pc(y46Pu7pYleN)!(v*hd z%M+yrQco5)@84vv_tz6?vh&!n^Q0syFr*l_uBr&p4kmODs#r%5{91WCE@m{~VoDQw z^15* zYgbm&-Y8L6I0UsC8K_gu!fNGIc20u{SvgCL-h38??QCiB6%c5mniw`^hm)RiINwJO z_XpWvTZjV-)WFC=c=_%HdDb^vAT3t!uiu~0zv+`T_Qn$ZRMhKbaF1z`RuqQG_8}-? zhiGMAlp2gex$PJ}?(rdyeSc#K{@GTBd)vk%*j7r(p+-V{^vFrhioSRuJ=O^h8URxg z&U=li_@%u7eRQN2{PbW`9_@G4PC_w}CF1qvSgB4-8--W9=V47&lym}`z98+gWa75n zUgjL5Mi{!{Qh5g+WN*VaW9x7ye+ybNW^%$qj0jxoZih`CCYY!ttxFaHyI@!r4$f>O z@2){YtbrMtkyvP)NZ!exl+F&hu5mcMxSQZy7nWvB@b|-b3xH6<_if1evMuzKDM6)s&f<3S4kOO8fLIlG-Za4P>Cbztn*P! zdncZKH0?_dLDd@+SKlNfeV-s~jkh)zFocnjIass;-^|#F1@37WEa!-pl112p41JrB=XittCx zNW5)~!@IiCz@~9{*_?)-yC!f)lsGw9y}p_`u!X`3nfUV1IVdaY@Okv+X({NMoXUIe zKuWtgeh#kB*pBm=O*kG`hjaOzI6+?bdg%@v&aOv@x+guWA(kp9pi30>g3{^OqLPIT6bna_1L|+&`0Zy=Sn+bz zQpOmv*axHgW7lvO)CTHeo|7uFtfef8)(&p?&(FW$)ti@iONuL?v9LlpV{=KU4Uw-I zg$Dg>Y*tLhChc@Im}H~YJQwvAg=jR$!94vKX3k3vaKVdRv+;XN0X9z5=U5{ z_@9QUn_=~kESxW?#ZQY5W6S6&&Y(JzXSAb@w33)$g!UkuDsRTkr8`kFIF^(}nU9U^ zB<4sWg>LkifWh+4d~Lzt-xU>zSVIklkJFT+u)r*pJeDqdMnTFJ8{&?Vk-l)Hdp)yd zB2LoV%ivQ}yF7hvhd>>74h=F)H979~6paElaacjuDvN*5l?ND!;gPC$sJdajfPmBt=8>o!i-txFYVZo(=MwqH4g}N0XadeYEj~rv{eWC}E0~5+;}{BUw}0xFL*R7=5oP(+_Xk zCIB5Jc(o-1@7mJwd}9oruN{Fm8^)3X$Ke^tM^S%EzVG?7=Hm66=Xm>8+F*X|@(qsf zg)v$ht?f^&~9Tk0v9g zk6}K2k9{_U9pLSBNkE`-CmSSb%W-d_SZG1VVL>;iM4Q~Wp^1-m-n@IvqbS9YptE0{ zBM2uN%N==`bEB-NAW1}rLKYgu&}aI4t86;f=q7TJ!4L;?Jl6 zN4ocLq1y&0mfC^Y-#M#JbQ5EC?yYoQQm6^cl?eJZW$duC6hhasRi*A{d$*+cu_ zOv@Y`s3T8fE`_;bl%q54!x*Co4Ak;ruUO}6i)wUWZuu)= zS6>~z|It?caJy^=Zp1co-Sf%(2J9_a&8VS_jLV_^W;hXQh5TNbap`?#fpmgNQOhG8 zaIwCG_I@_rbXVf;{Aiq>5{Y{&6Y;966o1tw08IpqHzwn+_DNVya9-TgqL~Z0rs>)9 zfAId*JM>(-#zh}OnP)~?;_q#6-L8oue1>6GZ5cB`iZ>id%S!5nu)~k-MI@p9SiP6s@6$j8SaoF z4@=HyhS^Xi>??>%UjNw?cFMH!N*&23`W4}w^iUxV(Updx#59R4whiJU6L^f@$M=HP z5tEUjWGG_=^7!`!{5HDI> zSzeGyUSmn^A{JeQJZeNT%f?rF4_CVoEEh?3|)hNwvd5BCrCz?TDEaByS@ z#u`h{Z*3N5N=04tkw8;cTEPpIDkG92^4L|n7F*I6pbxiu=^@!J z3SZCKhWk^u;r93rJesl>r&2cIV%auS51m2Z(dDA|L8d-9T+x90E5GEqw3CKp!(PUK z4UTSaZEcz)1nX=IFvVsxJ+m~%E+Tk)DaaCMgRBv+Ctc%GNf5>USy*8nPqDETXV68q z*^v}_W_}!OG?h7?WrdZ9`LUL$uuFg!K~munyZy}Z#QMD`Jc$op%sFsO3#dOpg z<)Tm{j1)>tayLcWj0T*W*NtJS?wmYhPoq5sD@{|$X!g>$(!0t|2R9>}aotS;H+)DD z`x$dKH&n#~w@SM4Fry0>;~R0IuocHDn-L{v%o+HuVSUgM=EQ{#BPbNvIynZ1%ZH+8 zb_{;sT!cTjRp7UMRXDmj8`*)z%w#FhOgOE@iiAG+qk9q_uZ_dwnpiyBJ{c=g0(tKj z%&y|0R?pu&W6yW<>UBm9qMS0tpP=}*srX?>C6YZAdb_biZ>};T)ErUlH5?lgreI52 z6($EI(3Q5;`mTgM=Yzj*nBB!n-&rQzb?P9RZC6S;$@&-qYy2!c@)@_;>x9w($Z(D>6oMw zO`EUV%VDcR-p&$}?GjOGJe(F&1zGXQcup$&Sj5WW=;--t_&YknieT}!Rpq$UwSswu zgyj~+;G(=uRKp0E+n+xFabpI-taSXdb{t-BpN_&%Cl;fu&~hEP%_? zC!;uMTyJ%bHV+y;l2DEN=}ovXb^~rFHQ{Pv3wp}-V8!66^gRPEXB0C{yYs5CIc5&s zgB=N-4i8E)QP5_kj;5G!qg6f@8^)0$8E||h*cgt4S>cj{3a*DbVw|2dk(Da(#9IAK zRIA0K%5WT)MQV^S5uQc7y|k_2Z|2HMD-wTc1b63HB=8;yuiEXRj;lj#QSKnEl^#l- zeX(u^#aTtzET4l~LOdCY!JO=y7E^*t%eK>+8?#`Gp47>DL$TOCnf^{OA;Wwb_LwWp zRq<7jDYrL%5$Vd;9nbeHSDNVST--b(*w<490g@DDY`+H!=$Ur{t9%(4S zZ(l6N>yApiYs$ydO{sX&U53`OaQG@p4TC^$DJIHnxCERPBnQ|&0e`QdICl3;%Im?;AhP<)Q}Oc1e2S?D@S62CazKQpD_vKRoGWviXMjZT zSgX>0sGwMP0BWprk*_|K`HA}nN8sa=xA^$%6?09C?jOOnI5D%3wysxnlC!6jr=O4j;Zl#5&WAN1|RQ6AkiYttFY*q)~=xT8TVC zJJ8DqzyI{D^jz%C8|HNt$~AA!A`)nI43hQ1YTZ0^sMEs{=HIN8z;SK8VhZZDvap7r z$V{0*n5i%XOEuz9W1NWvI^#(AEfC=7i3h)a#{?%rWoZp@_~0qFw8K12@NoB1+-jMC zvH= zrViLQy#|97ow@G0&?W}olyAk?DGm5Kp%yn&Hlrt_4L$iCxIc3@b{DL|2OMg<@JlHg~rSrm$dzYd+>!Cy*hr)|>#R}y#ETedGw60+DS4FU@J#syVHf!ggQf)9Fz2!v4;>5Bx&SV=(L%v;x?a|asb)j?7-yxg zI}VY;iZk8eDR53Vv>xf&u!{Z1=o{EAZkiDbmLmeENU!_%RM2tRzzEo@t}}@!`vLxK%SzS~;g` zftB_tSV1yXMhGTF;!cLKFLEhFS*1*|t3?`0O`~|yp1!g^&Yi!)T?8MVi2oxO{_#D& z{q83+2wJqC)@Tq+DvE+lB^x`m%CTBMm6YEUUY2$@KdZ8e*Rf;AtVCa^pewC2%tD=V zu5{z&3b0Z;4I@2ql9-sAO?*LeHtqe!fApKNMeDxX`$OMKaLY|u_bjY13> zl~d5JD*9#9(Ir=iPW1wGXyntiQ?W@UonS^55+!~3fO~W6CcGqd{pam-DN)-~Fxj;@ zvdHw;!%tt#!*5?L#sh*)4_hknYa2nS&WU*0R)BZ)arn4#4A2mdrwzFj&o1G)vLgAk zFT@hJ0(J3KfDzB>u^?}X z5)+*wx&PCIJdqy#>>yhoH07EZNI0u z@SdXrPKVgA7ZVCQNR;tuC1Jf*9v17QBGWvIeohOe?s2$N^A$R>7tnW&7@7skxniSp z5y5C*MikKmDbMyZ#}#*FoC-8Usgg9KEt>C($QTMkAdF!K39SPuv9wZCx3kOsL2ypt)-|$rgo4kAKDcH&3y>aT6bnjWBU1 zFRH}G_wcM@beE;EaU4#Da*Gi;8%Z463=6PUGZnQ)g{aZUK$A{3mg}&)@nfS}wm(tSPnbWE`7A}6#np!v`bF&! zT^YsdgV1C&o)4L8Whn;L&cuAvu_Qn`q&$k~?%d8=DpKtft5ZDt27mti2r(i3NdPo4 zO2!S#En`V(<54R~Lc638TP5SsDN{;|Nw7^mgFF7)WYW;3nTI*5Be^y;e#97tBu`%c z!*nVipMStlcOSyT(uk+R$NH$_^twF!x_v7C++2!ZRwv_WT{>RZCF0}SXnd?0f)BOB z@SoMg@cWLrDDc+f7;l4*F)sOQ;#hz_E36H9t%kAF&{N)ptK>-q9nQVHZhSXsH**@d zrq08puyN?8Db2VFB^jonE={D!s$u_{fQjMe`sLx?n&XIe2&LFn zi|*9~V^juWwQC6(HdhwRWFuKz2(`d9X9;eF=%CtMnt#wIL9`}VEqZwaND;*uqhQzA zKE4iZB}=*TC)Io~PR!Yg45wj8cNmVX`J3>~{F68yUxT})t++R9Cw8YU$9%60Om&RI zkQ2b_9*Pqc8*#3v4%a7c#j1cDHb9f?3~(yS4$IA@9(u|+PrTSY4Np5u zadc4vE34>lJrnJPuUzP!>3zpe7FR>;5wD}dHN;;|8;aLo&PREq9n1(hnVXv7yPyB) ztuKGUCkN?6#_`crnZsBV=nkaoD#1fhh1Ok;)>Vy1NQy}g9VBDTvJ}h9r=nUyD9@@4 zv-HLyOkzdGKpxdq3t4^z4U~Al7SsI5MO^y&oHUO>zoXimm%>-{?zM{$7#Lqu!LHW-P`rlkarvpEjfBFSfKwM9lc0eh=#7AbBD zYV|Y7<2aF*)xwE`hZz2ReD;Q0#KbQ+ck&3#wWZ~K0Td%`DjbBz9pve^&&IRnLj18l z0Z-SB!&~yMPwGbDX?HIEIBPP0`aSgeIZ0osVrkmJP5s-cr`cg8;4EZUB{ zW!rJ3q!BCplaXuKmjz7xobVP26l+a(HAUy}e#lT$Bt=lit~qt68j!=W(g0G34RKSk zDrOccgNv}Kpa!vKeHo5#39`j0Uu|3v)nh?===3sVr5AA7S#&m$0L|8n!c?6o?tT%& zrA|$1MpMds7|ZDJk%K3B>`L=Q%(BTMfwN}smu*FcE64!fkf*xiBa5w`s(f8r6%CAV z^rr79!Ar&hqm0AQLf-J+hKraQkxm{~g(+|DFF%92?1e~li$a#mIPA#SfIG$AxEi;C zP(}m3DcOaqWqa{({%M>nY$YRPLWV<=g?&-KbX=Rz#1rqg$IWL0ltyv+#VBj+3e;dv zpE%G0e{@yi&rP|wRGrQ1nIbrhhq&PQ07IM&(7~NZPi%2A;YzDO3KK4^$-}o>XTV2S znrMrUkLQY`7q6a68$#ZF;B#a_Njt+d9m`EJQKmdZ+UiFkRiVN_3I{UKN;1_Z_{HeY z26a+2(?aAa52kxCW@?-H6_dHl_U(&z(rze0$UsQ(@!Kcx^>bij+K;^G1g$Wv*G)r{ zQWn-KBxAO5JWn?q;2d)9bL;8wP6Gc z^x&p%kD~{VFk8G(+7GYZu~+=(yT36hZ6aq*MU_*sQV13qrlDR~EA>)zDHpJJ?T`p% zP3PmE7X2d3)QjV4lyKKTy!hvtlmSmna2Jb9n!D?ZHYf@LHyLT!-zXbhG-M6It-4Y? zJ2)SI?VgKYX~TctHWkbvRjdF4zP;VSO+`B!kF{HI83}@_+=g#Of4x${|SI z26vYo#<>YwacR*(3{!RB4E4@1CtT>Of(uTfFo6V3Tj~ibhGbyQfIKecbR?y;=e5$t zqKF*aT-lA0My@;oP`n3;WRiU<(zQh~y(PoxOiN9i3Dn0ef|a-2B{&ggfe=y%M_EmL zIk5&uifhoCwE*S*DTud-Ms@mPjB*L%YOSN0n{gtq6<%_dTv{k7a-wuRajU!qw^Qoy zAg6;zc%IB?#i^oB>`164!)3$CDUrvhkC=*EMO_r*x8SSHRct6?R3*4Fz!-;oq-VNA z+_ms)Ln&U@=iz1hRFt`^aPlff)ILW#Vtud$GW3<$JB$6v9bkbM7q(zltPf|z^^_Iy z`>(%o3GD0FFPTk~LN>Zrb&CB1P-9qzYULc%=@ntQW)kX+veBWLiw?OAbcre^#cVWC zs4+)B1w&N&k)bhyHlZpp#qK4Z(fcJ{J(Y56e|#eChR@GQ=7g3QSnVT`b`On}_r_A4 z1Z=P?K&)O6_f4;!y*&GK>*)XK)yK@eM^uH(G#P`9^5d{iB_BIj!Ln(wN|2-&&hf07 zwmupg8(CrBzUcLc^zhIBe24ngwS3fJPVWJ<;nQ_vutY5$Yc$hPNAX0hRwnAzvrw;; zj@9x>Sgx0fF%lnU49pmpA-$GRSaA+V|9eHN+jI9O0z-#DSwWMPRuo>ilAsQD?t0pNmL0?hMXHDP95mir7W~i}~RtM?Gs3EtHh&RQ|6~%w!wLE)utnstN zk>P!Dp5B+j1kbKMdc4)~jk^)LETqRA@owQbHm?Pt^7hQCk>)fAcc<;avDkIEPO;ut zWf%6aP5m5j+FKP@{nW9$pB=+O0U0}rR^j}DUFaUa9>v4bQ5>0sEh%&G&C(rM9F@xV z?4%^Rnp81X#T~QV;%N=t$aCuQ{g2Uhv=P2vYNcost20Np*aYvlh1(?8hK|Pg-j!Ys5H$# zaDk+_kr9JfHcC`Rph3SJtK~AWmSFFCg;a_)Q?Z4-;1<;sY@!fjvGzEWstjQRr$f%g z!O{~44;&FwVDT8w@z+}^GyYxaKTbnbwn#kQPvQNJ_-%PczmX( zt^1A7t(*UsuRR@mjEp22-0!)HJYTbXGDFyQNgg&xa%*B5*AubP6nl=*?9Tv zcWGxuZ+W3$3cUaAEsTg5z@%8hx_b~T8Liq6`KF^W!DK8JSf^o~MJ873CZpamAB!Eb z;4AOSV>6~?RgmVt#hZ_>Xo;UQ;rJ)^&XecA!R*O%5$xs(a}`+__HHzHu}CCLm1?0! zf<&>E@Mx8Gx;Pu{hMC&E<0j?h*b{_Fq%4b#Hd;8=-xj9_JL71i2iga^BF{`7!^xYc z)4y+XRmFcpEO61=1S906Emu2om*L#RHZ%^Ngr15HTp}UAoU$2@Chx)=7ipdCY(Gbw z8)T33;dUr6lX{svlm56iXD9YgsK=Cnnef$gKwfYRZm-ybtptVb$p8%0az+io?EVVQ zTC}wK!Q{fj$)Kh|!kq?d^E+_5&xIUcY+A%6k5* z;}jBU!(G-8%iMCY-jEyzdDe{-O0BoZ#Y(db%r%a|1mnRNC~Lz5&%}v`wSqAgRW1_>;VNVOA1np2aa?cYkY~4Ku>UP-E=yHbS|ol(to5vQ-6R z#kARlpIbNoZ(sAK&&v?PGFsw+)kZ03R87TZxpXwC7hw^>gh2|{3}5VeSqugQSm4B0 zds$&cx6KRkiBI1DNellB7tbC=Ojs1Wj9uxw;%Gsind(IRF_>bKaTGHrNxTs);{`WG z2WXI>>Cl3gBxK_6e|~4?K{3no$s6*vQq~mFp4%IPyv2pn$FXkpN~~U0jrzJR*th2p z@6g)mlUZ@*yP9*Ak)T5L=!Ib;$pf!)GsMZE-ncT<1IGf)vE54#)72$>o+y$=ek#&z zX(0(@K!wz0F(GHPclD@s@;}dU| z`0t?J&ypO1;HGE86>H1v)o?J%1Bv#hZ8su&6fWilpY2$wHg$WHIodoUTA7`FWQ&%ZD*Focbbv#bt=%D5m+ z#vi$I{z#GZ;X-`T_9%vE3l3y6MGbg3Iia$AJpTUmSGw41e0cr}FW$Vx%lGf`L0tRI z2Yhv4ANpFG@V$>D8E*475rOnpn8oJO_(PBnMTk^6ZW*8ni6ki@bDlMiE z=d-V$;@OMGJcL+G&HjMr=v86XV5VYyD-Eni`v}^6XW9;2 zPj92RuMIuvojjfGTk>%61VcTTpiCMQ#migbK;k0Y$lr!*6esRWm_x!w5L?L#0VX0* zWJCg|iHV-6xVGpJHk0R@KYSu)4=%)^33a$nO8B6%8{2c1k>V@yamt!NW1Jb`idt7a zR+3?+KIHXV(UaeXt7)ycKluP|Ec_CYWEh2~=p5mN4Q?tJFDK4{|0g^ZUPQ$3w!QJ2 zFj^_}E+h0(NycCrg&9=_a+swpMIC;a;_Y!nkbG_blb9G#O! zD+|kTV+k(S`QfK_YdmUmMC%k!o&?TZM&wa45{IC5%Q`&& z=l@{uy`!?qo^8<$eB_*S20=v-K?DI6446?t$vFo>MMTUwiy}yrphz@p8#>vxZO)ie zYX`N>2}!1TYpsoa&L4M-JKlNsJx~A6Z}<2HG=6;Sux8b)T2-^2^P$1$8p*+|C&Sb8 zr!R2t=52hldk6M?vmK4QYH{S$j~F#>BvD&wgj)c-Q`tXgDjCY{TnTHfr!A?%nzoy*1T&x!le{-SO=pThu$MqlT>Lo{@Ga z?WKtM1_JN>WPoJUIn+T5m8rh?ZR-@Y@6Exp9dnQ}s0UwwrB3oV=BbL4F6!9ZN1qof zu-{qf5s52Px8qXMcCN(V99Dv>DOET;wE{~u@M+Y-L!Dj%Mi70 zMp$L9j)k@=m~JMEBtvN=naCrdSKAI(LN^Yn_RLx?6G&&hiTk6#sd?l8xj)ByYcr?@W#l#_98i>1h&+`rL_6 zA3oz_OB>f!I`!kvu-3HX)RuJ{=?XGfv1l3gA3T8F+iJ0MTOEG-6SoEUwxR zbLp*s)5Gl%qawCH&PWT-`Pw-Ae{=-+jbF$V+xw^(inBp!p&wgng5Rrj(Y%2!GG7f( zD|+Jh5@&49P~#$1x?M44-<~}%VdO-tU0#6GCz|o>;VX2xOS+dI34df)J4FlF_VPL0 z9URE=5%si;MxJIAvXuP!U}ziiDz4gQh!2Rs){0s@dGJ(B9FSdR&Glch)vUyffqBl< zOzt%nn9AYU_&#VH)*bnStdY@MAHIqrwPOp-hhnZ}qpWdox*wj@Wa7p4bo^Nngx~Xg z@u4XN2WAIwFT}jcu@QDS(nB6M$Sc>_sq^Uqyi>?K7PoVD;7U{_E`*9hp0-Wigq)#i z_-0xWZm!sc^OGxZCT0@{?D>$bxRJ0Km*;Foq}xEgfck5zaE~=wvllLH_!bG4!^!ih z5QWtxP?)1RXB*D4iF0ucXwKb_Mg1ZPh!V~USb1PxuQ=SCydM`Ln{a+o1FlZoj{7rz zMzU)t2X}#`JWdeJJJHtw$NL)L>_8J-7+{EVPAa(EM*}xKOwjCRfRlYRd9%c={-(Iu z$ABvuHj^j+$;X(hN1h#Ih|5DvaMI5RhldzrldU{v%ZT21qk}qD`TF4{HYnpq*yUIWC9jVnS%B6mtuDf8Lo3z_%mbWhpioN(DC6NFTQ6#`|kT6(M`*Y zK1&C2dcK(KFq$X$Qlk>k`B^mBpCPJ4u)GG}SAF*hY_p=XYhuE&V@EM1GZj7qJi0oU zBydtU;*26gPX#B(x#MRt+!uQZ{MFo33fC#*x!}_csrvGqZH(;SxAJS_@4s|ROGyuB z7tQ$ms<{4mwtF;g7ir?^1_fMRDd6F1DLh#xk0+ZAaj(t^dsjLmVVE3`PxQL1DH}3n zuB8aq?sfS!YJYAN_d`o=#4%r-ih3U{9p!h%uz?f3o;} ziPr9!m53{))A6J!8}Ay@@vI^YubPqwxRGeD3B#lOacF7ELA0@$d{|FH#bQ8>M<7E1=l!B3+X$|B~A(xK5cI2GB5({bd{v$msV z;(Tljor&F33h-#zF9g;)G)FYxVn{7+gp&c8vKzwUrpod#BF5j}QL zCB~qSYkjqGr;j#nIBDTL(byZ_hB)J@O$%8QhaGirpob=^tRz@yN`}c$z#0k{RuC<& z=p~CC-ugH?syogR)&9=a5QluMv5o-E4CTV~G<*>de&6wdgOLI31KUmbAm$%hSyGYc z*4uY2c+U+jA8LZ)jb*f6RC$PyDDlP`;}GPSj^o>CZdQ)`mtVbpikA0p$$!%KpBdok z>+^P0Z`y`QVEeD_?T$A)9PzkJ4!^Dt@cSA8 zcUBAdb)z(XuQ0$vqRO{QEO2725f+BAeoyiw-34gKi@loCbR!=;d4ZM>pC}&vgpDiK z@$$wfbzfAev#fLsHcE$Kg<241+xTOgu@lTyRUt1Y1t~!s@u5JUAt4Y8@(PgC)q;&J zJt*^T^l!>glTrSgmf4!9V#Kh%ShF+>wzS|Ph`zOalaEIwNqAKmg;%xVc-9b$P|}xRXb}H>Dh>DK@?wS&#D(jRbh|qEVZ0ZB7%unYRTK?MGmwd~Y0K6-X(SxD-)> zyUC3>Flia5%0ubgj}NxQPi{KAyM~>sQ&*h2)JzpyTr9BBSsx|d7FbBkfr-xb?|P3z z*ZWz_Zr^oo?EfvgXs#c|`88qJS8x_r_YT)DB4}2z5D}nW|&Sz-< z#HJa16eme^wDL|Fa0>exm#<#IV4q>UslP944$&HiLcM6LRtV%HF8k3vbWittx;#(JL&9HD!1bKVa)nXwaB=YNOk-Ntg( zG?UiEh5i<3wwK3k9|P>@r;c!QQO3x_sprA3jko`6hgYv&Oe>QVcfbB zGF36eBxq{VR9 z$qv1Nk7?&c65|gLQ?Ky#ad)BqG)4d08y*uqh@v)}?%3TZ)q9C3J%f_x9 z7=+VPi*aLm6D}t=@M-E7qH1tFU>#1SZo))MKVl_XdQDEr%9^o&N^DgEJu>&!4j4RYk#Q|jvKFjbJ@EFp&2Q>n8KHu`kupOx$%fR<++_|)=|kJ^0t@j2e` z>FA&T9`ePW`t@_?v1dy?LPi8|y(u;+k+G5-m2udh7J~|W_!Do)il@;?34RcvJ;3qOv8nZsrY_v8WzTmp$BHb zYeD7Z39z*2Wt61R6(n)$&5m2QZott@6C;eJ@U(F;o{%SP-!&iU?izftGR6PN8lv}M zUM0m%A6Lt!;|;y%mjwYB)z!~BiERZ8w8qcwQaJA^jg!N=Aze-c!~_#p9GT0;C|2Nf zS`{uPSD`ts8rNs;K&Epr_f*WYHn^GL9L3h(_g2I{X8}hCD&mZ{27YkU#$qxGU%a7@ ziUqR!2B9HrInHO*;c8|*?h+-wzvv)&Vjp59%5<(87_Hn3S27xKDSiu1WK<$d!!8i|%|Q_-<~ zHafS>LR(V?-qt1K{oa{4x;744^xXSZAfMpnjjm}ndD*pemJ#t7ZXIQK)bZWPKjQcy0R#G6JcWus7G zkcJ?^1G;3KHdSol&-L3qJ7KCL3vC%OiIw0r5@#utxH)GV&PP_`R6rTuYC9iJtRt+7 zvyNM7O}M}80P51_^XEO;)CAG`YNB4Ws_=AXYHak^#@7F*M`2;1xrdia6VZszjQ6{% z(PFd}5a%W!XD9{t^flIj7Py_*``C+OilWK$G1AeCKd5I9?upwn1lZh!DO^e>%VY#L zs)V9KD*-XmUR-3XGAkV|=eFU^k9l~ze?DICnT;DIai~ujgvFyB5!Bs;@2P1K1!SrO zvI^qs%&F5|+XSC@HiFGh_2^;E!T8sv>0!HT!~lTuSCnig?QJLhF4`Fc$FWBcN+rG zS~v!;Hw;JT=1}~yaEv%_wzngmKNG8lc5H7zPa6~7$Er>Dz{OJic|80QG@e;aQVsz?2nU8;?YhN(ib|BQagp zk9P_6Rn|r1AU9c91o1Wn*6Mn-m|kR%PHt zSv)P~*_h=kZeK9*?FRB-=le)-y}uI0g9e;VGtkZ*lZ0baYjHkz2Nn!Z;2>wojtWO3 zoE+(ZlAbD@l789yWQnajO9@U4G{=v04$U4KIO3{}gKmb{Xex`z3SuAd7iExsQid3A z>54_c891@L4p$cJ#OdfQxR$jWtHxyV_b#D(bYf^Xtm$dQ|9`fZB3|ssBxVtTN2M|N zt9~{fZeNIF`Qg|y%?HbZ-LNTj1a4PMp%{KT-j;>pL)k>UFY(8R^6~gw6M@5XM#GSv zt8?$ZxJ`_OW$9Vn@2xvG5g8E-1!)N}9c6mHnvkdGqCx;xk%-`Ay9aEmq?^otjJ9O4 za1S|FCTfnwO5;(foQP8SRFuo5qD%-wm3$~Fb)v}lIPsi7c}W!yqxK)#1w9Ib(uNt~ zk8Q!o_7d-fxdZy!w?xaioxT3(x1L8%Fn&lc+1zo$k;WPNSi z{I@&SFJ150O)$gmv=TI@H{j;%-56!*0VT3iQY}t+ZdcAQ4B4bGl~S2v}jIi1TCYagJ#EX(wfz>7$CXUOM=0pdP9R8)4lbD`c4I z^7r=YqRoBC^Q<12h$}O;;dFK#hG_NV2B6klf{R0}k*F&caWtg$<(cru#ldK6%*OW2 zahPN-^>-Z0C_S%cB7p788o?!ZI?D;Lr4#UK{b-;*8I7qv;#7e#0dzwh5gr8rl;97poAaCmhFN)kpQZ9sR}$%}?) zm|%nzilNvjpTf&v8`USHST-2z)ci3?=!WiOq#A0P&`OW=;^nijP^bG(&+E~)zPP)! zC!z<*@^kZbaXdfB$@Ld2O@n*px(4^`tZXhjI5-^k^YblRuplRtsjPf$T>Q5^LdFEG zVa?S?rdFdlxrWDbW34>tLCWCITerKqh~FcB(Q;m@7q8=oGOa|E3*khG5-669!2;D` zNHK7Sr>cPnSU~}Cy~f}~dNqE_*^BeZ)i^q%0-i>;+>(b6^MH+(9F*mx(cbosJZu}E z9?url@zbXuPjq&ugC1V~xEQ-~yf~d=(lfi=%yGS+5w6?Iq1nqA>wT=nq>7Dz_U#n= z75Jg0Y$TplM-ZKyk5mtPzD>ZYpN{&P;zEBtY_?V9zhk3lfXSnixGWCK{%)|9!$m)H z9O$ou;ZkCC(Z(oG-etrZ@xRR;1{Z1Z=cCDUY;@7XcLTcN=l-TR=Sx)GT^T1`WN@LM z3alj8G;Ap$>^+(L|a)9UKfX-!c=ot_36rr0Pafg+uQou(N~Wwi)IGB8n=!L$G${8TU#4|fs$-noRl_&hwU znTjXhFXw8BEHgb#Z6u17lIi&;p;l=M@+6_eJVMFf8Ngb>5Esu~;WoJW>{*zo$zY75 zfO}2W_`S&ln`ZQcA>G3jIhkKibLpRcSZSNKkJfR{yl`SybuAy8FjmqRg&OgwlS;*QAp?~{B+5;qkZm-W7ML__3DnESPsPdHMl{FP z;aW%)uElRbW6*p~u~=+Ww=5H*dmHiXqgAU`a4*o={!DBpc;5z7V~Tm1L}y7d-u$!* zk^S^IElpM>(0bVN3Yhxd8XUyz=if{lfY#bXe5{^`k5%LGk|-ie%KTcl0-?6rd@Ex~ zHzhRt8t_SM{kn{b4o|2ESZpA{xsmqxjy&aLMe#GI_;ttQ+F2YtuZx1wQa>5{mV{z7 z8H;XRo{m*irO*P*rSod)Ess-fnz-*{f}`C8obRVaAU482FMEV2OL2g)Ji#b)2cATk zsHuQc!>zHkhZH{tPZN1O0BS&$zuJ8{5zAuUH`}9=~`5Q*#~2urV5z z2K+gU?=cXSQ}f`WVb8Zqn6YJ4c)FiGzF!i7ziMXS-QERwcxWN!jO)eEGg-|CJr2=$QQeyu4kZzQHu?1ets#Acjq z{`=Sd{&zjh6g3cOISAM1Zo{#Vb+|EaCsKUE2~3LkX4if(n@EiH*DH6?%fOCknH37O z61YM|gOG`hQZal_t`8R=Q$|Tp4$jRY>X*`hbKzTYY+@g4B@S<^BJj2@6;J9iu{C25lF5@!Fc-I3z9gPl z!}m;0B@{RrVE;gCTy!_aMQ0tH9@Yaf(&FDU5~MhAlg-s|XqYAD>4WV${(ZT#hCh=VNSf{@|-or_4GPIMqzRfu>fM@cpHEvrdEyPNw*53$vP|>?$L)8 zs^L>tOC@721)EACMfbr_RSMZ5qu`^hjbSoYyjS?AsWr&)h~|wB?7pjafj89EoX%?m z5{5YQb9WPzFyFu*<;tuPJ&9h)C{<5Dy4i3pB|F-4?BAtKC%*fEytfpRJXP>?YY*Jb zm&V;1F9bP@xs$KG?*EZTNkN_~yU~liV{vQ7cAN_xB#%@n_>H9==r?jwh92_-kVv-Z##{-Sv^Uoga=r zi{tQ|Xy@A>^6+5)a-6D4!~WGFC{7)WW#ilss3zg{yDYIaiOn7|VeNIsIMZL30Bp(s z9y2m5A(m;WjBh45A-YSg@Kiw-UR6*`S{;su6q|+`h&8}FhdAJfs|K#PDWlm{5hsV+ zBHUDk1E?{s4?4;7w^XO&epMEn^aVa%Wz*&|zL)y3O$2Qx8C(-fQ$Ff(h?5x(ZJ3Rb zWLUffO&m?D#L1+sxW4cZ@`7i=UeS;%MC!}Pa-(L;DZMIPmo~CAhhU>o1j=P2QAf|d zh6w@cCSjtw3q30dmd#u#ZsOA4t0~#Qw+RNbVz^g_5Y7M zR?J-xY)m(LU-&xQPu+}!a#HH@0&<7Pz`Zmy2P+bx-B*)ipNATbNy`KOZ41>KFgC0q&8Q=!U?XpQaJ;!_sruJS8umY zM`ztEJSt4U;q2j<>8rzOGv7O=-`(n}hNB~GQQ6m=%fB)zKix(Z{a-+ z+IQ2(=l5^W!6ue>l^Ir6l=ET=29z{^58U0i5uRL@R>HfDj;2)MhmZ}pH)|($Ml2(v z!n%_*5h!DWIayV(Bz?G8J8}=({$6A{&3CWETtk}WWpg$M%`us`k9%5Tb zkAM3W6NY+;%JKA&vxeE?^tu$h+&UMpYG>m4j#+#ZVn_W<4w#pWJ?_0riV&J7Y9^SFQSjxN{QiB6_ROCHamr=7?$=suTa2jh>uYcNDt z+_G5_kcsm-4LB27hD#F*d6WO<_&lx)?MG{1t^RmaswSgWlEG>44oMn?LdmEk@48tv z0dqA*^79|+-kTOlJ38LI;j?qYCb{#^|7D#6?w9KGve=ikwpcP=d@ctL95DIH%m1Hu zq@-ldVPawj(>CFL&H>!XXy7GvJEj-%EUK!a0^br~M{7$PS6~kuIf@Hr#c6q>Qa=>S zWk+%4gaK-9I6bQg*QPh(R`xbr%x=JZFE-zY37BcYmA<;rBL8`H0^ZigayP&U@|>xbq7h*Y*jW?3(Y`GgZ&~cS zB?>nRBeKE;CBJnLvL7$D1HESv=u*r@8`%(=68PmZDWtthI@2O!a_rS%NP5EqG}US~xct`Zy`<$xFs zF+o*3r9ZGg8-K0yLub`^v{VG5b?am_7i94LUJGqi#D)a&`^jS1Z64-mc2~!qUUH(! zVtgbXJb#5@exvzyFmUI`d*XCqG+yjqgwA6d@Mzx>{CRLaZXGDW?QhHQ+krKxo;3zu zW}>%JlanAbJ)1nL7(aG&$p-xO;02t!yFpD}tX}dVHgTT~JlnPa;dTmL$t4Bsj9P=6 z=}qE9g{XR*Nvy+<8Rc-6(j=p#g_V*3G|8lsXHDd>>lOlUsahK1)coll>R_;|hZxRu zzUJ+Chraz0Mnt(|Tm?LAbjFqSY=osIo@{ePL~kbK_V1+Af9c51o)ybf-1}>)|J^0R zVyt+gVv*`%%$b%R$y1H3Z5>_f{}ZNV<%13gd9H#Lisy)1HfU>+@N( z6NMgFqUw)LCP`fBz8fu$vAu0^tau7al1A_uwO&GRl-N(hWSPOVfR*5C+XL6mT;dDw zIsMJnuI7VJY*;ld!{7eAi;YG3NJ>gTa&jW#eC(VZEsM%p_qHZ)FGz$gW|^*O^Ntnwhw0jQRHPW zjkLj)uBm({2((8Bb;A@5acgJ$w2^p4@pyY_I6BLM@fUgMhmARyGQyrS0$+DGeEigo z*)yhaF|kS7O8CLQH>PQbt%Q3Ien)5fkq_f8&)A z6wgmUR^$luH`n3Mh8eB#W4+O^rH+ODJm2%Gqa80gUh@&8i4l=x1Y~$s5$_*07jSR) zeB7;=1%EO`?0k&rIVM~Cb-A5tTqAp%JIDWBUIjni*0+EI^f&g`?*FGa~f<;(EE0_2-(yDQT&a`(R}Wb zo%#5YhrG04+wivY3B8A`{ijy?{w)`wW+HJ_*TYFKZJZryf%<-yyb_Ah)O!`#Xem!Y zTTwV(=LeCuU5th~L7ciXb;!*Xm0Yjr$*ULWZecCPp98vcI_+j-g}CW^|)NuG>@2X~?UeG8|)Od9k(lOCnJ&`HK> z{_I&WA_M6mZH~znqv>1~Fvds`ua0fT(e=6L&&n6+`FTrh$S{!?9XK8LW*^4Im?r!j zSd5zszd^iv00CVM+0y=~RiAFvJc5I3 zcXT8AeQ8a1ye-zo-9-W(lp5iORXyQmNJeI)`+={$_W!YmlbS3d=;j_6(;Ghxu;e9w z=ex_`xTg*R6vc$dPuq8k8Asw-A6rGLdiGQ^)TNkAiV>1EhoQ(i5$gz`#j0W0q8*1C zwOC##&cxwL3&XKVEgt2PI9{V#tQ&z0r2%~WB^!e= zJ$DXXe)ysbB~mUn#q34vQ@nfsnm1m*c=?)QrjLBlu&I5YJ}}jc4zZ;2BiFvc?Q6FX zG=3uYNQ};}Te=qQtsExkATWP!eUIzE9OuC3O(4Bkn2xu*mZC0W1f09}PnovxbUR(l zbd-?e@b=;$g1{eZTX=Q#Pp0W_9v#KNp8SUzhyD%P*S@dLZ?@X8h7U1yg< zekXzTCBHwPiBYfyxtR;+K~sv&sI|Z}t?^i6k%j@pdOW36v17%2#0~T1>>*jv1-beo z(MvGqlM!;<<8X3T1MV$5fL(E`DD2TDpqpc@(j+u0B%)d-9OcG|2vq3DpU+?)U*7lH z+5VnuUo%nhox8X2t)=7u6Fh0~#gh%H_PFI7$*Gbe@c#nkz#oqv7%S{xdEVBcXrEsR;{H0_}% zGmXM#r4XV`6S0k~F&k&OO(_*+GV$0biQ$v-%CzE9Xq1UO^djFf$_^kM7?RrQSYway?}BUk4A`K5<}nwtOO5*vdt{+FrcI zsUMGH@r=3fbaH{cxfRbw%S*{ZSxyOaX3gbTe%AJqdn2wd_O=cAi{`?dfH~Ay8dt04 z-0bLRC(qd4!54k&yVs&V7OOI2y@yOZF2?R4m|~WC0I`=?R2oi0g5b?PD%%gY;6ib_ zSgkq+rTP&_)Mnv{9{r9c#w$A^tNU0!UxBc4`U#;&CZb+GMzqrM2`D9ivcX7u6jOL#WsPh+ zHqrlYQH?=`RvH$ng(FbPgAYq)i4h)aJNCiS1xv7t;=W_&F5r**xAE}KEnGWwk-X6{ zESg6E_4I_Aiar5U35rC4SyGCXN zdRZyr=YnZ?eIO4n4=l#c+`&loRK@fmI{0qxFtqNRiMIMVXlY!86Zr|4JE<3}6hxVx z@qR<`^zk#Xc!9D5Kv41`UL)oHC@OWFXM_3?1r??+^Tdwl`g6NqlgT=xN#T z?02m%@aWY`yng=yZ$Gr*6@mH9^A>z02ix(9`&Igl5BUE3Z((L)PDV}%g9K|V(wl%< z74nKgBsR%Kp-?jdsZw4BHY#!0tPqQQ)o3iy3PPY@LqKLyvC8CGbrB)B zVwFZ1s`XQlryGtSC0E`}{@})C)0apzmvCQc*3HfK5^n1mti|p$l}Au*fbNQPxbgL6diuuqk?mTo+l5 z7N#oS3SwDR1KxEa#Q`bPwZ*{zZYn2WxSKtEJbUrN0roR3i9~!4n=*IyEXB9vr8@Y| z58B>~G4b@A3{Icfb|8x1G5-l^2PfS>uuEO);Q?n5|`> zKO-|q+>&BNmhU^bw$aDWEqMF(F@h(KgG8DEm8ovXLRuo8FKcrf;^B>o$|4*+{sZpc zxl7)volDVv;3+e4*g`x1O!1yG$Na~`r}+8Eal{0M(e=yHIV;k=QN#rGK3HZPfO3^c zG$|*cL?#G@O2Nq2B=8z0p+Y$twF(rrkfCHrqzZaIRT{C_s2746ii41>F$h`4W3j z@#!Ni8@BJlx_F45ed)Knc;*sKcnll^2c(7XpxTN$Ed(p>q1 zd8A7hu5^ixb@CFvx9uW>s4gkOC~sH3)xx}{shR*+ieLNoGJvbC8VtJYW$%}jm4zUy06|7VhC~|H8sc6mV*)Zn$sN1f zA~-MrsZ&!if5l?tZOBLU<{H%R*oLjO^(b7i0oh5@(a*t)u1lRyBp4uP&NY*iiH&Fy zu$VeXyoN8b6-J=Kl+C1#MVV|Awn*Z{>4aoFo9Jr;eXSHi#96^?X0Q$c*gP3)%px#Z z*AISjEKw*=&p`@vrc5D_w(~H8W#Kz01o_b3!6|V@a3;M^A3^kNiu4o7C=kQa2*(Qj zF&Lv}%?+!Wj`oAEz1IIFj?&UnYu3b`%v2zTbjRtw^0-Q%y<#okTpvBujdZ~X10}w2 zvr^NzcV(-bZIZWlzT??iCe-$+?K8^PmBYcp0ZcEM#Y7_nD`ct+#(dQYDAY|vsZJ6$ z>PDkLJA!{L(NCi9ld(c27IWk$B9`ddAd0^%2&k-ShF$fw+$Ay(%i#K!RS2;d_vs^4SCwPxlnnU#41}4fA$0XLpr$Sl6;)YS zSeatPh!MzJz77v=KH{E+0hW*X(3dF^03b6CbMO zY-ot3nehl4?eVt(VBSc!s}f9yK*)sKbqR z17mD1uY#q95$~?@p!+{w=z(dH!N}8#MxJT}inU_+{j1WAMTKq@iVdQO@`hr)ek47E zG02ee#Yn-941o%-5uOw<7C#(4z{xkevX^h3^6y!Ki>WSdq-Sm{7}9gI!&;p6%nAFLz$T*Iw)YGDp-9uTqvd%rPVH>T8B;Jr!`%MiuA#b;Hb_ z`n-PCh^VI$Eu7@IRGvur&?SD^`MHDBx6Y0h-ir6vqX&G^40j*Q#k<&85jI(y>G-+| zX7G};fTye}+}U(@!Gw<+>`CCZrqBP5 z%hq9xOE>7V8e0kp=H<>1iw-(E&`Q_RO6X(P_MQccbggYqU*hro-|+aid$@n|5^gjf z#~*huq2<*hK5~M2>9+QdXzMCmVB1fd>nosVpvq%ab&88KhM3^MibQ^mzLu^yGQS>P zf-z50CHVKly@N$KLUHq)iSAt3n|b$v#@)I0FEe^^1iVbyzL>8u0Si=vv066<#m4a{ z(F(x=!?7G({XD(+`QE&63l&8baJKBpl?p8g^sGd*2i3;KTuknAmqnnoSob8X+_cg|8cWYdv*sst~lj|HY zP)yYA2WP>8yqyNz?L2Vo=QA9*Y-^(9!&}}O_on3$E%Z)qe_y|gcG6$OmebpdFWT9h* zuwVk)wq3Y-_ddT|HdL7>ti@dboaa=lPz4RoM znI)2u?a8zKixw>n{o3pMU+!pXD(S&!C>uajHNp#1tPOe1>_DQYS!(?$Hi^Urok#>z z{KzJ@83;z0o4Xvp|Nf`Q1)28VyT^RA1Iu8(@A$H}2(hM@fc@gtOWeEj0M{T_dYzvHSiLvnI_48-AbK@qiG+)K_<{S9y?gRdQQQwrcyLa-MZg$_>T0ii-5-$;L z6Ys@ek6&QL(mbN?@_cM&uEubbYlZUU))x6#I>%s?7$hKBXE>i*JE)h}_g{N$|H~dp z(GxRSjjgw;qS$aw7C2L-KgxANP$w6SdWCotX+kvUhYTi*s+Ueh=&q=+o&Ce62%a#)Cl30(45`pGf z^|%mLiEHt7IGR}jZ$)#S{BgIH#r?Xec(H2+Qv3`#$UU?z;2<%hg)a{_(z9^UdYn0Y z2KR6OCW5xDlMjda(3P=e9`)tRmpFIqC~Av~;p6Da<3^@t-&0AKd(wVN0xoTsj5h}g zF?IY9{&xl|TH)NREjXW0g67Oh6!=f4^OkTUY$|&&%4Ers8pNT%AOzupBY|3n03r(mS!G0p1!H;PYBU_$$(8zEzj{HK{4&9g zC1gHxg?R?tmX3G0bNf0DZf`=-ilqn+97U8(1}Z8NE zlwYhLfC8mp6sbpItwuPKg@FhV91thlA8}gVe7d|N#Z+fzRpHv?Ew~s^j;k?s_&%YC z$IqIA4D3_{+$)YldtDL-h`SW)z|lZ4R?Jtz6BL! z=!w%Ar8pH^h_k5`I5n#YUefj)?5se;$6SKOC84;yV=>BeBDh!f6s)m9C5FJ7j3%i> zG!PxGCg2vR$0A(GlVVRLq{pU;RaFGYWh<7$$;ks*Gv=eXYBLTU{sF)L_7GnRs@`>q zRodKjzW+~5=red0xU;Lej1O?7(BSC7{g{;y&sm5Z85etLV=Ofcz-Fx&R4T`zL@E+B zib*JtkHAWOR)%WBJ$}*3qH$k)J^zn5qC=vW%MoCENvx2mGz8TK@hFiCLWOK7c4{P1 zoH7noGJ)7?9EZ6&V-Tr6fG=`GS~v`B0_){8kzn)y8-$MQi?ryGm>M65$uR*)iSpZangk_5slM#`{Bxx5E7{#EF zta^nKQ9{jRqUy;gHc3ae`groVx|re;j*Bzua3-P{S3)=AR_addj$23nrb8f9=HBn% z^bu&^HWiN>W+L0Y8v$JrNtzRoZ<@%PwqsO=VyK)m(LNmxCKe;I$@LlpP#N+t0-JQN zV8+3gpga((v?tPeMPQNnL;}Ae{4_Ojyl4*ZxLFnEBnq|DVox#m#oakgI2BWb!(oMJ z&fSMxw-nA+Y-DwLHknnJjk7f7S?=!iJBf+|P^q5AWm#&a2&_^Os8Wi=D!m}?U6tuQ zXU?4BwbPewUxorPBncS@MS33cd?chI`dK?6VpI^OP08X~T6^oa;l#nixcJi<+-tsr zTNiKO{OL0|efnqY-&cq7b@MSZVGgW@<|Qu$8)+#Flrh12b$?U|6jv+6qEI#l zMQU+8$KXe-$C3=))VRz!Uwa+@k2+?|n47M|M>MD-Uc(3Zx?!kNjzXVkWzPBJSvN0ZvatHPjFlVTMiX>J1 zTBrm{}6-Y<9y^6T+QBrm1CyTIq0H?q&qJH2y@cH&8A$uJY0m;p`&^7 zBtl^{DpZotAfJQ^W(c&Sv5btsa^3OBk@v+kqmdYG)*nVP+FUBsO|3ifx+kDqBMzID z$ivY6nW67b9$o>#HuiXSau15;Pl5qaV|6((xiq=k5ZqzS{?U~<6|or?r|d>e=sLPb zI`C5KiFA{}#2A=5g&sx=W|$*47{$aSs+5vZDV>DPQVFP{`(B_GfHVzH&Ti5Z6L~Fl zd*@5coI3*&DY0pQHCtp4BhWbwLx1v$Y_PHxy_AV%=#mjKlhJ{htP!j=tYNHYik{u9 z`LqZ&c7+*IQOij{h(tg^cTH>?>VyOXHQp4FCfK3YFc$d)+D-KA7Z^rjn9zrZF41En z)_v{u`#)w6L;V4;LDqw%dtkj@6iS5%UL{o{pNwj?7^Dl{6gwFq zFJLiFrZwSgObyONSL4ErMugf8r_a8Ji^5TT{EIB`-h4HB1Dhz3urxVDvh+XJC zL$!6_AkP)-(T6C#DO3D6?uTph8gXP&5w65-!{xNy*cV+wUQCBPvnlc{!?1~k99jw3 zq?3Xstt3=RQ3xP}qgpYQt~mx}nlZ@L8v;A}JR1!|G+(^LQ@O2g9&@k`=wpQJN&R_T zzhKBXTv^kEb2B$#fAShsCN4ydUlihc`y;&jNKCRCj-h6r(3DccP{xH-GPqx2gg5)?D8Gzg}1*5e+#rmR9tict(&v2G1?$Qw=#Hpk`qICv|HTXF}p^U<8K376%YTDw*?V!7z8;%h2QNKKc*qF&ai}ZKc$nb0mljU;SI6Z(TDaCr5x08_ zINx2sRS#3-YbtQbo$=cCh_@R-e?ym*C4Nep7&q^0uhoAaT}NJizQ41*^Cdl6h|c5* zqGi0WNH-X3P06zwrlLSU4JqV>ndVVNsv!Z<1ozeoxR)o3J9!dZTP5Jy3ITUl%HsZd zP4cXkc)G(Kr}KJX!8i#|t~kgFs0*8e=2<(iGqH%`CNsG8^u&{wZ}8~@MY8Q}`0clQ zaJK4B^i~m3^8HYx6V8)j+f-w*LT)U@qFR_>^}?UC51Mc!4FyqGYFmrZV!WKgUgkFARFMERl!bVIo0O;24b zJpBDP-dR(=CLc_Qy+3*NWx7FFryPWQiuEgv#5g!tehfBfMPQRIeFk~TAi6)SyD2|x zHm*&t=acU4X6(TJ;C1}GM+mkk(+Qz)gJM*H&Os&>^>Xx;j8d6YI0_UavBoG0Bl$KC zdAONb_|*CSO9vusG?ma@S-`hzUGZ?oXv`lW#Y2&#e*U<%WT%*fi`|5?p=CH9T!phi z)!fS;PAq}DoF*5DJK=1KTecG1q;Tab0rZZIG=8;{=878^deF;77eD*CW2mAO(RgXj zHcVBGo~>B8!tZOZ(SINRn`7Og<*^>t&bM_0If_>l;2@Y_oPjqodj`_NRmLzQ0l)5! z!1G2|Jg+dqGX~5mD?F(+!;`I6cv;&A52^=Z-vVbW3N?kBz94EJX$i2FQzo$1qM2yy zjf_3W=^jThmp0a{EEGk}SrzNYcJAHmj4a99DPoH1V3eqZ5WvEbF9{&8X3Isyyp*gF zY&V2}&<*zF*(M1+k*^hmdL=e4Gn#v^dYw#EX(sXFgG!eDmIRYm4I-Ky$?KfAke4ga z3`4YBf1-OT&{H$ScRwB#8*1LR@M4O^Su^;3@L>DWM&nVU8Ho)9`ZD!oifz+Sp%72N zkH9wN$yg{IK`-0e6=-ff!WM2fvt5G?J2jk>X2)Hju=a567OC>6$G z3o)9ddZF-^vV$6V`M^m5c=YA@l=x* zEURT@8BRw{qGS^^u_{Uio04Tw9j}7DGt5w(p^W@!DP+-tnqb4gDHbc(>MLQxy2V4L zW~HZU69B)Z#d9aN7T2O0aWt_OeHEObuV{pa4}RlK?Cq=sl8zH6Ps2n>kHDykXu%cv z+My^hiA9cS07ghV@~s_5qQ`bbOCuC~uvTj#DiuSyazdjF6BJ|ZXK`F#mvs#>D!fHH zoa^o~vFvj71gy~t<2|4@WB}CU)zR?HH{6-M>kviGSR+JR>ub!MlEEhlI1^2sqU?ua zgCyk1Mj@YoS}UK3I_Wqx(%&mpji*@8o*R^@Cc{wRnSgl9AwcG2*C*p> zi#cP&QqP3Al*OL*1MXXpQR%B-hnZfn_%5{q7qWNZ`rL!Kx_l2t8(DKrVLs?Da zd8Oj_tlc;jT8#5q^+fB^2-vb1iH1XwXAy-w z0@^B#2rQGGhzgBJR4Rv{LMaSe)d`d`(Y(d4n!r#e&yrVKw2rr0dG5>s`-opetPJtZ-9sYHwV2S1Oe0+gEM8DB{V>w_Ls_#D6f~Hp+`p!GlU0+*mEa!~fOZbpTa$ZS4b>Cc>p( zZjs*Z1>_<~6Of`n6s#0Ql#ac}U^jLR5(|hFK}AHwLNrFBCK_W!V>e<&#TMhUpomKG zegEG3l9!qPmHFTNF-(&4&75K64)<)&-s`Nj_Fmt&D%>zSm}6e|@#DuG=`)@-eDX}G zk%)Lkb=V5b5M<EYMx~eis`a-r; z<6ewQh~;zDKNHTJIip#)qfnBwF2{NK@~psR3l;?DE?wGrVTGtn2%p);R5{EpaVXV7-3GwU& zhUv%=r(u$QBz!mv)^WjF%LH53ZTyEo`0F-h$;I>MF)upIn?v0eFVwEmL2a%cu9kL1 zm>mZzlYdqzoV#f55FZb(6CzE67V5D(5sy#F9rUP;b;xV`>C$$zLk-o-L4G)E-on@q zzj}E5Vc_Q~za%H&^{J^PxHxY(L%B==nHgt{VK++M-q=TZqO zXIR3H{C?n|kWK&TndfEYg{KTjS`Zl&Rv8r(R2AjtT@~HU=Zl1}(2Y})hs@oydR33# zY5IBm(J(e8VX+l?(-#ezhN~Y};$%!du8#Nu*XHfRq@D?kawanr;l__OOz()QDN>ch zM!apKwE@NJH=$S0NOZQ4Grp-6S@cTc?RpSnjON@hl0Ns&y0-Vc^7xZt*REaW^w=ocIs}(zSK-u{4LCNn9OK;kv9OGKEL!L6=`6#oo2RHM z6B7b!dH)VCiBY|$qGe2^w*}S5j$`qsi!mu>JbHPA!o|df7^NY(Oo&m4VZ%uwH?T$T zZejR%oiyvd>UNIR-+hDPx`Nq>Kir341ML zcy;Q6SpOI-88Z*-vWsx5u9g+;Q~oLS?jSFLx38YEJfO6A4J1Mi_9V9~9dC?B8=P?a za~<4Uu7j8BZSnmgJ1C4v7^@UtZtpqe@h6AU#Hj5K8=m9Mo7XBKwB{B(`}qmZT{w^9N2_sU_X&0# zJ9-M2uU}`ZAW9~q@+ZuTk-w$#C)D7|x0b=DvoYJy8Pb)*sp3eS$nS@49XNywC8%Dx z2YHE$;Gu2HyziiXQTVauBJ=c(HNS-8Eya@iXzJ^t}7t zG7h)1gm|zn2$MtA84tIpD3?DQbU`sGNTO5Dt=sZ>s#i*=w=b6 z08;CI|E?9pPH_GDP4tTR2x2XcwG=5F!r@M_0(E6wQC$=Ue;wKmQh@W*%5iq`HtZi& zjCk8nM$NMn+hg{;EVhdc)rK~nKd)!^LJ!?ElkJ_ zDk?FaK6!>AvGGjxgH||Aj}YN;MIT&QDa7qu4v$DUTwkU{{s;woHW7i|yW4v%dHh9S zXXp9@J(PDRA>SmK5c~b@aox)RHxwK$E3|Of*BWDNO;{BVy{5z`;_=NZs&XHyTHMmY zsC@M2`^E;eHom~SchqQJpsBtQEsagACv6MbjF{FQylzI_&6`My>jM$-pd#X-LM%8O zn$rm{O6~CDV&cV0T~PFi6C7#BJwqvOF4%$N35B>kdIwHS+Ja?K)0uLhkmSuCwn}U( ztwdu(+dZJ788$bzFfuqLhBuHGME$#FJb%}O`nT^Hc^`B`>9vY%{*JtKUe>?C7n{C> zr=^myh1|4k*g0q)BMzrO^FiGPYn=Ivc89aa-WgI@k^I`)-1xgPK)3c(hK8OU3T+c2Y^o(42O0zu~w(tqN!3H{i$gowzme8yrh1#dzEPj2J-A zqum{yP`0iJ_wLj%g^JeJR;H2ECWZWK%Mn%7tcvVOIDh-W4eZ=gMe@)t%yTQqOCXl( zf~AfrNYe3OoXFE7EUG+};6AR_++=dGJJ(lWTG~j6w5ZOo zI;%Yn=j51Y8jBp`B;*?=vHrZ>IU|MI6k?*yhilI<&p#j>lgV$nD>ZS*L4Ye>R;Uj5MYM@7qvl0vxU#;bN=gW4;^VqZ zwxtu32&Kgp`b<2Gsx(kT>TJqkPLdVA&vM7z;?8(h=7>jmLOjUUz`ZOD+|4z@z0JOu z5vP)R4e086jE;@?LM@TD-YdDT2xTLe;>N@;aV35uj>Tl->?b9toUjz`#4|>a@H*XA z2ca6Oe3<@!tPOM!?CXWz;bG_%+ykM0-66M8z(iokBu!~MjR4LP3EF;`qZ5M?!?CQs zxQI)_dhJB4H5!UVqDTx-7sHFB4N5T;Nhhhnn3##}J!d@r;)v)SRBF~nqTb;x#HkPo zPIT>vqpoVW>?OoSCw=U+HD#pgAkG{MEr(&5c`D|b#9+K(7*a$b7$yovytWV0jYE-S z(i5qY2#mMshd{0){7D#jaZ7(ZDRV+y7Kfi!aj0Fwp>7d}X9YHRToHoIk5uGypUyTX zYHMo^ei>VSe*OS8O3^d1#i6k!xHe%cs#9}taaIYUr7mzKpDnc4!*>JRP!(d0JWmlO z*y|&_BMFt&Roq|7AC@tazb*oV&KPDIgo!2}VZJyHtIbkT)`6B!j=?r=95!>qu~sky zxrT9AB8x?`$e)Z$oe8KfnmZ+~J?DuBkAGlz%AjnzsA*H^8MZ=v6Y4;`tpQGveD*3a zgq5NWtc7E;FaXQN=~&${19=7`vBofiEbe4h*;FDPg#wdw5; z#b%S|9foXr%s)qM!dJ5o&tMD z=b?7yRvaCj#b}1TNKSktuoLSDcvhi-3!a8J*IkDFzDC#=D#gw)JCuiZCb=nxkBH}= zDTzX%BpvGwhNDC`75Rb$ln7E7sh*0jRp?}3jqxzdlJrLp{VuGpk%NWf&8n&@MSIK( z4<7#(%a(mU)Jk9f1=SWBNQv8WZT!&N4tv6#S-;kvB#fLP8i-Z;X~e@d5APe+9oZJn5iLfxSlO>#r(;c_OLOY2k?-U0uobxilUGieNL-OxC3U%C7YT-P23DA}( z$Gke=V6Z(BC>flD>r0IKpja@Bj5!$y-V71|EdC&t^!kmP$D(gX?=SR`YE{z%4jSxXlE29on_ zR!c^ufOuG9u;m&gywps^dbK!|87ECf9t~Kt=#q&n03L@vIy5GO$)N=`yT$E0sDS@=eq9{M8$e?j4%hJ=yNV z<7WpSZ$H=>yL;D{*Mc#M#)er2LBYwh-4CW1_Fw#V{0-mVjZr2{m5WS7IxYt!&FfK` zoU&$epZmO*9Ba(vx@0C>tl89aTx4~^4k3Oik3&~E#ILqZSgCjY(pmqF)v4DGz4%`i zQ(gY9v}{A6wP$~^jYpiNdt#e@?VJKDhrU-1-XXwaF?yD3p40HmxN}tCe)Y^p4m*TS zGKpHJ%~>NJcEUp=XV$q}1!pe4Z$B6lK52e1Z-(L;UfuUS9w!! zdIP-li}CjRlA@ol3VkL6x5`|$OTCm-{jv9b1d+0T4iJvp0y z0zblc@7aI3mNnJ#w350y->FW%m)q7)zw|R^!P+;w*0=tAyUyriXubOK%Yy&@S=-B* yCx&?@COTC2Ol0Smv#I#-;9xT`jN|Nw|1*?SibNj$_3}3Z5O})!xvXncZxj*(A|wDzfM(L?{3N09{^AN&^4@I{Y^XkP!ZxsXG`Y|Bn#5OY6F8I$64V zeRZ_}h?_f^S&+*+e6_OBu=r~3<1%3(1OSM|$xDfAd9PpOA@-73+`o7Al|72#fZ&i8 z%084)AuS{uo%WC`4XZ9u6Ex+YACuf!tZR&*i{{zue>nV4F_(COf8}|Jb zp*`^q)_j)sMq3l#s%vIH{-=r+yvL)Lic8?HPUAidXHhFe=$RndNpEC+EAzNnt+Vl2 zZ^P|jE~cBvpikwYV8PFPX;<)d7$M-Yj+~*r3Qv;Ev`gOuBKZbv%%u#we zjDH|VNqaf`+u50_$H1)^1_JoTw+~xScJT7&-fP#bD8DG=*(sOo)ZY&Z@erAOZk~DJ zYj87WV9!inGj0rMjJWM1kt^VAZ+~D!ELN4lnEM&xAM^6IDu5-L)7RMruj#9)U&%eQ z3Rekn6`6Xrhic{xoV+4K_w)X3J;To=di67jiGZ*g;9u{>ENn`JWCS6r!23Vn>}(yq zO!<50$+!C0TmT~T(l43avwt(S z?{T++c_zEB=Fpy@TXY)zDxBacoc_!B_l*^o$x#-_d9bfOD5TpC&`_Vx-d;5Ustf3X z*Ey@pnB8*-2Kfv=n~_<2K}nO?T;Hp1p?Q$q*V&oGLuj2CUP&ag;({;P4Y%x83p5<# ziBfr0$tBhs1GVudmVRbzso_4eE;3>wrGqtM4$shqTjU-f`aKS8n?`93PP zcM|9-|G$RY#OU%3*Qj3u?(f;R8@UDW!3{^fncBt2EaQ~Mi!#%7Fut=zBm8kU8q5_4 z0_@})G4Vgk4pi;jw0AR;2v?CBq?3s@SM-#0I)Q=BXUQ2+=YDcbK+vD(_!(7~cS$Hy z3SQluLDFGYMBVI;+UnB{8=@(T1>zdypx49=aa9k_ET(%3ZTKu|SXSdMsP%S$FKF!< z4~ic=lz_ z+OXq`k`LG$-y(Fyx+U*6H5VfGZAOP*t7xsD05!n1?soqej=1(LuQs;L8gF}cbZM!V z+IeQuW0rVz$sK>1e_a)H-5}nZjM4IzXCeV|vy2?gD+KiaIH*u(hYCPOo^RB+eUCW} z+)9k-_VqC0LT|nE#-INJ2kfYAiT@I^RI_YJCbqXg9 z-=Rl!TFMM~aSU-Z7kV56IqJ2?>wtOt=qy5KQ~c3Tw-t9MD+Ggd zJ~&SmBf_vN;f$5~9&$;3_QYqr&{>cC!&W9}i|JLg?6YScBygUJ8Nkj2>P7-vKO7=& zU%YNvseRf6i`OD}7?k_w#d!t?lninc?1;!H^EDUl80~|dVtWfhZ)XmWwr`W-+g4us zfKKVC(pJTiHt^nnlW2kHk*@>$1#-V5wd(ksbd|3mVB6a00W|frI+Bf>w^<{;R|KmK!{*YmOG$LLO=D>{7fc)|aZa zwHh+616rW;R*sifsBK86N9}RxW1U+55pSgrAv-E`+H*?%2kN_WvwkP6*7zya|1!O$ z{pJC*#ulU_CW_N1samF=vHMu+w&(XbTK;;Yxp#1b7UDnq49gRhZj)n8i_UD!4Uu_baMykK5^13haly>=7LpIn z`Z0X4vDe{dhM4h<;HOt_aHGA`ZNEb5p&YaEj8?9+&(&6)yYBYoE0R=$7OgIv8%WJS zu<-}&pc0m{hNfE!wGlYjCzvyYOI|b8I;GyFGXKPY$9j*myVr`U1K;o z!GlrgKGR2ymQbcjShZyqQ&`w3#7i9V?SAd=-%$9ZX#C7<>xr**OHN96wr09h{UVL; z&63|tBTN?>Z5s29Bb8MNAu3De1NpMig=1bp6BNz@{$6bAwD5jGB_w=8Y{5$G${Hp? z?NzoYwFCK^Z34WnO=u1$O0P4x9k=GrFV+=a0osIzug>KIs?$xA!wq(3qC-dLZ(#*S zbXN&?eak(z$(nF+(O$S#8{+QvkkH(X))(Gxo7daYQWM%^17+oaKMbkcaoPg0c2nPl z7*a>9Lri`yVXD*4_cd^nkSpQSms2wM`0z(7U>oTak#-Bd{99%=bqJuQMRaC*qp6|i zC3yYn$8!CWH1bBCC{;GVvOQXv_w&wMd2S+g#Z~=b0yMnTdCz-pC^O#%9|Wl&gq<*R zE;z*L_~YdTp%T3S|E`}?lsGnUK&eTsMWPj8hyJ4<+X^JIqr8TsrB_xxwt|n-8NjG59jyY8Bp3ElmhrytKxt9d8iD!?{i$J_T@oMOT@l zFLqRov;BT+!tSmc&;N5tTd2KuNujKyvAV0f|(xREX|-r60Cr>?{TLd}V3}s;zmJMLj;CoNwLH zepB%9quTWNP$>OLUcQCd7lfj&ms~RVcn!8jR+S~;B+h;pxq%~MkB-#NPE_G5ixHQA zvp<;5#6byzY|BO|1V5H4xJ+AK7u%^ZAmpOUpLE&8_kMMkc1U%qXvu+!9j6HX;q+ZR z`^an=7vJDZZ{>sHP_2iDyfX+BMCF9<;7A?Du3UG~t&G6e!jE>2#h{ z@nd|v^j4TH6}rM2%}WnhVzDhXr%&0^{9*ly_*}695YKd3{XmY$LKqt+yLGmx{7gwi zt4I~q4KW4U+fF2M29Dkr%P7!N_~@g2Z$kLXRh#E;7JO;l5IsYAO{M;#r7n(Q?2axU z1KusSk`c=^|LEn(rv7;48rS`aySO@e;W}F0p|!~B7o%XHl>3_t;1gw!UeK?Cj{F3X znEFNd?R3Lv98nzH}cTB5r#%YT&?D~Y{ugcu=TueY^{%75(p6WP^}iDTUc zw}j`LrXqKkrvTSkLyz7{eHd?@*eW~hF(4B@;kzPZfKbTN$iyPbB>r<*&O8f7M?VQy zC|NEMd9K7zc$|czsKJv|DwH#9rYNQU2t5vh#mgwjvyxo)Jqm zKSUz^sKveMNdu!CEAX9?if?~n$mCche1X`M=4FtQ{u$uAFl`nK(5 zY_)%)<IzEZl$yC)Pl5(0NjSci7*6#}{qN-uIh*e6bq7nSKTlmqb zvv2NSCrMplJ7B);E$cDYWIX8-0oXpcL9E=0+p=pZEtP3LC)?S8N94MRP(bDF%)`|3|59>R#w2MZW8gm4LRp)Fv z@4nR0Lv$c($%%OfN4t>EbV%nvj>Rv-=G$p0r)Fn!0E98E(#)xDLY42SU+gSb3#L>M<2Dj7j zmbUk)ABCCw_c(}6NRiYL`dWY;t>Ux2&e23UmywBL4PFzL=QGAFE?r5L=+AQ9%m>-) zv7$Cc5Zo)yT{|Quu{N3iW@+7_&1c2#tYYFM?^`RN=U38zy#MAB3uFSeGslE?Hs3-9 zr=%y`f<{{N3h46wTgk96Bf;Q1gn|*AnEwH%u|cB2ShLtX+2}cfPZTf72#;d+V!3D? ztw-5@9;Nlr2Iv4es613#_e()&DKr{}wLI{CL2s|cLY_3Pgx{8o5X9v$awXPBi!M?8 zUvscNgsDfB`vrXL4fBc zqnIzDZ=QoGBAAV$QZe^}WtCA3Opc)D=aRN*r(2{@JuIDY8uBmUPZO0d1E*9J9t(An!p{W;>dGC6AcOljxSs;Ke-uXD7X z0*a9-f|k!pg+|ScL6HZ5HHdh|?od*&gE9})$BhJjt(jhY11AAdoq;pdde4x+PMHq1 ziw*G4IV=?a6--cD_HO<(bV?cWKm+PpxOEZswI{%7Tn*{=6NNLi`iSm{P2!mcFd(2Y z)hP@ONLSq~hX+8)S};eS-VO#`>u@>&{sWorXuh6gX&p0^eLe68(9`ws#? zVvncishi1h&^E6$&SHFRBUzKLmaB&?4Ni(o)B` z_d8YJphUQ&LBo0H9;gtAfNC^|BhegbYgd>9?Q1S|<9$yXgWuq9H9Baqa5~3P5LAYC zAxB=7d8D)WY{#=rDTDaA1$a%C(FM?aC8+^%l0V)Z^9}fGhnK4lmwk65Ei-@DVSmhG z_jD4tcrF*wO*i6Qw4qi>?!Uv*$lo)U{+hecP_Vf6)q}@*+@=j^A`7f21w`FMk`NylVR%7M?ZBneTJnV3glGCTMFR@TNM8$$l}nUXmLA z?K-q-%F8-nH1lwT3)||?mlus{ET{cT#aASlAg9V-VOVAYU(dS8!eYrZD&zOOFD~E) zyPjLeNDbE0`vNCuu7k>BVgw!P+<|LUb2vW2)NNKFGoOD;Ee{jwF&8>afA+(|e`yG9 z*}X@AKDqU+!?vt5vdB1`{jd{|A4p*S&l2_@Hx3+!2J(0meiiGzSaFn`+do{kt&VOX z`$UL-*h|$hBB@+KB+HD&mz4AX>= zKE4wm&$X2tbvdL8#vFLr0PVmMvjnqQEq5olD)f_992kO8BS@Q`gRo_J3`@Yx&}{hc zpXSF@eCa|eZ8(X|onjkLP|lp+I4z< z6f@7Dal{G7z5w$&+G>9Qx-->ZVGn2MH;LbKQ)Sp=M;8}(Wg;C8N@J0MKcohE#AYlt zM-x@?3jW)o^{hU;Oy=}-<`#qn*npb|lryG24^CuT`%EmSDn-C+tuuG;VHHVjE;v8- zpuQsca$v+38pr_WJS&T7A$mH?MESHS{2zqP&6F8@VB|@`Soc)yw0S;6O%HD6Fh%r4 zBImI(wplZb1-@>f4LWMr6fir^)rUB}J0SwN^PgCm5@USTf4$X(YaK?yALrlktSr*w z%cK;NthQ9BQ%}nS?G?EqnmR=xwK~RnL@OwxPC7aeaQtrFfJfniWjGp%zMjsDcpXxs zMN?=y4RT^3Yg@_WHlI`}%C%pO8tlbL?y$8Hd6G9d>(iEc6?^2Y(E4>TCM|qx&t5|+ zXuV6HqS&G0)C+}6hWqTYm&DQcA`MI`Nh((s&|Dn+AXd$4>9Me7A)g@*|GJe8S}$JMF|0-?Wn*m}=kK~c)Avj&DT`d6M!u5Q7O87sp~2;d{$3AlQsID zkMYbIy1z$?MNCQRJdme#0kJz=MY1paanpxOB$0#KCxF%^@mz<0qeEds)P0z$*&0DDY=1I5nz>I5G z{q0o<-

    sI>Cz~cq2A9zs$j>tC4tqa69B@I0oK&%4Va+6=yd|+I#c7z{4BmOD{LK zlloy(`7KkIP55C`1vz=ya0xSZ;T9(Hq+XuX2cDmnEu9}22ZcXga-0_Z{3IP{9HK~u zpHb0jbFDJAmqo2fg^)B-EZr=?I#1qyK_2t5blS^3n`_Dv_>#`m z`ZIM;0@M`4cbW1ss9K15|{CxKl|d%i1^P)06Tc2JV=J(!Rc_ID^WMD=+R`F z5hg}XR){m*-TE~DX=e`BlFilHf5DKMSP#bhgO`9_>!SREHtmj^uhwwCbrIJGtWK+9 z=_buNq$%1wzRNq;Rfeugys%D z9*g}L6|OLcq5<>6K;)O+ZSmW0r<16JE(WdlNQkRR_Ji?(Q$?(kexDs~iP7bRztX)_ zgtTxEO9AT%EH=bVvAa!#CdD=>Z{)c9x0J`WydA%<_;E(g=r{Djs3RzmsLi9nVrOB! zb*a{+c}JtB|9cg_iZ(IdE^A*@7~LziOt{t#+K!WAKX`_S`h z5&J-RQ$Ni^+9Qi;&_cJc)x$nUyz((@WcWYRAO@x%n~VODers0dH{t$?s3JPqMap36 zy5L9fMcSD}(xj%@pJ(H0->~E0JN2of-+X;E8Cb@txDN# z)F}f;7Rh!3TL%ZXWXz__`E@Q>iAvlY5fL{NyL@-s%|hFx8%BO$5^9!30UsK2$$k@A zPb3p`rPS+&gfce;cL;H&vKXbkd`kcCb}6b{jveHUz{5GJX1)k@)Af)XD44mjA#SRU zB5!{B*`1bS53rA|?=WYXoxNrc#OpFnf1JQUcR%CUXI-4oo*&-Dl>75YC{{Lx3t!84 z9lXKC%xY06VHUhmY?Fw=pm%YA>f z{kgH2lf4aSjFeC}QdJIM<)t;C>VXRKYSG4mH*52s_E-sel;gTqQaBmj9P#assVbWs z8Q7g?%P#_6F7Ffoj@-jJ?Hb~pdQ0C)bQMD9 zj93zyOFVnSHISELSEghGVm7~@`2L|pY%8T^;~#D!TXIEUp?0!EP-`sGA?mufoyNN` zdS|3tdLRw$PJfP}cmeZZU&8Xw#It3)nEfvJ$t^oG)%!z?YM%z$19!~?ntWsB2XzIJ z$pw&QydekV)J)yLVtBVqtwCY6f|vPe8l>#=82S?g#T0;~RzdK${M(aB=-K#8ZSlo| z6ft|ICu;g71_tRNZfA+@;}!g0Vwp>YoGpq%m|4VD3J{Y27y%MJ-Y@hdAgh!u_{Wz1 z6@!Bp6TTu!L$krmgIkf~ubzl%EqETdMytz&5Pw0uaRB7D`DT)gKS)4UpL%HUcx$4Ujt=aob9YF_t^At{AkthqW40Xw@dUL#x30^+ z>$19<#yTo@=5y7h^HYMQ+{kwlNUVAgRG(5)j$Bc5$wrxbzXwpyLz&yAaPH@)H9;?< zrp!9mJCT6AHD>cfh$lwj3{ZdM%XH7#V^o?%tTnP2UmG2jcU~1-Lobarn7DQ?wRAoA z_Yb>Kq9L=W0ygN^N6dOOU41BN=rfEC42reYkwv~-{21JmHJVrew{%c{WXeI&aLuaD z-&gu`W3apED-KP0h85wT5w|AGMhD=QA@1Zuzv|_=Skgoantq>}WX^iL^9*5Gt~MfI zr3gJhA8pV9vB>B-5e>BIKk6&8k4%HS4M8|lH*)#CnexT__$HITzk$Fp=}dvnAcH5y zl-}*O`;FDvT<&(FKlC4T?w@s?Md%#C!nQ7nKr=4Mnf-a#rI6Q zzGS`|i%r(iRI5FV+~ZFql)mfq&}MtTeUY3xsVsihIPYZ1!HD^?y34|>1B~1adG<>ZE^IkcGb*Up zA%(nYSGb+l9-Sf+%N01~TNdkoarUai)bY`L6g8BEYYdO5^CJ75)9hu)RX!@YaWmz3 zgOP#MZ7W@KV1-Lw0nS)^`F!%h*x4eEcabrWyyW6kGEhfx=Y8eb%4cb2K<2sZPTIT* zTt#X)OXrbl)DdO5#aR+ZRHfS)snN_A{6fP>5dqbo5LUZ*deUuveKpe$8 zrt#>o2(76m=!QJT)Bp%)m3QDMPv^UiWaYA9x%wvT8ZtII{(QT%H%gecdOLIapm_^= z!&$lcB+nSE_E#xdfhxQMbh~$Agah<=-K9YTq`U^s;pE`9k&Zi@;SKUs77U9!lZ#rp z1zrYAxD&X(@DD!|`)v9j;of7eB5~*uiBI50`2LP_Vm!x=arzc(1f|SjGM@w6>S2C;K~!ILY6Zgq6EWX zg>1=hvOZFOGPL>!Cz;w_ENr%rz~g&C^V4{ki<4^_v!`}DJOLRdW2KsVh?o15gq=n1 z=Q2-fq`Y}(`$wKjg~tEM|2}5*uP;Y`l}GAzbqV){EUz`@*6k+l=@%egHa(5SdGXZ) z16{RCL{YJ|fK8oVZyk92G9GT(JwM*rtHmwr>hH+?oBS2k;}@ayCVbGgAe5r#^iv=$ zVPk5sy*~)DnSiL$ynF?@Im>~;+`A|*!rTM+k;6J& zi~2zC3D`w+#l2%h8XXpY%-$yFg$aGZW+#znd6ZvDEKn}K!g2I2hrP3v(;m99&lK0* zvj_h3jAMAgK$JAuw!)8$3O35%o2x<^wDMaN@?6-vz^Toav)@{bU;9E4`~rVk9XSfW zDROZwke!fGW@AMqHkYl9fe=`0g!q_N|JxlEKfw}UI!O9VIyqP8KP|?V)wngYRNbWAJw@!8mDK!Wg|_g&==1+3fw8|F-Y|tO#|sU;C22+OaN;Y{NoWmEl8I7RTc2eF!%%>bYYz> zhToYUmZAvX?fhJO&65uWQQl09Bd=|DCU1^7&2vIR5hyW#6GzRo5t_pz=FpzDKxS~} z-=;@hPNFUP+U_beohWBnSa$*=#+^-dcOIl?WKi$E6<+ynl3o1xaY{yrzz`M^YH)=sQz>D8m-vF&K#I689Fou`2|pWavqEOCaE* zTJcw&4E1)~r@K(XOyJsk|KvLu05#zhOR32&(g984KTi|WD7A9d5 zBvxdWA^6El4->su%Um7!yPDckzgzD|!Cb#_MFqie*OwIU7TcW1Z?^r{PwQiHm-n~Y z=1aeXH>}pNg4-`AMX`lNwe350WMhGQ4#F!;H_J-fs7_ z?k(bL~fW#FbiT`@GtsW|oJ#s-3_NuC&qZFWv6jpP5wL=kqnPOu)mdXDI>aJ;7$C`p2+c+fa3-l zY;DtVH^eJ=IkHW8n|)6yhzH0?4@<<4{!sU}nVO=3mq=QbrNZhwp1Fqxa|`NUO$j$Q z;oh_Rdq=G=IOkk0q=T6lX3MhHVJV-%Vyce5pgBd@nN#T!g!NaVkmgYqVnT^)2W|_J z+Ul{!{nIg6nlKt-)hzW*Q(m9@wCeD+whxGcSeP?U*_h%5-2O-NuaV=fj3??&C~Mr%_GZbXn9=%CFAxqZtgT_ z$ut96@w>1cN;%;Z5$cWqL=?}I;kpLr>u*PzV@A-PM||JH<E#=cI?d-}b7Q@-&O;y<6J=i)-_#y^)kLcDnu%(?X1y;K1>C?3Y)Ar;XP~c{Ki~HC}Ejp3Q5CO6Gs9xuxii-l&Juf$QmI=zPm*7{b{W z*p}ASf2O1o?>66gN6LT!QATrlfmna^U6!BEN~Eq|m0WjOiGE;|f;~jb&vgTL$6jCF zwN(EEM;5Rb+KTt->gj?AC-fejvtgQr2|RCxs@XdyvWrhP{fy5iZbaSrmZfLn=|Qhss12tXmng1@=Qii!mkts;Tm zF~rCY{jCs0<4QHE`dfemtJwqem9sUgkjrn~Gc8eT}0Q!K-CE4v;MgrSPqEh(EZL<>Udoxw)h8#lG#>Pm`?| zr=;aHbVlUhsN=KfXNZ*p-moa2durzjqn?#r>RoTNMw{(s2dap|_}MU>e z;Z`l&IG60zACYj|LKU4Mb#7OJlI>8o+GC!JpvVGuR=dHt{e#P(XPZA>EcV9OPD-dwgDn&3?+lFZ>uvttK@TyB`5*yi z448#Kz!2SOg=K*n>-U{G9PiBFa*r~+CyWIV&-|pcANu}{`c2_caQIMtH{+(*Hkw0d zD9j7y>37gt4~dzXzrEdQy+Cm1miG!VQTQMZAKi&si2PlR3X@jvs0pkK`%M|tJZzJM zHh*WnJzEg1#Vb~8&AokXCH-Xo`QzV4g(MeuE-nW}cvU>u6yLSxV*TUH*LK!4_4-*0 z3Qo{Mzv_QZQyOL}F&NHH#_H|8z{gRrx9u9m=VNMAjV#l^^YOh~6MfHgr{fX-xLI2e*V9=V$y=1&}MGS^I&c;`-Z3LUUwNQ319Y zN<>v1H_f5%^4IL=b}1ay!I!p7a@h;uJ)BfpLeaI^53))@9~BRhxktp`Mp7qrOCMm1 zMx04rU5xIddr^TfQNr7dhrVtB?yJ~aT~W3o#!71Qn3D6l6Ei#1PT(bZO#xnbtF6LN zf1=bm)lybRCi(p}c4}CCsgb{8Cu9_BPf=LiBKM=Zw#>&47<;~#_M&pJgN`ev`W4JA z_aDVYNqc7iNv4%?ar~F3wy?kx;V#5QrO(1U57$2-p>&rs60TydQ~&WKv8l$xl;m{bH-( zSF{ZzKwunsnrKqvzXt`Wf{LtAr!G85glw|fY{#h;MZia<1|&STx_x(j%^*CBxe7!)bzv z+;iy<&-zX$@+KeJYKIz$XRVP>@INyhC2?nd{U{hy+CF0>A-B6VEH3WOFS~2u4EI~Y zfGyf2P4dD_(G^ymTQrvC6uQnGDF3`h)AS^eoEt0$Hranh2`yQ!WSJU|m+JY;SdW}WLJ8ab zBim>##r9;;tEK=?NwJLmm&1bdE7kdTd+HM*gbNt`fpvu&0PRC&p30nK;oto%EHSHXqtAl!oZAY@u4mjQcK**XoGlxLg`N`Hja47-WaV~9m6l#qej^@&K%w+@W1{9P z%Vnk}UlxA)0=_NxM;*5}{pkHUTK!R;&QvEQx}Q?&L@h$;{XN*0Vz7HA)4UaFe;SXL z&|v&hR0jR#tF_eK?QtTP6u$`TJ!aY`OEaOXBiSDf<5#ThDx8s1;x=7zFl_VzoUhzk z#9N6kOwT`5{`(S?gPB4b!gcXbW$1XhZB)&P4{01+gz)*s^ z*HNT`8{67RDsQH=l?h$*n|^1z$geQZnohmwUNH-Pm#{PtslrSVH_ctT@}wU3QNRlB zNr+pOSHYzsqoo;Nr6qVR$4wCjQ2rFtV>gZ?+F*F93*aSVH0K)n4lBKEWud_vzo2$$ zFUG6kVZkSd7kW~q|ITPyzZLYQK$v{gYAJPQ#nZ^uGW za&9nWo*%&IUxQPYV5QkX`HL)Je0DcpFiiJ9XdP+p*&xY{k!7+LEXww z{lSq0&xMEbPs>2&E`}rxNSi3fPA#e{@e}GzBC-a@UJVLi3<@OOIX@PcD1>`R2QnG_ zXWB=lP5-Xwmf9e>LN}@Lu{SIMa%kpDpj=ya!cn(NuySQVEu4dAo~FXpDp(QZHxB<# z^?-v3EVbH~Wc$WKqwI!Dq!%P@_j;ekzRpstn&Kgb)8F5#F=&)kpIW*w&8C+q{LPo3 z9WgKyDwS2p8#UYYi4^@4<$HG+&yuZDGlrnUe>gdwRn;jlkmWC4WKv^p_F#1q8u5vA zN>St-_PV0!r#}K`vCO|(C>S~=c$Y~CJ`}o836}&LmE_Y-EgnSo%Wli@4&kgTAt;Qc z?qb#;cnWVNrf*#xyxHh?0$g&Wkz?yOc3<)><5m(08s4x`@N2&}$L zZvDrTSod}e{@Zys@SbAl-d{nYNVjZAQX?{Fo%MI2afGdGIoa6ur?bWc&ejdN{Eu$+#ZR977`!dGf@Jf9Kx3S}*Z@$UdihkHfXOZM| zUNoymWlTfhIN0%`z7VB3rlmnG^N6S{F1WXZ1!0)Xp-}o~9=eFl!Q=C{9WEy9N2cUfR%lk2+49#_XShOoQmr_k%U6fm|b`f%FdVJ zPy32>lCBaV02-NKaF)5VVg zdyXcFz+Pd7=(eQFPJHg4{)0VPGbcv!F}7a`uHX}bU-FVE2aP2>rsC7^6CSi4@4ifV zviRZCWXiBxExcdaTeqhxy3hw>_M)4vN?W)IjlgxaPtMYD^hR4x{Oaq>M>`G>+|_J+ zBiXNTb{$(>-_R7w{;i|ljLq9%s0jS5r7tA*_*H(v(1Yq zu>Rp&%&w3;oW@>l^x-+kK7MEX_=$%ng3$f>X2lJ=Kp<1nGHLSBTyL-f+od^n+{Zjs zbsWIcVzVrQr?+s*IT9g2KZeVYXY?a9;T?UPO~+1Krlm5{8T~JPQEQZ!bU=Dcl96`* ze_4v7#2;O(sHQH(p6p2{+C2-{jtCxwLPb1_gzD{~0XMJJNJ$UH!Xk0`UJ<#AE@|er z>POEK*`3|JxpO!D1jbMIOOSf%c(5Mn>YI2}#wSI9Ga}bUko9C&7KbY$r;3upA4puc zU-6Hit=U)9KjihcsadO4UHI=ePggeiMH`Q4zLo;~+AlCLr+I zD=MS8g+;6d4cxk@Ob+!vmMcG*b}r zE$OFq4cOGuimDxc(B`Ib?C=0odE&Ty7<9>$E&xInmw4#l27i2spscMo`~nT$inSX@ z<)9%I{#s$zDZ*M)jincTS@#}y=vyH@Exsp=kfO1Vl%4A>c0924S-HjjR3rpa<{gfO*&X!P5oYM=YH8 zwX9k8=`tW$FMtE^mL0+)kUyw`S}B><$7;H+K|a`i{H6!B5`c*5Q#5lTUWObbkbaBP zvzknwZ8G7ZT-D0Dfo|Lbuh_E>nvacY~)Q~Y?A3yaj~bDI86QZ{Fk=zQ8wsb;wDZu*eo^xwwg;8no?n%>_{-3@1ydiz7iMJ!Y?Pe4EkEt1x7{A4zfTW3Y1V-8A>y-hnY=Lp7yAG<`Hctf# z)aRA(X+_v=3`w0aF)cEs9!fLBA>5Hpr?gJ(Oj~b3W&xX$S$LwobJ2$(`sl10?6Wk9!sac*W-p@dS5F)+r}-$NIEW#GN%&%zu!v`~-KR20T-; zQh~2EAAj{>;?BulyZIfZY~HGqDXV?3WAC`u6@l(^{cb(LdI}hg|B8FPwrf1Da188C zK1}1CIR|#gkp6ogqnh8lmoot`R zi>np4o&JWxSLnC=JIYEQ{t6wCW8}ZDjS9j~Nwd3l zMof!6YEa4$yQ;S|aa2|FD7Z~5`W(yQF37CQOQrmxbDSl9D6-S3hFT_psZFc6)PHAN z#4A(s;xw1x=2ob(2RIwiO55CfwUXnA#Ymnow?N+U*!=z&EYOuB0Q2#=nNhFwWhHNJ zpZGjhguk6BDa)oxo67JP;UgyXPcJ6yr#Os>A*B$?Q_ofnTFoXiFd0Uu*#%W&#)Nru zJ+PN;2<%xxd2WV+Voz`udF;s+hUs)hdA*k9CqK#aeknBhZd^Qhz)7FOV%=>+sapPl z>c1*_AfOk7V!;j%FE}UnXm_VrD{*deoYgBzIH8n9;^t_xl^EwRr36SE!L_hZ5vYbWqyYWYJXFC>}XSNQ!BV4jJu oJoW!ktp9&q0rV)({{b8G#0V!Z literal 0 HcmV?d00001 diff --git a/public/images/arrow-down.gif b/public/images/arrow-down.gif new file mode 100755 index 0000000000000000000000000000000000000000..4101399cf5157c322d8f5ef7609bd8d20b442da2 GIT binary patch literal 454 zcmZ?wbhEHb#3=AJH&AsXkCfB2guNK|<#D=+@> zlXaug0+C%SBSH^fU1-hVYr4rwC$Dw2TX6f`Xb0CBui7F+7#Kb}{&Uh|*{=>Xg2B_( K&t;ucLK6Ud+agl{ literal 0 HcmV?d00001 diff --git a/public/images/arrow-right.gif b/public/images/arrow-right.gif new file mode 100755 index 0000000000000000000000000000000000000000..e1f23827f67b5acf0cd9739c83f416eec23fcba7 GIT binary patch literal 70 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 P@J!~WmL|2v?uq{cp8bgi literal 0 HcmV?d00001 diff --git a/public/images/envelope_icon.gif b/public/images/envelope_icon.gif new file mode 100755 index 0000000000000000000000000000000000000000..21ee3258a18211220d6e561256d17368ce760634 GIT binary patch literal 259 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%0AuC@w+YI!j$$7TJbMPVRd=vkfI> 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 BLeu~N literal 0 HcmV?d00001 diff --git a/public/images/indicator.gif b/public/images/indicator.gif new file mode 100755 index 0000000000000000000000000000000000000000..915c1984cb8541c40f28762a09970b6578632aa3 GIT binary patch literal 3897 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 literal 0 HcmV?d00001 diff --git a/public/images/key-square-1.png b/public/images/key-square-1.png new file mode 100755 index 0000000000000000000000000000000000000000..94a598642fe12dd1e610608ae948d7f2064a7764 GIT binary patch literal 2140 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 FV1kjA4mJP) literal 0 HcmV?d00001 diff --git a/public/images/legacy/beta-flag-legacy.png b/public/images/legacy/beta-flag-legacy.png new file mode 100755 index 0000000000000000000000000000000000000000..4dafbfc3bab15de304aa2f609cbeb5914ca1d09c GIT binary patch literal 10817 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 alHrQ>%ZG;MUe-YK89ZJ6T-G@yGywo2ayzpC literal 0 HcmV?d00001 diff --git a/public/images/legacy/ccc-fff.png b/public/images/legacy/ccc-fff.png new file mode 100755 index 0000000000000000000000000000000000000000..de89d0f11bda0fa6fcddceb21c493565bbe78b14 GIT binary patch literal 128 zcmeAS@N?(olHy`uVBq!ia0vp^tU$~qzyu^0pT4gGq&Uk89MfSE4EsMEF#rh`ctjQh zX%8@VJDF_mdKI;Vst0DzYuRsaA1 literal 0 HcmV?d00001 diff --git a/public/images/legacy/drop-shadow-light.gif b/public/images/legacy/drop-shadow-light.gif new file mode 100755 index 0000000000000000000000000000000000000000..3cb4b20931666b315b30d2f70f976c9944356939 GIT binary patch literal 7047 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 literal 0 HcmV?d00001 diff --git a/public/images/legacy/fffef9-ccc.png b/public/images/legacy/fffef9-ccc.png new file mode 100755 index 0000000000000000000000000000000000000000..3470c73530519705c1e924fe40395e8117f95ba8 GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1g!2~2fM>D4bDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MY^6Yjv*Y;$v^+US7#PV`1$+0KG*;6@9i`G+}HRMzdzuo lef{4<+WqI;&H2yTF??AoJ8iB+{5+sW22WQ%mvv4FO#rnaFNpvE literal 0 HcmV?d00001 diff --git a/public/images/legacy/header-red.png b/public/images/legacy/header-red.png new file mode 100755 index 0000000000000000000000000000000000000000..2d6bfa6504270d265324081ee41e7583d6f723b4 GIT binary patch literal 1035 zcmV+m1oZofP)*K?qCpyLIvGfQ?hmM~6yn4rF%MSqv0;rB4 zLb+nr0lAgRuj6{4Xcq;W_?4}9XG5h53}23D!tk%1judn5N8OLHKHdTPuA>R(BiPPh zh6h%~f4G!X;B|@6x>=C_pTPy03LI|!{hWUI}Y*uf)IOGz--^QQCZ|qJ-6l zHL{YVi@4cAC8oc&H??>p*I^S^J(zlxxdo>*ca@4P^2B7mJ z`OC|PIz&3kD?470_>4@5NOGmn8^}YL6`W0dJm!zGD%UN{(jk$PV z>$JZp5S`*#CpGhJ$?U>;xjXWCzW2xcJfG>+>O<-QmX3w6^VwgzmnG;&r1|kq;C_I(6;?O-}4kBE#s4x_icGF zE5FMrXcm^RzCzGfT4ygI>_>LbGJ zf64V*=Wn}14G)$C>LUp}4?0NL$J54CyXy4eTE?!?r8Nz%R~4@9HgynpBF@u_`lF8< zUrRndRk!U;J+}Ossn`|aG3z+u`pjpw74kS(A5R`vk3a$}{)fD4)i=W&x+mJ?+RlAt z4bT1Q_r`}hY>3{+)2h?SU*M=v$w_Hg)WXfn|9V|ETKA#7D}_9dc;7&P!{dxhu-1O0 zEDPCIu-D<|mQ^A4y|Xh_t5+SFeOIA*So}^HG9Z0CWcQjr5%=PVi-ql2{w)ICc!e}C zmjPR}_h8}u`9uY%k0TJa`ir3tI|qG!I#TR!x#%wx??0gDSr z1<%~X^wgl##FWaylc_d9Ma7;jjv*3Lr=EA@Vm9P)zNl}IImg2G*`5DvuMRCOF>B5G ze&9q|%=M$;Nj-(1=kPN$v-F*DnPlj8}74cQSB(s^l!)U&ND0%HvIng^RxZCpV#$G-pcs$&$x3PXg!0ctDnm{ Hr-UW|9Y0Wc literal 0 HcmV?d00001 diff --git a/public/images/legacy/kudos-legacy.png b/public/images/legacy/kudos-legacy.png new file mode 100644 index 0000000000000000000000000000000000000000..e974824e0b134db6368f02ececa8b4aaca7197ec GIT binary patch literal 116074 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≪qPe$l;oo3XVmZVu8C(7Zg*Xd-cHr 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

    3sMqTL&M5=j^5zs_MuOj@g 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 V#P$2%{eUJjc)I$ztaD0e0st`hLSz5{ literal 0 HcmV?d00001 diff --git a/public/images/legacy/logo-stroke-legacy.gif b/public/images/legacy/logo-stroke-legacy.gif new file mode 100755 index 0000000000000000000000000000000000000000..2df6d93cf34a28b9817cc693cdeb3be13f687cd2 GIT binary patch literal 4216 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 FV1h*RP9gvR literal 0 HcmV?d00001 diff --git a/public/images/lockblack.png b/public/images/lockblack.png new file mode 100755 index 0000000000000000000000000000000000000000..e94d5505fe62aca1dbc6d9d82e8069a99f567b2b GIT binary patch literal 2965 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≪qPe$l;oo3XVmZVu8C(7Zg*Xd-cHr z=PU%voJcs-`Ak(ntn(XkNg;;t_i;TVV5w)qt!m?gQgCzjemt0T2v@VV;7WQsuIFsQ z^{lP9U9=lFChoz2b%P6>k?B5-l(Zk!$8jH5YKXdFHVLkt2)v6K*KWKV{KVsckM zJbLs!56C|B`2lE>()i1} zO9rTNI@*^NpkZDbR!ts;S)+R+fxKL}lLovERR}pK)9Z|p*=;aq*ag>@U=gunxU7iW z?gLTWE0KPtg+4kyIFzxDv*2fkufDafL#FOG&l(D!&~!vg>g^Z3AwM??9>3 z06y0i+3D?W#<&vgj79EBQe_*(t`EQa7Qg=T6Dz9-(m(Q;(NB2uK_XK7;g6?CO3D)P zB`h>F;AdhAFIB-RqJo|>cTChAg=*bGtX4`vg+&sVCyF}q&kpV5&_j$Uy?pIF8>UeX zp=?O*j%mitoJ}}Cv6&#cIBQmWy?5_ky?QzdxS|=AJ27S2re^gi!-v24q^)I}6 z`<(Um%k$^pXk`GAmEJb1AD$nWiC=fj$FT(|xU@1IKQ)fS>&{XEcqD3m*IG zBxAPB9*QI7Suj#2Sl+S;m#$of zr<13|7O&xg=8WY8`#P9ePzdAQjCLN%d?{rkdy`wUI#AMM2pgwisUsN4ZExL73aN-W z!;5gCVjpHiWN`hiaTgRHpP7JZDG}2DlV=wV+)jD~-84-8Deq*@*9Bvx*D0ZF(o8mt zch1~|yMY6HgN^+c;`-Q~d>(y0y#Z$u>u_WGZWIQNU=OsSpf|p3or)7p3vsM@CHB_L z#lG4(*uQZGjyBE2l|9RGY5P1}Zk>h)yDBiq-I_h1IDZxizI^p)ta2EQ2_{JhA*B$l zdhJDPu`_!mPK~L>gNb`^Gphr4(n#=A8*!05{OQ~loFVw%*k=}w5<@&f^Y%Snym^gxZ$JGr%5?GU zWgH&(s##MAGz_b(vr(@<9?dEfu~C+bI)i)^8^n>JRz>lUM2gRzb0w8{zhQmjIcZki zZwkJdxErU3R^d{?W{mYq5|lE3Et;_)_21Ud|KnF|VBm2f9P2YpajPZ_k9Uqh%`|^5 zFi*=&#Oqg2ndyH@Q6YI=btK6mv085&%H?xWVOqe$icAO&AKvyQ-t!T|3w-$N6(0Wj z2w{-{ya5f<67lxLa$Hz368Rp=oVgTTHJN5I?4QsVPd87&@3o`wc6$-pCJ$nz66av8 zA;!4a+Zu}vr6kfYt8iQ|YQ?RTO}Ls~hZ9L_a3Oyq_K&IHSWUcdnT8S$d70sMFB_cl zQ^x6T+Suc&h9jiN^R2Y`{7)!%l72Ay>jaWAs51<#$c)6#2iNhGyzq$bJdgC{%a@on zX(~5_i){0P0j2nQ;XaB*t8p#02G>Sa;||@&mGo*{DXv3Z+BCSC+dxL|aqz_F*tKgH zDVRJmBL||du^YqDP%9%O#s=^dz=;{XasTi-^!1QBe}u)iQBgo38M(nx4(Jp?gvnRE7bZbSj@&maVl)`A;pP3+k&q}22AQI5A@@sNXs zyfj1Au*(35OZR_?XI*KHJ#@%0lEK` zkzw8&>w-%`X6SI#;(c+@R78xqA$(NjI3y9q&p=ff`I+gs|Mgu#w#$U`pTw-;_tMd` zm=kPBir1a)XN7SV+LVgWDl0&X!dR>}$sv#HLaAebB|QK}nVWwqE}KevL`bEHze^;+Z}!Bp9(en3Np|YfB|4(9geq zaF;FGPv8Cwe=A>tM1~lx-xt+J`B(wK}AW1F}-Z@ z?T*FRzhpE9n#pm-Fo9ym0&P(TEWzC=1eKq*Ou(NtY51^fB32Bt;Y86Odj0WGU7UZPgRqfKO3?x~G~vCg;}=Z5Qk zMz|7egSiHOx8Nxu%%&TRRkT@IX2$vB@zyG??RB&=!N-@+yQZSO$M(&g(9$p_0XM+n z{>8M(6r+tJ4@QvnW?Bt@{>I_cxuS~4P$6$mFCl0Qei6|TT zd{Wqx^%HSxUj<@pqNY5INi4rdiMxI>hS(38J&iO(Q7{7UF1Gr?TTMAYb}ahK0>s~pY+coS?~ zkTL}m2Bjm$${js4Z4s(sjW}&LObJZJ#j;)4lV8JL%#2$X)iAAB7D{3>*t@QFQpNFb zJ$xQ!gvAchxXg;eA^5&yK29%5#_F*l$n0+k0|hCrcK5Qxq2v1*B7b`Gjt4!91_3eT zIc-!b%;k&`uNI72U5UxR!L*ROuq-H)%g@N=5arX0=j@p?60^xjX=Cl^Ik>)L3$|y@ z$C`u*+^(0NlGXNa>*W9OD{n;FGEY;7H@0$m=wi#?(Cs0p%WuPCyxw+N2@UO5U+tA^q2)~QJLvgV_Jg=Fs9;b7vad-ND94%?Uq}XJ5D5|jn2=eeDB8g$7j9tz; zI2me(&jtr$vbQZmP9tS4rd$;Yo91SQUw1bmr&lnH>DiC%-O0-O^y$ysTz~N78R%-7 zGZW#e!NoXNT8*Pmk6i zIlzRKcU6)Ho*gSk$zV^;)@J$`;!$Tge%V!tl}Vup)sYO;P-g|4SUnccK3|0u8R1;i zA<7O#C^Ig0ATC#I#g%#6ak97>Cq~!ddTBe3r>(}Nu^X{FZw0pyhWmu!m!EzoMEG19 z;lMS!pYZa<~a}2(@U5q1e zAAkFS9E=T9vCbx$thLNUfpRpTC0lA+;JcrGU*) zZM#B_(W6tA{mZKPzkiL%%b9JWru9bjNA}WmLF>>m+@87_x29~tf&A6zoW2Y_Y#lkp zFGqhe%QYO zWpVZ_d?U!K?hiG?`9LkE6geJe$K5(&1Gg6i<9+97{J3HuUN#otQNtouP*G6P5^jyd zaSoVmCiSWI(euVPOOK-}dK&ky_A~Oq$;mA^S=NRTevzzz(sVc($BchBP7CiIu1QMl zY7G}1Ew1qJ7;>Yy~`%zO8WxjL|gH_Bu3id$?5f|D~{m%>TM~*Z`;c7 z;H7T8ei?MKtiZ985gxW!A(D^sYEAPnPCbt6u8q2sRCMJmHdVwfe;phO(Zb;{ z1MCfRK(U$_V8F*7Z9IrPd;g5BR_}Em0S6gReVQLQv#w#gc=HywD(!TmARgQdmhyA;@(f!I{ zpq4B0Yq@cZFf^f8b&czLKf zE=3sPIzeyIEPXQ83O#Azd!KM2O?DF$yrw0E+v+ZG30op zrK+-YoFU%x^M!f1-(JDr2l+TLYIrReF+RM-%UAC>(X+LwkttV(n{>yK{5sqzJ%q*q zi@EmLRacoavh#)n;>FQ5m^ajs->Z7+DExF{4ML2h&puc=6Zbn8pn7a?Sd-WAvDH9c ze=o$iYB2RlfW0wJZ- zOT80tXHo}lWNyUc;+;5C)Qlc_9(>I9WuPhU1sS0wz?Eyqi@VA2YkM|6R3!sz6Y*DN z0zOub#G94zcvGE?KX%N))r!DfBl#g@GU*+CmwO|hMxTJfz!xJ$c2%TK6_bFlWXH>jVoVWXGMPhr*xdNqHHEx z;faI8@%-d^3^bK0UDkx#;&O-~&e}-X+txr`PA2stkMnfBS&k!E$Vswz?fM)bVi-7pbv4mYB=l@=^?HBsN*hR08Sqv!v? z)58U|$cyJsF?Gy%{@g{wOY!CW9fSmI*n7_&84V}e=vgCz@%(5xdK*Yh0#`aKv3c19 zRyr#!83soB^Jfa!EHcB2UEhlkLX(V_0U42QCTi&8VvMZbLHxSjRyugFV*`FUS&0V+ z7vR?3r8wQT7`5}pA-zvDY*jQ^n9cZ-gOR)W&qHgG>#N5e+>X|0y;mW|%SCeal2Fu9bbs|;TKJMs!=+$D zoN<%kswX|8n19<%mFt3s)8}_1Lr^z(E-n|g;#A@~+%0J5S+za1oH>W^1u5&5Kt0q3 zx^RKa>~Iad=p2I&8&mLl)et;gKN!!eN073P!jtt0__-zpKXy#PFbZu%;>^R^3Ew?< zOt$9(kChZ*OH)fDt)&w56!f7^#wOUK2No?{hU<54^Kp)7j2B2_`mEVd(^i2Rp_o~@ z_PE*YwSIDhp2Gi9AJeoDT8H_>iBXegS43*+l? zb4&})XEx)@)J^!RXgdxjtw3)LM^>_olu`KkkDnx7CyHI4P@sP9{AJ`P6_JAKOQYpU zK!=z|z+KS_-2!|_s3}HxBbDWe4BpVVI2N9z8U66h?mE~Uq=#d{S~wS?i@pB(SY#^_P|AD+;HYPW zA?`g6oe+hXTzAW*QU%DGDTl zJq$2rurIFE&%|dlGqGSmILFjtqb#&d5fv1HysT`rw$QMLq(BGF zd(kJX57!g>=-OlTh-r8*VIQs(Hc8cBE}HoB^J?<2=KPuA=KjbriYA1j#4xtNRso$9 zdy1K~rzo~Q>r9I0L7p{CoB5A+69P(6lH%AYjze*0+CH4m+Jtk-8*n9SBRPd?1gcsx zls?tn2={tgVwr~-cgU<7WR2$?WAW>%c)YJq$A_(@__Mtjzfnl=dfQ|??aasbO=EC$ zQ6^LDh_$M(u46fU`|c&jvsZ3jg{he}bmjFBY3R>ID5hM{ql;zpm*JP6|G=vk5`Aym z=56qBH-!n^Zz6g3YwO(beXS{Ot&rhCl?*?3I%EG_CqCjd_QzziwvIBgeeq|I{y%E)TFmoT8(wD$j(T004m(QM$k00MNMb)2gUUJrVZDlR2 zG_A?n>XY|!$0V(OSYnopWzIRAN)K~&!>_+T6y3nQ5Wl~A4sSnKjti#_3dGYb6Y)!Z zF0$MuBD3BU$7Z^jqo;ua!{mH#W&F8$CZ4v=!pv^EyxA$_?e+v);6jKME_b)W$tXw6 zu~p$Dl6#l18xiyoMf~&nkH!6UpQCZeG_vY~SlR|fwgXUZpN4XaG)y%fh7oEZeC8@j zERDP3+kVc<*tt9t-yT|z&5QDoALYpkA}$}Y&_k?yV5n6n7Y&FiF9Ex|yZB(?jQOmz zlL|_hSzi!#`)VlRhaF2%p5)4~d(*s;`1Okl%t{Vquc@V|!hONoU7sy#XG`cAR}w_7 zCj+%H#sYpy5-cA_vD^$j3MbU1HZT9K=hgpT6xxkEL$;3!3WGH;v9C3z4YtDiEC)Q^ zKLZ*4oS;Dhy|KNSVBkl*rx2xe($PW2F~FdBPBgu%y!40H@;|a4F6WXG3jqJK7nS$;+PT<%~`;!V?^oc;1dM z%wuihaI16|&L=kDPF5SPr&Qycu`M{9xfp)Rx`-vieX5%wu95Pu@HS#}QXcP!=Q}6k z_u3S^Y%WB5ZZyWx=j2A%pt!Fij;u_lproW)b5 zBqq>3>!8ef7*<%MB26h09x_p&qJgMxVNxyeN9ip0o3HL8ZD0(ei%1I@POtUH&ke@- zZlw%AuF=H9HMY1@6^UVP(%P?Bx;Xj&nz9}{cFfRFP6d7>7=j&NEc$f&ezZBHuw!;` zmrG;PJb0?vaQBBe&k{}L@9979@PR8zaE(!5J0{{~%V>OCHv!{AY}hOOT@IHKXoNd!v+!

    3sMqTL&M5=j^5zs_MuOj@g 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≪qPe$l;oo3XVmZVu8C(7Zg*Xd-cHr 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

    3sMqTL&M5=j^5zs_MuOj@g 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≪qPe$l;oo3XVmZVu8C(7Zg*Xd-cHr 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

    3sMqTL&M5=j^5zs_MuOj@g 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 literal 0 HcmV?d00001 diff --git a/public/images/mailer/mailer-logo-bottom.gif b/public/images/mailer/mailer-logo-bottom.gif new file mode 100755 index 0000000000000000000000000000000000000000..933eb8664724d46738b456ee02fbbc4d807025d9 GIT binary patch literal 3722 zcmbVOdpMM9*B|3Fq#P>3;K76(XB@^D=P{-silU@c!%R_QMvTzj?Pi=SM1&kN4i$+I z5h|xdYUflNDT8r74LLPV@7V8df8X_9`+EO)??0aBUiVtR^;>J*YhBNC&<=+(A$am> zf>uDFp2DJ%6DJ>9VTzoNz6pzX6&Uo)q@f_;@cZ6{emf3(Y~HpB#2dRoP#5%A+|vG9)A<+t_5Fy5{wj;5>7y z8j4?c-h=yagYMkC3W8UATE_3msp*JEW;=BrB;T$tfhtLX+g6iE_~K@$uEw z)%ErDL|KK|zAv-0vtwgp>s&6I&0gfGIGmxOq0RO6A3uJ49~rr~UxPC+Ff%i=JUu-* zIr+#2$K`V8=H`;1N=fpH-@bjzx5aO6Y;3HpZEbG$S3DmW7#MA9TU%LK7#gm+;4?8X zF)}i;z-F(ktR%`Quvo0plc%c5zTdxpZ;p%}X=xp8eYY|*!(p-VOf5JAtZ!8>rayn~ zFRxfwSm1CtEjMGD=%Ft!2Ye}eHu152@YU<5u5P2FqXl^T#_ROW%}ws&;$&xMds_O^ zk4rU)jxX6Xg~DD0sX)HT5?7MiV2f#+UlipSCzQ_Tg^w`-H@S znp*DC(p-Q4OmAO_>xs#Z&iVQILWjdk6BDeLukI=Uyb^TW&zkM;pZoT0X=1W9CU*4Q zyEJvpECXcElcG-#9@pCFw$2TU&cZW=F<- z?)UE<9Ua}>-S_U@%goGdqB92T>VM2HH2!vdczAelaPV_}frp1j7c;x}Y028!T5N3W zD_Y>f@bL8X^x*3{3 zURN)9nGjVhEdaA%bg-|VFNsC~f_=%90Ccdq3V}%VB%yix?PEO^;7=3UC36+)Z3VE+ zX+!lV0YV_2m?c7V`FVVAC7?Q!S(eJ`Z@?>w1GYv4hQ~PDm*rS;(7E@ zEbcEZo@B1#O{4jt_4I;*f^>rnbgBLq^bjT{Cfh#r^>ug_IsqXR8X;JR5}^9i1C|uv zfB|!Jjgmk^AzIwp~KRtvlT+i2cJFh>j z187G{{};wTS_im<_>uIEk^-oK{$3=Wx#~|auXg{PXxoq%4f=?`5ARY4WGvMy(3eD^ z*LheY8`j6ZKQ z__j7T*4MZ{R#%pn7QZjdbLM7erl%$+#>YlS*uz7EtbuP|`@i({_WberQ+HQqNBhU$ zKfG^y*V^*7`At(}Lw()rS1)U8s$W!9KCdW$R#sZ_w7BR=;p2k*M-Lz5<>q8Fv+ieR zq^I3WO-a6+lz1m0{&rk!%&nU@qN5@s!oxxt^y|M}`}LQrA;Cdc0%-yMm;I;|U-G4k zKHeA3lZalPgmY)lc$_}ve$ws4aaWgPN1dIH9Cma#WN(K*h_l7oV63eyEzHeK(IzNk zq>-V4K5r~_b+olK4``^X?T4wVC<9803Q&1D*?lt7d-v>?l9UkNwNq?|s0c(@NKk+u z%m)G~{}2FeFYWEe_BR&<*#fPJK=CEa`Y_0D&C@L<*^N;Ws`eT9(wsN9!0GF2>ieS$ zV&z+*YlFG$2vcCpMZ?6Q8)q)^fevGbvD0DYzrxxD79h=8R$-zF_T~8!r3hGhJGx8CfM z1lR?Fu+J8RS;?_>r^Wh$YqL6I zZ<=i^Cq#U-bW_$y*%G)s+m-U@P?_L9i;BIe!Z2I9Sy%0=jkQ%oaj%BDb#!cq811WN zg;P^Zd|2#uj=*u}-$k`}}US!=vR zsidlKzUv)vO)?fE4*OK@5oe+82Hu^JHbQ*ojWK10zW;$9+cb zx}7f=Nj}YOtj9q>j5-`t;{czA{QNOKS81t|gnb9R35>W9;v zfkFul+LhA_ZE%@Oha}fIAD@Oz}=y_!}2;-T>E+n7A3IJfUu)p<;xN=*^aOl7piAJRV z9*7<}PsA=GSIzi9v4xwr9B{coOP6^Up!?$Z^MwSccOiVMzCk-R8*vQ?0Oc?Q^2lwh zKzXAMa~Dz?xHc!zB{yQta^gb@W5lmIMIPi#?&du1cex`IV@M8{Vm))xg7Rt57Nt^I zVq-~y497#65iVrwm-u) zQIHJU->7LTf-f_IY7m$>8CIq831er;|(K~X1H(vW$o63ToDz-udA3Ghd zYNj(}`IJHO&Y_lE$tL3^zM%ag0`G$FJV4v za>bl5zH@VTd5%8g9L!nP|8s-pyoal{odmcdDS%qR~>a#nG7pqk;F;M zVgM3Wa$Z#n63V|XJMGKp@{6do2IQ!VERa`zUG!38t<^%frXgYH1gg;kDFsr30J8GE zp#j-#XDSBy7#4Vj{uyauAjw*)3T$(d*xpRVVQKge&MvDXEx_zS4P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!!%0LzR5;6}l+ABUVHC!n^Ks|1Gh>nx zMTxH>{s1hRNRU{G#D8FCXJti7k+e3}79?V8Czd3>B7(3GEkdOmqExiKcc!=ZzQ^Lu zOz+f;mcDtDdvEgI-+9jSo^$lsv!}&kF^VE0!hbC@Q&r#hwNj~U-MXz_udRla%jG8~ zKB;qY7}mpZel;v+axPXTVj^JzI~qR zVQn_{>mqDR;~{}4D^%uHRoX$w(yV0-oWF)v>Vr>9sH45W|=L79X} zn7J(!BUi5alb^?S?fX&xW`GCmICE~x=&)7S*o+UNbRG#rnUU;8znsgKtNw>~F9&uz zVCU&G>rb5=+kbTY%EkGQ6MJso3bMj3ov0-Q6%iI;mb5GdYR_K>z?P#Y2Cj|**!%X$ zlfI2}_a6}8sb^8tmWGIkXv?J56&V45mP-J%R7i}cC zPCtH-;oSE-ce8;1W_I? zJW6%UHpB>lC@C}%*2S7@J|&-PbWdWeNZR2+Yqcf4+unTSx-@wQRzpbl zxqyFQd0xYyKc)gvmvPdSH9HprZq7GYy9$O`41Zzethg40z`XmJ&ZpJ-4p^aI1caMM zE^QvUwCps6g-i0)4$hMO#gyi;@Xs@f#k!%?xn*&*^kxmJDgZ!PtZu1_&iR4E7Z=5# f|HT+sCGdmaTe1owhreN300000NkvXXu0mjfpgC!7 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/bookmark-private.png b/public/images/skins/iconsets/default/bookmark-private.png new file mode 100755 index 0000000000000000000000000000000000000000..f7473b67167ced2c95c2cfff71d381121757c5d1 GIT binary patch literal 554 zcmV+_0@eMAP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz%t=H+R5;7!lueESK^TTBwoYOrF2F`2 zaSw?ND>hEx27(JXhmEi@2_hsyLVB2C7@cY3e;&SRikL9QZk`48^Sw`XRaaUSi^WQ% zQZARD?u9G{JgQ!=&*$^WWb%G5WHI1T)oPXgU@&;O7qS@es9LQyolY5gy##g7Hb2!c zjscHqG#Zv=y`3^1kB7ryzu(_#$daSch}pAx40u$t*__R0lT$=To^Ui8jYJ};R7#Aj z!PHqj20W_OYAqIv=_%}=SfNl*8o^*tbhu2@)axdz0w%hGy ziXG|oM^~rQS+Cb08cY*NCX<9+E|)wDmq>K9SF6>>DH!k^U6zfwGMNlXpU)?*-78nh z;c(DiE|+@!(besCnf~0vm19D}`Fx(R-|s)XM7mC=Q@RvmpgIum3AVLxY0$u1Zm^>r>~_z si)8toi!bN)5#UkncAG!rZ(zXl1%{iCQM6NBO8@`>07*qoM6N<$f+`XF8UO$Q literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/bookmark-public.png b/public/images/skins/iconsets/default/bookmark-public.png new file mode 100755 index 0000000000000000000000000000000000000000..f4c22e7df9ad4526c0ab02746722c2960c58b1f5 GIT binary patch literal 708 zcmV;#0z3VQP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!W=TXrR5;6}R6A%CQ4~FQ=DFGICK4h< zJ3+xl5kjJcU?YMc8W4muHr5s*+5{v`5Nk^-3(?9(v52-Mh>tZc* zbUu7FS(%-0r8Paj6ag?Zh1|HvEW(a3G;g|k`pA9cj;MD1c-v9Oo=d&P7&^adm^?P^4NvJkw|R zaKL={{`;Bxlbk^ySkI36zqBYI$Ws-eEts4^=72%%X_?79Krr`q qT>%0D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 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/category-multi.png b/public/images/skins/iconsets/default/category-multi.png new file mode 100755 index 0000000000000000000000000000000000000000..5fc146f8626983c901a4f5c34b839867fdb460d1 GIT binary patch literal 415 zcmV;Q0bu@#P)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0W3*G zK~y-)jnutLT~QE*;df7UDj}K#FCZvbnjishC--4#nKp%Xf@R1R*jS5QAZ_dfn*`6^ z^S3NcKeHE4x%e1{nUS9l)PDWp>f8DC=JI;~q9&|)6Y6f!Sd}$RsHe`OCTogeS59k%qR!gPQrSF4d0oZE!S0S^BK) zhT6Qrr+M(dCHp@<)INUSdwx2)JN|Ni^0_AOZx3pRH}78le)@g-_3`AaCd#(9uq9vl z*Av5Qj%Nny?No>owS|mORI!FEWNjuq9G%gnCPs8Jck9?R!(<^^9*!c zBgKhY5Rrjv+YCuYEf}7GB^EUqj2ev0u{*CdnaCPsWa6W})=Zc?e@BfPUcUeJ7 myF4J<_FL-xYaTNb&T-1r^&3AfWYq;ahr!d;&t;ucLK6VHidi)P literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/category-other.png b/public/images/skins/iconsets/default/category-other.png new file mode 100755 index 0000000000000000000000000000000000000000..6fbb40658192bec90eaa8fa349cc70909a8c630d GIT binary patch literal 1002 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%3?x6Bmj(hUmUKs7M+S!VC(K#9UNSH+GX(gA zxB|uh|Nr06(BR-0AwfYwAs`??KtN!_h7AS=1|L3rxNzY@K|#TU z2@`-?M!{$Z437}_Wjrwh=o85j*NBqf{Irtt#G+IN$CUh}R0Yr6#Prml)Wnp^!jq{s zKt%zD;MdjM@{(Qr{Al|yJ?wvo=$J4R=8<{-nuM? n*qE6N{CO{)J~$^a`F=ISJUgbXeP+!eprH12^>bP0l+XkK{P}9i literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/category-slash.png b/public/images/skins/iconsets/default/category-slash.png new file mode 100755 index 0000000000000000000000000000000000000000..870093be28309c027fea5791bad5939a707034ff GIT binary patch literal 1050 zcmV+#1m*jQP)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1E)zu zK~y+Tt(0F(TV)u=ALFjPF0O zlS~umK!j!Ptfeh&X%AE=rDb%5q!dPJHf$1#RlM@uMyZ?Htnb-j;IP3p0A*vW(L$= z+$c4Z1^Ze_Vuq~VCCj&07UzKrz7#&_^~(b!^)nn?LgN`ETaBFWjD+PY|+9 z$e)A|6pk#Ioc=Ohr{lj1g3fq3i;*qtJ}v%YFTbdP1p0!%_>@L`6a3q$RBuJT0ffyN_8Ti*HT)b1n3r>ZO{ z2|_#ewD!2o!qI*jge*^J*vGQ+e5@B0gAdRJpc#H%_d)Z?&wiQxo{%KT980Tq8y zx-2K>>G`pwyG;D)B<*&Rj#=o1$-%qK$WUQ0vZvLy+-n^)+aJmXr5|sUbS~BXV3q z0|nY{#x76!>kVY(o;!RE5?iJypwtby>9?C#Y1|flH&k6h12jBJc@(-@+ghmU*}YyU zoUAB{oUi}HN^S3+iK4(ERH1f4?Lxun!E=3VEhOetWgSXf@;AO9IRpeTQD%1|B zJ0U+c8Va(kY$H^TR8b6tGpp`XLKfVipCC00Rj6!G*^$>C40vhQ=4uB@I#NY3ik)Tq zJ|txEbAF1p2vw-?R-qyDqp)wSZ6$#bw9C)G`mfB9Hp^E2AU{fFL*#m1@f zzVQ+yMvQU$}Ak+lgo-^y{^F>Ti!!Hw@#Yv*JO*EH<4D64O>g zr`11|Nc^4-oxM5VaP|^%+mUZxH%KHa4gD-=Cmn&V@rxXLDVdo)=3j!=&H7LL1$rP000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1I|fA zK~y-6rBho>Q+F8u&N(gW!(w85@e&_QAM{PPEHTF5(@>)_A2zc@-N`S`%kqK$2Pi;?@Yb4_cQ6ZWigK6;Xd{ZGq19-}CPM)_6p-Z>qp>*+t%}@E zWSKJc$HkwNlNzog(@4?t^cmJ z^W4Ly&l8!?L?Uti`rZ8ns}B%0DT?j|1?W(nB!vxzkfHz(+C0lt>S}uYEU7XUi`@)2 z4q9y^q0r0M{|Y01I@^zXh(Z86LIFCOR?uJokhyuL$rd>w9Bwr z{@wT;LFkPR!V;8a;jU@mT5tdU(a8H(NkP3iW%%5f?R+JZy-rX=ZM22b-Rzgxk@p8Ub2F^au%t)k8mNP(PFZ^5(oa_P}@^Bopc^9msm#{)E>P`*wgHYgsA>wT8n#k>`=Ka+6V1W1Ff(Qhr(5C z(SalToVgQR>9w1`TT^z({Y=zw;(|7xjT@6%HT+Y)=_gp9{yAo4OFEFhYsII@h5Dtd zg89g+blQw_u@M-<^X5C5nG904aM26V=D8+kW@>IOC%kR9kULVg2V=pwiq?KR{x>?A zu%!}8vhn|7`~eQ)!z0!#EjM@ic%)s()fcQNK?X<9;C;wdqqpTvUn7JvI3vKOsAQR_E}D&}v#_ut%Qr_~&`bY<5959PiCoWs&8G6*&UVaUa`R4AvgpD5r6<4s z=C`u4(_a+@O(s#V>n&cnt@?2H^Kw=5w==azZ^OIJ-WUG?gM#d9=H2xJ00000NkvXX Hu0mjfX7>$6 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/complete-yes.png b/public/images/skins/iconsets/default/complete-yes.png new file mode 100755 index 0000000000000000000000000000000000000000..51d55ccb74944caf676d28a2aed02fcfa16d3e8b GIT binary patch literal 776 zcmV+j1NZ!iP)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0+mTb zK~y+TrITGuQgIlEe`nQ2>#m#D*4n!0K5x3Kn{K-9&Mj?omL{Tn2?Bnmkv0;AIa-k6 z2Z{$W2p6W)QWvGj1zV-9T3a=1T{KsIB$)L60mqIa2aP?0bI$wn?DwAc9Mle>c?8XY z|6>H?K~sRUggJ9)U(CT0hB-vv9C>hKm@@^rwikP&eFmlwZcReZA2d#LrkBivhR2+7 zio5-M50ItOa#X3mY_s-G1cEK&FitTK>V0T^hL(w3xif<+@-q*4?`A9(kHe(!KR@v%;yu78p!jWG|Bdu$4bb8{3j8_XtaQsj#iYJI6v zYL7J@x@~Cmi$FcKe#qpKKWo29^yaHe&I_vKfzHiFt@Db|ID$f1-u&CwBwATpl=cg% zWFQZ8Jd0P8l{z0v+Ya@1_a&#Rc0=b8G?0Nj&<;ZH&WZL$_Ojn!**Xm<8*0Zo4z zcFBVZJCx2;xoQwndC}S`+g&YxMAawg--bY}a-v9jp~vp-bmx;!>p_9)R5&zCqS1)1 z{K2k?Qn}J6ZWJrdyDxF9o~TwbEZZ%~xzYV`ZJ&m@}rXfNv$7YSU1#D?&z2urrP zPP*iiNg~ndGPo4|u=g2KE~bkQ&0MYQ7Pn+@sRy9!JP}<^28zdGze?}t8fv?XP&m=< zx%g=@IRC}3=s}fpd&3@F1U*^h4oDqP=bUI)*S-<&$en*sA4vP=mYl}`0000 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/icon-template.png b/public/images/skins/iconsets/default/icon-template.png new file mode 100755 index 0000000000000000000000000000000000000000..4a507cd11e6d92e92d64f1ce811f2c35600177b2 GIT binary patch literal 53082 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 XB1L3}fW7B^00000NkvXXu0mjf{H1U^ literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/icon_admin.jpeg b/public/images/skins/iconsets/default/icon_admin.jpeg new file mode 100755 index 0000000000000000000000000000000000000000..a032e3507824e1dda195df7c621c192f48b42544 GIT binary patch literal 2998 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 K_y}oO002A3Pf#iV literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/icon_user.png b/public/images/skins/iconsets/default/icon_user.png new file mode 100755 index 0000000000000000000000000000000000000000..29049908c1263b4544e0461fe39028209f9f3fdc GIT binary patch literal 4625 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≪qPe$l;oo3XVmZVu8C(7Zg*Xd-cHr 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

    3sMqTL&M5=j^5zs_MuOj@g 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 N002ovPDHLkV1n`0LF@nk literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/rating-explicit.png b/public/images/skins/iconsets/default/rating-explicit.png new file mode 100755 index 0000000000000000000000000000000000000000..6652d14d006c2be68da4b5faed228a499fc8b236 GIT binary patch literal 715 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/rating-notrated.png b/public/images/skins/iconsets/default/rating-notrated.png new file mode 100755 index 0000000000000000000000000000000000000000..e73d7dc6612a81633866f861213c5002312efce8 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-n1HXMsm#F#`kNVGw3Kp1&dmq@u(% zq9iy!t)x7$D3!r6B|j-u!8128JvAsbF{QHbWU38NQM0FuV~EA+x0h}C8VopC6Do?! ztN-7YFkjpLA^)A0tFMnt)=Zc?e@BfPUcUeJ7 myF4J<_FL-xYaTNb&T-1r^&3AfWYq;ahr!d;&t;ucLK6VHidi)P literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/rating-teen-orange.png b/public/images/skins/iconsets/default/rating-teen-orange.png new file mode 100755 index 0000000000000000000000000000000000000000..44bfd764b1afa9b0a47db380ec376774034febc4 GIT binary patch literal 647 zcmV;20(kw2P)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0u)I^ zK~y*qt-(!;n^hQq;rlr`P12+_GX=G)qAmp8xKw{eSFS9yn<6d+DFtbNiBP)pkGK;Q z?822G^n)_BWy&OzH|M#{gwAT-WGZ@H@$}BPjxS;IUqo3gUe`LBjQ6ja$-hxB2~I^R zix-cpnYmnQ0vF4wbVq5jAtfR>V-P->m)UfZ6gDD?nN`#5G%uF+<6l>wesb%*y;+(P z)9&T`@E|pS2x5Q@a~{*-$DiK(<6BrsuogwLV%nN!w&V8B2S42YrqDsMmW?vul*?B! zoN?;l-q(ZSgb3C`%y@Qpa$&Nk27(+uOM;Es`TOVhzWC~Xf%z{Fj~?8J5duO`F28RS zHX@=sdRb9(h04bC-QbPt;?ZwEe|CK_9gbc6?Q|I9S@4D?CL2be)wR|jIYZkZ0s@G| zq1nt8{fb&K%@uN1nzPkG*AhsuHCxgv60^G28hx}KFPE(~AWRdpv4vX0)CO{fHp$>b zqKU5P7h%?fl1+MOA`n2hMrP6{AfcjW(o0Z+HI)XL^byb+3P~SDWy2GM$rhnC5v7j; zvJs||Cfn7Jt)$SDHKPC_J5+*gLSDp`3$*~b{}Bnn4uzdY<4GM1fTEnI@ODJbQ`jk^ zL~z37JcaENu5{0rWeCLHHDtHKc3tr0;@3Za`hNcUx%(e-o_PEnyGSf)$51Gj*sZc# h;D|EfZ4~}L{{UddR%JPcW{v;=002ovPDHLkV1h@lBo_bx literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/rating-teen.png b/public/images/skins/iconsets/default/rating-teen.png new file mode 100755 index 0000000000000000000000000000000000000000..29403e13a0d3c8be3de67b5d3d63d188ec07ddba GIT binary patch literal 643 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/warning-external-work.png b/public/images/skins/iconsets/default/warning-external-work.png new file mode 100755 index 0000000000000000000000000000000000000000..92ce78ce7b246c0e217e2bd52b57ea92747a1d47 GIT binary patch literal 1364 zcmV-a1*`grP)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1mQ_U zK~y*qg~3~lly@D*@$d70-XEwmiMvamaQC}l@rcV>2G_x(Mx#9kUd z9}Vn2%>QK&V3vsgAqNv6BVmJ#Wk`U)AY)kw1Gca&i6sWHM9%F%!iaE4DL@8-MQA%K z;u;}mqLL^j8%Y5KBw-|QICmJ3h%mwiqHs1>Xmz@Dch~Hiq4LVUN=v2jy8dv!IMeLy zE|Uv{?2zOL37iXz2}{DpG@K0=|NhR+lT$tK{`P~LCmGCH{PTsmi4$YTo>+18{H2}G zUpzP8(N`8&#HmA5`7+Y(0jYUJ5q<*vs!4vto*j=dF?JlTMk;H=}mM*-R3ma|Ry)O(h9KD=%7@bK{7qvIdwt=%{@ z@Z|&5-<_NpYnF~w>(vV*y_I~=C$}CyS3Q2IUC9v0NaQ$-0Gm8o8wMBdxqa15L%qQ6 z53h!`KRA5)&gJE5-4(f`BkjAOJNm|7sin_uyy1n>3q_D5Y@rl35ssKQpIA2iQtPG< z-qO)OGz>J_-uV5Oo;-MFe6Gl`95_15JU7}JO6`4redEdZ_RX~lBES)mh%gpjScu`C z(wdIO;NT!IdAZsB^*_EgaWzZiBJ3a>F1dJZwxd)#|MM^0zw2WgRkRC7guywO@FKb; zub*!9?zppO+pk7flt&~;sku&^y~pv(({X+G;21U|iCpS&g}pSYq;E| z)U)^0)n)3ePF$MLyKEMX>Z0?}< zhEm4+2kY$uIUH7m9E9blE#~c3o9haL1BWAWyTB59vz6}eHf0_@Fth%~?!(hQS(M2Z zvyvoZ8-W#&vLC;CWpkYE%@(UOvq_35KnX8N#CWrG*Rr69dcomy&2PPH`nTIVzjt>u z8_h;@5gS`!Vl` zdJy>h_Ob6i`;VuO%&V(Z$&d^xC06vcN3K+GfCz__<@fH85oF@UvF84V-tn`)&n)jO zc0F`&XWufQtGEAwO>6sFQ{C;EYBRMhaJ$XZ>zlhzbtMue2I27TZs)sZDjgbN|WNN^TWaSavwFeACB`F|xr~&e4g+ zKc^c9cdl*J>l<$FFL(DIuhv$6<=3^#GoQI_;j8OAe>C2IXrx{#BQVBb1FAgnOF-Bb z*9qDY(Olee$G|g>+%unbH0yJdlM|;VYJZyY%OkTYQ%T~#Y)dkr@)v(0VUV$vWD8s1 zb`dleA&|&&GLcdx2Mdeg^U9bn2_YK(|-V! Wr4Dj&DkRYW0000)=Zc?e@BfPUcUeJ7 myF4J<_FL-xYaTNb&T-1r^&3AfWYq;ahr!d;&t;ucLK6VHidi)P literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default/warning-underage.png b/public/images/skins/iconsets/default/warning-underage.png new file mode 100755 index 0000000000000000000000000000000000000000..0fe4ffd2fe66719527cf26acd5b1a7e0b9b93c3c GIT binary patch literal 1321 zcmV+^1=jkBP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$%Sl8*R5%fR!A);mkDYaC{C!f6MhX=kfKi3#*m0MdkE?&HT>{#vW*~xxi6Kyzlh$27$F-eXj(cMMXz5LR# z^4Mb!z468)i;JC!3F0;_EcBj#{sc`t=Wu?Mtf{*;koD57ZyG}cyMfa*(N9PFDywZ$=xNTe*cT_?)%Zv zqxa6u5$G)~oj-i|)c*ayduadJ0|%Dgf4?eA0Mj!w-}&H!ywyTcKmY^+LU=sbtc5<5 z73GyyYwue}e(=N-B(MGEx2K(A;2w3a=y(j=-gwdPQYz<9eIVg%5=bg6I+dOagS27rWt(S2)e?drbYkJzt^4Ih8)%v>C>l0?bFUklhlWG_- z(g2Q#2qsz(Wo8H|^(H5)lx_kyu3o)sdYU1``|exI^W8DV?QP2}3LxO15g?s35&%gV zMT1d*yAK+TZ@=@-?4CU{v$Ftb_Q>($Q_IU6FTGUWxRF9I01gNv4&CCAYs4iVl2Vqn z*4E;gGxHBT(CT!sqtkBRaq84yc{w$klES0FUZ4a-;uZ-bf+z|gMi@M8od2YA;NaAr zJ=l?NY@B}Kh3HiyW~)^){DVeZ5FkiGg5+?yOD^{;Yi#!Z`1k}@P)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0m(^3 zK~y-)rIf#F6j2z(f8U)u6S8ZOv=Our5yZv^5PS*SEiA;>NNJl&QL*p|#LCi66vSk+ zD2oP7k>DCPt7Op3&djm6tAflw+{0}K&OP7x&YT&0V3wGPYM5k_%w$GA3^K{bWb!QkhsNqTAkz_`_ zT$-K$v+bcRu2dUC@&bj2nt@=z^vyQV&{%<&SzQW$S#bFBRYP83jBlRyXZNGsk#A;# zSA9~8D4c~toN34_?D%_$S~wqNvoF?0TlA~NR}{_m_Bv@9ZMi2&-0z2vt{IM2JbBi; zbS3KG%kH&{aSF-uz8svuWMjSPFw!;udB4NwyPJdEo%36F@?~~3*xy(mjD{E2&X&ry z+)D4ieF-)Wj^EvXIM33j*RChaXP-j`NvL&mzv#edCw1*tXZ!*uSUW=QPnWg;0000< KMNUMnLSTZ3`3JcG literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/bookmark-hidden.png b/public/images/skins/iconsets/default_large/bookmark-hidden.png new file mode 100755 index 0000000000000000000000000000000000000000..f531a7c504d6ab1d6e2788c38a3d8dc5ff379f0d GIT binary patch literal 1037 zcmV+o1oHcdP)004R=004l4008;_004mK004C`008P>0026d000+nm#LZ5000A+ zNkl3rP-}}8cTY75h z73IH&qiMROrNvj6B9RD&1&^;_0iH4}LRgf~P+>g2wH5~FGgwra@};0W(lnaqeMfm( z5Uft@-e6|-y&;OGB+~*f9BUGq8Y;WHLVXwijT19-3)0wxG&-&5 z!V#qY|u2Oln3#_ z+#*laK;iA2${((AOlN^imW3FGJ9N-P9pEul1Ch5<5QWq)QO9&G`W-Y3sTydk9{=gh ziHs!>L`{u;vooVE&(1qWGmFc}(DA5YW!7gH6j&1@*tJUHOeUT)>|ZDTu#q?KnVl;^V8 z5B+BXnF#C-WCFQDx`wljbVL4Cd|0NE zE$J5<*Ov-Z$Tp-AL*~StH0-4+;EE3`S1A;5og_52YgjA;OM6!@I1GmC$uz27D_;Q=wKPfW$|B(2eopJ+EyyeKL*-6brv8H_O4q;|6|wf>K?<* z-B)qg(z#ku*GVnyJ`&kIxolZ6A9t<;XdsQ^1K`X<_8rBowazCZdP?M~t9HmHN^IU8 z&@o!zLlCr%UD@6D(jsCiX{s*6D#I$n`tM+2Ifei4{08ec6I+b})u`s=00000NkvXX Hu0mjf0m9wo literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/bookmark-private.png b/public/images/skins/iconsets/default_large/bookmark-private.png new file mode 100755 index 0000000000000000000000000000000000000000..3d5338c7e1a8d0b1ab2b7fa522498961f981c395 GIT binary patch literal 717 zcmV;;0y6!HP)004R=004l4008;_004mK004C`008P>0026d000+nm#LZ500075 zNkl;`8~$AP@)`jYeqA3WY+gR$HxBzu({Kbbc*~uyX~2!9tL?RA{1G&rPQYaMicswSOIGIe) z!Zw@DU@#y{Bodj;X5@}WBj!pT6%c4XpHtlRdX3y0;&gj$2?THvxzp*C2`p&nP)vit04)sN99jUn0mh9+1G(*X z+w1jiw_E73uno{$Tkz1?Y^Kxc^m;vPeB`38R4Op9QmM3BEeyb|*Xzh#EEdq~A<-I* z#%{NtPA8gc3)X`mT`rfmkAO@;2#3QV+(0HK^zlBISQraq(Sg-tnE>e-T)Z$ptVha&00000NkvXXu0mjf1Q|i= literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/bookmark-public.png b/public/images/skins/iconsets/default_large/bookmark-public.png new file mode 100755 index 0000000000000000000000000000000000000000..129ac5c546db51476b92872d7cd3918e66ddfb6e GIT binary patch literal 2134 zcmV-c2&wmpP)004R=004l4008;_004mK004C`008P>0026d000+nm#LZ5000N! zNkl^mXQI0fs9!HL{$Gu zL13g%qZuFu#v~y_02N>Y7zh(2i#&vwa51(Zk^lbP&%Srzm+MROdn=A&n4i1hjlp2U zz1TcWHcyZQqV!=PiU=Tr!5SA@;*J0q0RXL1zn3+xMg+)`yV}O9m^lCHB>Z+-O81h||ziWK!A# zuRE8jb64+HB0K%bm>BkOy@XE1;YilbPPfR~{AlFifgB%;;&;zgYKgb&|0WN`s zr|(){o}ir=B5rll-o2^kODRKcvYtkU0*y>y?SSTY5s{v_U8kZ859E? z(-@z&=b!rOXP^IX?&{t3rTK3h_+sW!%L$4}ZYYeuB^-5jdG*sb77p&8%rwBug+%Y# zJ+}DF}|H=d}!5oam3b70A7xPblcK^Y`wY6--N6G_?ib3CvaN*5U)0c1kEgP{` zaw9?v+jY~hX^B{S^4IIPU!5HUFM#>)i;$}|L0s!e#+!O<|DJ-Ap)CQ=v^DU3M- z)N(Ls(1IFmUrq1JtpYNjSgT+jVj?6BLHWn{jrpi9cq-4iIG9+=;B*mj#v-fK!_BBv z!yLp-gOu}-4ItLiB?U2(@|$~XIni}p8~SZi>|6xZmP3KlIyYU2<)f}-ZojZy~KTC5FpsRnZ?!z@Fa zA{WwAtPPQkj9TbpO~@Iq?qV(Loqr0JF;>aOoDKfg36UOdG%^S4A=V0Vi9(jFG= z#9Eq*N%2j?DLS;06typz1u1X0i?uSiskshiIH>CDgxaEck(7WS|! zEl}IiP#8;#wSt@olBmox=~kXFw&GDD)*gN9BZ*EJGH>tJPG?mr`WLFtm5&~_xh0oL zaUNZg>KmR85r5xn9|Bt>tm!3*Ni8fb8D(lg`usota>TJQpG2ddTXtE6g)Omajdrcd zQRW215JPalf`Taz*HRXMs?VZX^Ks09u}P%lVnB{8OZneJjVwIvSW@N@kC8JFs5SP| z6%?-Sg?)7)a2W>{g&@RUC#1@C-$2F;E?v~=e0OF{h6n@9VXSMcxpAQZtFY|NVmm*Q z*|z5;Vu3Rb7RR!o?Xb`wm$Cl=%G9$0K?EmFW<(fj!r#N$y7eFR>L2O21u#p`G6azh z26mtOBQUAmo797rBqTBacQ?QxA_Q18a%j4Fh5FCQb9_$*(USsjwo+J*gunfBLwR#S zU~tKV+}k8~&iPwA0yWaNb6EBw>)=E|DL>MvQ9`mK6Lb&--XpzD!jRt(nv(4($e5gZ7O8c|_11w9-8KoO9#Q*>R M07*qoM6N<$f~6ebCjbBd literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/bookmark-rec.png b/public/images/skins/iconsets/default_large/bookmark-rec.png new file mode 100755 index 0000000000000000000000000000000000000000..e8b9e439f0697f0ff9dcde111edfdc2b70966b25 GIT binary patch literal 2299 zcmVJNRCwC$TWNFK))mDL5CC^-A!$(y zwYX9gd5c{;lj-)ByCYH33?7!FbI(2Z@{yrG{sn>KV!^<7U~&Ni@z$uNw-}7VyDF3pgN4Dufx*IHVX!b**A*;;alp)S2P{mj3xkEB!kUHC5DPp8 z>)L7-PD9Kr4AxcqtbU~-Y3g(}Ls^D%QC_w@e%lj#=ac9PrB(^ngDA$9Lf4R4RHG=Q zzX@BlKrra_2UuRPY`v)-mP=+?O6Z{^L6UE|(ZVKQ+78+c(IW_=M0a@8vXlx@rGu@= zg3Zgnfg9X29y zVXqMM`y@I2#d@wRM2E7GW{TT!RK9!X(a#>i%3Ioa1N$MRpVtgJl#=;7^~$!I{5cp46)NwUWtSniyGqXouUPLR`v zO@6jhQ(52eHPYVP%lW1G4{k5tOhh9xAVmYG&XNRvVYJ;NmMe0eWE9iN$;81cy>`(~uh@B)IsF<}wGVKN)~_E{9^2$Pzw*0R@EP;}0?SE~qbUzV$s9fEmj$Y-+RSih7Ohrf zpD!5jd3ct2U6apgV!DEjK<~lC(#|=$lyTNxgdt=%mpPh*!YcEuhapr0xs-;N%`8)w zBC;rWm|ms7VAI!qX6i?|O0r8X#=(mMhH@0;Mu~TYStPPJjt5z$-1O6L;uqQDBVgr9 ziFe0207F34Db&ZYB6u^~F>8)fMTm5xYV`#ElFw_i0*nNVjtw1&)dh@n9VsyM1oThP zUAH^70eHE_tV=$x#rvCTwy7J?DjSw9*r)xVdjV`RZ5uAvGAyOtX&JVAnsv$1ks{^N zPFZOwdIyZ6#3DyWT!YI-4yRPZ2AHavd05lb&JeXbBvB-MhlNVMu7xEIxk`kD5!m!=@h<-YC`s< zPPEOE`q`_TlYnl9>$_-j%=jm38MWPM%q8YVy}FNw`UveVOikaFV!h$2Q}}vvuA138 za7ufbQ~t75bd^)?YS!yfq5^-|sN`#{`qI?gcxWOZj7TgfS(jqu*`WF2gsN(tLen^` z>yUka-7T$Us(@f0nuI=WInpWN?|JK}y8igRL@hBs84}06Tu5ZSJPqA8471Lm*#8m= zL@HBjZx@@NZ|1XAt#2Jw|2DJP1ijxD%P%tbiq-oIlgUy4jesyJae;GHtZNPsv;obw z1zHY-I;yo(Rqe}EW%Zx}MC)gx-tWz9FdcuIF?I^yJzl)AG&wpG@y2{SP|U~Ez4v}z zw_-gT1&AnZtK2fc9~@NmjePUZ>$!YgC;A=?(f1ukh@cMJ!mn0ycaJL{Elu5w1rtHh zk~s^}l9P}`Pr|IOjRM07J<~BLR88NjXis-aU+o$Wtp#Rv}mKSDse!q6V(JcUp=b-b}*142IoTq z1}%JXs1fKp(^{N}1fVPyTjqMc@tfxdiaroX5d*aW*QA7J>4r^gzN8<3abk&MJDAwVJqQ*yZN7*33?HAg_fJI+7;9f9}EwSSG zDSi;a8niHYzd;OQ;7?c#IkN^DEQFbbnT0hAGi#{8!py<~kJAtfJZ9GQ)GRFU?~;ZX z2W%ZMvoN!UN#JqdG{k9$O(|}7Ftczq#LU9g5T_xw4wzY3voNzTS{Jtt*pyx@{sp<# VEaadv&Dj6|002ovPDHLkV1l_^V7CAO literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/category-femslash.png b/public/images/skins/iconsets/default_large/category-femslash.png new file mode 100755 index 0000000000000000000000000000000000000000..f1ee09cadcd409acf85c600a1c3e3e2cd32be431 GIT binary patch literal 1982 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 Z;0Ld)ye!qT27>?q002ovPDHLkV1lf-jQ9Wm literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/category-none.png b/public/images/skins/iconsets/default_large/category-none.png new file mode 100755 index 0000000000000000000000000000000000000000..be901539acf18be3cfe9be63e0a8f220e6a2d556 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~Ak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XGCf@!Ln02py&A}Sz<`H2aCgWt`J*9Hhl6;2-pbvj!7xup zJF@!zf!JLA8(U&s`_?FGA2_`a!+ tOuf9P=|pZyIXOuc#F(FIyTP-FVUxSSl*Gjx{|yZd4h{|n4jfppV8Me24-yg*6ciK!0s;gC1U78gU|?YI;lqau7cLYO6ik>f zp`GiR5>T6DiEBhjaDG}zd16s2gJVj5QmTSyZen_BP-fmA8H>v6y6hh)@SX^P)Thrkj$n`Mw12E=_ywkOcE~6ofymSz`Wz- zAqN+R_AmwINu7%;EUoi(mhW%cxoGYB(AXK4TMBo+Zk~C?divWf29tMvS{pgTb8Sr6 z-I-ZY;=g>YgI7;qCU)<|KMm>kI)PrkcK@DmUzKHcRNRw(0_X__Pgg&ebxsLQ00ZQX A!2kdN literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/category-slash.png b/public/images/skins/iconsets/default_large/category-slash.png new file mode 100755 index 0000000000000000000000000000000000000000..37ce6329d59bb1868b66f9cc16e2fbb4c2876ed8 GIT binary patch literal 1918 zcmV-^2Z8vBP)v5M!DtyWnHf{eO``mwR+lCtoYh*>yqtTT!{W$$`3KKXIWV=1GBH%2-I^TS$J zpsA&;Ur1#2g9oFd?}w_Oy7$$~;Ww{G$7SK|k+yIi_>$>scFaD28(sV85%&2)Guytg zENN_RdiJbuTo&F1Y3GqeS(~rQ3fgSsp>FJ{alrj26Q6A+KI;s_mNNNL?bTS`=2i|t zVYeRE)nS@~(_0mod0&|3#v}-uA2)xHh4Vs;9D*!nq^@Ui==+^4&p10>;&=y!N5mw? zC8h9gr@o;uW8a9AR5~D|`j9psMD+;+iM^{CZ(U`@M%<(DBKuQE*E<5D0L zHHya)t{@b<=kV$$$5+zgX&no(^((j<`v92m6wy+oqNo+m*k|L)xqh#_0_$mLc-Y)S zq(GN$k0Gy>!gR=fP~QxhNj$E@qa&;LW=`WJ1+2>Lc377+DCJ9!fP$iC?A z9SlPSgFi6z;uGEE$uuU825-8jnYg8n@?&V|;RIe}50WqEF&O z2?Me)j|Y}jRAK{GUfW945mDptEYakiuyrXaDaGGIEB7-tT2lpD=9&GRsn> zU9om_g)E3w@%t_bWta64HJlR=38gx=`Il7IEANs;(_#u&*VG0MVOXevq32MJ$}S7o zamc^qo(OwIr~$pAgmNT5C49bZdbW_6p{R%I9^yE2MI<6fe^F}0wcz;9t`2O#dU~Fo zcIQK4B&;do2bRNWhs!V-#w)g`10T}~57kt%fUopJ^9zfy+6JmFI4`&c@KZpu&krSCr>Dtpa`z4s)oN@%Gdl1U)F5-7u0^$b#N#|+5i9m07*qoM6N<$ Eg6sR5M*si- literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/complete-no.png b/public/images/skins/iconsets/default_large/complete-no.png new file mode 100755 index 0000000000000000000000000000000000000000..7930a9068dbf8e2d7f81021a78fbf57520726e64 GIT binary patch literal 2314 zcmV+l3HA1gP)#*;+7w6xp&sLPAJ^0J4ZE$f7J_*o`a- z0wO}OR8TfiT>Cz~x2M-|xk>DFhCj;un91aP=bYd9&bOT}6QU9WJpUPy8E8w(_ zF`45EIIR>Wb6nxYX~i496gtcNqkmmb^L|M<)a+f4TOTl1JBW9Axj-_jM{m+jV zqc~Gi(c0EAFgWz+(c|AV{ecXSzIv?_R4DkyE!KRp#=R7XRwA8F0q%@9wrtt$&E>(> zzy_cU(8_PR{DJ(?o#893?dj>+BK92W?EpBf1Uh{zc)mGz>n@M5sCY1)-dlY{4UP2n zHp^sXZhH&t9WvkLD2$EM=h$S-eK+56i%Kf%z0nO9N<0AEGOVCfR!inDq}VY5(TbE6f)I@R5KBMptMu?s%X zK3 zlYlrnecPuFzCnV@3-xfa(e~SYvp3OUliDn5$R-+|j1WT9K-LMjc{VDBR2Zif2UG~~ zevR$y?te13xUYW@)BMfy@_Pe=SY*N!1`$iP-~+XZ)QDvn91n?vBVo*7DewTrs?SDC z;vlhOJXpW6yh_Gos)>=%@||hzb}+E8v=WqzG03yC!x^u!Z)|P@LdbH<^NS>A<~lLs z+suPlgBFJmsjEICrxmNGhp_Ww`v_42+!20#RaL}Msq;P zJaiZokC{I#qDo0q6ToRnVZUb(7#Qww^#QAb+=8oW-Fh?%kU(+>j=0f%6DxZv#O!?_E-i(ZBdcYq^yKguvSc+ z!0)MJI(?-*Es4H%wIat041Z=V;&y&=3*Am;X_iTLcv|?y947=AjD$;U#di(Gj-0X;k)WDzpPDOPs zvRv?k#>>rO_S<90tKl$vZp!goP&qdJN=`0uRGpUdcDI~@Qpon0^fAsnilqfhS3nLy zCx-M=U7{3Co30J5;OQ0+gF1fx1y8aqtt7O>G#UmMSFaLf4GIBr3kx(v4yT<^dqJgu z$=?~iTbP_4J<(9ZEE+A;*eozi($aPvk2U=R#8Guxd%g>Rgo83ytf?vW>LSRjzJZ-x z-6(KFV#o@K5bNnvPvo-XHMg`y z+i=E`_k5kr4HY+E#ck_)egVm2AHieEs?%rAqt#2ff!cQsc#9U-He3OJ{G+0(xFEEc zK`QLFXgSdnRS}U?w79QXC#GhDp2m`nMw}068W^wR4%LghrFp#b~sh zU$_wCR`v#aDq1|I!BL(J(gHfMV(D@nXwhggchBpcH&8Bz2V=HC6!olxLh!P9ecz!Y z@X$puPd0TL6)k}8HWzS4A8DkzjG?D1f_TQ5dYB?CR7}88$QR6{qjsGeTfwWJm56b66)zk z9^qZP-h~!zQq@PBnCiqV@>R={;xgEnSY(UmFXXc(Zr!vCR0X*KQ|DlNyZG5NS_3UW z5a<2k^VP%xvLIR#MK+m=8D{|)gIbX-_U0ZH$ib?Rv!8Kt8nYWX8iM^^sFugx0>_W? zgiMxhc4oIht;mKoA+n=d?M7*-=y`9@K#ON&oRM+@%?Ey9#pw}I0z)I6m`R-XfjuC{ zgb%y`pF_W9BFhnCD-0TLrZr| zpIY>E!*tQp9CbW9s zZHJ5jFOgkcwQ7KCuv{CCs-~9Mu>rM#^MlWWPo-t$3na+_p)tOJ0#E-4zaOK4iX=Wg z55NnYm!spYP9K{ zLcYshyY>ZtTzLV+n471ruq_P?Qb}X46_@n1UWIxFOsBiDvP)T36B3fOYPHnV^iTcf kGfsbs`kU6@wEhbGAF5rzmrT9EdH?_b07*qoM6N<$g2C)>uK)l5 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/complete-yes.png b/public/images/skins/iconsets/default_large/complete-yes.png new file mode 100755 index 0000000000000000000000000000000000000000..e48f1b32c6417e7f1284e0ac1bc4c1d5f69d2d44 GIT binary patch literal 1209 zcmV;q1V;ObP)|KC0LJL|-?>!OgAUvV!Z zsz6$W7DiNovjqwywPEZgc;D**-jIw2Hlk zA+4O-47$lOu1^%OB&RtbWbN;9xn8*6O@4Sk-{&av9gMWH|E8UU6xJDaYFkHx(>b!V zIQ#F%MPO{oyy{@2rEaGej$*e=!R_d5oS1OJ6T(h;oiVG9M_MW)jqnP#LUkMdx(dNz zC-rzQIlpN6P|EL|TfQktD9p2&P7@ojf9ccGufvORa9w*M;_ynaxb{@jd8(DM_Q*1gkekKvovB$ z?;Y4PaeNhbSV2xlTJi>x@Jd$VYiiNME`{T3ACv^Y!Y8d8#E|NkY_4~F_OaHG7C~CF z>%?G-z2k$DQW|1HS_EmO)srE)XqEUbcCtcU2Wd&`2q3CqCi=wJW|gdADWoOQ6ChFK z9iQWkd2LI5($a+s?_4ZjcpNrQ93PZac4OSyRzq50BD~CGCm$%S$hF%CaC`;}C*0#} zn4C!81zkCO`{w2*D5w4xx-i!aYLKAvD~Ji6itjCc=_an=m+KAH&`#m_((7aB)k;1W z%NBm0BKlR8BT^T$eFr4)e=Itm`SjVNrKLIQQB~hQ7=8l&?w!}r~s87CEA04+%8H}28O>H-j&p8n_kvKw077PHDT*(Cm9=saJ& zvQgbIk@x~=C1vi&$xG|AnmilJsY#biw-LoB*qf`B!+?ePY3i=7`xp@?e_A~4wyMiT zuU`*iCjj36i!Cdq!%^)N%ab77$+u%vrQ4jXq@4U|rIvpUUlIt&Qww^kFLDbkMA?Or9ORC)m-#Gl= z6krL}2B!vmePU*atWyB3)Z*>Xr9hc`<>|%gE5dw!gD+ZNv?9uX XA1f`~CL9|i00000NkvXXu0mjfo#aRM literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/external-work.png b/public/images/skins/iconsets/default_large/external-work.png new file mode 100755 index 0000000000000000000000000000000000000000..d3313bcaf6d09ddf37e55f26dce95284bdae5b04 GIT binary patch literal 3615 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 W`KLZV`0SJb0000wE%)@!7Y0_6J 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 DQPmed literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/rating-na.png b/public/images/skins/iconsets/default_large/rating-na.png new file mode 100755 index 0000000000000000000000000000000000000000..6bb8073a9396bfe8310f1f3721f818818c2f9e9f GIT binary patch literal 2709 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 P00000NkvXXu0mjflMVBs literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/rating-notrated.png b/public/images/skins/iconsets/default_large/rating-notrated.png new file mode 100755 index 0000000000000000000000000000000000000000..be901539acf18be3cfe9be63e0a8f220e6a2d556 GIT binary patch literal 199 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 P00000NkvXXu0mjflMVBs literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/warning-eschewed.png b/public/images/skins/iconsets/default_large/warning-eschewed.png new file mode 100755 index 0000000000000000000000000000000000000000..6b5293cec4138624ff75c69ba52f562c19c6d3e1 GIT binary patch literal 1087 zcmV-F1i<@=P)$_YUy)5lT$()vEX+F|YGILm2Syn!_`M8g5 z&c|l+S^eVPyTqb8XA>_Ze0Jdeald@{o!>n>=Zql5BLv8gpY`l=LBVNRlp;aFX|>0? z2?}28^fFW)om_?S)<42&wZ$w!CCF#{4Pq}7?S}F0U*WZ)7o*}UJCv4wBP%1RAZ8~W zxfCPe4{%zoQ45hMlZzDLzOO4vjK)S7Q&N*uG5en?Hc%0+s8PR#*NRwxghnokjSsG= zdH1!iv#Yb6Vd~#iYI5`MUAq~d7P;rOVg+j80649d@cBrP#6sn{keb@cZ(qAudU`tA z+6;}2HE-UQKFC(7&v|_$mZQf0%xAUCVe?Q?hwrX<^BipKW_G_8GgV#vHt%uzlQX+8 zk^x?en2QP-IzKx#-e72ec^qH{^!9vdZDrnnC@;F|i4)FhHHXf|0L)(A4TY}%wPq~c zT^7Cm)60Z?$jO|RViq=Jq?_)(+*qgSw6*V=fRYssfNkuv{9x9(gd$vV51AzFl#z-bvyO>rVg$JSiErfg`aW}R%+k5LnN zt$<0+qDnf$Tf9H>VY0cI0;j$X#u&FAHH6b*PEK?RI@uI|k40y_UsaAfQw>ed(ZFjo=Y^Y_m$8 z2*)1tLz#fIVkKL1^6tWd&SZ!Mq?IUf&o9V;eHEP@EFi5MUsqTfV5eZ#Y6PSO6h>_M zRFJ@wtLqf50@51XOUhxb!PlxiG3JtoD8gscE%CZK@mN7$Begm? zPA730dM&6EIKdu^qI7Tz0%OJXBSWtRa|d+-8}?ieBc)Ldy%zKn%pKIpenvIr5<{;A zJr4b3uU4;>CIhAl;!A`chkk;&`%x#SIt?$U!&?8J)^`)Lx_-TrXOsW{002ovPDHLk FV1jJs1qlEE literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/warning-no.png b/public/images/skins/iconsets/default_large/warning-no.png new file mode 100755 index 0000000000000000000000000000000000000000..be901539acf18be3cfe9be63e0a8f220e6a2d556 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~Ak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XGCf@!Ln02py&A}Sz<`H2aCgWt`J*9Hhl6;2-pbvj!7xup zJF@!zf!JLA8(U&s`_?FGA2_`a!+ tOuf9P=|pZyIXOuc#F(FIyTP-FVUxSSl*`a!+ tOuf9P=|pZyIXOuc#F(FIyTP-FVUxSSl*CC{+AHaeH5>o#FcD8OU3oJnhsUS*d3bdloG)ZaFP&;SG zvEz@}=7JjtFp)dt6Ur&haFSpB{5+4}J0Ja!B60ZO6$=E2ViF9agXNH^R^M1+G}sDp z&3Ke$*igN3s&ec%+SsuA8;0Na`Qo&HK65%f5ebjL8A+C`$4_I~mpP?W*1W+1yp0ckrl%SfWyEw@ur&8Kx5nelzcQZer(lMNw51lDR#iSuCNO z$e_p5vTWVZfB2}B%M=MFI+Oz)bh>5g>#vBw>K$^ih@~2Xx8F#61tR(u^{d)nb2;?9 z{|ggKB$^2FTi);G|L~9!KWvkz7W&=+U*x-b9lzbgl6TB%wFI7s@5J9f8w&+orEsbx z?-wZou{sMQfmpcmju|UBIYAKC@NUugzTXs@!VyQ3jy5)|IzY#w z$vh2Yr~%gBb$Qg~Ip8Z^n6k%HVbF}_b^;B>do0NG=Ek+jnR92SW=A4X>8L8+zQY2^ zV=Sl>WLjLfIy-%y<2ZP9^ZHY{a&OsVEa)B72{O3{f|0OuCNo#@Jn}G4&^xG;dq@fY z&1%j2H!-oE7ps+4tK}|;IsotPKk&ZGGnTDA$pS^TbiK5?_Wb58_2A2(%MY*ySpNss YH+s{e>JogUssI2007*qoM6N<$f(^`h&Hw-a literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/warnings-death.png b/public/images/skins/iconsets/default_large/warnings-death.png new file mode 100755 index 0000000000000000000000000000000000000000..10112ba1e9849eec4ec976904d305e547afc60b4 GIT binary patch literal 1367 zcmV-d1*rOoP)}vF2V2hA zi8B)K(}8znazk!V-#q<(Ge_dz95QRF`uFSlm-~*02uYDwMCBu|$SbdWlY|+Pk2#j3 zS9OBjzJv=2bTG@n66B zpZkAzcr`{A9?EMpA2FVl`B)moHq{7|kHsAMF6K)5*x9Nyb6sl%n>6@8ReDOG`Tn1RNLeyG0d0cXr|hH zY_zo4sIbXo$_V+UjACRXM)EN~{P4pMKm72+5C32EtNM@oMo7w0>7WBiq2ekkg;FUg z)pD`aRY-afDx#8vB=MiW{p~%TEwMCHteKW;b1c^=qm3TRDzh}le5~adMvGxwV#+aJ z%401#?lJRat47SRW;MbvVoPkUW@KiqE+d<~hM2O&F6LNW=F7-y#yvJnVOw5Hqil{C z*<3M4JX~JSs+rZET{W*wO>Mg*Hgaqa`AM@Ybmra=G($kVT=2$$cnO7`F>uDF;bhUU^ z)W$u`e8hY=M~rHYdBrR}v`IX3F~?IqY9?Q@$!cUVGp`+$8G5!Gb1XKJBSz15)iyOU zn&;XzLz+o!|79ov(hmHFoO-MnIs#k?N7v`uK+mB*UnNiu8{+LoiW zYmVich3rwWsfJCCZQTCYh+&v&*3g>8R&C`qb4;aYORP+`(6c46k=PiGi>0YBZhvAE z+DMz)Gjh!&yLAI}!qR%jEmSea~PLrmGD zwl2g*YZr!=k8L8A*|oOa{*sZIr}COtJaZY%$Yc|9WYd&cY%$VW^I8iV#n7zu*tq=_ z^JUhon5SYGu}xPP(tO#YX4I|`^JTi9HUJ(vxJ&8TeXeb zKVq1*G`2;yrCB3n+r?NeHpht7HILC{+H`q6TN<~YVVHb0%#kUciRM^Lj?GbRE40l~ zJgvpFar;?Db1X(PBSu?!RLrbGGgI5H(0ptbb7dZGKi9n4gnTo?%rPo9ujUxpjA~oC zn6_QocHjOfqmeHgZMufdM`DheSsI!-(qp9=H~o@-_0P&T`L3FhSH4LluZX;&!|T`2 Z^9PwxM2Z32%Mkzo002ovPDHLkV1gyZmcal3 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/warnings-na.png b/public/images/skins/iconsets/default_large/warnings-na.png new file mode 100755 index 0000000000000000000000000000000000000000..4020bbc5b58efaedc3d0dc292b46a0faa3d17b05 GIT binary patch literal 1495 zcmXYxe@qi+7{}ipchH_NujQ(gq285iy;d-^YZr}Vxt_G#l|uSUQrXO)p$^DY6cce- zw)SXEA+nX9Dd@Jg{79*F2^;%kYLS;fIHCEe*W}IpcVk+JYQ$=`eewLlCiRStj@6Z1&KjzU6nO42A%l*ROf$Bi^No- zz4v~Pq`Urwrxk`XPfl0dUY0C{4nVa}|2_8%lQE3wM3C-){;(@~gpMt~^Up8Ol|y71 zSYXwZ3K{5NvmH&}>o+BNQP5ZZ`6OQ;3l-igS)?$^+;S*xH@~%&4>k-PW!Ahu(U`GG z%kNu4yV%GazdO&E96Jwnw7TJ88QCS2(}y!;^+WM1q7~Y;HoX?<=hN8)u*T*lZR;)k zlRQZfYW#9*y4VC8C+3!QiCemvVUGMuBtek6sF{kD$20tJHfy{J>q}f7T7lj!5aD=P z2+9l<${GWoC4Kl9-{v+f3#@TbWYWM$x^-W1ixl-G+860kKTeVnS2DH<0CCAdnV5M< z7i7HJq)DkhiXf44AF}y301yO2PzcAp#mTO;PF51p5nWVBC;~Y~>V#KOMZp@VZ&2t9 zhO{x-$*6J#AVI%sFk;B;S7_X{zlLlZu4s1pG|=dgXf0qQrBRc&50?H26gdcAqSG>-_=&>Q7(x{M_9Do}Q zpco0Ayh%;xsyih~48coLL2N&f98xDuUWbc2;IlI8%`*wE>e8eDUmR@|d%kwmRTrmZ zjh#3>v3ipHbl;L9MUYrRL>t$g^7!zA!yDF`hfv)kR9!Nn_65Hd5$MH2mAb=B3V@B|AH0BtSe rJgRw@sgPEL3PP2^N>H)2`10Z0>nqfC`K}MBiu{YWHr0L1whI3Pj5)bR literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/default_large/warnings-noncon.png b/public/images/skins/iconsets/default_large/warnings-noncon.png new file mode 100755 index 0000000000000000000000000000000000000000..79bf8cc18dacc7f6c47945343b3d8bf2d0882c8f GIT binary patch literal 3178 zcmV-w43+bVP)+6 zC0I*Rj*U%CPNrAqJ70RK@xce9`}VbO+^7Jp`f>~Z)A8l14({#@?_7{)ZpWfA3JvJ<5Q=4Kl$XIW5?(Nz>h2?6a=ud z9JXoM)f5OtgrIY}5w|Wwy0{X7^1Y$KGrM;6^z~JHdUovEwXRyN0R~uITwGpR8SCr2 zqqFn2#~xc-S!w?A7nRyt3^R&@tD_HkUrJm*CAFJk02^M$S*=2$h!R3VpyIu(P$Qpj z*|O*0!TmtTx^=yG-`&^UeUVh4FoxvnE3Yg*^_2Pc!41Fp_59S`#gQY1ZZ8DULP%+U zrDdax127_ZEWDH?)Puu;jS7Mny1Lr7Y}uEqD;$8vfyER7OjDnMXnaA^D1t)ovqdHu&fs=f1$h)9~0p-Vu) z5|mp$MRXvV@8hh*ls?y4-l71(dSOr=Az@*0WsG~uJ5luyV~s*&3t8LrN|5W8UU!O zvXt%YVgW$<`|Ahpo*fw}DC&KvF(jQ|HGT!aR0DfZ#7ij#kNcgJG_6!BcDQ;aO^QPE zW?);W5}-O6Vg-ral(xNlI}aR~d;k4U{{H&L_ulQP)#!tfpspj zsZ_$2#4PNvjgVgqqe8RKoWisC2t$afRY(dp)3j2l!0EvldfLLEu%K^Txk6=Dh-!+At4dP9OM(R{qrpE3KS>vUhSE22ib8jL{y(758#9v9O`76iZ+}H~P#L zWrW%Y5JWl+iwvcU)BObP9fk``61$1oLRMaEh)8E=m>*r$$WS2@xzWX-lt(41ijb;( z+Vo@{D=j;*6#}4=5HZFiJv{*P#IRB^ZEZ>b%&Jvm43Z=W0_o~vis{;*i&LUgXK-umK8 zbN@J!XhCwvsZ(nof1GBSz?qe<@1>Y>gqDjTSDlk8BBZbTncCN^_HhAg019m-9)v-U?FI`g0u|TC(liC^uBB*4U)a%w2rpN VMJ0uHWs4QUvO}0QCtyb@O;V z?dzLRz*}fat}KeerWdg^Xv4r-5GppiLq;glGzI{h&Bz%dOj3&w3Jrv?@UlaRaYYx> zkk(w;OYu=2njHYuuCiFGxqB25sx5&j1So3gwCEQ-y=TV9+c$6CbL*{@MqO1UFQ_Wj zs`U5k^w~gl5@#3V;cdMYOp2`lK`C38>R3rq6uG52T2<6EuH)!vh`#K65NYZF1Y1XZ4uC5x`L;=88+r+z*lRGCT_jhz$ z`R#9ul@+@T3T=^Mvw97z4=z>X#)1;1(uGk8H5*E{@7UpVXQ|vHnI%cv zwr%?-Cgy+lyL@>$YG|($Rx1@&Dti5T^UE(oZS6W%^kO)Ud6QWseNk$eD3i4;SM9m$ zE*e{i2O*AJ0<}WlB&*mPbZ5ZQ3;d?6bvc%@-!NM0d+u7#J8D9+u^0W@}D8 zl?pX=BFdF?B)`He#CC`)6980}m*?l_t7Bs>lazWXAltjTh6V?l3k$9u)KWu(AlV!k z7#tkL(z5HlIE<7!98Q2ZFQoVnS4l<*!L(6dx^Mw$THUi}<@j+?!gq0#qL_I7^`$r8 zka{EhT3srI2xs~SlFgfMSz20r?KQHc%O*ktAA!Db)UVvcn|msRv}alOGtXSQa^?0X zo?x1miVrF&MWJh%$8PLPS!AEty?fivop|fb`s{41y6pbieoXL~C$s-%mXAwOwqL${ z`qfv_*}3KLVNENHjSOd@#+>XzOUbu)?Hb&(=eD)l!e3uh%^mWz)FO6b-4>;=wPdmb zxE=rFMV>q<2M+AI|NiB^^^5;Hp4985-ajN9bO;1!Ch5uT+Z*@Zd(ZfI^Y9;wYYXKg z4a>BxryH&dai-b)8fFQR*6UYJpY9mHeaC|ju5H~qKRumiS=wmELk>WVS*UhjyXBU1 z$vvz_R-ee%hLBS%c%&C4k!>5K#7x0R$8sJyNZ;RA|zh(l-K+ZyU%%8gv48rlCYqJ97GVINNjcqi4a5t z0XAS_8$4$0F>}v!Pgm_%XV(nmfPL9E%=C0sSO4lef8W>m4}^@mE=I`y2mj$uotx`e z{%X63+CTNJ@Xg>4sdMp@e~2HLi4$gS(AVLF!DD{%eRq@V{w0~j3I~>0;DcyXW(cW! zF%cLwvTy{8XWD+iY(}cpc%_o8R+C3A9K?=D@#bF_EsX3unzAwTU zCAgSO0w8~ID7o#~(VaW9qoY0R*T++-NG#^KE_W14Tb|db)k;fCg)3J|moL|DTu#h`) z_H%8(0;6ztA~&#@9cXOZHne;9=DmA|Cnf+;BpP+Py0E>Rr6?Ez#HsG?^@D@?@$tp8 zXX~GRmRwnt288Xo*z!SbHr(VX*BSVs)SM1Um=A#PeAitX9PoDTd}exja?hR(!|Iaga;tS>Ejg+i-broN9rih2%*=eqH9 zIyE_2W2|xQn&WxxqU}gT=z60e!>NuiA~q1ML|C#CkFD+4G5Nv^JNEAfdxEVSt%1`O zE?ihSf4(v^sfKo0*;-Ie0L$aU%edcY(~h2L{Ft9lCYtl6&)}v1gU`Y*&EE+X>m`IGsE| z$g0@W-PpHp>ZO+^cI^UtQoiQ<56+#tbNF!n)F-Wcp4IEP<*T?0GHCgvT4T%0wb|LV zT+Yd6>gd?eM1V$ZY*uuvjduwZIEp>~f2nkJMQj$Zlg@uKS7fY+F ze82k0OikfLf=bIVbjCtPwD8qssSJLWOs0E#V~K=Wi?&+j*;y6@%8;0{ENKHmOo*!V z6RH=`RIXlKd+?wI@k}3yY}QF8k+Ex}*_Ea`#3V8*7NbJ=d_0keC6lfZ6+(WgG#7i6`l zon-t z3!JnCVXvL%FVt#oIgxPRcmtSImx8a3?se<>hlXrvMS6NB-+kA;dNseeXdB9}=4=SX zJW0f2_VwYn-)`>P*P5HNl`D_fkt1%zaW+j&ZF}*>WOuhc23D0wr(J88m=M7F?B2aF zA3ezddjr9Dz=G(tdFRfJTeh&!71fbDb;<>shuwf+!0&!_-yqQrp+5Bi+lJ_qe%#P{ zpq32%KOSyZv$=Bm^!1xJBe6Kfc5PzH==L0r!@{Yr1v4;X z56+ya&CdtmI*hf^FO28r=I|d8elw(fqDUixFslMy`5Vz#h%__77m23uvP+=J6~^jD z{zam()LUq zHY!R!Ecb*d(ZzQ_oWON?odYWoT&>q@!!lD{;|M5HRU{UPny3k|KJ$l%`(JylZ(sn>K;;AV zQb*hxIdq8b-W^?704)cnKA}rFtXpDW7%s9qCd_s-m{`_tp;#Y&~!QN<|2#VC)?M55npA)YQ<#MDfz4x%>A$yE`Qrgb@x4PeQtAOj5Hv zhC%|vsKraEp-({&TU;!jIRmUF)8F4M8UmzUiGUTtc#@FSlP8-qv!-z+eT8(yu@ISN z^r)TVE8fWrb{gTO!kuiNL&l?sKQikp>nj-+QmQvSN7*3M-difMw9hnvz-;M^Pv&q)k=V zVH8=FBafz@=Y9LFw0%?j%pE(n`pv&-E0AS@sRj(S|20@v#4tHZKiD)f6hdkW4P+IN z5XK6H+=+kQzj32kuk#A@&YjtR9QM`T>7+JiPX!-V)WNlu7W+9##{WO2_B-BDA?1>}Ot!1jS{6w%!orzTsNF;695m#M#7QR(sGDV6?i%Y;=Sh#!g zWU1M#&d(E-Ja{inrd6VYkzD!7V6~ysY|?7E%RU+vW00nv!ftYzQq2CNh)xx8w=4(uo-RRui04q8|Fbdx#G5yX=P*wWWu z3fWxJYWta&1d1_F$AmL{b x8vCE?C;Z5XR29aLc?oJ?Y?Y*F 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 s0%bM8~^|S literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/bookmark-hidden.png b/public/images/skins/iconsets/legacy/bookmark-hidden.png new file mode 100755 index 0000000000000000000000000000000000000000..f531a7c504d6ab1d6e2788c38a3d8dc5ff379f0d GIT binary patch literal 1037 zcmV+o1oHcdP)004R=004l4008;_004mK004C`008P>0026d000+nm#LZ5000A+ zNkl3rP-}}8cTY75h z73IH&qiMROrNvj6B9RD&1&^;_0iH4}LRgf~P+>g2wH5~FGgwra@};0W(lnaqeMfm( z5Uft@-e6|-y&;OGB+~*f9BUGq8Y;WHLVXwijT19-3)0wxG&-&5 z!V#qY|u2Oln3#_ z+#*laK;iA2${((AOlN^imW3FGJ9N-P9pEul1Ch5<5QWq)QO9&G`W-Y3sTydk9{=gh ziHs!>L`{u;vooVE&(1qWGmFc}(DA5YW!7gH6j&1@*tJUHOeUT)>|ZDTu#q?KnVl;^V8 z5B+BXnF#C-WCFQDx`wljbVL4Cd|0NE zE$J5<*Ov-Z$Tp-AL*~StH0-4+;EE3`S1A;5og_52YgjA;OM6!@I1GmC$uz27D_;Q=wKPfW$|B(2eopJ+EyyeKL*-6brv8H_O4q;|6|wf>K?<* z-B)qg(z#ku*GVnyJ`&kIxolZ6A9t<;XdsQ^1K`X<_8rBowazCZdP?M~t9HmHN^IU8 z&@o!zLlCr%UD@6D(jsCiX{s*6D#I$n`tM+2Ifei4{08ec6I+b})u`s=00000NkvXX Hu0mjf0m9wo literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/bookmark-private.png b/public/images/skins/iconsets/legacy/bookmark-private.png new file mode 100755 index 0000000000000000000000000000000000000000..3d5338c7e1a8d0b1ab2b7fa522498961f981c395 GIT binary patch literal 717 zcmV;;0y6!HP)004R=004l4008;_004mK004C`008P>0026d000+nm#LZ500075 zNkl;`8~$AP@)`jYeqA3WY+gR$HxBzu({Kbbc*~uyX~2!9tL?RA{1G&rPQYaMicswSOIGIe) z!Zw@DU@#y{Bodj;X5@}WBj!pT6%c4XpHtlRdX3y0;&gj$2?THvxzp*C2`p&nP)vit04)sN99jUn0mh9+1G(*X z+w1jiw_E73uno{$Tkz1?Y^Kxc^m;vPeB`38R4Op9QmM3BEeyb|*Xzh#EEdq~A<-I* z#%{NtPA8gc3)X`mT`rfmkAO@;2#3QV+(0HK^zlBISQraq(Sg-tnE>e-T)Z$ptVha&00000NkvXXu0mjf1Q|i= literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/bookmark-public.png b/public/images/skins/iconsets/legacy/bookmark-public.png new file mode 100755 index 0000000000000000000000000000000000000000..129ac5c546db51476b92872d7cd3918e66ddfb6e GIT binary patch literal 2134 zcmV-c2&wmpP)004R=004l4008;_004mK004C`008P>0026d000+nm#LZ5000N! zNkl^mXQI0fs9!HL{$Gu zL13g%qZuFu#v~y_02N>Y7zh(2i#&vwa51(Zk^lbP&%Srzm+MROdn=A&n4i1hjlp2U zz1TcWHcyZQqV!=PiU=Tr!5SA@;*J0q0RXL1zn3+xMg+)`yV}O9m^lCHB>Z+-O81h||ziWK!A# zuRE8jb64+HB0K%bm>BkOy@XE1;YilbPPfR~{AlFifgB%;;&;zgYKgb&|0WN`s zr|(){o}ir=B5rll-o2^kODRKcvYtkU0*y>y?SSTY5s{v_U8kZ859E? z(-@z&=b!rOXP^IX?&{t3rTK3h_+sW!%L$4}ZYYeuB^-5jdG*sb77p&8%rwBug+%Y# zJ+}DF}|H=d}!5oam3b70A7xPblcK^Y`wY6--N6G_?ib3CvaN*5U)0c1kEgP{` zaw9?v+jY~hX^B{S^4IIPU!5HUFM#>)i;$}|L0s!e#+!O<|DJ-Ap)CQ=v^DU3M- z)N(Ls(1IFmUrq1JtpYNjSgT+jVj?6BLHWn{jrpi9cq-4iIG9+=;B*mj#v-fK!_BBv z!yLp-gOu}-4ItLiB?U2(@|$~XIni}p8~SZi>|6xZmP3KlIyYU2<)f}-ZojZy~KTC5FpsRnZ?!z@Fa zA{WwAtPPQkj9TbpO~@Iq?qV(Loqr0JF;>aOoDKfg36UOdG%^S4A=V0Vi9(jFG= z#9Eq*N%2j?DLS;06typz1u1X0i?uSiskshiIH>CDgxaEck(7WS|! zEl}IiP#8;#wSt@olBmox=~kXFw&GDD)*gN9BZ*EJGH>tJPG?mr`WLFtm5&~_xh0oL zaUNZg>KmR85r5xn9|Bt>tm!3*Ni8fb8D(lg`usota>TJQpG2ddTXtE6g)Omajdrcd zQRW215JPalf`Taz*HRXMs?VZX^Ks09u}P%lVnB{8OZneJjVwIvSW@N@kC8JFs5SP| z6%?-Sg?)7)a2W>{g&@RUC#1@C-$2F;E?v~=e0OF{h6n@9VXSMcxpAQZtFY|NVmm*Q z*|z5;Vu3Rb7RR!o?Xb`wm$Cl=%G9$0K?EmFW<(fj!r#N$y7eFR>L2O21u#p`G6azh z26mtOBQUAmo797rBqTBacQ?QxA_Q18a%j4Fh5FCQb9_$*(USsjwo+J*gunfBLwR#S zU~tKV+}k8~&iPwA0yWaNb6EBw>)=E|DL>MvQ9`mK6Lb&--XpzD!jRt(nv(4($e5gZ7O8c|_11w9-8KoO9#Q*>R M07*qoM6N<$f~6ebCjbBd literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/bookmark-rec.png b/public/images/skins/iconsets/legacy/bookmark-rec.png new file mode 100755 index 0000000000000000000000000000000000000000..e8b9e439f0697f0ff9dcde111edfdc2b70966b25 GIT binary patch literal 2299 zcmVJNRCwC$TWNFK))mDL5CC^-A!$(y zwYX9gd5c{;lj-)ByCYH33?7!FbI(2Z@{yrG{sn>KV!^<7U~&Ni@z$uNw-}7VyDF3pgN4Dufx*IHVX!b**A*;;alp)S2P{mj3xkEB!kUHC5DPp8 z>)L7-PD9Kr4AxcqtbU~-Y3g(}Ls^D%QC_w@e%lj#=ac9PrB(^ngDA$9Lf4R4RHG=Q zzX@BlKrra_2UuRPY`v)-mP=+?O6Z{^L6UE|(ZVKQ+78+c(IW_=M0a@8vXlx@rGu@= zg3Zgnfg9X29y zVXqMM`y@I2#d@wRM2E7GW{TT!RK9!X(a#>i%3Ioa1N$MRpVtgJl#=;7^~$!I{5cp46)NwUWtSniyGqXouUPLR`v zO@6jhQ(52eHPYVP%lW1G4{k5tOhh9xAVmYG&XNRvVYJ;NmMe0eWE9iN$;81cy>`(~uh@B)IsF<}wGVKN)~_E{9^2$Pzw*0R@EP;}0?SE~qbUzV$s9fEmj$Y-+RSih7Ohrf zpD!5jd3ct2U6apgV!DEjK<~lC(#|=$lyTNxgdt=%mpPh*!YcEuhapr0xs-;N%`8)w zBC;rWm|ms7VAI!qX6i?|O0r8X#=(mMhH@0;Mu~TYStPPJjt5z$-1O6L;uqQDBVgr9 ziFe0207F34Db&ZYB6u^~F>8)fMTm5xYV`#ElFw_i0*nNVjtw1&)dh@n9VsyM1oThP zUAH^70eHE_tV=$x#rvCTwy7J?DjSw9*r)xVdjV`RZ5uAvGAyOtX&JVAnsv$1ks{^N zPFZOwdIyZ6#3DyWT!YI-4yRPZ2AHavd05lb&JeXbBvB-MhlNVMu7xEIxk`kD5!m!=@h<-YC`s< zPPEOE`q`_TlYnl9>$_-j%=jm38MWPM%q8YVy}FNw`UveVOikaFV!h$2Q}}vvuA138 za7ufbQ~t75bd^)?YS!yfq5^-|sN`#{`qI?gcxWOZj7TgfS(jqu*`WF2gsN(tLen^` z>yUka-7T$Us(@f0nuI=WInpWN?|JK}y8igRL@hBs84}06Tu5ZSJPqA8471Lm*#8m= zL@HBjZx@@NZ|1XAt#2Jw|2DJP1ijxD%P%tbiq-oIlgUy4jesyJae;GHtZNPsv;obw z1zHY-I;yo(Rqe}EW%Zx}MC)gx-tWz9FdcuIF?I^yJzl)AG&wpG@y2{SP|U~Ez4v}z zw_-gT1&AnZtK2fc9~@NmjePUZ>$!YgC;A=?(f1ukh@cMJ!mn0ycaJL{Elu5w1rtHh zk~s^}l9P}`Pr|IOjRM07J<~BLR88NjXis-aU+o$Wtp#Rv}mKSDse!q6V(JcUp=b-b}*142IoTq z1}%JXs1fKp(^{N}1fVPyTjqMc@tfxdiaroX5d*aW*QA7J>4r^gzN8<3abk&MJDAwVJqQ*yZN7*33?HAg_fJI+7;9f9}EwSSG zDSi;a8niHYzd;OQ;7?c#IkN^DEQFbbnT0hAGi#{8!py<~kJAtfJZ9GQ)GRFU?~;ZX z2W%ZMvoN!UN#JqdG{k9$O(|}7Ftczq#LU9g5T_xw4wzY3voNzTS{Jtt*pyx@{sp<# VEaadv&Dj6|002ovPDHLkV1l_^V7CAO literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/category-femslash-s.png b/public/images/skins/iconsets/legacy/category-femslash-s.png new file mode 100755 index 0000000000000000000000000000000000000000..ff5a07da29dcf5c0616d6c0060db3b6a82ad6bdd GIT binary patch literal 1231 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/category-multi-s.png b/public/images/skins/iconsets/legacy/category-multi-s.png new file mode 100755 index 0000000000000000000000000000000000000000..5fc146f8626983c901a4f5c34b839867fdb460d1 GIT binary patch literal 415 zcmV;Q0bu@#P)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0W3*G zK~y-)jnutLT~QE*;df7UDj}K#FCZvbnjishC--4#nKp%Xf@R1R*jS5QAZ_dfn*`6^ z^S3NcKeHE4x%e1{nUS9l)PDWp>f8DC=JI;~q9&|)6Y6f!Sd}$RsHe`OCTogeS59k%qR!gPQrSF4d0oZE!S0S^BK) zhT6Qrr+M(dCHp@<)INUSdwx2)JN|Ni^0_AOZx3pRH}78le)@g-_3`AaCd#(9uq9vl z*Av5Qj%Nny?No>owS|mORI!FEWNjuq9G%gnCPs8Jck9?R!(<^^9*!c zBgKhY5Rrjv+YCuYEf}7GB^EUqj2ev0u{*CdnaCPsWa6W})=Zc?e@BfPUcUeJ7 myF4J<_FL-xYaTNb&T-1r^&3AfWYq;ahr!d;&t;ucLK6VHidi)P literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/category-other-s.png b/public/images/skins/iconsets/legacy/category-other-s.png new file mode 100755 index 0000000000000000000000000000000000000000..6fbb40658192bec90eaa8fa349cc70909a8c630d GIT binary patch literal 1002 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%3?x6Bmj(hUmUKs7M+S!VC(K#9UNSH+GX(gA zxB|uh|Nr06(BR-0AwfYwAs`??KtN!_h7AS=1|L3rxNzY@K|#TU z2@`-?M!{$Z437}_Wjrwh=o85j*NBqf{Irtt#G+IN$CUh}R0Yr6#Prml)Wnp^!jq{s zKt%zD;MdjM@{(Qr{Al|yJ?wvo=$J4R=8<{-nuM? n*qE6N{CO{)J~$^a`F=ISJUgbXeP+!eprH12^>bP0l+XkK{P}9i literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/category-slash-s.png b/public/images/skins/iconsets/legacy/category-slash-s.png new file mode 100755 index 0000000000000000000000000000000000000000..870093be28309c027fea5791bad5939a707034ff GIT binary patch literal 1050 zcmV+#1m*jQP)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1E)zu zK~y+Tt(0F(TV)u=ALFjPF0O zlS~umK!j!Ptfeh&X%AE=rDb%5q!dPJHf$1#RlM@uMyZ?Htnb-j;IP3p0A*vW(L$= z+$c4Z1^Ze_Vuq~VCCj&07UzKrz7#&_^~(b!^)nn?LgN`ETaBFWjD+PY|+9 z$e)A|6pk#Ioc=Ohr{lj1g3fq3i;*qtJ}v%YFTbdP1p0!%_>@L`6a3q$RBuJT0ffyN_8Ti*HT)b1n3r>ZO{ z2|_#ewD!2o!qI*jge*^J*vGQ+e5@B0gAdRJpc#H%_d)Z?&wiQxo{%KT980Tq8y zx-2K>>G`pwyG;D)B<*&Rj#=o1$-%qK$WUQ0vZvLy+-n^)+aJmXr5|sUbS~BXV3q z0|nY{#x76!>kVY(o;!RE5?iJypwtby>9?C#Y1|flH&k6h12jBJc@(-@+ghmU*}YyU zoUAB{oUi}HN^S3+iK4(ERH1f4?Lxun!E=3VEhOetWgSXf@;AO9IRpeTQD%1|B zJ0U+c8Va(kY$H^TR8b6tGpp`XLKfVipCC00Rj6!G*^$>C40vhQ=4uB@I#NY3ik)Tq zJ|txEbAF1p2vw-?R-qyDqp)wSZ6$#bw9C)G`mfB9Hp^E2AU{fFL*#m1@f zzVQ+yMvQU$}Ak+lgo-^y{^F>Ti!!Hw@#Yv*JO*EH<4D64O>g zr`11|Nc^4-oxM5VaP|^%+mUZxH%KHa4gD-=Cmn&V@rxXLDVdo)=3j!=&H7LL1$rP000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?1I|fA zK~y-6rBho>Q+F8u&N(gW!(w85@e&_QAM{PPEHTF5(@>)_A2zc@-N`S`%kqK$2Pi;?@Yb4_cQ6ZWigK6;Xd{ZGq19-}CPM)_6p-Z>qp>*+t%}@E zWSKJc$HkwNlNzog(@4?t^cmJ z^W4Ly&l8!?L?Uti`rZ8ns}B%0DT?j|1?W(nB!vxzkfHz(+C0lt>S}uYEU7XUi`@)2 z4q9y^q0r0M{|Y01I@^zXh(Z86LIFCOR?uJokhyuL$rd>w9Bwr z{@wT;LFkPR!V;8a;jU@mT5tdU(a8H(NkP3iW%%5f?R+JZy-rX=ZM22b-Rzgxk@p8Ub2F^au%t)k8mNP(PFZ^5(oa_P}@^Bopc^9msm#{)E>P`*wgHYgsA>wT8n#k>`=Ka+6V1W1Ff(Qhr(5C z(SalToVgQR>9w1`TT^z({Y=zw;(|7xjT@6%HT+Y)=_gp9{yAo4OFEFhYsII@h5Dtd zg89g+blQw_u@M-<^X5C5nG904aM26V=D8+kW@>IOC%kR9kULVg2V=pwiq?KR{x>?A zu%!}8vhn|7`~eQ)!z0!#EjM@ic%)s()fcQNK?X<9;C;wdqqpTvUn7JvI3vKOsAQR_E}D&}v#_ut%Qr_~&`bY<5959PiCoWs&8G6*&UVaUa`R4AvgpD5r6<4s z=C`u4(_a+@O(s#V>n&cnt@?2H^Kw=5w==azZ^OIJ-WUG?gM#d9=H2xJ00000NkvXX Hu0mjfX7>$6 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/complete-yes-s.png b/public/images/skins/iconsets/legacy/complete-yes-s.png new file mode 100755 index 0000000000000000000000000000000000000000..51d55ccb74944caf676d28a2aed02fcfa16d3e8b GIT binary patch literal 776 zcmV+j1NZ!iP)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0+mTb zK~y+TrITGuQgIlEe`nQ2>#m#D*4n!0K5x3Kn{K-9&Mj?omL{Tn2?Bnmkv0;AIa-k6 z2Z{$W2p6W)QWvGj1zV-9T3a=1T{KsIB$)L60mqIa2aP?0bI$wn?DwAc9Mle>c?8XY z|6>H?K~sRUggJ9)U(CT0hB-vv9C>hKm@@^rwikP&eFmlwZcReZA2d#LrkBivhR2+7 zio5-M50ItOa#X3mY_s-G1cEK&FitTK>V0T^hL(w3xif<+@-q*4?`A9(kHe(!KR@v%;yu78p!jWG|Bdu$4bb8{3j8_XtaQsj#iYJI6v zYL7J@x@~Cmi$FcKe#qpKKWo29^yaHe&I_vKfzHiFt@Db|ID$f1-u&CwBwATpl=cg% zWFQZ8Jd0P8l{z0v+Ya@1_a&#Rc0=b8G?0Nj&<;ZH&WZL$_Ojn!**Xm<8*0Zo4z zcFBVZJCx2;xoQwndC}S`+g&YxMAawg--bY}a-v9jp~vp-bmx;!>p_9)R5&zCqS1)1 z{K2k?Qn}J6ZWJrdyDxF9o~TwbEZZ%~xzYV`ZJ&m@}rXfNv$7YSU1#D?&z2urrP zPP*iiNg~ndGPo4|u=g2KE~bkQ&0MYQ7Pn+@sRy9!JP}<^28zdGze?}t8fv?XP&m=< zx%g=@IRC}3=s}fpd&3@F1U*^h4oDqP=bUI)*S-<&$en*sA4vP=mYl}`0000 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/icon_admin.jpeg b/public/images/skins/iconsets/legacy/icon_admin.jpeg new file mode 100755 index 0000000000000000000000000000000000000000..a032e3507824e1dda195df7c621c192f48b42544 GIT binary patch literal 2998 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/icon_collection.png b/public/images/skins/iconsets/legacy/icon_collection.png new file mode 100755 index 0000000000000000000000000000000000000000..0fa189339b95bc0d0148bbfd7d14418b2dc6686d GIT binary patch literal 5882 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 Teuz=m00000NkvXXu0mjfety{0 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/rating-explicit-s.png b/public/images/skins/iconsets/legacy/rating-explicit-s.png new file mode 100755 index 0000000000000000000000000000000000000000..6652d14d006c2be68da4b5faed228a499fc8b236 GIT binary patch literal 715 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/rating-notrated-s.png b/public/images/skins/iconsets/legacy/rating-notrated-s.png new file mode 100755 index 0000000000000000000000000000000000000000..e73d7dc6612a81633866f861213c5002312efce8 GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-n1HXMsm#F#`kNVGw3Kp1&dmq@u(% zq9iy!t)x7$D3!r6B|j-u!8128JvAsbF{QHbWU38NQM0FuV~EA+x0h}C8VopC6Do?! ztN-7YFkjpLA^)A0tFMnt)=Zc?e@BfPUcUeJ7 myF4J<_FL-xYaTNb&T-1r^&3AfWYq;ahr!d;&t;ucLK6VHidi)P literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/rating-teen-orange-s.png b/public/images/skins/iconsets/legacy/rating-teen-orange-s.png new file mode 100755 index 0000000000000000000000000000000000000000..44bfd764b1afa9b0a47db380ec376774034febc4 GIT binary patch literal 647 zcmV;20(kw2P)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0u)I^ zK~y*qt-(!;n^hQq;rlr`P12+_GX=G)qAmp8xKw{eSFS9yn<6d+DFtbNiBP)pkGK;Q z?822G^n)_BWy&OzH|M#{gwAT-WGZ@H@$}BPjxS;IUqo3gUe`LBjQ6ja$-hxB2~I^R zix-cpnYmnQ0vF4wbVq5jAtfR>V-P->m)UfZ6gDD?nN`#5G%uF+<6l>wesb%*y;+(P z)9&T`@E|pS2x5Q@a~{*-$DiK(<6BrsuogwLV%nN!w&V8B2S42YrqDsMmW?vul*?B! zoN?;l-q(ZSgb3C`%y@Qpa$&Nk27(+uOM;Es`TOVhzWC~Xf%z{Fj~?8J5duO`F28RS zHX@=sdRb9(h04bC-QbPt;?ZwEe|CK_9gbc6?Q|I9S@4D?CL2be)wR|jIYZkZ0s@G| zq1nt8{fb&K%@uN1nzPkG*AhsuHCxgv60^G28hx}KFPE(~AWRdpv4vX0)CO{fHp$>b zqKU5P7h%?fl1+MOA`n2hMrP6{AfcjW(o0Z+HI)XL^byb+3P~SDWy2GM$rhnC5v7j; zvJs||Cfn7Jt)$SDHKPC_J5+*gLSDp`3$*~b{}Bnn4uzdY<4GM1fTEnI@ODJbQ`jk^ zL~z37JcaENu5{0rWeCLHHDtHKc3tr0;@3Za`hNcUx%(e-o_PEnyGSf)$51Gj*sZc# h;D|EfZ4~}L{{UddR%JPcW{v;=002ovPDHLkV1h@lBo_bx literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/rating-teen-s.png b/public/images/skins/iconsets/legacy/rating-teen-s.png new file mode 100755 index 0000000000000000000000000000000000000000..29403e13a0d3c8be3de67b5d3d63d188ec07ddba GIT binary patch literal 643 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 Wr4Dj&DkRYW0000)=Zc?e@BfPUcUeJ7 myF4J<_FL-xYaTNb&T-1r^&3AfWYq;ahr!d;&t;ucLK6VHidi)P literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/warning-yes-s.png b/public/images/skins/iconsets/legacy/warning-yes-s.png new file mode 100755 index 0000000000000000000000000000000000000000..874f8eb3eefd3cb7b1bd4e367afe23e31d7024db GIT binary patch literal 572 zcmV-C0>k}@P)P000>X0ssI2ON$aT00009a7bBm000id z000id0mpBsWB>pF8FWQhbW?9;ba!ELWdK2BZ(?O2No`?gWm08fWO;GPWjp`?0m(^3 zK~y-)rIf#F6j2z(f8U)u6S8ZOv=Our5yZv^5PS*SEiA;>NNJl&QL*p|#LCi66vSk+ zD2oP7k>DCPt7Op3&djm6tAflw+{0}K&OP7x&YT&0V3wGPYM5k_%w$GA3^K{bWb!QkhsNqTAkz_`_ zT$-K$v+bcRu2dUC@&bj2nt@=z^vyQV&{%<&SzQW$S#bFBRYP83jBlRyXZNGsk#A;# zSA9~8D4c~toN34_?D%_$S~wqNvoF?0TlA~NR}{_m_Bv@9ZMi2&-0z2vt{IM2JbBi; zbS3KG%kH&{aSF-uz8svuWMjSPFw!;udB4NwyPJdEo%36F@?~~3*xy(mjD{E2&X&ry z+)D4ieF-)Wj^EvXIM33j*RChaXP-j`NvL&mzv#edCw1*tXZ!*uSUW=QPnWg;0000< KMNUMnLSTZ3`3JcG literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/warnings-death-s.png b/public/images/skins/iconsets/legacy/warnings-death-s.png new file mode 100755 index 0000000000000000000000000000000000000000..954e1905b5ce75eefb00b9cf910d072d5fee9c2f GIT binary patch literal 586 zcmV-Q0=4~#P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz>`6pHR5*?8l}(P*KoEuB_ne6>h6Aue z8~~AlD{uwQ0gOiC7%Vs!LW+k2Fgx}PNgO9;QQhqhnurApHaI_OcidmUs(M}Fy6c`@ zERK=|V1xu9EJ^c>=4+COuNW`Hw_(S}%f~Ofc9aYtV~~MBOW2t%gd~wLnX9Gz<>x)0 zE+4&WyI>`RX-JpT9wc0mNBU@zG_~gQk9%HUES@xrqXcQ&v>*vly`Ga$=V1fihoR2G z-(LS&|B%&6O^trA=6{p`hiT%io9Fg{WJPCN&US_QR>D|mvUqz5UpHGm*eiR?6x#?R zS0K;tu&c`hfo|>fX2XrWg1z8my)5IHv6CDJtDxhs8d}_MH(bLC#(a1(PRO7VX&v%> za-lJx4zIU6-lLV+gW`A#oK9Za9GbXw{93X>Xh(E*zuWOnT1i8WQ6+J8zNFtpl|ji@ zuwF=maOzK?MWtAY8=`7T4&2Z}KMaLcHJPMB&aaYksKd;aH7&j!_7yAJ&g5PeD@*wa zE*MX^iH9+C_WDHEiH$)~^Hk6|N6|HLp0QD9`u+GYO9G~R7Al;wU2FG1XWyP@1#j-! zl{r$m$^Qn1*6zmxH`3J^Ru!+(^2*O4${5kY`gq`t^i&$pvxJytjoIt<8 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/legacy/warnings-underage-s.png b/public/images/skins/iconsets/legacy/warnings-underage-s.png new file mode 100755 index 0000000000000000000000000000000000000000..0fe4ffd2fe66719527cf26acd5b1a7e0b9b93c3c GIT binary patch literal 1321 zcmV+^1=jkBP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$%Sl8*R5%fR!A);mkDYaC{C!f6MhX=kfKi3#*m0MdkE?&HT>{#vW*~xxi6Kyzlh$27$F-eXj(cMMXz5LR# z^4Mb!z468)i;JC!3F0;_EcBj#{sc`t=Wu?Mtf{*;koD57ZyG}cyMfa*(N9PFDywZ$=xNTe*cT_?)%Zv zqxa6u5$G)~oj-i|)c*ayduadJ0|%Dgf4?eA0Mj!w-}&H!ywyTcKmY^+LU=sbtc5<5 z73GyyYwue}e(=N-B(MGEx2K(A;2w3a=y(j=-gwdPQYz<9eIVg%5=bg6I+dOagS27rWt(S2)e?drbYkJzt^4Ih8)%v>C>l0?bFUklhlWG_- z(g2Q#2qsz(Wo8H|^(H5)lx_kyu3o)sdYU1``|exI^W8DV?QP2}3LxO15g?s35&%gV zMT1d*yAK+TZ@=@-?4CU{v$Ftb_Q>($Q_IU6FTGUWxRF9I01gNv4&CCAYs4iVl2Vqn z*4E;gGxHBT(CT!sqtkBRaq84yc{w$klES0FUZ4a-;uZ-bf+z|gMi@M8od2YA;NaAr zJ=l?NY@B}Kh3HiyW~)^){DVeZ5FkiGg5+?yOD^{;Yi#!Z`1P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#@<~KNR5*=eU|=?;8ltvYOhyb0`V5Rl zq-Zk$Aq=yOSlG?^h3wflEr4ty&EgZV5twa`(#l z_wV1wk6(WO{tF}>oznw@OWwZy@a5}|Z{L12H_w)oa@@1`Y54EaPZLC=g;5Vz57H#(QW0bT|jGAuiXn& zkdoGHZJPvStX;SF-1!@?UcLMC=g*wE>lqkzVBx@^{z2PnRy={`dd? zp~L4H801^q<^rXFZUK@;Ceb|nwm_rzA2@UI(k);R0|h5dS;4@d2{%jA$G-q5`uX$M z$B$ot0YzjmL{P38G|E8xCt&1YaxL`vQadOG^y(`T+Jubi}Q!~U+GMbXjKn>HWnpRkmR z+afTeWb3vg+qNG~%V_1~v7Rz@Rb9i3*>l#NI(_xuzyH95Sza-5#>_Rm0=5i{2B3KK z_R9xa^6AsphYz0v8Ng%#iO}HCQeXhjnX?|K6UYU!KY#uPWb8k17MLvl{{6QGobG_Z z&%~q)4tsFAhomn%hg2Y=ps2^*DGkWTE$9XY%E^B5E2jfg3NRs+6QSYdW|nctjQql$^&9pB^UB$C*WbMPP+Zy%41{UZR|CVo zvT6!YK|pZH$x~N=f(pt$;3$HXU#uMFENo`T3}!Y{U`Ze-;s`8c_yp}ad93&Z?YMZY zfm%4YErAMvvh17|z{CvXf{F^1aut&SN(cJTQWV5C03{Sqq63SAlo>!7G$`+fxmf^^ W0~=*CVB&)S0000ymOw05bi170A0 z_?E-vjU9 zkUo5!%#NGeM{R;*lmfC%z{0{(MI%-@povCm61abOA#{@f(H+Z$Pfq*oPNW(vdwL%D zO8wN~ASMCK42SP703W#k+$1be${{>bI~HxjM~fX=UV~!yl-?0o6ab1(3QGegsYYi@ zCdvS=)$^!|1xr^2s#uF=A}quc_*wC_GE<^9g$~F-1Wn;)zj!hpvc{isPk4;f%X39=* z=0+{AQ(S;vc5pX_<_~b#YSz#I6rAWasuE{aEZS4Ob~!^VOk$?2-~1XXeei4$?$8F#pPAE8 z1T0zfH?W{gZ3#0V*m8ce>fx^@dkI(ySf;AS?;=>(s{GHg1T62E=R2_p%Xf%P{g1K2 zpH;lbVEpgYiWRbI#+BJYBvxW2R$?VqVojefWmR#b7ucTy00000NkvXXu0mjf;_)@T literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-bookmark-rec-s.png b/public/images/skins/iconsets/low_vision/lvb-bookmark-rec-s.png new file mode 100755 index 0000000000000000000000000000000000000000..d5586f5e94a493c44b0c78fa94a0db857737d509 GIT binary patch literal 497 zcmVP000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzlSxEDR5;6HU|=?;8X7fg)GR_~G3YZe z=z>Wt1_lE#(t@%P3Q$F`o5f@#E$5-78!9g4>h77tD`3YfVC(Lg4Mco`_Fy}71VtQO z+_SuV^2Mdx7?=!kn8jqoz@R;2)|&6%e>{Hj^8f$;we{04UB3P8+xM?uzXKUkQf?NO z@ptb&`40x&J&PC^)bW`$cm778y6ZRYr=~WZJ$D_*j*YL4im3)Ndi$0fIdTEWXzQ5g z>Y8S58PC9^i_fe%^ELogM@CmMFeqKQdKbvPbLa8Bdr#iI`?P$;&QG7d0^P{WX2!rE z3wD$VKC|X8+ziz3>Yl~Gptf<-K_Gkfob|u}%FOPtwNE*7_8Q1t?elDH6HG1QK;Z?{ zh0Cm&v)BIk`ODPoj&^Y~stg`Ht)O;J_gJ=+C7 zXBkhQElG1@^LefR(e6cL{T0#f4_DhixY@TAZLC?Bb!gK6RaY&RKKPF(=w!=hMif37Z`&bWCn;*^}e%jOK5Yv(?=Wk_(>(u{L(HE0h y;k_f`hVxe@*XjIAbL?mQY8HU_7V7a?Uu9#~x=Fr^^aVx)1B0ilpUXO@geCxHy2gM2 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-category-femslash-s.png b/public/images/skins/iconsets/low_vision/lvb-category-femslash-s.png new file mode 100755 index 0000000000000000000000000000000000000000..c734fa7fa87cdf71b2ec0a02b005b3ac72ac4250 GIT binary patch literal 447 zcmV;w0YLtVP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzVM#}JndfA8KC|G;99(L|f2R$e*j|Ns9JCodNewCL$uvU|^oppa6a$nupt zH8lMg81;xVi$TlHGyB=|*Fc^751cVHi3E}xHXb;8?mAH9%-L(st{Dsr+QgZ~sHdgv zw`b2upw7nTS(Y}5FJ8Ry3oKf&a5GS3)|_=(+5tqniy0W$3N^LUfI0<59D_s4o;-O8 zbVy`$HBiLXA%%fK6{Lpf@KWjQS_ssssN%PH>DG1Y_c1WYWoEYnMZEnAum?PDvozxp z>UQoruB7U}YW42e_&T6VJ$-U_?LJ{*9?QU>OJe#0CP*eDMiyfZE=!mQ7?G3ifo3rp pf>jto6FNi$SE3&+Cq~V}L;&nu=2Exe$c_L2002ovPDHLkV1oKBzl;C? literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-category-femslash.png b/public/images/skins/iconsets/low_vision/lvb-category-femslash.png new file mode 100755 index 0000000000000000000000000000000000000000..964b846121fa94db5415b6235c161cab92446f4d GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkD0|TRpr;B4q#NoHs47mDfa@PL)Y*5N>ufVcL>jiP%UHi&Q8dg)lyN2ZSqPEor%$3qpU*s6^mvY`)cSiX z<%^8{Saz7Go;-a{;oTfjSAI3;q$kajK3dc%d5Cpn3ODCPPRqCA*17T4S7M2fNFM+3 z)t~P*DaW!cIWlc;>$^mOXqHIJXm;x96BVXcR1oShlXrUpwLB;e}2=&&R5ED>J_hRSw(y^!anwuR7AdX1p;? zdN}RlG10zBpCV2iIr^y}E9Fx0hg%!2{@2}jM95nQLj0Tlm9dj+hI-7;i;ciQX7F_N Kb6Mw<&;$VXuC81F literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-category-gen-s.png b/public/images/skins/iconsets/low_vision/lvb-category-gen-s.png new file mode 100755 index 0000000000000000000000000000000000000000..97c30d944be1921627e66642583af325dd0d373d GIT binary patch literal 555 zcmV+`0@VG9P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz%}GQ-R5;6HU|=?;8X7fg)GQ**Vl-r6 zGJ+x?7f3=xAZ!SNi{Lbi3CPz5sbkP#V9;V<&|_dQ05TX^jKLy6u0BWs5CIJWil7;X zYLH%3boK5%Cl@c-+TJ-oub_utz_z7r?%^Zn7cJf*CG8d+Thr6GWWvN{2M(U8sG7{k zjOschmaejz|F2)apFMxQX3d`e|NrmYb-cH4F_6*Tx!~2ScWc+}TexTokbCjct%nbv z0U0Ldu^`uBGfT_MHxHd>S?S~gG-dY8=LqXX$ zC9Mg_@b=3G1qD`jY3YXk`}gnW&4<&buL3eQZaO$;?gpTq&aMT8#eJ~}b@LZ&0&=D0 zJ>wJWfebHSTxNlSQ$Ibk^~8zGd-k4s^Y#PKk8*Mzt5)xR{`~dBhtH#8s!GZxT)Tcx zLfXwQpz!*Q`!@E;pm@M;7NZ`}{uwjZEM2x8Xzi3~s~8y6fEEY}I|v9nFtV7iu$ysk zTLKx(tfoK)6RRn%cm%mCH?Qm1@ry@~UF@H*R9MuJfysb@(FmL}44}yh$bc#~z?~*w tp$1Kjp!B6rS-OWbpWV+TA5!Knd_62Lx-UVx?nq6bl7vLB0$ew=6>H+IDezy8!+uII!n??QU zKW_B9tn68}@#nPd*Kb?>=)W9s%xK!io>ZM=$y0<^(zM(X&Zfy1b~jYNbe}WpsIpT;v+Iga{}!mYOLni&=(2e#x^}_* zjR74hV!KxzJQcQOMTyJ86WR+;opd@Eu}a;w{A|RJ?Bu^zMq)+3zk2DUwmAMO5^axt zIwix^P;|4fPG8l%+Q5G|TphcABuno|pX(!99ibj3XfSt2&i1tnmXvphUV9ljt}D*9kod6>ivYLA5xa7 t+Ey{oe`OIfYfAX`!cYH^!-(yfINR&?kVTo>UI1f`!PC{xWt~$(69B*)**X9K literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-category-het-s.png b/public/images/skins/iconsets/low_vision/lvb-category-het-s.png new file mode 100755 index 0000000000000000000000000000000000000000..e5388ebbe6745ae41d27789b2021d81e0ddd51a5 GIT binary patch literal 491 zcmVP000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzjY&j7R5;6HU|=?;8X7fgIGe?2$iQGg zxmhL*47!ZW#vI(1%xtC%3_1)9+T@zWplxCnyLaE|3m0$k3ECN(MEUsTgWL#mDHt&s zLm33jVlrZ2(3-zs)Bpefi%a@}`uFWWJ$K#)1_pJYV_DeEm{@@>)ns8eXXP+wV9>*D z7RVso;?n+i?>+&|TCsAMl&r_&$1n4XdY3NSI&;>#>o@KnJao3TeeR7L4^E%CW^NUa z?tK)q81;C=w2lPvO=lor}kE>}00d-EBzD8Wi4ak@^d%dKzJCLzx@fMJ~fLd^yrM-N` zPM}gj5yy)cZ&lY$lU48na_7$5sHEx-WXzenK}ppQ$XK>~2Y$1RAwjlz%OQCsA7JPh z7)6Rny6)U{JSVS9LfQ?PQB=|gR1DIBFRg+C&Ip*e*tsmB)&faf3}(V+!O{^EEE_;{ hVlqa{iBYrgAOLB3359*!88`p{002ovPDHLkV1n`K-^u_0 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-category-het.png b/public/images/skins/iconsets/low_vision/lvb-category-het.png new file mode 100755 index 0000000000000000000000000000000000000000..0028676bac92cd8b16bb642b27c64e01213f3398 GIT binary patch literal 445 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkD0|TR%r;B4q#NoHo4852gMcSC< z98R#Z=qsqOb1V@%a!G5+M&6UGPF0T4+PP~)^(V+Uc+A!debpdtAphq>#hXb2hhDAw zz~7(x?EdjH=I{5;yc_m<&21OsX&ZY|b&@4dM;tSnwvq2v#-9)W4Cm|btB8w}4V zr_`=Gu2k4Q-NtRDoVL-T( gKZ+;+v0mewl&<#RqvvEEV9+yoy85}Sb4q9e0HLh5$N&HU literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-category-multi-s.png b/public/images/skins/iconsets/low_vision/lvb-category-multi-s.png new file mode 100755 index 0000000000000000000000000000000000000000..4a2d4ddfab8534d2debcc4352f73adde08658a0f GIT binary patch literal 649 zcmV;40(Sk0P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!D@jB_R5;6HU|=?;8X7fgB$~x&$iSe_ zz+{9F0kRnkpdzH0WyHa4$uDHj%3%)D&!7n;nb}M^d90Y(%wT3Qg3V?C+NlR(Fv1uh zJM}?akUF3O<*MqbA3l7xb4+FDGz|(VBuuiyp?@3rh1=wh2BQ{P8enF6J%4+^R z{5C+HKnAaX9nch@D}ZhRs^Jr`BAVnq~ow zSh95cj~~B)j90JUx3tcA`0#mDOcl@^pjqmv=`BEs^&9prTecm@*u3S?ij_NojIxSJ zK(euMCIf@oqleEoY&-}tDS_a50GmE&u;9?-d z$|f-|xCF>3EuZ-B-@h3%*9ZvOe){xf)tWsJvkZ)*N=hdH8QlCf=2r1Q2G9hES!%iY zT|mCAeR4ul1BhVg6CV?d}UH5x{5_YiO{b<{;W%=_L*%Q&$9hDb8`KTE5}}aJGT0(9?$%L z8Je8?CRt9ndhC)*resd&c;guz!y6(I>!j0|SN8W^~dr$6) zOk1hCEkfx~RL}z9&zskLpSfq{=E#aW&t4xpt7RLYDxvUfPXDrLsuH)f|0FxZed!vO b92svT6n$>eyI(oLP-pOT^>bP0l+XkK7_+@1 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-category-other-s.png b/public/images/skins/iconsets/low_vision/lvb-category-other-s.png new file mode 100755 index 0000000000000000000000000000000000000000..4378686cfb2bee65ac8a441bc05b1298c9f0087b GIT binary patch literal 674 zcmV;T0$u%yP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!L`g(JR5;6HU|=?;8X7fgM3}{B#K34s znOO`53=Fy;29ps8k!BXqat3_{21AHJf+7w&dSO6Eb#^aYuy8Xot0@D69@J1E39`um z!3OCyfS6^%z@P(U2?{%~u$wV3XmavcojG%D|A8~?9OlQ4UwroL6$iH!FRwM&G9c39 z6SU*zvjOU2Vl`#sv;gV_av52G<}m0Oo5t+hf9mVk@8{3o2nsHlF>~$z|Nnpg{=IGc zk%I@%zIpQjDE{{C$C}z{+&rdz{Y#!ad3oo~CGHw;yKATmw|Fckii9n-1*RcWUVZ;+4xcY7?sIj|0l!U5M$JM)0JX_AKK?npLv(}VAA%A z!wzNl&g}bscJ}|XX(qRX9PvUzw>I?m>#1+=|MI!pbAH5a>tqf;zkCyx7thz9 zy=Px_cvpReAd3m}A*C|=2$>77OSZ+-X$!r)dDnW{+=Xwp9DU@yS+IMu==Yj`nR#=q zoqZoN{@1wl^0?pePhb8V)0yY3qpoZ=?VbD_%bJ`u+wUI9YY`Ei@^yF6a%HE-D@E5x z%;0@^Wn#sSUHe|23rjw%Yq>!R#|?00p3)+g;0y1juzr*yZw&beKZrw^sve<8wM zl@+{#ze+c3E$`Jvu08kCJ6#_{)NZVqllc1j_2W@%UWBzOP1*Lv{7!Vr)^)}ALOyj( zILdmlO?CU$4Q2;|sw}N*YhT`pIGQ!-edMF7^Iz>y*e7~-Q$+MrN3r+~KkKzO3Lzo3 b8}*D$lfs=k4$F4~P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzo=HSOR5;6HU|=?;8X7fgWSPZeL>044 z7#Q>!7<5T7i_wsQ!2pbOQ5o8{4ynzpa~PP6!G`LA5Tg;4f$Uxw%ZP*9l3&n{o6kl| zHr637KIxOlA@7*rQ8*?RcMc|JZ1Ha1fwRX=GtPoOEvYW|AKz6=b87-li3RaQ@V z|NhgB8~6YG`3ux}_U!dPfBx*-cbb>a`uzDDQ>U%IdF#QID|deV`u+0d+pXIU|NZ;- zLoU<5|iRb%ZX95up$8FS0*(+e(!Gp0000Lb%fhQ=*rE7vgZJn+O{PO`02ZT4CA z?mdZJGpEnJd;i=Uo|RW$iHEL9o0&Q-5=v~1&NW#dHGS^p&$F{Ow#6?NIQ0AYhNv|g zG`{oyP2S+=7p=oP^;kUT*4n$G+R;ZUKF*RBOKnZvx%aj2a^tO;7kq_d7byCl&o5D* zEI)7g{D|PzLW@T_4^vNV*fgmrX_4aNkLGs|zD`dO)!gIeDdwM4FpXnjQ?spvx_)Y7 zTGgfLk-n!kRQ2nZ%=|N>;IhuaMz`F#f;WYZpMQ6K36FN&s@KBL`q_d#=4}ed^Wi&j zNh@0^Ts~6erhRv_7jN$BRU0g>ZFiMvUYdJUv$Wt^*womS#)s;2&KRB6*$g3mODmY1OhWV2Cq#y85}Sb4q9e0J0{xoB#j- literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-collections.png b/public/images/skins/iconsets/low_vision/lvb-collections.png new file mode 100755 index 0000000000000000000000000000000000000000..13652e52059eae4774454e8273e6da103ece512f GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^<{-?$1SHjWx(Wg*$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GZ#-QbLo)8Yy|$6_kb}svj}6QmdI~!l7BI7{VcobzNSeK% z@qt9xuEs}9g$#;oW3^s4a3A4kdU&8itg+ht-|^M!eto=qw_4nFZze;lkgC@djle}N zokFUo^fcNRSK8dZc2)k!wkaq7O?ZC(Q*!FfWShvJ;aUcPr{1q_b%|CNJF30+Zs^y2 z|AntR?mqJPk;^YT}(w6tUY&gaZb>I>g`Po+1E*T?ykRrvSk*P8nGTfv}jCC89ZJ6T-G@yGywqG+Kev% literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-complete-no-s.png b/public/images/skins/iconsets/low_vision/lvb-complete-no-s.png new file mode 100755 index 0000000000000000000000000000000000000000..a2808b649d3701f6d94b28cdb4445d4103fdeebf GIT binary patch literal 425 zcmV;a0apHrP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzOG!jQR5;6HU|=?;8X7fg)GQ**V$f$` z&;^s)AjD`05@a-DV9;S;&;pSV5yECM8A;1|XzPUvi8?vEX4*TZF|(R7Fz5k|)-#Oo z4=l2;0f`VWiwS7C_KaC;e*F0P=+TS+|NsB{_iyr)6$X`;+Dz4p#J#r%coCYPn)(1C{j^5iGhJDD5Mm~Uc6)*C@6vI@tZY&;bx#}XV(m1 z7~Q=2@a@}=Ik}xckrO8`1KqWB*>)1#HFNgbA3uLNxui2N7+kt^``x>bLZXf{W~_mP z*MDNe3l@*M2H`yXHbAzDdVrR0DA*2C;}JQ1K@t%tHR!^eOltZX&D*19QPC^__s{`5 T$t%0`00000NkvXXu0mjflKHqk literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-complete-no.png b/public/images/skins/iconsets/low_vision/lvb-complete-no.png new file mode 100755 index 0000000000000000000000000000000000000000..b10fa7c048e408fa8600472c7fd806d7f6389ccd GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkD0|TS9r;B4q#NoHs47mDfa@PL)Y*5N>ufVcL>jiP%UHi&Q8dg)lyN2ZSqPEor!Q#I{V!^S@=iq3?K1>HN6sjO*yrDFHU7*NwZ9R zSbzC=#JV!iBJZmmi?|mQG5>a+k>(~7|F&S;n(4`#ZKZ@eEK|ic@kiWP`=R7ob=z47 z$zMyeFU0#?nVo)W&V~*1G9x#eUI} z-IBU6c#^xe_kl~kQ=VRQnOlDKh)meT{u;j3C&XR&Uf*6HT>Ile!bBT6k(1&DKR$3b h!JXc{ratX1V{aPA!Vb-;rogad@O1TaS?83{1OTp`qPhS8 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-complete-yes-s.png b/public/images/skins/iconsets/low_vision/lvb-complete-yes-s.png new file mode 100755 index 0000000000000000000000000000000000000000..d71edc54e1e34b3dc256a40598a02485dde0c379 GIT binary patch literal 584 zcmV-O0=NB%P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz>PbXFR5;6HU|=?;8X7fg)GWMaG3YWd zXfZGtFff}iFz7+qjD}!_21o>`hRKM5K?lqQ3L4@ti^<5uEY{mMUsBqgfl)_GC&VwH zP+ZcLna$M4uOKOI)IMO=Djn_obYkfIC$pQuix+AfBNv@lcRH5W_CMJ{Nu+jpFe*~NNNB%5Sv-LYMMd6fB(6D z{l1oN*uVe(SFhPqRWlW6`kc8NoLw`4QiqS6KXmvUP^7bap@&zln1nL}qXBk50*%|W z`QYEbf4A>A3e@1^TQGUbN+9F;^EdbIJ$~}!<^KJr{ez0moxA?;-@mtSKPDzOf_x3s zh%M|j{R4~sgTbT6FBq8(3X6Mz?2Vfa*xAPg1{VWE%D^bn+BOkl$Nqz7z>$O9EInYX zUAb}x7HVpI0@kZm?*jVn$B$p%zyFAishKx_KCvThq3%TM^oE3UUq}+0(U34{-a~RXq7~~(braPkz*uJRboFyt=akR{07DG)N&o-= literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-external-work-s.png b/public/images/skins/iconsets/low_vision/lvb-external-work-s.png new file mode 100755 index 0000000000000000000000000000000000000000..4fd8bca0327a087e2e5f0e1fa81a55c6c03685fb GIT binary patch literal 598 zcmV-c0;&CpP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz_(?=TR5;6HU|=?;8X7fggqp=@#K2%c z4YPozFc|U+*)y@45HgFwkbyyifkBmlK@+S^6U+rNbQu`bfryL8YUj@5tJdrRiyPuL zi$R}@*E%`1siSj2cw`08@`R*@l(c3bLq{(xC$GytAit(|+W-ImZ{L2DnAE_^ZVvJ< z7PA-)Il0aE>^%uodinBgAUSc;^2JNG0U0x9t~qn|8jz7+)cfYm2O#6$zkhGve&iFh zLk~C@r40c~K=i%+b-cmL_H-+#V;|FLxGwkucezIydeTQ6+os$Ji{{b*>M z#l)n)apM7?(T^X$XltMM`}ZH9eV{l+k4KPkS{&R~>RLe((r(bpWV+TA5#>2+OOl?z8`j*lNy%#~8Y>zcqIQQ|Ym8B-GqB+KY^Jg%GV;)W z38!yQ-=5k2|IhnetGUga&Du7!sOltgdPf`*nzrE^%j+Lc7P&@D4?q0z^zo#PGI#B_ zv#u_;i}>4Dd;AdZ3;X%?(f4k?>AuqLZu?AqelY*7BT3Kh-&41%ye$9mq;8+9-0zqE z5jGla5u(jr0ycJgk5#Q{zmdK|w$y8}omi`~@GQYP&futm>hBMx*EpVY+n^!reQU{U z$Hd!7Q$rWGm%Y*5C9qXdS&((H+-Za0n~&IZxFEp-4x!arbqxOv&#wK`%5(x4UkskEelF{r5}E*{p3bWP literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-mystery-s.png b/public/images/skins/iconsets/low_vision/lvb-mystery-s.png new file mode 100755 index 0000000000000000000000000000000000000000..5b34b33685bcb07e1e4bca78c7c66d8f9b58d6c9 GIT binary patch literal 312 zcmV-80muG{P)@ zt5@${y=Kq<|Nnpf{H3Jg$H1UVq4!O|ij>$mEnd8M`}*~J2`N_w20eU1eLZVFSCso`wgkEVd2@q6ECPH*OT& z>##w5%hpTBZarXq#MrW>Y~>o}I0ZhIHjZh^K40RO-BhdDGxubkfXOdYjVT&|i(EQ| zRK0+Vf7>?QsRsJ(pS4l>siof=_v2xfb6u;hO>>D} zdS=JR3pJYFKeat?#@n~uza+isuH>)KtYEJ>8vh+5`}aLr+Xrz6#6kUEnJ#B&_S?10 Ra{_vr!PC{xWt~$(696d*g?Rt~ literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-rating-explicit-s.png b/public/images/skins/iconsets/low_vision/lvb-rating-explicit-s.png new file mode 100755 index 0000000000000000000000000000000000000000..5445daaac1f01ab9acde20cfd9582e0daa88e9e4 GIT binary patch literal 317 zcmV-D0mA-?P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy-$_J4R5;6HU|=?;8X7fg_?yLK#K2&{ zz@QI92IQN?%x20jWG^6OFDUE)L_h{3iwRj~G3aV&hrE3G_T#57KY#xE_3QVm*YANw zgB(bPSvvaR|NsAg_3B+>a${UvO=L_p8>a;WlOZ`~Y3qgk`}gnR!{<&e8FqHb8rs32 z5G2o!K(l`Q_z5%);>XQf4uQ;Kq`+Nw?mSl22$Waw5)yS{U@#=pU6Am4{rY`sdP`zr zeL`Zrpok*_lL4ji`19BAPoKVO>4pNusgb^f9e^U#OZQ~P<7k;PQq2MY#vjgPly-zm P00000NkvXXu0mjfhhT}e literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-rating-explicit.png b/public/images/skins/iconsets/low_vision/lvb-rating-explicit.png new file mode 100755 index 0000000000000000000000000000000000000000..7358d77d4bdc7642af89c3254b3ff384e0a5eb4b GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP|*ZW7srr@!^sH=W^z3lS0Wdm zlPbNoVzb*^(^qQ((|fJ5K|)HbH?5ccJL2h(NmZl=zUr9xbj|PY z^RJnob8&OHd2q&)Mm_0LF~0P<_VvssT-`o-*)8_0%dq6mE?ku_Vkx05-*u|v;j=Xt hzhT$`wsu7?!%kZZYu+q_BS5z?c)I$ztaD0e0szArVyXZD literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-rating-general-audience-s.png b/public/images/skins/iconsets/low_vision/lvb-rating-general-audience-s.png new file mode 100755 index 0000000000000000000000000000000000000000..8b9505f80b359e0fb22fc9ba0bd6f7827d7409a1 GIT binary patch literal 365 zcmV-z0h0cSP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz4@pEpR5;6HU|=?;8X7fgq?pBEz`&pj zLk8rU#c0UDpvB2!rKTCAXAq&K8_LUX%fMtrx>-Oyj0S~8y|->X{0{?5mTqHU(8FmQ zZc8-NGFu@=Oq;eUF21U?Y+`b169c0@0~1N^VlZT3Gd*?sD$t<(!XBWxvI?HE3f>CJ zK8!3TB)W^ifP>rW&Yj0Vvt;Bwa{sF^|bhAJbTIpGBK(oGm`_bAqJ2ANtXx8o9kH|6$5|72b4<9{;#K8CO zKMx!{%gSL6bTygji-+F^n6iNB3z*7)Y_if9)OFNK_oHRbh%^fToI~8r#Tru_00000 LNkvXXu0mjfRkxgc literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-rating-general-audience.png b/public/images/skins/iconsets/low_vision/lvb-rating-general-audience.png new file mode 100755 index 0000000000000000000000000000000000000000..a44c2220163a0ede16e86d04c84990bd574b0494 GIT binary patch literal 366 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP|mWOJra3g;Sp&y;hfU4Pm&Vpjz#x>@%}Ef tP000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzHc3Q5R5;6HU|=?;8X7fgn4865z`&pn zLQF;=E|7$Z7?5TbBZ~>Ypgq432tfszjQ9lYKq7+nKv|;AV$cU_d-&-2hYz3Mz5C?u zmBYZGXl4=j=FJD72v8g-3vwWlW&!R0^5xrqFqkrRB?E(ObITkE7bp&LEJwk{;ukO9lH*69{x4s?%PM$1eE1ybv}@PyiA%bE z{rVj!PMTT3n0os3)sv^M*f=dFOidvFqGGz7Tr1ba;Z>f7&DZj8^siY^f9R6qLmh<& z;+xvFchvuXnNT>bK0$Dv#FFis@9qE3l6WS51E((A!yx7dIt#KN^f`1p?zqBW!99b0 z;$uNew#GY*#bO3amD^>CcowZ(vU+nvOu|csa;_pCz73lvJQmbV=34@$fATNc+>r6V z(KzE~ae#&P{tfKe7p)GQn-u=(V2@*!b@rCM$c}}(UuTvgL!6Z1MavgekAXgA@O1Ta JS?83{1OO!ChW`Kn literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-rating-notrated-s.png b/public/images/skins/iconsets/low_vision/lvb-rating-notrated-s.png new file mode 100755 index 0000000000000000000000000000000000000000..adcd6f6b9b0503cec62fbd42c7e4922646d09b33 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-k%464!{5;QX|b^2DN42FH~Aq*MjZ z+{EbP0l+XkKu#qhS literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-rating-teen-s.png b/public/images/skins/iconsets/low_vision/lvb-rating-teen-s.png new file mode 100755 index 0000000000000000000000000000000000000000..3d8d5a52a047751205b736874d46f6d9663ca958 GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-k%464!{5;QX|b^2DN42FH~Aq*MjZ z+{ERlL2%jcJUY3bQwvIL26<#vI`_0Kc)>hr@zWzKB9|yJtbMnWP5a_c R5uoE4JYD@<);T3K0RS-rXP*E7 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-rating-teen.png b/public/images/skins/iconsets/low_vision/lvb-rating-teen.png new file mode 100755 index 0000000000000000000000000000000000000000..b6632a6237e2282f81b2455897e0736d4141eab6 GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP*Jd_i(^Q{;kVZ|axy6JxH=x3 zC}UvJb~!6sl|#%?Zx7?TAFf_2b(16Dz}!{-bHzpWu%c`C)_Iy#>Hxu-`H}y0K@1RB bBd$Af{!{U;~6|%{an^LB{Ts5rg1vO literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-warning-choosenotto-s.png b/public/images/skins/iconsets/low_vision/lvb-warning-choosenotto-s.png new file mode 100755 index 0000000000000000000000000000000000000000..e69a0fc59350c7f381f69c99927717d7dd032ebc GIT binary patch literal 414 zcmV;P0b%}$P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzKuJVFR5;6HU|=?;8X7fg@SDYC1VUt) zWx~Lq&A_0_z@P_Kqz>i+kp=^!A&F)&>H7v0HZ;yOFpdIhuCAH7cwX<F$*S4kjHzA^R&=?>>I~Qclr}fl-envosQu z8-D%zZDQ@3>!2kdN07*qo IM6N<$f=?8#egFUf literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-warning-choosenotto.png b/public/images/skins/iconsets/low_vision/lvb-warning-choosenotto.png new file mode 100755 index 0000000000000000000000000000000000000000..e8896ad5dd21c2a842347a543fa8f5af3571507d GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkD0|O(Yr;B4q#Np(G1T(pwj4P3g z&ql|A+UJN+hdY~kF$`4e~b1HXR%HOnV&Zt&#l-`udVbB^%K@VtX_ zTTN9STx9q8SEB3p@Z2Gv(Fm&% z`P5pMi(>(Y>(Q$~zf|0k%AMN>@(Q}|y3IHkbT(LPt;>rn0frcZr>mdKI;Vst09oyr A9RL6T literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-warning-eschewed-s.png b/public/images/skins/iconsets/low_vision/lvb-warning-eschewed-s.png new file mode 100755 index 0000000000000000000000000000000000000000..e38811cf115fa1b723c110af179a9b4321389dc4 GIT binary patch literal 313 zcmV-90mlA`P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy+et)0R5;6HU|=?;8X7fgM3}{B$iSe- zz@W>(U_hx^Ts&3^%D!5~Sz%FI%2X`2fS zEKl!Tpc^SOi^)J#!bL|v9F)HBggUW#2$JjS-qI_nQ>?iqY#d7d{ozfS&d6MJU=AyfP{N_6;?LaG56;cnpKv+hWaqy| z*MfA$xfU8g$!$QRobIsn1Uw0l@kn2Lf5ZH&mvf`eb@{Jpcb6Bv8S REC%RX22WQ%mvv4FO#pnuhlBtC literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-warning-no-s.png b/public/images/skins/iconsets/low_vision/lvb-warning-no-s.png new file mode 100755 index 0000000000000000000000000000000000000000..adcd6f6b9b0503cec62fbd42c7e4922646d09b33 GIT binary patch literal 125 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-k%464!{5;QX|b^2DN42FH~Aq*MjZ z+{EbP0l+XkKu#qhS literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-warning-yes-s.png b/public/images/skins/iconsets/low_vision/lvb-warning-yes-s.png new file mode 100755 index 0000000000000000000000000000000000000000..ed27d4990b06299105c9dfe5e41849cbb3537de8 GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-k%464!{5;QX|b^2DN42FH~Aq*MjZ z+{Ec<0)dGf!aIq-o-P`>t{N?Qe@gnoagh3Yt~-_ZP22T2`njxgN@xNALK9o1 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvb-warning-yes.png b/public/images/skins/iconsets/low_vision/lvb-warning-yes.png new file mode 100755 index 0000000000000000000000000000000000000000..d41e28f0ac29767f13ac4b809022e41b2f7485e0 GIT binary patch literal 242 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP*J_7i(^Q{;kVZ|ayA%BA1u?RO)jHe_wRYtpm&Qo)f~(^pgnN$qio__H0M cv+^}#heVfm&bMdcK&LQxy85}Sb4q9e096!N00000 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-bookmark-public-s.png b/public/images/skins/iconsets/low_vision/lvy-bookmark-public-s.png new file mode 100755 index 0000000000000000000000000000000000000000..71be02efa89a3edc949bc5e31786045debacc45b GIT binary patch literal 1123 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-femslash.png b/public/images/skins/iconsets/low_vision/lvy-category-femslash.png new file mode 100755 index 0000000000000000000000000000000000000000..70b3abd1c5477c83a83be553d9964dfadb812d21 GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~Ak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7)?A~977@wzrAM2b;v=0^@5CpNAA>f*A6j1VOq4cw`>}h z+<_Q}joSpYy#?Q>igQ#j9^~eTbGX1S-=^xB_)tx7U(Q5Xv1h49))IT-Bbmb$rbQ%m zszQnQ^L&5Q%g$}cv= z#J-((?ZBgU=hm+IyZyx6*>0_NT=QI6_gwd{NV6}7H>Hmp(tX^kEvtHUP000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz%}GQ-R5;6H`2Xh&wGhLoS)*nVVb;I1 z|NjEf84wBN0vZ3#A=rPxvLF$HX8pecQuqJz|NmG2|G)VE|9KDtBn}k007h3p2xuHo z1Y!Xevw-&ezqoX9i;J^aOtfc3c|w0*@yGXvt16SMtn`5*&z|gBys)XLFuEW=($3DP ztu_1q-*d>uA({36;+VaBvdGgECRM^j;8epeUsM-R7$1Urk03Q9|hEm_pu)sd&JuJGdN z&JFAO)YRk;ADjb<0c>Ugqvk?SS3yR4aCDR>(Auob(EtB$0tG+3J@Db(fq%bG|Ne3E z$Jb*(#@}D3fQ-MtPUDJ4kXe%^lv0O^I-AwAOuQQK=wJ9;&Zsu t1T@qxLDMQI9i68}x`!AyT272evj8o{D&+p{c^d!#002ovPDHLkV1gky1E~N2 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-gen.png b/public/images/skins/iconsets/low_vision/lvy-category-gen.png new file mode 100755 index 0000000000000000000000000000000000000000..19032e168403c0d010bacbcbc02583b4f7864d1f GIT binary patch literal 487 zcmVxha`*L0EM d#xmA6<`)u?r^RU_Su_9u002ovPDHLkV1g56*X{rS literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-het-s.png b/public/images/skins/iconsets/low_vision/lvy-category-het-s.png new file mode 100755 index 0000000000000000000000000000000000000000..73fc9b9965a7a3363e2f5e2c0137fc3ef62073dd GIT binary patch literal 496 zcmVP000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzl1W5CR5;6H`2Xh&wGhLoS;N_^f9L-H zKTo+?r~m)I^zZlS?_ZAn`FZO9|I7dXUm@45|5r|*T;%9rqNk_&@!i2QrN09fuX0X0I0#i!6Yfc@BjZBK*#?6aq{mkpi8g)`hEh4 z{{O##+boblm%6+11qFG5W`&2jK6$iVMnWrhLtVkn)~K=~QC&^m*jV%U z(fMfJM>Xr;g+04x85*hs&6+u*dh^D9pjmr%O$TyCgav|woPZ2IKJK7EM<637D-7gb zpf22gyaRLsBO@cwFXd(Nt}f;`uB`>?%t#M@{&Xjhk(v_l?C}mDBR0kx0000v^82)wgfIE-+m?{!6u? z?QpThlJ(QLJ1w>}h@O6Kk$Cx}sMr4czhA2aIdA@bd-m(@14$h(btgIpuJo+0n|1Mc z{7KhD>BxnX&C8U+`hxTJB$a)2X@0Tok@IN|&!EnhdZN4ZY?Ok@S?9L`n+;P}jZm~(fsN}_s zueiimmjs8EX9#zopr0Kyu$@&Et; literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-multi-s.png b/public/images/skins/iconsets/low_vision/lvy-category-multi-s.png new file mode 100755 index 0000000000000000000000000000000000000000..e29f0827650c8c94deb31cfa36923338b216db10 GIT binary patch literal 641 zcmV-{0)G98P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!BS}O-R5;6H`2Xh&wGhLoStHS`zi0pd zI|m}MiI8pXO{l{ zeg53(CEvduKYe16nVHUpb-n-pUj>=<=jW-P-;M*deR_WgtnJdL_Xq#|2I>F)<=F3^ zCxL=M1;2k^D=&*@U|=}7Z`OqV5>{50i|3bLzqUR%C*tU#dH?@iX88aA+Uk{^dU~op z-nM*vJf0p_3Gu!>JY2p$b|;Q4(9lqvI;8^W9XD5t!h-0!+Ek!f$;knNg1kV6va(E9 zXTGhi;l>SpV0Zn$F=JX4P{Q0y$I-zA$S^b2c62ZXGCDi*fMi`w3Q&!-w3xTI4a6*< zdVfEAAfvSr;m=zJh!=JaZaSvRLlDhKk99GbUaej|`^^zgg|3qXw7 zGi!td`FMG`ZEXyI+`s_Git+>?oB>K4mqCpGmq3XFIeq=V`2YU}M504UU!Y`#m2n1|;{JgVTpW~KVJV)>bU#|= bi~zF$SKsvHqhzEd00000NkvXXu0mjfF9$JJ literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-multi.png b/public/images/skins/iconsets/low_vision/lvy-category-multi.png new file mode 100755 index 0000000000000000000000000000000000000000..59d81c90da253b645a21295b9d31be665dbdc66f GIT binary patch literal 444 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~Ak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7~?!$977@wzrALk#pEc$_QBTSz^yFn=x&(=eSxI8YGs>iCdZ|e3RH~&#le=B$TQjX_MKmX~j71R?s|46xef$6e^ z8@Pm+bXF%neluIcHKFNV-s;|h3Y*ijYyR|m@`QEA-ihgr*m%(^wbUwHg2zW@-w`GE z4N2MBQ%(2m*K}pu?z%PneAACNI@yct9!0)k-Z5!0tJt!uzaIQMYOs9sj=BEl53SYR z`d}W%rax7=+n!vG%(xPKK{zbYmiza{oBS*f|3&zA-f-+r&ilM|L$n%8f0obu{_O=J ium2-FJ}tuclsS9oNxiNabq2ubVDNPHb6Mw<&;$U%gvgly literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-other-s.png b/public/images/skins/iconsets/low_vision/lvy-category-other-s.png new file mode 100755 index 0000000000000000000000000000000000000000..066abe90bb91dcabbb68faf49f1af6dfa04ff594 GIT binary patch literal 675 zcmV;U0$lxxP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!MM*?KR5;6H`2Xh&wGhLoStG)%e`o*y zJ4cyW|Ih#be+k6+dlrO9GYe?>{|o>BpMx0m?)Cml7ghotRaO!g7w7Zm=c)hyFG39k zk|3MTBiJCl=OJdD{{R0nkoE4({@*`N{{MgN+vlUk#+vr_#y`HFu(Z&Vlob8`<>;qR zN5GZ=(Z!GN4u1J~7^v&-uTww29S7?D{PFO=-=`UXLT64bc62b|;$k;2P+z;cJ1sSc zfq{XAg~h|e%FfP6Sco4eE-1*?+?4s{)2YJzC~0XiWhI#v%i1?@oS?6-=Imr9CMNjd z?E!|L-%o03D)RAhFId=YWT?T$#@gPND<&qSsv@^+S(}TCIndmMIA0|tX`pdkoq0fR zZFNd?lqU}lS9Mh~kPDP*Y|8rn^%%qZH~WEnXJ@nj|39?1<^b8-woKH~QSorM`v3o- zi?f-eqzKUCK*tIR@u#N+0~I(qn)>?M1Igs103dh4{Ko(Pp8&&-;n&YIcD9C$jEq&4 z$#QZMKn=HVZUUOc%fkg!WM--@B_#?B+URI6CMKqNbL)YcU0p328nS22sGiVQ4CHRz zJn{ektKhKzcj4iKZK)}NCMH@T!Oq8yF8Kfd#`2}DK;Om1`sC+FB_{d-?d{j1OUg#^~|)_ncx5b002ov JPDHLkV1g@2P1pbc literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-other.png b/public/images/skins/iconsets/low_vision/lvy-category-other.png new file mode 100755 index 0000000000000000000000000000000000000000..b3ed2651768a3964f922b1fa429fa4a70b18043b GIT binary patch literal 525 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~Ak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7}tBcIEF+Veml+3%h^$&t(ZY^YpB(25xEDk4qLWeJQsA3 zc?P$}HL;{r&8EFim>BgHDi{xPbNqVfU#GVFy(&xh_b$n875QcN&uriPKga0T&p4if z9wF_G$Y`6)=j*#~UX^_OuDinw~Gu-pge2YxA<3?|EN8`V%2=frq2}&fkPW z2lw`~6?+!@OnLtJuWMc0)8lHBW6!$j_=VlM{BqvT(sz5Zx;T!wPt>!oW1Dw*GILsI zOwvw?ixI!JRh0b7ShM~95woB!&QrglS6-G}`0)x?n9rFuj#oZ5ckackTOYPsaGI0_ zheq7`Ra?Z8SWoXU*!gpB$lv{L(RvPFKD?UygH3Ut&5{0yqoSLaL`O|=eHhc6>U-qu z5ss~%>#LqExUKr%U#C1tT�xUVq2Y$nD9IGu}wgedOpL%k|YU|H!JX3+)1$um9HB z=pnOPe_OwH&fj0ZZghwqUKQAKDfHj8>h4w7YR^sAikrA;hr+H6BHP5SiA8AXr!S9> zXEP7mIO|dMw3@H}r7;5gyAmVUto@|WuYcpu{;3h2NQhZx{}YGn^Mqa&p997(gQu&X J%Q~loCIB)B^KAeC literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-slash-s.png b/public/images/skins/iconsets/low_vision/lvy-category-slash-s.png new file mode 100755 index 0000000000000000000000000000000000000000..7ba46825b98ee60a7d9d06870be4561bb694377d GIT binary patch literal 514 zcmV+d0{#7oP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzq)9|UR5;6H`2Xh&wGhLoStHA=zh|jp z*6IKMFZ}<1i4?Q`o&Ep+JQ!X2|Nk5qK^T`09hhBJnFLY;lD!Br8t6+k+RMhq;M1q$zkZ&&dwb)PN85p>02%l1 zZUUK(Zr1;sZ7tdS{5it42I@>qO!jt0Up^nz(^bvR3R6~+)z(&KVPO^( z5%l!5W@KdK<>lJ2zW4wCt7vB3s;y38U|=XLh;nu^12Xb*B3xa}fs9ov+9f1JRxE2{ zW@ggWRcWYC2MTIyDK$2L7*&;t|Nq~{Zr1xZ`@1^wfQ)yq_jR`CF)}e_qz4-tXP0i_c1ckzQ10oY?KM@&5C+6_AwfQ%2k+nA4ABV`M`i$ZVYutx z<$Zf*G}NVi{&48f{@D=5;e&JPYg5xw15X}b`02wTpde7{Gb#h93#b<@9)XGIGRU={ zl!3|s1}!kM{+$D}FN4KV89=?nrd1+R{Af8bY8G|`0FG`Y=}b~v2><{907*qoM6N<$ Ef-+m}=Kufz literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-category-slash.png b/public/images/skins/iconsets/low_vision/lvy-category-slash.png new file mode 100755 index 0000000000000000000000000000000000000000..05e7d2096ff2980b636da1c150b8084067cb4997 GIT binary patch literal 415 zcmV;Q0bu@#P))?^Ie?JbDqY$X z9$+sZNo}K@Wda_+T)<$RLab6sz+Q5JKrSHU0)iJ1^p6jRVe;W-^T86{FvZNv&hBq# zc7}xSuUQRiFv~2n%reU?v&=HftljG3{dM{_n$O1dVimctAb<#Bj-4A$qz zl%=84SeH;IFArj6ix@B7aKo~!@K>In293s<+BE22UFb+qY zCA>@(R#s9_Of;n3ZqdEDzKpCgh1aOa;z;;Nfp-M{+2G2 z9}{kxB{|{%A0TR$4$j)DvMY5)_>YZQW|?J{S!S7KmRTps`T@uPlJ?tNvBCfV002ov JPDHLkV1lC(zIXrt literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-collections.png b/public/images/skins/iconsets/low_vision/lvy-collections.png new file mode 100755 index 0000000000000000000000000000000000000000..ba857ddfbf24e49d611e62966ec1e25183711c15 GIT binary patch literal 330 zcmeAS@N?(olHy`uVBq!ia0vp^<{-?$1SHjWx(Wg*$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GZ#-QbLo)8Yy|$6_kb}svkJ1hvxl_-XwKAtLUgX_U%(Jk*A$Jw zMJ}D2_)p#bI%U3j>D|+JrWr-+KCXCiFKkke-ch?fL5-b{?ACwl+_hhLamIvY$)S7Y z{~am4U{`23|HsLfv$E9pT-x8gIWy~HueO=JhiZD@%DBhcz28pfX_Ow3wfLB~XWsg` z9;G&G4r@!Z`(M2p8n)|~zVM|ZGV8OppOsoGHKT1x>AHXC*Y54#Zv}M>*j2w5)-e9L XdyL8LK*VC8zZpDT{an^LB{Ts5;D3!@ literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-complete-no-s.png b/public/images/skins/iconsets/low_vision/lvy-complete-no-s.png new file mode 100755 index 0000000000000000000000000000000000000000..de03356ee3bb67026ec9c68feed8da5b81ec15c4 GIT binary patch literal 439 zcmV;o0Z9IdP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzSxH1eR5;6H`2Xh&wGhLoS)*nVVb=c( z|NmbClUM)$zw-azIgsGLv;Y5J28&#ViV!yI@7X60w_Ulo>dni&dv;Dcuy5v{pQrx+ zzX&w?!ntMZ*YzAbGVkB-(;yK7X8i?PekCn6n4O(XMn;^0fq{{cF*_^l>zA`BDFHw> z6BAI3!NtY=`LjL$|6L$#R$_u5NQ1LkOJgRGAtNI;ZAt}@VPc|n^5p8UP*)(kraJlm z|LY+2_{~a61evvK$F%?dZvYLFk`l?x2nC9CwB`K&|8@1ME+9K5$`cfn1kH+%^8u>f zvuipqjMUWRgoOAePb>q9n49SwJGL@1!X4zUD&pLgni9y)#=3Vm(5&;ix+;Q#d~aXv zOG^u8WCR8u@!1#A^kD5hAvjE-9O0kXfx?BJN002ovPDHLkV1g!G%ToXV literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-complete-no.png b/public/images/skins/iconsets/low_vision/lvy-complete-no.png new file mode 100755 index 0000000000000000000000000000000000000000..fac0a6ebbe373597d63417eeca3fcef6f8c480f8 GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkD0|TRir;B4q#NoHs47m;&h_F47 zad`3O%Gs^W>@Qed(#7w}h}tylZFuxX!LLtghqr#f2c{-*fjtci_OrZiZU;*53J zE(Pe%-F(-_FhGBv@9EaopE)P_E=EOPY>s@Y?-LaEmq}tO_vve=+vdIhxF&pQOWcMj zrDx7KEnOnNbPa>Ic;GU3!P5FTSD%Evxs@`RM{|F&gw14kVOss-aY($~j)*1l(yqU} pchvk~brg$Cndk~8uGw#X_w<*#LZ_X3Ffc$FJYD@<);T3K0RTv3qzeE5 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-complete-yes-s.png b/public/images/skins/iconsets/low_vision/lvy-complete-yes-s.png new file mode 100755 index 0000000000000000000000000000000000000000..1dc227ae22764d46380021dddeaf5c020b6fb629 GIT binary patch literal 618 zcmV-w0+s!VP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!3`s;mR5;6H`2Xh&wGhLoS)*p*HS7PS z|NpQ4|9|2CpVKh*`TzgVff?69B0x2N&;I{^`TzeLP+2Ty{RJsHbz;%xjs4FaZ~y=A z^3_YLHmvJ?@pRYkA161i@0&fd=GOIfU{lVWIJRK=)XMd1d)~a<`~Tm0Y-atxUSF5S zz`#&i5({KoTI#W|Fz?(p*}=htjg3`MkWWyMckk{Q)23Dc#rgSp`1rWz&#ebJ5Q`uG zU%GyE4KoX~riS9B^UE0-8H0nJnwv6#rY9x%?bteriHXVDO5euD5GYbq7_(*5gcr|u zV{;b}{X6^r-z8rkTc92{Hw&PKO&j`iv%`T5DJfA^Re4!iaVIC!b!)nfjkTDWnT3S~ z=FX`DY5|2Hwy?jxeqApE7|6*={QZ5tzqbg;_V%{fw|DO9m7T|r&Odi{*@69YGBZMf z;`a8&|NmY1|L+`Dvo8MsdrntJ8K|zL7#M1|KD<8?8tTHz%EHOX&c(&CWN~wHl0OFr z8;}hQFOa+bUjch{6tqzcPRS?bGLR*J7)g zs>a90F88#sDp%=YjEd?D$zHi)#z_CuZnk2XA2cG8(^9*NBC39rwsQPK~8SyvX__+m0&#=OgQ!qTbNE7gTuYf~i6Pi%9|lC@y1imcSw)oYc! zQu*AIqyNNpxDP#^TA(|-u=M_=L)Vked!7As-R|Uex5M|Vbk?f-&z^s^xAWYgus9Re z+rl!7g^zqOdO9^C>PO_}4d23cE#^y;bz%R$?(3(EhxE@X?Rutj_|n`R8z<@4{#mQg zuvsrvUo|`MpWNqQpMUGFD(J|FE->4gQs*5nkor&a$^ZWwF2*L;)}(&g-q_mwYpu}y eM&tk${md=Q5p&anw+fUd7(8A5T-G@yGywpKa_J-h literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-external-work-s.png b/public/images/skins/iconsets/low_vision/lvy-external-work-s.png new file mode 100755 index 0000000000000000000000000000000000000000..800b0abba0bca1042d867c02bbebdc8a310beb26 GIT binary patch literal 607 zcmV-l0-*hgP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!0ZBwbR5;6H`2Xh&wGhLoStHb}e`o*y zKTi#_fTsLA_x|nvzrRisG7G5m|Mma>Z~gy&4a~j<<^ma){{O!LL|;B1b#t`{33djH zpTlj|{|jF~9hp6=ro1eE#j^JIZw}0#TR(ed4bT;rFRYw2v2^|V2~CZe3=9k^DzfwD z*8lo(0_0yTX8k+&^~-T*CsUwO9UT=QnVS<49pwpRq@@NK8EF6+{k=uP!u&u6BO{}b z5Z}jl2hjo!X4e0!>(+Dw)mfP9Zr(IeTT2P3;naymYHD%}U{G8X^Z)dw zB{=xNj>2Zv<@&ErTsAl~I8h3HQyaojYDHaxH4i5IHC=Z}dMMVWKUtAd)>cYv% zUSFH~_wNNiUwc+o78x1wii$*_$~m)YL2-&6k09f&e*bdx#?`gYpX~hd>B!sH`#uB1 z<^RRsKTZNe`u&^z|Nnvl=-!=8Pabaj_VpN0@aOjv|NorDkye4J=Kn=t`T&J1C}o|8 t#4;q6!qPoN0XPF-39r#|V$>`c0st&b88Cy>4H*Cc002ovPDHLkV1lci7xn-E literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-external-work.png b/public/images/skins/iconsets/low_vision/lvy-external-work.png new file mode 100755 index 0000000000000000000000000000000000000000..86cca4041a8926a0dbbb716f1cede722b2728678 GIT binary patch literal 477 zcmV<30V4j1P))##yr_7+`;+K`cm zf>DoUn5k@WhnA06jl;0YPT}+&VIe@=cNVX!r$+j2)ruR(KO6!XO{t;(&i(sy#@*eL0Sx5jC08zQ2buf# zECq)CJ^T09si{-SCrzr%&y56{YiOwc_xEW~fKcN7e;^|+|NsAV(}sSap*dM$6uT4} zQI~FBU(d(OZEmLX?(O0K|1MA^_OI;PF~!r<`sDG2|Nmd3R+759c1?F&tk2a;t3YXs zN`~I5s!Rd~=(a7BfEG~6(0}J&KHGKi{Blq_{dbmn*%X+UfRX<1+-NB^YUrq;_z?i4 WhgRnLvXT=300008_N zSkHL$hC>gJtHJc_2M5?#qy=&uE;KejWH~J8_IJ9c+3yPL&AT5K>i-RQ=oC`*nxYZ7 z$fZ;0X})&;^+guzR()DAr{}llC64vl$G)w+V-@slb6~~xmONI|V6Tdx$ZM;dRnzpn zIDKXXZ9jc9Wa?qZ<1c&Omlub2-B=vt2Ex4zIOY3(J(CU+Rk}f6)#3; z8s}M?%s&;Br>gn+`SGBY`cIzLd{}*D*%XVwf6bq)e@)tN1#<|P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy2zP%qt+8IPl7&PX*20CMPk Ule9{9mH+?%07*qoM6N<$f((I>4*&oF literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-rating-explicit.png b/public/images/skins/iconsets/low_vision/lvy-rating-explicit.png new file mode 100755 index 0000000000000000000000000000000000000000..0602069d2879fe6b66a6f3497a645ad4564de4f2 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP|*ZW7srr@!*8!0XCO?RgOBe$4N#D;`} zO|0D4rnc=9T+ThMT{SgGKqoQxAUHu;tvFYq|5R-2TO` wIsCfBB)6yE|Ag#EOR@jDP&0srm2YRfx$gUegP000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz97#k$R5;6H`2Xh&wGhLoStG@)|L6Yy zzxew~+S|NTDw|1U{q{Xh5P>oFxI8K7BUBQ|kyaj>zn7#OJk{B|5y4B&Ftxj#Qo z85*bq&6+vA3h1ugJEt)+GODV|k!}_^yrxg90Gh?g$zD~NGH*^j&@5m)kYyG$9t&k< z#UU}k&dzFMWAOXONuaCAOkZC<9Ra2+VEVdwechLjN61QF2+y8}CHjjLr2Ek_XGEF> Y0H$|uE}Df^&j0`b07*qoM6N<$g5edWg#Z8m literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-rating-general-audience.png b/public/images/skins/iconsets/low_vision/lvy-rating-general-audience.png new file mode 100755 index 0000000000000000000000000000000000000000..f9085027655ba22f020f2b721ea07d5ef9280df1 GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP|+Vx7srr@!^uDXKR=`3!n63C zROz)9o89J`zFHHQ-fNY8B@!qkb4y uxnb)M2J@U1p%ePH`MIO|2kgZSn;GgK?2`Z7plc2c2L?}9KbLh*2~7YHP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzHAzH4R5;6H`2Xh&wGhLoS;O3{|L6bz zzW_pi&w{u>5-M_@G_(HwKK;DCyHaS@detsT7 zLEi0KC;$I{@5Hf%!ovJO5ui9w7UV!8%>vrb&CSUG23eV*|NlR#u1bb*f#M*?l4KS? z9}f!)Gtgb?YVuz`9@f)S6%^nFitzFAkZcwY52u)@U}%U7&@B!1X-tfaak1Xw;zB@i zlFb78MM7M7*^(AUMn*O^RwgE)Z%KtdbZDs=z=002ovPDHLkV1k;+toi@| literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-rating-mature.png b/public/images/skins/iconsets/low_vision/lvy-rating-mature.png new file mode 100755 index 0000000000000000000000000000000000000000..96751efe8d8f4c77cfabe23e60ae37e298d178fd GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP|-b47srr@!^uDXKR=`3!n63C zROz)9o89J`zFHHQ-fNY8B@!egW+-KF;LpylC%DedkL+5R#xUpU`}F=b3ikR%0T$dG z_x9i94_DCFw~UyxwJw)`p2U*vn}7VQROtC(A-_eU#hbTbbHlnuYbIT`he6B_bQ0uT z`rMyLuoSVMi99f+Pp0UEVaKvb>&`J1H7;eoqj|#6;=nnlKKCs>mJ`7A6Z;A0n3Srk zlefIF)R=Siess&$4B3SAyZbkD8neB8yXN9IEKUXrWwbFk=lqjoS!tIA^eKaVhN*rhj0zJi R?*r8`c)I$ztaD0e0s!;uCqDoH literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-rating-notrated.png b/public/images/skins/iconsets/low_vision/lvy-rating-notrated.png new file mode 100755 index 0000000000000000000000000000000000000000..4153de3da30a3e44203494276441e9d6e24a3cc5 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP?5E#i(^Q{;kV})IT;u@m^XYs rpQhrNt-&LfFmqk=qNTXO*VS9!K2rFU7o@8NG={;`)z4*}Q$iB}g@Zbt literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-rating-teen-s.png b/public/images/skins/iconsets/low_vision/lvy-rating-teen-s.png new file mode 100755 index 0000000000000000000000000000000000000000..7b369ace38a63f59d12c7e363d1795cd60de04d0 GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-k%464!{5;QX|b^2DN42FH~Aq*MjZ z+{EWBN6A58qRX|t_(hS&s_O^!+qg+`A*{$Ja+%Va^MgV2d(I=%td*X)`l z0_069+MHLm@O1TaS?83{1OU`8M2!Fd literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-warning-choosenotto-s.png b/public/images/skins/iconsets/low_vision/lvy-warning-choosenotto-s.png new file mode 100755 index 0000000000000000000000000000000000000000..34f0aa0c70b379a1c6851a63f24f8719ea8a08b8 GIT binary patch literal 431 zcmV;g0Z{&lP)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzQAtEWR5;6H`2Xh&wGhLoS;O3{|L6Yy zzwrOxSup$j|Noc3=sY=QeffC!!`lNtza9Vo_w1+lhpt^&bN%WX5Ep3TpVOq6_5WIV zX*@qa&yq#W|NfqploVkA14Bdgb7z+R|96Qbvu;&aB>^?BUfKEY_nC^a_^DIty}fLJ zBFRYs|NmeA|CbcAni?{II(KZF{Qv(|pfmsfe^Oo+4-{EAzX8N0#a%b2OezQJ+_P&s z*sQA?H}nCy>1o0L{$7Me2+?L;*|lS8fWO0|`&<71zxeRlH&3I z)pcuo;^TZSUswq=2pBqD9eIffzRw=-`2X($sb<}(ssx4o*3FZ^A$``t-WbTebYTVQ z?)rEB<+EKE&oBS{;n4qo=YS&j?{2z$apjM%$AIRNk?z519c&PodlAINZO~|$GinwV Z1OQP^eO%NLYAgT%002ovPDHLkV1m2y*c1Q& literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-warning-choosenotto.png b/public/images/skins/iconsets/low_vision/lvy-warning-choosenotto.png new file mode 100755 index 0000000000000000000000000000000000000000..33ddf492ba0ed571d9741dda7c0056e55fdb62c6 GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkD0|O(Qr;B4q#Np&0|DT^xaN${e zPO9|Uip_3wO<%1EOz*YIz7h!(@;YZ#pZ4Ns`U`_NRz$F&FMw6;C)2j%%d02Gq&(5y}%fEjY0~&VVO7ro^1B)2nz58Jy z|7&V=K{}%|tN$0pbdFtC+{U`h&0UjtJSJ{#Xk_WJQ#iCmLW60d(ryLS`;ik~v36{* z;@0EVQG4-9$A*<9pk>mdtSgbqwz<9A{M=D}2J&p%p3MyD1z*0DX)e_O1{;H?tDnm{ Hr-UW|0^6R* literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-warning-eschewed-s.png b/public/images/skins/iconsets/low_vision/lvy-warning-eschewed-s.png new file mode 100755 index 0000000000000000000000000000000000000000..e6e219dbb1871647e8878cea9b609355f49ad27a GIT binary patch literal 319 zcmV-F0l@x=P)P000>X0ssI2ON$aT0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUy;Ymb6R5;6H`2Xh&wGhLoStG)%|L6Yy zzxeT($D~w!sLBsyi z&Fky=c)88Zbl$x^{QuttO5*X#t{qc6J*`h3U-;n@bet zhQ?1n*1*ef*K6VF6%TY0J}^w&w@+%*=>|s2gmX-6oCb*pcmCb$T9AJ9_)nf`b9U6_ z^52PcQ0L=HXKeP3ixYaJme8Wq{>Z`V^!@YmqF&C;IycLHyPRC@l--?K=a`9h;9G? literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-warning-no-s.png b/public/images/skins/iconsets/low_vision/lvy-warning-no-s.png new file mode 100755 index 0000000000000000000000000000000000000000..64922663e9efafa8f4ac54df1af9813d8696a13e GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-k%464!{5;QX|b^2DN42FH~Aq*MjZ z+{EVhN*rhj0zJi R?*r8`c)I$ztaD0e0s!;uCqDoH literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-warning-no.png b/public/images/skins/iconsets/low_vision/lvy-warning-no.png new file mode 100755 index 0000000000000000000000000000000000000000..4153de3da30a3e44203494276441e9d6e24a3cc5 GIT binary patch literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1SBWM%0B~AoCO|{#S9GG!XV7ZFl&wkP*AeO zHKHUqKdq!Zu_%?nF(p4KRlzeiF+DXXH8G{K@MNkDP?5E#i(^Q{;kV})IT;u@m^XYs rpQhrNt-&LfFmqk=qNTXO*VS9!K2rFU7o@8NG={;`)z4*}Q$iB}g@Zbt literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/low_vision/lvy-warning-yes-s.png b/public/images/skins/iconsets/low_vision/lvy-warning-yes-s.png new file mode 100755 index 0000000000000000000000000000000000000000..257440e70fea80bd90d03e89930af345481e3f31 GIT binary patch literal 251 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1SGw?g-k%464!{5;QX|b^2DN42FH~Aq*MjZ z+{EZ)s8gova`BlGpvF`N#erXS;nwI#cRA0pHStb5n&Gv#~?{y)% dK-%wBG32jX`n=BVb{^0z44$rjF6*2UngBSKQ%?W@ literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/template-grids/icon-template-invert-mono.png b/public/images/skins/iconsets/template-grids/icon-template-invert-mono.png new file mode 100755 index 0000000000000000000000000000000000000000..132d63e15cf6d6b0e52918f0ecebc2d5e1059a28 GIT binary patch literal 31527 zcmV*aKvlnqP)(RCwC$od?`3ReAqMay7<81%jZU z(vc3L^xma|f)qh)7!gav9#Iiv2{sTLic+LV2a(>3^j@V`MN|@vlH{*O|NA|6ew*h$ zoS8YZJG14!b3UKB?|b*%ot-)J{GMK(^YyQP{jXVz>lLqfMfS`y&xGSS&v{Pa`~LdZ z|GNymPe1M7VxRl_zyJGe)~s3CpZ@fx*6!oE&wXyT_~MIazxvg$vU%p2r}6XuGZoBQ4wY}C@V~y;;{_DR=pZTDRXa0g0ydb;& z`s-W2k6FV!Y#wUa;@p4pH-D4;_kaI)Az^V2Zg#%;=F9%@hd*QwJ@ioapa1!vf#Cn~ zAOA6X=}TXl{lEYB|FS>-`Oi_H@Oj?z{O3PE352n8@R_R50m7%BemcA3jyuA&HNCjM zRaaegVDOePk#Q`ZW!ubT6l-9BaFGzr|Nig)77`U)4S?_+JVgIpd={?!zyl9tM;>`( zcK6+PKMQm(eBleTEwWMKKW!2|J(!TLsG%LH`!#9@Lms6 z0fc+t{rs#84DJaK+Uw(cxEIbZX*&p!4D#8w7xz}BVNBw=8&$DbOD?%&0Lb6|?cZh( zKKNizk01hW0FGz@Vr>c}$5BTem7R6gS>YTX`p}1-#Tho;bkpp&zx{1?@WBUXzx?Gd zvrm5Vli63k@|Ey?+MqIk0N{D&oj1GUiYu}o{pd&8Z+`Qepvo=3{PNk0U;N_mcV4^o z)?2ej9(g4D$xnWgZMD@_K}VNjH$&q5hqD=9$?EC!Ej+8Nhhm>t2_==}m76 zVCDb*`cuv=aI~SybO0FwAbgIC+;6}A!o!6S4?FCz?8+;z>_24Q14!&cgxKJw*IjpA z0LO|eu9&_5{qGM%9}}CL_sd`Ya(2)`2W5{w`e^pO?|mtbid4iZfaqB?wRYTb#~}R|TWqnyzq5}A9(Z8kdt~pmp$fHi z-YA`04jenm3|k&34|;(G7Rb&&|NQK#tF8*R0vu9=r}OY$4gm9afA@FUamO7O-t&PE zd?1`dAo2&_&EKV7-E`AUfw0iK^&T%lAU42p#1TgXaO}PJ-htqGO)8B&cx|n<*2<1O z_SkHN6;=p9)c4u*%9biRcs~S>tpfpZzzhHtuk-yk-gsm7n%BH$4wX%xxBHcHSjH3E zyP~6NAx*8r04a`?WxeGsZwb=y=%bG=1c&AFZ5|^5NNfYe>3OKqogaSq;h;i2_0&^+ zE-G)r>8GEbegFI4&o#eu$8{kFXA-f2!2uL1#?6K^JKm1`|0#*S8 zLPu>w5~9)}xga6{fnm?zzV@}R1vf4#BkH4oJ}5xsI4Ik@qI)e{0HW;wb=06~2gs}< z&k7F|i2%2F{PD;8hA|t=1LpywHk@?QNkO;XeDlo%cj0{eUGLRH7f_HM_uY42`1@;L z``SJyO;INR-Z|%-6M)M3ta_#QaP7bT^{>M<;RM)bn{9%+m8wee-p_pIGXYp)K9@|Ca5e({T6WG9|@V%Wh@ETI&j5E&2cGzKu@Y;;DLG++dN#K5{3vYbm8$-a4 zcm}Rmyg>lxf(tGPuK|=j_Shq+LVT9ZlX_x}bQT1Lhl(}-{PWlHz@W7V*BB0fJTK=hd=-Mk|H*xpzhq{>cc6Ch);LHJ_SDm+Di1N(r73INba z*Is+=phDrA<#!$~3j*S^ItShv)C;|4Z4m3C#r0ZOJy6h2|F?#%z8`}dZ=#Bo;DB)~wbW8!Uyu^0rZ0KPOR|$sJ~>Db zfP!@8b6f|~%ATw4Ug&!2*dHm(NGcV3jY9#|5Glz2S6OA1?6S))3z8&-h}$|wW`kHY z2!bN!aNBLSWuO22=Y!$u19Q4Kz(W9!^|{Y|?peC9eEZ(Wm3qO#;1&n0I`}+x5Z?{4 z`SXgnu>o)i186T@SP&>uf%pxE_&2`sjlTM4Z5cpFOa?W{evb%R2LQqI1yf-E6!6m_ zLixleJ`p1QsH;c}e;(~0pRaSo0A6)et$+UKfA0T|A?|Guz#*f(%G1>5F;W!^Aiz~2 z9`b0=-{oD3E#ANHzWavMi@WZ+D?EJJ9(IXiSx&$5$}5MTr<`(1(DADxqkI>f7-_~r zqDd+aG#e>Q&ME>UyyN2a=BO=e|;ps)cmGGig;WfdXS4CIirM2ha5qM4lh? zZPGee3opEIAh0TN%;#S9s#k@FD=y|QJQn2!g!}Kme+V){^bjc02;wu>Va5qobC<6L1jek z*k_-8qPj8HirW~QXWMPJ?VqP8ohA9<<#}YXi<(+esZg%~gMF5DiF4ADD2FoAMWA)K z7+etokhdr%IegHN-ywYTau&fnygEoQh*IxGU&j-Lp@>QZ_lijcpVq;-Z@A%xsCNgh z3n)<6P_>BN#O$o!|Ni&EolHuM&v~-(BG&6)|N0QyLCPta(FR5V4en{O2Kc*mTKMzT zJqGz)%3|LE2aFF7oc4hInn`PxP0f)03vtBki5Pc)a3KI}gd*2qktD*9#{2WZ4}LHN z4!`uJF9m|ah~;{u4xqDt^{Zd)OO-Oo#@{(F5BJ(@uMM#l&&8A)qu*m3pIFV$fBy5} zjIeIu80SYNCGN84o_mIS05IaV5ZGy_ofh1{q?yPSUbN~+5S#DTbh0865p~u^%L#rG zADU4BvFZ$l`Gpr=7y@J%okgkaT8Q>L@4PcS^!3(TuQV;C=mEp+i5;N#^4( zAy~Nj>Z=D;67>)!!ahmTR;f*O)E8^RbgKmw%Wn3XYpxl%H_`DjVif1)fDm~fwn!1t z6&YD@J^BC1PeSD)Erdn91@4XXP^4NmPL;v7$RdkmTW+~!AY9Zl<%U%)z(HUXa1h(T z-bvB9Rr|tTklq3~kQx}!1RL+a|NgMARp79Whg9{dEfovNfg$eQzetrCB|+?ec%YzG{&Pb+@fBfSiRuijAv|t5D1UQj8+i$;p0Bve1D=HoCZuSsqdfs{Gg*_pi z1oexU3f{Y_J*q1~tVgWLg}ujKcqS?5#*73AM2kMngGOJbR^dJGc~6L%%m0ts01*>S zC)y6tF1zfqeYa}rQs56lis|8;&;Je83Dqklipq78zK%i8{SfPT``h21t-t>I0o-yb z@Lkwk_uO+&kQ}H&fP?p@f&;FMy@G1RIdL@L@W4X{Nco+NV#SuK&Xu|ZjyjT|ZoEMZ z3(wY|CBf6Yp3~!&e~sA|JZxecEVwoz7b70`DK1Mkk7zW}_A){OJa~9w3*8*oryefu zUep@6F8MwXv(61+5kZH`r%EbGrDKjcCP+m|KCTI;0^bWbAOfxfg5&!kgqXBhX{D7) z30vwSk`XC_SB~!i(29IlEr6D~I3EogcqVluh!PRoT)4goJh#=ffqmt^M=C+=#=rNy z?+u1JTopr8`Y7q`NDW26hv_6j>;>D!F1WX94FH6d7K8ZUxfi@kTra8<_d+SJRcZJx zJZTWMa-`}mKBv-S?u$jWA~sE(yrH@UQ#Lr;tq}o4ghj13Di&&rC(@=eDn0S&|JWQ& zB&De!3hoY2_S$Q&IS9($PhC5z==+d_*d(?zxD9|c%83yd;2w z>uPcn1e8$`hccZ9`D`sWWF*yQ5*AVvHK;8WOH#UZ8>Hvm`K#}?(d3O_w@{(iCUK%> za1U)aj>D=C(kYhSV^eVS6RiNEjX6dJBA!Spk5)?jXxL{?@+Y-L zHU*|=uZltfMSI2GqCw5#f#abNCmM!p`_J+bR0qY$N{0cm3c8Kj=GX$XBZZ ziT28t-g;mZ{l83_ct=&J?eT<#mx@k@Y8%N(*i<%4gers9b`b#_WC8Q=VkNCbo5cgA zmRskQnq(6V@dhD@h$R$lUaT*c2L^xV!9xVZJ20dH2d_~>j@OJD5YPE+Uo5FUxL2uX zp@NX#Q_{%Ua9qWtrQj;Zos61bo5%Skd-egNck?W8OOuR=JDKZe&nbx}?@ZU?ug4OE zRVS>P0vY1(ui2n5T@Dx1L_)9q7g}H9$Ef-*8Em|R9#M#wXUmbKt zbZ?Cuu$F(3p;)Gm@{l#UKssfS8Wq!lJz;r6k%vrP5s`Fi8Q%4-cRedguGj@B^<)R2 z3w!YS?@--`qVc4&6JvppV&a-SEYt@D6YY5g248u}=h%Cg5+D>fAgG;p-Z|I|dN5+qRM)6Z{IqYSxDEB2`{n(y((1Bj z?hkBNmTFH@pZUlEQj}6HP$=K0>N7FIiru¨{t{w?l^qsWuR94rgbPN+QQX*&(|r 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 US!DFy7;Y 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

    ;qAUFQN;D_ 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 X+}_Jx$*;iVYmlna3&l!#i;({Z;AREY literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/template-grids/icon-template-invert.png b/public/images/skins/iconsets/template-grids/icon-template-invert.png new file mode 100755 index 0000000000000000000000000000000000000000..be72134c8086b1198a0ecbfb7fc54fca25e1be91 GIT binary patch literal 53145 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

    %uoZ5kVri2I8L>O`>4;hbQd!8x$bVX-6#CJ6lE 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⪼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 K?$>J|V*d+|7-WS2 literal 0 HcmV?d00001 diff --git a/public/images/skins/iconsets/template-grids/icon-template.png b/public/images/skins/iconsets/template-grids/icon-template.png new file mode 100755 index 0000000000000000000000000000000000000000..17f68c81ba18fb95fbe6db8d3e52b12e776a9559 GIT binary patch literal 51991 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 z zE;%0FT$``BO;Mq;w#$a}WJQOdro}P`q5Cbn9PLL(_pn31f7R7iuDR5j8?sk*ve@wM z5VWqk0TSO=N?%iLGa%`;PD&@I^n7p0z0V*c$dPqbiR!$L<&D`Vvn}w!*yrPa%rl1- zkZ^-m)k@b?ZNH^|9em3DN9h7^JB|?Lv>Dw3_lS-Mwhn8RyPuq8($spL`po&9R=W6% z$t)wo$zVP#EPZD+MKtF4N}ShJAM78lld!}bB;s9Yx=g0CeM!20bEQ3@OaXIrnUwNX zWZv^tT^v=^yPlax&!mA8dZ3(oz#{S42-O~cdg!oS@?3sc7!VCc`6$e4ei{JUdx)j~ zkw2+?DMI1o@JA)+4sm$*HoBgU9x`Z;TX>+$tOR-h3N2X1m6s+O?fJ2cs%#0*sO3Ym%vk@ z`3RED&q_R!bJu%+UZ0w=F~bQ~-^XfLSvnJmHRdz`4#c3JVe zt3xa^nt3G&i{FEgN|8b5<}fE>(Zv?y99`e~rT0442&HqDfA~EPwnAPHSdB*+*U-`P z);E_7t7=+u5h|htFWA)nRNOcn?(W`tLlQHZP?D5{4gAJ{lVOUp=Xt(xrS?cZ%xuCI8i2Jq3yE{Ei_frWN7VB`*e`A@H#qp4`pT zOnW&9KJMWPbY#u9n4F2c1QhP(VbMfAof2uKWF}mWSgi!gmYeQ;liG;@uTceGA%}L1 z8%;cYySsVZU6D19RhH3gE6%7EduDjpjGe+D7-loTrdTSn^N6of2QD+9IYv+E9l_xF zGEb&DOK454&pN5I%~*_{^%nHO?keexeUG(rp)llN7ShM&iv{vwF#w^_mKhpXZ1vM= z3JC0q-4cQ%`(s6bS8RUv2g+3mbqUA9yaV3%M11QSJg)ivBo(G02jg$HDw->#v#h1o zZY2%{ai*E>t1^tuu45w9tvd)Gj&3!Xo5xxxK!5z6jwk7#*H;?6UUsul0;OU_;m}k31SV;#Fq0%2AA

    a62AC9io9lo**F!dL4vx|>x} zQIUT27ggWVl_CbBtPQ>ugVS9~+ zW?%W;`g|hH;OTzpmrLHPghYQrLaTb=g*gnJlz_`NNRWf_q@~V01+wbieD(I5$3SEh z84-A(sgyT$Y#u6o$S>uz(n6!}vvT6k3G&#}<54x_As%VsmEEa!b@L7tF+uOp>jqgHeog!Rnvn^g%v!#lT?DSFCJBxE3T)Dpp@;6zTrndHhvx8%&JeXU*~Y?-4|Vtd2_6UG_;cvcAf2vs|9(y)Ar6gTEmgN3IH$34Pn>KbtFF*_Puu*{ zue0Y@WMmee|6|wm`&p%;G9$}WUS2OpZ!WJ8V?*&-U1r=j;Du-8-rjc(tPbjA+`1y; z=8iZ(&Cv?J7J>YiAS^6z^=d9J z4=WV*MzBUp)#a?_pcA+oi;9Y_TY-Z$gEC|V8eUm~$smY1p(Wy1u;?zCNd3ebZE0+ULo~2fg|dZ#G-1s||%W3(x=Y$7f$uW@TUc za)r1u=k|itp`DCdS7h9n`D=`-_J|4*05uxpUwEPN?AeHi9`YGDQ10%I5R%JeEWpjv zr;}H&&Od&fk;}0}a!WJWYplAz#UF42tfZee`wbr|(|Xt+tjNf`^7XeVo3`55SzrmP z4hX2o%mPYzvpHnq_=q{P()a8$m6jqx!e`A8fs;$6a!*gss7Qs*`@oV%#UaVwJSP%p=Ae_RaQ+MFO2%~tlNO?f+a%6)wm{{EO@0AovOsj;Ad@;s|jVV1Q| zE7*cThg2bk!OdM&(Uq$OXU~oQ_AC1w`o+(er)=8F+odYBk=?t_o*6c6ibuDIWB+(A zWz$vwIQG=Da!+mg?!5ru868#AZN^Tj^YQ^e(L!a_0h!z_!XQmjziDh;its2s+F;)CXVtc#z2DfMs<9zRZWy)S*aBJR7joWWoV z3A;?29JO?@Za{xqCVlkhpP0+avko1hJb(DHCwMCd0RF>=+Fp~lSjv);({}8>`t52) zF7NyFleZD9+tbOo6-CC**+d7&+v2?2zn5JJXr0Qcy2T5(=5TC@t9lu%+JjBJZ(dAn z#@+*iUw=j7rcPM9{``MGH5M0(|5Ez-MlOCZYUyHykIq4IYt@Q9^Bycb|A)DvQaoq_ zi?>*IOqp4H^%?+pbc-1M#iyRpQMV7Q+tJCmRYk`2>8Ur1(jd`*Y>g6Hz5J`;^*Acr z!*(ev`>C6HiVD|z+&Eag#S-(zGNr$tci%ocr_L%ke?dI14i4`7)Z^Xe&tX-n#-7V6 zmE*r%vGcy!`n-GqzzpNwwPv1?u&mruD?aw_*T*xe$L&jy-o8%8ttc{f-u%^j%~pX` z|9WiH+OM>+&C(DevVv=?VjNP17zVK{X4$5r!VCZXq$EB8GwhMS{#~R>6&Nt;;|~_Z z9E<+T(k7^?;V&p~%$J{GmH_~DNU&Q-i0$r9`DxwMU)G0A7?-kX>xO8 zK?}ryME%uS8NdU ze&VkSVvhBB@^R;pvPsyq$@5Me?l$j!b9qI>|7ya!Oy2Ol)o9E-c(@~dtlQklxYb3* zPSnZNceYv>6*~0l8rCd0tlg_;2XDDqEL(GsWpC-N2Bwe-!tXEs(^Ogp0D+@N-Sht2 z^%lRk=Ef58$7f#zjJzkLK}RHWSvgSJu%S&mG(l`^g84RdGH&aHpwq{RMB=>0LiN_z z)Gmt04K1L3tXEe*i4O?F5W5Gs!Q+O_Z7Vag^3R-;x@*RLv;4j-KewGKQTjjkkE9J7 zkNxAh+!H6QdOZMeMq}pwgS%$V4H`Qpc-)x!gYY_lwC%kc>Sn6!J*|dn%rR;J^{k{l zXEj|w9aa3B+%)^J9-&W4{YISQt8|o@- zU%GBjm7PLDwOZ=dW6@`47%Y)shRIJ&ow{~yy-T=x@v_|8%V7_Xwur!SSqBcMZrhV(WK@AnB!>2SXFht1AFvU)&?RvXAi3M0l5D-F$QbZ{d1jO^0i18A?J3U~CH>IY)~rbp88wM6iz;CUnX~iN-DG*zu~IT&16%TS#!!l0^<(xBmkL WTQ>UHyxn`suAN`T`)^qs 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 P00000NkvXXu0mjf(&1Zx literal 0 HcmV?d00001 diff --git a/public/images/skins/objects/coffee-cup.png b/public/images/skins/objects/coffee-cup.png new file mode 100755 index 0000000000000000000000000000000000000000..8e99f5bb1dbe7d483026bd1b42746012c3ba361c GIT binary patch literal 76981 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�VviwT+FG-l;|3WQxo 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/objects/glitter-pens-l-b-matte.png b/public/images/skins/objects/glitter-pens-l-b-matte.png new file mode 100755 index 0000000000000000000000000000000000000000..830a553c46ecc7786819217cb7aef7cbb6342bba GIT binary patch literal 145944 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%0Da%L$8N3Lt*o7E=3Nh68xk+V4V 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

    wx3eqWf%gsaVla$e#OZ!o0HzMJCJob}};x+plF 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�G{jI)QF2PGL!pler%H}fetMS%6h}!i3DRUs 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

    y<-<*EVF(4K^3CC~lgGxjPUGsI z`s^16tIefXhkkJ3r@rvTt&Ni>d#}Fn`qoc;;pwR#u5tC^TWIZb;lk?#{v7EvCupB# zINfD39g(FOd646U>LUXHAqBo)V>WXnwF%BS#-l08v`3y-rSiLYG`GIKJ%x4mj^=kO zQ+`}C&+h@|4=tH_uk!l?-h;eR`hVd2{2>7Js&!zHDxmwsIkbqOC>|l$e=?x{U_PVx zLCI-^YHHM>->87I*2}D?B+HvV{K_wQ_3LUF+(4CJM*aW+Fnx@-g z(OTlLfmGrk62tg}m4$5HUrfxNvoogYUmdyDL}=eQJ$mE@j*7@Af(D7dVkp1IkiRXhAMD zrE>VCq3uQZvBTMdMnm9)Bl0X>!w`4|s}m+cf$PI!O(5!qaaLjyNvib`p%0jWC#u#* z)Q)-X)2CUOdj>fd(rB+T(}r5GLEHB!1nd`Y!q`ysr|g~o7E^PL?c@!Teo9zh;$U}+ zrcfAbm>8G^upnVDl6W-%GiWbBnwLZZ;+CT5LMSTH!KeTmRCegbgSZZHy|M^hiXrw2 zR*uIIFHt0xaXup(7WB6IT->?N?!g|Hu559*zlTdQW<^4y5he2ri-QHg%Dx9+dGFw;AfR6aEB%1FXtSjB|>2OH9@hn+ha@gCfGWFZ^%J1>e zJ8@^m?j9T&#eK@ypE#)9j?V9XuO3Hi`G*67JJyeYPO$g)bbM1<}Rtaf9+yLKzO2O5j$Suxu>|UH<>M&G-uz*_NP(bEMC}E-D@M6hoGooIv zgBBF|h=pdGbH`p{dbrCV5-dI4K)R3<^^n?A8wlmGzW5?SKEvw5YhVl_`Z;hX2xN(s zmk=ri4Au#RlN7}@Z2lUpy2qu%uQ0syCMydatV^jaxA?=WL$3VZRU%QcxA)sDbS%&K zKhJ2P%d5Tr7rWaH4&NLTTFt&rC})<$TwtxCcoM^(`j`F{{_yZOdG%ZSm}9`A&*b`f zBI)6YKGOPRWr3+Vmb-#70=x+8PmwO++;SZk#_VqnXf4&4B{Kr&k))dONF%b6OhP^d zk-|U=YAX&kaJ+K-89wt1{~CYz_TOVZXfeOEieFnmh87{} zP$PWH00;jn2RErt1wR{M47eNUO8R@AbYz zVI4)GNoFaN$&@lFDa&d;`*s4_jZD`M0ve4r)*5%?0dY1YnK^{~2(npGNzliwMXc%2 z-#kDbmCJ9xu6vY|Z&RGQP4VRsd-4wljIJWaDeul~`#z=bk6`H^#4_^71LX#R&txoV zw%4)N+>{3YUh0 zA}3gtY$i}&1rvfyz!spjV4)iz%beV}N~gNDz)VDV2U~n`sm1kG%fZzNyF+Msb>>_1 zc!8jKQZW}V6F9|8CL9l1h_Fp9P;?hwVeUl8irXRbe-d9VAzTFPq5KZk)yVV$p701f z4{HyBoMiSUBiE;#e22N9NhDId=Ff6v@7EEN-(r2~Ut~Bg*-6Hv*SC=cT>HZ*?Kx=1 z9-I9!-+#5oGso7+JO7B`)_@)9O$BD|(Elm@)#^6t3p$jJR z@I{Ab&aKi~euAa?GGcLoSwH2>%IE0~zD3*=96$Awj1SMVdGIQib;NhR`EAZN4AESV zE8C9p;7ArX0HXz}7L!{=Glt0XkcFnvfSf854-U8JwiLt?e_pUwb7T|2D3kOK4ab+@ zYWQe_nFhb z5s+Vh;S0a8)d<^HlW%s#nCe4@9!6vaT}K#NIql zJoRa`mB@SbdEI?QP~44ceiW~y_ZN5_*6O1kHk77BMh$+LVz_e;>XpB@^nQN~!2F{D^baXJFhz><e2%Ew#SyWXX#y($OE_tAx1rEJ^Vez1`no zXgobZ*IqHN0-YG%uN@u+V^|^)`*ra`wzGGZ6*7?Gb06{1WZ88lt8M z^eV~l0#WRk%8)<&-nY4O^%8G?_kW_ddjY2%iK^!O{TME!;0hS)fMOzv478W38UNW3 z!Ul|{8L=;D0QH6@wIBkhEASmSt*E!4H-+sjN2dlS*Bt50Fc8q1gM|f0y)Vf74qAfR zB4oK^t|93Lg5lJ#v1FNxp?#{sVShr+6HI3@zxuZevMXKw*5CQ}|9sGH{K4=4&wrnD zFFa2&%y>r|(kv%UGtx9A2`pNhTLiR+s_|7*RDRT8ef>0(sRnZ;S`7u_?r`|Y;9Ca9*45j1)D`d_&u-paew;xy@reZGcO$>Xe z{`C!eN`Rs;c=IQbO5i>sGmMW9%x`?wKN$My4oj=POf6g{FdeM-QMs^*2bXytgZW1Y z=pPc8-xyz+4Tgxj1SLQ?i;6nPuyr#+ND-1vU;Sco^-A4kkb0F+i?A^2LGL_lJXc8@ zFJpQ3vrlu_mqfua7S>j<#zPQeH&$q$TBY0{FyDzOn~RiV0pr*4%6Z~i&T8irMCYI! z5QHAu?BnDinLT8td(>QpF*`U4u8qD;@5(nQ^BT)@b!IN+aP&5(Wt)zWyt*|eC=EJx zeBVgbkE`WKCR|+v=1|5Hz~hZ;F|U40@r}Qq@ah%K|Mjo^@;~r{)8Ckluc1pvo@HpQKX7=IvXY1$j04id z(QeI?<|WBakEQMg;}Nvm=2j~i$Bo?G-Y%>ps!^)xY)X6a7{2eZ?mUX|_ARh{kHdu! zkmiQ0Xi#sqZ}!d~hGcgG)ZgvZeZO|w9aZ`FNC@9I6#NkMOCJWze^4s|yMk89r zSc9?pBmbSkiQ63H9`XhW@d2tmKkk73QLs?oHTrUA2A?2g?Pg?fUO<^&Jrkq}gaWM~ zn^iqgQaE`Ms6#)2aRKot<;3FCEUx`YT>W`=um1y9m(SvN&SCYG#_9>Sw!Xn+^KEkG z$mN9MaFcj2;KZk1V$c3}WW$nKW^ly>VI&8m^MrBA;c&v{&Xf~Pg;!5GIGo_DBbXJAa_Ugd;dz27DOdJjZ9~xX9I^q2N}|V(hI9m7@WxQi9D}hS&>l~{e2Qzk zu<~3;dAQFii^T3UYbRe|N<2|C{!-|xq zY86S%%PZU2b_co(kmQa=0x=4WrKmZ)x}&)u=#;P;OTyUUDkC$jgA>bOeTg3kbSl`~ zw;b$Sdap?i&P!hFDfX^g-grHy+|Ie4RE(uFr&rB?_V54VSN`~~{MEnS8>9|5&#{v~ zS1FEv0HRjqiR_S~!F=lpCR2sOA}}|FRlsA|Gt9<&2vK7^ncNBD_YAsK|2WSJT5~Jd z_7a2P1mz-vMz_lK?)l7C@~e|+N?AIDFpr!*y;~Xb=ASETFn7;G06!kiUCuq=AoK}V zq#y0q3Y>LlKHjQ_aN@o3;^^Ebg!*CMD(~yl_1^o~C~m)_A0L>%$9uK50Gkj*&1xoA zDH;K5{T$L1u9Yy{13iXg8&xpZQ>Z6Z3BEUhur@&_7uaa5Q(J6tY5$+#<=g1w5}jH= zsvNuhYaHqssTr_f6w~t|zqa)Tv(|v7i`Y5nBb6Z#31J|ZO)b~^a5#W$SjoXE?{x{Jk#kvzz@Kbhoq$>_AUJ}Z1rHFS!Mh&(CtdbxgeRsTn3G$3V06= zp;Lp_36Q$lotXf?R+-!6vx;nWY#v%&@QVt#bzEuemj%q7P{hLG)u9+V>Q>OGL*xsF zsbl4=pfhL53W=*%V{)|y}vKu>I~ zJ;!`=ok73A^ZX;7>w9JJl^(hf9_9V5EAJ{xSH>h2C}&BACj!Fm2IH9^b{R4d_bFT3 zhauP9Up7_T4V{E;>dth?@?-2_gpD7j)||4i$r5iQ3wx)lqo0O1UoS z85*q`qby|_2^t34Hb5!I=&+zJC7uWMnqbgR@k(ee2!sbpfE{VtR8qC3U$MC-J;>^U ztr6`1j|suTlq?bCTA+nsxSi9>GnDV>U4pY+Nf=4gkqAg@0hU83dVV3^nFdu?%1=AGTO^Gfo%N>X7 zLU&EzYe$4*aYN9bKtn1fDeUL)z1QL54vfbmcF#+$UMtz%&pGJBWPEG?#6gX2C(h0u zTOV{@nLB^trRN7vwdSwPuQs=y{E43&_ct$m^;Bo|nkfgRj1|hOkxbJ{&>ED(8Rsef+$QF-YmR7<$%FLlC9A!C0`2vMP$y;WLAJP2! zkGJ3EM;RwSHcoF2cjh*FuK5$IdOds&kGo5js0Fy zS-Q_JRhguakn3vZJeyV`GRDEsDMqsqtCJC>ar87KyMm3AbL1gY^@Vt-*->Ey3YM zLA~R6VjZr1A8hXN!c%ZCF(gCK2Kv_p(eac{2Z{_l>u7fZFeU4!n~ai-!(BtF!6lA* zSb4DTPpWaOz(J%c!%ie540BkSbEG+x(+a%nEud2!qUu3)AQ}3Qq~!^^ ztwz~iTRS-W!l~(*mCoDC>!&ZCIdklMNdNNjC(c}1T0OIU>Eh+lu@^o?Ee+}QE^+*c zXZhylrHYZBB?KZs)y>UNcB>TrXz|UOf>yhW*E&I#ci7%4(7L!^H2zRSv_jo+u{W+? z7Y-vdN@l1jSRn|4=tovp{F4E4@o|L1j}-OAV=#ZDO#OpPz`noF%DcP7{zLO1OAt0s z#{^-$vXrE@6}Nn9Ma62iu6l*5jp5(Y$#prc)s6`+x1SPDtmbr3$ms~r%wqR~SFxqkKPD<8W5FJQ5 zK}0XhXgZjUVPyrfv1NY?x=S#cRwGr%PFCgMWdlV7=}3@IrX73%P^g2!f&l-+CRUIam$Ru}URR`IW$mJo@`U!LfA+ zEqJynnfp|So>)0#EJ!o3B`gGv_8RCwB7KW6aC}kGXd1c=i7$L!I#&>P9Xox2EgVG& z`AqUoFW~CsoZ$iNUAA1=E4jAm*xiBA?A9h|AX%Jmo6g4Z;ZL1g9h^A1ynSN1`_B5Q zXWuzh6W^CnaAkLN{orSQ`L86iy|(qJ!1j{l*2v_N;YlU+qR_ptY6p15#jt#o3pM4$|G%!YE^5SN&{HR=~sxYkX8;ozf zCu2)=A^@M7ACQ;Hab=~^J}#jZL)-?Fz$C2- z7^M-^m0&UuklRYYWC~%^@%{5V^wWIz+y9h~ zEm2N^RLqRV7!Mhiw7Z5vQz@l|RmDPhRVmy}!PlTPL^0S9bXn=&FSa3y9Ln>s(qKJU zwvs>zYN4Z!#GgAlY6(HJshO+8pzmmQ!A25FN1%bBWMBke`5zqp(z1O8UcF@5IkX&Z z8iq-Jo0_0tzEx+w**N@(&v%C>pL${^D5tNz@~NM{XqsZP7DX3d{`^mF&9&x6d;QIH zqY*LA+LSx*Fw8Qty@Di3naxs?#F3`y&2chqO1cXh6!=HwbQle$D4Msmm#QAN(U9gj z`bg|W2thuP;9^#ve+lhWRZ>5C9cvBF=}OQ3V1VB|gSHl-i(5MAM}TXb`AF)f@&RCe zR}OX~YcF%8ly`~RJYGMJQ2rRq-(Qw4upds9%iaCj@)1k!9}jfj(Hj)EwG8jdR_>IP zQx1%{*zSzoMMgR+*!flArvKe%?i|gSy__S1dMl}c7n?6BZVjc zUrDU3`n}~0TnZ+r81w4L4@Sv~Y&XdqqT|R@s4rBR?sNb_2vGxOh2!{2K(G+<{kKNU z*F0iR@%_z$aC@6>S5XV0NFhlo|MZm@+6~C4Mz*wurhsU*dR^^F0$HhiHtP|G(}GcI z@f~=9Bn$+To$s@;r0_EEP#E9fjSK2?0rLw1_%oc7$P(%u80FAz!DMtqPE%k-Rn|eKh_mbgoCt&xw z=5SMUc&OPQ-Pi;c2`n}ux-0X^3!hu*pE+nImz(vzS1+39kZZw}wSaLGGu zlb3$-=cfPYzxmJk>`Px{ryQ_*eG4HfW0mQ2!c=IoGQgGv_Mt(^ar=I}_16|9eP)Rx zI|B3D|J}LDzM*mY8For&H&+OKhjSAe%`T1hGaL*B+RTvheoEm2DHP6qn6tbBiF|*- z_(;}N-E=>DydH!3zr}UV63IvZohrSJ)=+C%bxTz^gt2RVBS@uQc_pozPNBil#46S-n;Af#FcFye?sCF?Fcd14tmx90Z1DC@5-dFF zC^Cpk%d_ht(efJaY<-WotB`>pPaXYhu)XPV@lDHxp5fcunqu40zYe=2%`NdwjUNZB zv=@?dPs9gb+E}=}div8>&ulDhuAH9RIo1u%HzR$e`{bWE2y{NY{Q6fM-bt3%U%}{2 zrkAdhCPQYE8Ch16rYVIfj?~s{rK(nX9FCee1hEWpF2}x)Iazmfh;gb$=2j?Y0Z`sw z+{I{e2kquOtwsk^PI=~2G0F?Ew!A|o^?t!qhz~DQSML|h@4$6|^1R2O{us<3uO9$V zS4ts-IMSdHA0nVzJ``e{e6)doabzKQ`_QTr!ci6(&OxnSd*{q^zxa=T=c~W*<)8j? zgy$DTQm|dX;TYUr1-R`Rr>V6%hs`R`&OOCJw(^5>U zpjFd^4Z}=o!T{=Fi61~S5X2otqnlIC1WzqR9QHyMHv;PG%alorQK{J4sWEtG#9+6^ z)$Now4*E=YFYwtX9Y6PZQMt{9)h~JGg)@4LZ$9k`(D@Sak9)W1=@cf`sqHC>E8hbzWvb#3ujdHv2T1aEDwtS>8s)UDe`U8Qw z`cUO11WKvL<@d*6{&;Qw(PbtkqhbChe(9I~lmE@%|F6FM^tEqt?0Lc7mSa5>$R+6MN;RrkgYiCe;;PR* z7gi%~zJyU)F|c!8W!$BL8qjJ&T|>=5exwDyxKy#`;|N3uIu^*#ky_YjSNh|x8)7ux7y@5%V#%=AhjzyhhdzGf6SxM^({*fa&`E=mI@Z(}WdT<& zmmKU|X_WYl8`dZqC<>#lYKJY51G9r6*7SjlcUlYrpwh z@X!CeBz{5=Hzes)Fx)jv6S#8dC=`eqyz^a4@6a(CXwsY5q!9?ZojS)>I-{4LSst#R zSbS%7!JKceu3dZO%-M^z=E?K^#C9d*TGWodz}ym`o?kl7whB zL*^+~<_MSLoIVnHa_^Zz<1A6wpxN4B)N^P(MJa{6QOLIr5wuub`7Hh21Y6!MrgH1c zY71IputiA}wy{zojJek~_o(z{?t78$NTdCIJ-k9;-)H%~>Y2aiGyg~_w~*DVJ_hw4 zA4vZMewq6Lz7Zez+CB)VE2$pXH~;Ve-92QcE^eIp#Qh-umKBq})eQ7_qq>v%3qsJG+cC&1Ae! zl4J-Y5kL?s*Qk5bW~66Js|({Z=Z?Mk(oc8ZdEwOR=5y!1c=+1kZ@u|bzwk@b?DfOF ztKa&y@gMz{|C^P6`0Ky^fBS2H^*X8mE@$`d@x-eW!iq#O}B; zx$u*p{=(k5C!W1BPOo1)d;H1E&7jjeob4qxeTO%%PB?MqB!UwpevR35N?ur|<1XI* zIg}H^$(cL-@}I_)hqpF?ut>i_Y1Wtw3SwoeQqa+?x4^+sX&vEEen6%Lp1(}DU1i4i z-1E-jfF#if7Vv}grURD{4r3g~DeRHf_YIdQV=AXT?p-R^4?b-0Fk@fdQLW3~D~`w` zP=AzwD-iGH=l$Rh`|*0bKK|u?Sg%cpN4s<>A6;}t3i;4r{=oqKVax9isB^ko=O26X z*4+}Xkw;(o4p%zo9PTE=Puxt>Ts151gu^<^cr?^M_k}O~n{WRs|EJIYZ~qVf+PVMy z-{|nn@r2jL1@mo1S%>Yc0_Vm)=myLT1QDbf{Gf8*s!5PjFg3w2xA+agTmxpMqvk_e z8gv8dIMk7Eww?)E4MC%=2tuE*Y~o5uGH;0eF8f;oowV2=IJPe&d~;{Ol|#X#KVfrs z%;9i`nIu>);Ca|?yO}l{jJ#%e?cC|p`)emxh8xG89WKvvIg_oue6qRsrO$o3U*wbC zg)4jM^RN7L`ou+`jmP9^w)@ZiFaOe?T{(8@xBt$6 z|6lxxYZu;L8SnSlWQNs}Lb52}+V8{)Q9)A7N0Q!SK{o$IHH{>d-Z??iA9SAH!NQ*0_=Sc_7nVU^i zhjTb%tDmlZk1)D)Ru>%XZEgQc|Lec>&n4;bzy3@A_W$|CfA!C``TUm}M2r|F7UK)> z1&y^zcxKrHg`f-^fhSlBz!MH#w}i1{Nmb)(YjXmjBthiksV0FR;;7Rf)yPanI9Dg{ zE3RD#xOlx}Fo5%WhwSX`(;wvY#|1@UkrEp9mTATEaG@LSZ=Cx4`1Ff$uhx(kUwrD* zm!CXwY-js>zkBJ~&;0CkZE4}~@BZW8?4R9`JoEAkv|FDgO)v9}*Y}wmW-P5Nu(zwp zvT8JII!!22pCZf1vkYr3#u`)*QlEbgV;s{-W}klInZNPZ|JuL&H%y`V`tSUGd|&ZI zH{eS@|IhIC?|cnxz$;(;GTT?a%{zr=mZW&o8Cg=0Bneqqjec2c5W?b!K^`ND_TgQ` zE+M_@0T8aT6LXL!BjVN^fnUQopE4;C!rZ1-1}a!X`j$yLB`X~Dji>R{X?CwTLcfc< zJK3ys&YZb7^a^lDN-b$EzC>0wcrP`kcUyjbh^ph|{oEC_8)eI|fOQHXtV230EW%X*Sb&n!3Fic!x|spFTLdYAb5&kn zCGnI+=K6cPul?(P^{@ZZ%1ZnH`EUR0|IRPI__dUO;h(SZ%1e@E3bytNX3|oQ1?x43 zRD$SOB@x^56m1lR4GH1~y*z}m$F7#lu1?q)&9k=~GdkSo+Aa)tdQ2x13R{vD4$t$Q ztOdjFTz9&(Ha|Y|{AYGgt(r@xPd>fhTz#@%i>|(P@`+crThYdDT1*Fv%bnbWQ-1qv zU*W}5pJR1?h5q?(;T#z2$g+az3?`EVDW?>9Mp>3*VE zpJMmYHcQJACoRRKi6?9F3t#xl_Vw4l!gzd{WHKes3IvcQ$pf9loU7*eW~suuW8gi( z`dZE`-=$Iaj|5c&?*>?FHCpEcVaRMW!wLCr7Wh#GruyA!mKnoj?PI!Fz3k}YEYMFRRQ|}DWwFVT9>1Kyszu@}egv0AKuJ6s*J;>PG zn=r`=^1{$?KCR{~Q=M9}64~n~R#$tk{Oq%v?bg=$*0aw}&OZOA_h+yEgE#x8=>62s z{JH7UaerdXXLZv1KB4cCxf9IBhqT%frE1K~6647hu9%Xg1!k3#OH=*PI5hNpB{ew*Z5yy|Qg|7e8DUF{(H?^GraIaCJ?#l$@%)ITl^5~6CdO1H{j5;zZs)Y36WF6M zDCZDD3LMsr27SU>9pwc_7M_oG9S8eU6ziDM+`iETI9EA$mgrotb$yH!9gNAjy{K~U zeR{9IcOUA8f7nOvKCdN?_Of}XSNQ}zs~@k&>+$*l1M^#X_I={r2aj&v`+B+iiDcX> zo2-D}-X7y_`&LnTCu6Ft`i?pCJF>JRljZ6_AS$~>fiSnFS~rt@Tjn?~KuC!|FiWOb zXI}sEPyexh>lZ(N{Qr1;KYwZa;Ofhl-*{v3VE<~ccQ`Tm_GJ1;e(AI0CqKP>ZD(}h za*;nb{<%;8O7E+`@$c#=USxekq4khNEg)o*Jnv#nz;rr>X+oBj6nROWWjBRzsto(~ z^N73UnDv1oy~8mT*!Mz zx<@a$%SSC0RDt?kQUy{9EC^?vlh!z-z#X+oofEjD(mc+&n}8sdcjGO2Lg0iDIO_!N zXtYg;n`P=eo#33I-sqrYrLmo6DaBN1rP|**b>a)(TJ4@9@V436AJe;5a{6qCjpLT- z>|sl7e#?Y2wf}Cup7}omM*EPrdwCz#CydMk5O$98&p&s>%G?lMJWwNUF2y zH)n+g1dVVFcW)x3dCx=G!)ya7xW`zsd&G_LVI3Y&HRFski4S zbpU#kJsb%gO;7Y4={gU zN_;nd$UYd*OS~%iAvZhE&asK{$JdP=<5Gd;LCf>r7y!l;l}L zSyo_cokL2A1Lbf=3Q3ZBI4Q6ucQ{2+)b1oK2uIX>62dPajj4pr5lRRQSfnV)Y>W%e zJdyywqu<6lRXFO7m`nyGKFhefDY|ugB~0db}R5AG(C*{|{47CKw6?9s&RW N002ovPDHLkV1kgZY%Tx* literal 0 HcmV?d00001 diff --git a/public/images/skins/objects/glitter-pens.png b/public/images/skins/objects/glitter-pens.png new file mode 100755 index 0000000000000000000000000000000000000000..69eddba3e9501c94f69b3320b0595611ec66ebcc GIT binary patch literal 139811 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ë&<&}L>Iz+Rz_vz8 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­P%Ti^y*}utvf10sSK*W!Mk~(k{uL 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 U4KxW(LI3~&07*qoM6N<$f^j>sEdT%j literal 0 HcmV?d00001 diff --git a/public/images/skins/objects/track-bike.png b/public/images/skins/objects/track-bike.png new file mode 100755 index 0000000000000000000000000000000000000000..fc595f842f458e76b93ff2cf3900e04961e1274d GIT binary patch literal 5833 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 b#JV2<``DW9E5HKde=OSSdTO=cmtp@0X`bk% literal 0 HcmV?d00001 diff --git a/public/images/skins/previews/basic_formatting.png b/public/images/skins/previews/basic_formatting.png new file mode 100755 index 0000000000000000000000000000000000000000..8b73d5b432bd9cfe2a0389659a80825cc25c63b1 GIT binary patch literal 238726 zcmcG#Wmr`2-!F;+0wN(uiS$rX3JTKF3@P0pB_f?eqcqapAW|ybF~BGcEg+pk4h=K( z0K>qUUp)Kyzj)5IuYK)v-rck6p7mX8eb=W}^cxK&lKYSEAOi-f2>sJ1IYTp*`@wYTP zA0(J~-7cagXE2j9We^Vyl&GEn4&0nNA%idmClRW?fo>IhCM(-b+Y>K`#c(nUh?OB}HQiMwG+Ot5y0)@LZzSp`qZ^M4QR(wik zsmtGG6<`xWn8D}zo1(yQrJo&Pyid8Z6?G_yb7(^y!-R_i{0OJp*{3Zg^|dq&r-D?@NhqO z@_q1>!p3z8VZQqfY<(RmoG>QcqH;CIIA_up*=%18@bjzEuuoa@d#*O# zL4UXSRrO@FT`QVbNP1YnHA`n4lLvv&leY^tbCsn9c;*s&WUXsw@mRAvo*HK1y51f6 zNooJ!E#7I;yL%y@h!25rgKB1m?dyu>)YAMM!fBQX`)ynd_fm$YCoE}q>9<2~Ir(y% z+5ITNKJm=E+bC1&I(>0m_>)(`qv4Ksz7UDpokk%=)7)$p*w9}+M8x9?I#cBYOrL!u z4Esczc=z}<-FqCfw}fh+sA}XotHclQ-C=%ILEuPEoQ%U{^KtksK|e13Tc%fpgTJ1? z!QK4@bbZ_qdh&(d6kp^Q4(;89k2tZR8E@~k6L^s0tuo)24=rZKSEd?|c);S(f6qNa zf<>C^(dUm=%>1eMoFcqs@!vexCDoH5`6KX0^c#H}DTyrE7p?dA{cr;#w4TvXhi<%m z=|km6y3oz&iqlRS|0!kF@fFPyamKHyL!uTEM1)J1Tn$bT(dbv4&tYGS9%;34d8D!p z(o;ozRy@)&(YpMmt^4u^-Bk3h987`e&BQm&_q^E=@4k4A>Ax58WX_J$P;^nC`8qUq zwk_-_aK-QUNHX*$qVTQF^Lbj;2b7c{(Z6io9zQF|G*;u;y#J0+DBd@r$7;vWtAcKt zg#L3}pK}+rRl-}78naoMeOhno$Zp_jgWL2gmnXy-pNF~`dh>pob-{kctxK%|eel~^ zmhhP(w$?ljOD+_z6|Nbs@q*%+W#6zHQnV92k){QXcNdRN}T3g>x# zOQ@luBZoPQ6h|j}lClbbI9Y%@z9COnQB0vt@iBWKtImM2jgtE-(YW>uQzZneG&7{+ z4cCW9;wrT4X>}RnuUpl8RW7;YDaR?T?z@FG5$O>&62Tt&v8$2mQ#H|;3*_>dJ`GU3 zXgX{ll#y45YK5`a=@rYubNi$EE4b7rUr(C605-g7&^m3~22d&K6^ZGHPMUroITQ4X zjrhtv@xyjrW z)FqsQ^0pou?>8tm7&qvs@TmmShM%fGCDSANvH7F+N2D%VSNhxca{TfGZ3lxK-3(p3 zA9m#;-=(L&yr2C5aL{#FoPd7FcHnr=IQHaENTXVVRpZkJXNT_jQfz^g8VJ0eiBXH0 z=6%R}XjWI%;oRn&g80U0HmW0_RBeWwdYYzZS$CSIoO z7rh*xT$5$^swCUzq?j?`BGRIn-uYgwUZpr>&L6dQHSes`%z&3Kg*I}8b2PHPXDVds zWyfX4WT7)@vMuU=8on}gtbgTlG%!9XICb2xQJ~+ZPoy8GpHe<$pj0W<>G#`sAluf= zmaoQgR(|%{hOI`g!FEo6L8@M-X?=ETUVYYKzHgzRCV1lu@+auM*Tu^FotB>3A)*cV zZYpvTspduM$qx$J{R*d8ABPLBe^_f9XdEJ0-&}24b_(O}vk{`t6hgd1m@N8B_A}lv zZZM8YG)i3N=b6`JfM@Ph_c`d!xXv{A#q4RDQ)J@r`9$u13ezt%lh~uRlF8r*OQ`t&qX8rRGb` ze9c_rhyz&_1DOcXC^3_HStq{-?CflOk8;Lhmbv{?h_i=M!DzFi`pc~0>1?eT-

    YIuIORAm%^&`p19D`9SwTuZ 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 L@O+R8Y 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

    RS0B3@tTK=$nNiBxqU|ECMN7g!k=Folf(*XG5+3 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ℑ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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/aaaaa-readme.txt b/public/images/skins/textures/tiles/aaaaa-readme.txt new file mode 100755 index 0000000..154fe0f --- /dev/null +++ b/public/images/skins/textures/tiles/aaaaa-readme.txt @@ -0,0 +1,21 @@ +README + +these images are all free for commercial and noncommercial use +or have been made by ao3 +many are from +http://webtreats.mysitemyway.com/ +http://www.dinpattern.com/ (most illos) +http://elemis.iki-bir.com +http://borysses.deviantart.com/ +http://www.fuzzimo.com/ +http://www.bittbox.com +http://colorburned.com/ + +please make sure additions: +1) are under 75k +2) seamlessly tile +3) are named conventionally +4) are of excellent quality +5) do not have a restricted license + +If they don't match these criteria, they don't go in this folder. diff --git a/public/images/skins/textures/tiles/black-denim.jpg b/public/images/skins/textures/tiles/black-denim.jpg new file mode 100755 index 0000000000000000000000000000000000000000..5af3d35a92e660e8efbfa487178ecfd309d86f7e GIT binary patch literal 68501 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
      iiR5xNxop!?(Um!&mgi#0b0==}VLtpB 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/black-illo-breeze.gif b/public/images/skins/textures/tiles/black-illo-breeze.gif new file mode 100755 index 0000000000000000000000000000000000000000..d1ba032e4d0a07c5d8eafd363ed9bcf824393dec GIT binary patch literal 33690 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�?)-6d3b1E#|%W(MVRwhx$h!vziQ_ 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/black-metal-grid.jpg b/public/images/skins/textures/tiles/black-metal-grid.jpg new file mode 100755 index 0000000000000000000000000000000000000000..2e9a3c0b9e9e2746d564d1e3344457600eb0af9f GIT binary patch literal 50803 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 KrrJi7AOG1i0}sLg literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/black-noise.jpg b/public/images/skins/textures/tiles/black-noise.jpg new file mode 100755 index 0000000000000000000000000000000000000000..baa55dd0b8c0492c510b13aa0fcdb4be3dfa39da GIT binary patch literal 4459 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 DFQ-nL literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/black-scribble-x.png b/public/images/skins/textures/tiles/black-scribble-x.png new file mode 100755 index 0000000000000000000000000000000000000000..24602369255b98bde7ba1075461741c73e7541f1 GIT binary patch literal 21938 zcmd>FV{;`853RQCmfNjuYirx>*0yciwzjtITidqVTid<0`#%5U%}kQ-$;_F|IVX_{ zauSGeIB;NKV2DzZqDueuvH!9e7V^JJ&n?&l1_lYH@K;5wziUK8SxrGk*3#5sZgOQ~ zc{eg7N={08xNl-|WX{acG&du^FsE2bR4g_kPFqdGKwHm9*B~<`du1NDwzxe$G?N&U zG(EPkFui7BY^E%yATA`Vs-Tpbn69U(lai2nb^4GL_fJZP6&4h6xN{yB7`8mO;bP|$5gZZX7vkdJ zQc+yp*E!_j;*pZTVsd2vwK%d@BY?VpiiKZf}*>Vi-)UM zc~RBr!HtcTZ9Aab$*sQg&)62uB1JGTZ zR~8-=?(6C2>fq|?SbkuCq@8#-wd+`Fge7!zK*Ir7!(r_tg8kz)HJs=bojV?`+530+B#aBTOIFRS(#f}TiDc9H8uPc-^f_Q);9xFFa?0QT-vOrl3`71OJYc(sX}Boc zo4L3fI+=nAnb;ed5=q$_nwu(_8k%@Ij+^p=fhqDzi3+KBfN$-=>nw!_p89^D%pf4J z{6YAG35|8#`o{?uTL=o$s0~*17a0{zB%;u7qd3`3+jI7HXyF#ke8$}Sg{I-I1=n}2 zTWUJ{2sp>+4H049EVJ&V0SEd=G(?X#m2uqJn+)tl(d0$Dr)(2}cdnhfzHefvFJ$6d z{}42&o`4CLubi`8a8+w;i0?uov)5NA&w}iw%DY@h#&|EMJjt-tRaU)(CN)_V`wo3$0v*;of|J7K(G2zkrD~ z<4^LKTk5U*&mwn$AApa$oetVpLL5w@-Vh;HE`iUjx=3p4i8_C*Gtl zBqT4DqGDoq60ePsxl^tk#y&PQ#FYX@!X(w8lkT$LBM&TmKH&U5s$udmw-PzR=)SlQ zXFhb>zeFYsg>DaKE0*maC#HQh=S_S+M(ulo%2=&ji_|4>;FN3~DI#tO}&2=Ks_ zA8KsuVb53qpCL#nG+{EY$tlzXMBT)pFZ!FHKru4Wry{pQ)}HSfk7X88*o2UfCEZXl zm*Vy$h84TMJUqtL2PM*Dt??}!_k}rhLHnEdnabFKdc%P_GgnO}U`@ZSwZX(4y@+ep}Ei3(jB370n1j+cPZP@0DfF?q!m|t(NEHqj4EckAN zK1BLMPz34=L&hmSktE8&JDax@1d}&k#>jK@>pG}1HK=LW`FFZ|u>Ko5Cz`!m!=)D# zDEdQ+yelg9WVw4XDr$=5n>#V1Bf3RxJ`yCoXX-Tk%>M}d%}5gnNC2R+?)hB(GMQ^- z{N{Tx-tcfm9cS)LMn&Be!&32h37Iyiv~c6EUC#AW!ufF-a6<45C85zgGrr1oJ<~}b zD#tLUBTBrYYhX<@qvDq8<8%B3$V0I?Ao|(zHPZj3F0og}PWd_t%ttvy=L^7n_d9xI zqBd*bm81|fw-H9?KWYAWa&_#VxDz6k6ga9RJV34!@|m_xr*roT>WHKHso>y{^=l;W zA7`Uho5SsGDc_L~F^|Lj{3WAy`>?q$W%jq~7R}WXFG2qe;lvR6UnSiy&Pia879;q; z7lX>KGtH~U{N)YXCc`{->j{hxN>!U}o%-4J+S_YPjvw>09?fZ`in!)3xV~7(?8=N2yPK|ah?xd)P5I|^0!N(O<)#`%DzNg4)lQ$ z09wrH6W+Vm>5ihKGhV|8^G~3cU$C6Fy7fB#hqvID=zzCG`+hm%LrOch-R#&s6*=x{LvP z#cN>U)@&^4O^{YNy(N{|3`>|;Z4ZOIAkd38rH^(?WDhKrKAF*7Iem=@`HB5JzIE4@ z%vkQSWZ_)_9^U}j#uYnml&>M62qMkjlg=fIJn>W7zh98gqeFtQOl_I;nE=}CsMn7L z`=ys?mhe{w!yxQqbbFY1Cov*d8Xp|nT^DupmLI}PcR2DL7_%UtN=r zfBib_l%hHT*ZpjCbXt-ZI*QH;6J|CGQ~s=;FeTXigX8@jR2?czFc-Ypp3q-jGH*bz zd*u(xkp=lw>bUX;F;djH>#5AIMsK1>gCwg{Ae~E|2y@Q@5JNA15Ijs9v;&Hiw!quX zr8PfK7i6c5SdekbUr*-kXhzbf-IHZ%a+i#|(UA{~fasV4 zCd7Kjd?zI2ad&aY@eH*&SjHxU9^Yb6?<9F7j&K$^OD=$Fj@rs zX7xAd?sr0yRGju%qmw!(86~c{sI56shmXb!`LnVYz4;~YKthbJ-@%e)$La)!6l>jW z{>ywba^CLs*5szztLWzDBIyBN1}S6870~rU4Gvj@5X@fuzCxEUBmQ>yZ)A7!YIRaC z^v0r-qc!h9eC;4&5vNyL4~8@yaZtoNerf@(n@OGU4l|ISxaGE4SP=nvE?%=*^LPtJ zJIoZ@hvaXj66&i3IIgcaE>FWE$T)FZpYE<|COnoZ1>UtstM7}P>_}Q_nwL9@!AuT)xFN3u$)qQX0zwNgd zwU+bmX0Cbf5M70d{9Rl^#wsjI+13&M1HpMGy{!1nrctaaw#-q1eSRUv%Gj?Jzmov& z;8bk>l_Z?|=8vd8=*_yYdZ^Ohb`i&@iGzRjw%a4+@%~2mxM@rzO68O8mzg@J9>lfIhS)LV)`qhw~=w%GksY%-k?a&;lyg1&+6J?OV z+aFt#`l^*^dAb~F-qF1Lx*hUna;jNJ`H`wP^k9z@JV3}M=#RyF`QdY_+VGTp&3N)> zNF8hiFnJl0Dsas+@5EdaSF9qd(fV>81Jr!3aE*=J4v(D~HIQ?&Q@NdX`wt)x9xpYi zBJ{?$zj9yH%%;LdMT@KUsxqqJvJ?jnldu$*rIxrgns;~c3flw%eF6_!F+3C+6qMmx zY4MbR=WWTV)$wXr?x)<0%kq@8j4wZ(c-fK0z)V?5CERS#JqiDeI53SB}xy6>7 zOdsxqy^Rb716Xd`WYLl^jWsQOBvkC(G+V_q2EpfY#|bPM-o@c%3?}Xss>d~K+LJWq zrnAqrKbH2Ci0C8AYTZ&D?iWp#u49H|-EpY%5I z9IoFLxgC@<^eI+JGxXB@-J561{@FzQ#~MD)6Hri#S#qOsD0MJS(eM&rA{ak;JZbih zwPd*xA^YrA?7Z4A6|wR3hqtSUgEgHr8MPRGT;iXtqUCZs%ldsA>ly@1n{EOo#YSH2 zbFsSWjD+Rem8U!b@@Nd$Uo*hS{|;HLRCcKC5oMunaKz*kxK2myPA zJTLmLKB??xf$9_5l77mb3W<&Q@iLgH@p5e)8M7V8bvoAIOjp4qZ*K6xGRo;-2kZ_ybJ z6xSgTU?9-Z3zmtW$k@*Yv5P5`@GV%OwE{dQp9B-rk)%R=#5-@ba<+P-rE$z0?>R8V z%;~=7B7k)rc?Nu31M-7%h%!e(v+bGw4#{`5Jivf=A6x*w}+BZF`x!DG`ugPumX~vxpTB z&=&}WM8!si;qDbWkwRq8S$We=219H;pn#!*-!xRw zIqE5o8fH1_@?Yr`k*^X~Qmt;(8|0dsoTl3>G}O0@V0? zXCWvvjscX;z1C=$NBw9|bzj7)c^$(Yt%bu=FqPD-4SEs`G3mJtw8A{`bYe4t)~z0q z@G7*z{V?)Hk5KTE{^z^Wt?}@%40?-vOYP@W8-vO!R<{fMb{%MwoGu}5f~=xp4~yKq z&aHnKU?F@AjnS~5a6C^Xg zyrAbcJI~9s2ZW=l$uWMH)}_~ZTi4=mLcdryPyVn5$nrvL^eS6>v!kT4=C~_LwiQ${_vSgmI!@c_hc5!%yFjV6WeDfdCl2KPcGiBhPC)PR{u$ zd##xq+2yUd$-(7RZ7_|m*=fGb7b$pKY-xR=iL85Wwq}aTiV+7my`UL-08_Ch9K81` z=&GKR+f4Kubo|+x5IC+(lcj1av?qhKq<(r4F3TMV7ZDTh$k_KNZFyjR5i4U8P&>$b zyJLeA9n5B4;F~=wo`%XVLAn>eV>b9Y%9ab{(;y@eqf+bMR6K>gpCYwhOl!8V>4> z#A0^Yl2~(=FrGOy#Ksd<@~5*dG&kI;^DmJ}oK)FvnA6;KJFL6?F}FlHQBkgaLX7q> zormX+%Ik`hsH=3re13u6$eS4^w-Qs`_T+`*h_+25nPCQnJ7FnsS}H$Y{c&G>jW|kF zAC6-4$4|)OUZC)SiErO;qB|%01d!~fnvocE3g^zXKg3C!vg@Vgs(67X{SH3>q0?=r zux2+!jG%o@!-eH09T;(Q4bG(7W4P3Qo>MvrIiRW1#}(BWRyqsYuidOS$Ec_W2nP7+s&H0ZF5s>IIEX0 z33hB6xDdp4xZsv6_=QYpscH{E3Zk$!m-(QFc_2}Qc;lMcS||0CPToW0$`H3s{YI=f z702OqwkoXTe%pmx0O<*?yjqhCUHm3;*YGwCtL$+y)!(UQzd`PF%!u>kV~SXM*_z~8 zaHhL}C{vDHCHuySm+K8B<9!I9iXs6*bi|TRHzc-M+OGUed|NI1GCH<&ca&pD9Yz6|=?Ybh>#$kW2hW+H==>jU)aJFL9(R17)J8f;4e-8xIO~jZh&|A#> z41)(;SSD!Y(sD*+(TODN@AwrKsik zu5$a&kL$Pu9f#`ln*BTzScB&Mx67ewsj>-M-Ac{c4HYhG&cJKK#8^DDt5oIV%AbLd z_p7(&MBbNC0*5M8Qvml_G~%P!BYOuGGiWnYny;X;qF;C%x`UXG(8Q5Fmo%d+mV{bM?Aex#DX!R62^oaX|oA*2Mf}&xz*uG0ar(5j4&RSe%V_& zxYSp|Q==)FlCxY1DmhVCGN7(REq%6xaHgbV(|J)9i;#p1Lqw7~a~5jWtJ^F5p7$OO zhC&msrR75pYwe+jEzcz!Af^9p3eQlLNHNcAS7LqMDm)9bOA*Oa-GZ}Zdljyn2}680 zJdde$wPN!6a++c3s_4L&um3I*QJ>+x4{y>fm_BT9dAT}q)iMcWmv0^#%gM2i8F$d+ zjk5@z=;d&yyd*@$ERhwpF-y*e0`R|c$5(ukNxC80c!I=W34Ja^jt-ri_ir5TJLVs$ znlxvgBxSBOZz8w}%}Azv{u1P7#Ax?5&O2dpEVs&SPEX43Kly_0wU-}9pl?8@&d|Sf z7qDX;Dd~be`8*lN)Aw?V> zpMNh^DtG@v1SLVf7eKuoyxSQKWZnaW;&;_o7PKK+wPSc#J!Xsl_VSoTCNNyny6u9x z71z^i!H`G8n~UOwsG>%48zIe_rnY~#!QS46$WaHIxIb41>5yo-FKv7P0a-4ulLXc0 z)ABVC*+$#Bxpo~kJ+mu~zW5*0tU9Eh;4HpDC zB!xbM?&+4FSB>Uzw9L^Xr%=?W(mZ+hZw-*Mj<27g-naugPf=N;_jCTh7Cw z-lTfBS~~A_>a#w3)el|*TxV3jz)cP@ZDSZ(N6U203AtKtNX$V4wNHX7qf&!Qo%v&t zUwd;@GZ{fnEJ*Gu<;%oUs}5(a=^aGi1+hRl9@X!j&_yvb41H5WHbA?sIwB`PP32D)Z&_dHIYU4@JA@6Xne#l z70Wy`tPkf@Spm5_p{f||dJdW=unpe*8a{NV*cWZF@XmK^ubXF&Mo;#C>qV}{j1_ud zV%cmNA?p4lC{+5wDi1R9aj2Fg9&lXr^VJl$Oywf+bF87pi7&`HSNc_D1~1z=#{>|H z@>%X0;A>rU-)(8TZS?)kk>TgvcnIVdq?ylhb+t;izdb^Hks;E^N;G2C4ewMGvohAu z=3uD0k^4Df2DJMArMUwp8bhN*a1u50u(Nwy&8k^DtCb#A=A}<5&-hmxLHg2oP)tNKl6}{ zcl&5}x^Abf`q@YBuI=bdVW)T!$rNX23x2fjac`<^ogMV*MWXVnG-u6muzJtV+oWr2 zO=Gu@Tqc|31#v%hYotU|u*I;4C>^h%0!Yn+sq8Id%1jkQt=aUqBC0@8(^HNKIdL(N zLVtWlgR3g5X`{`XZr+^ARfTV|$K*b+ixSvE_qpYoDb~|1xlPq0(l)Wox?-U^O>GVZ3m8UU z`iRub_EAr1^nmD6I_vB_=VL#`Lb8sw@6DW%hFS3r~+ z$LKbZh!BhNRhT!A!I@9RA^jGSXue^Qe9LDquKC19w{828zKSF`T|1e9JLQHy-RTNj zdA=)m&E-k?Bh6_(vg`*?dZT?VlgcVMxag;Oc8~W|)rHSh>yga7~j({goa4hz2ulZ5T zRDI55TzchhWIK}HdxdP{2~3O?Rhe>{GF8)B5z+?*>H&%P)$%qaRk$}M~QGX zv5_`O7Lk1$)1VT8o)F z0K$$0l)Bt&%OyPj0R3IT?JK`$=C@uUx}ve6X8n5^hlMNGH#q7i{d33FMxX8v{$Fwh zf(hAJ%^^OeX(r&*e|kwz8-2e~sXreBBB`;Gc6JH7XH1$O3qsHcKWVS&7gbT|q8-OI zzArRKj#_#gY`+*I;ixGf7yHSAjf=)S0kXFEN`VdJPTN zc7&Y&Hq5|+VE9OTbkIQ&iXPnqSx85WQX^iIfoAi4)SIj_Z`(P;y zEsB{~o1uoT`%2&69`x@^9j*(lqLbjn?zoCrz%fy!@~ zncgHfZX=U&gS*@PrQ_3>91#A@QFE>z)9)YO@I%EqEWG5kQY44EX$oD+zQ6fbRtGXH zZugo4D_egDK6f-f4$HsFTLQof8qsIx!1L0UT%64-;|B5iG#WkuekqU%3*oB6*UDMn z!u=y~Cd;tU_gIqmu+#o%cfovp|0EAt6h7{16Upj5Fn0nuECf#KRO`AVBV)%G)l9-Z zB5PuJV(8=h+3tky#KNUlj+dy<4(9@E%%#K+t=G&mge z)#m+PEp1fUZI`fzf6BDE%%p{C|1cH$D>-pQ`Xtk4cK;z`E>Zv@f=M= zjqBMn4(L4$vur=eIGKC5=#HoHa$vodUN&=y+=#J^vJMXee8aJZJ^n9WNu)wPY;Fr_ zZj2;fH-`!f3F2*+e zAuW}VrtY}%*NN}L782xxLY9QDHeh#TBW+T<8r6=CrV`x?;8Jmw_IS$_f%Zb`A>5Vb*xh+w?gBHvtV9D?_iX8QyNuYMkIG#a?F*lp59u}~8 zZ2NFl5?r+DUY_}JrEUF_wH&_9N&L29dvr@kDvu*M>A0uk+Epps_%*Y6ysAEt4VoTk zK-T3lrS#4Z6(**BsEtmB06C5?uO+Q)4iam}$DfS#f2*u6UuV%N)e%z>lB^Luu{hN( zXc2O>;KATlN~V*xxk!)+Tv}Kx(ae82OY7F{O!}oLs*W_iNC}q2q2__dVbMQnU&&Ue zH1Zw`Sbgx(>H0aAg}Id(x~JkvKdL3R8U9f-?X#8Zv^U5c>^UCD)NWN(bm&yCL*a31 zKlul;%-<_*H)Fb^a1dh%`t6L!ka%AK?r+K6QoH@$;4G^T^ZNcg{TeNi9$r}wD)WuIE@;0r(L$yhA&PY$y1agrIyE5J zzoE1qHUpo<&;^Yn8hyFGlXjJgg0s9$o7oX&8!Y8$Na zAb87Z@XqfVWs^`Z{ zJf%1Cd)zpb4_id4?xj8@=F_NMLoMuZ4&i!orp>asksmB;7o40qb&6Z-xW3@Gs3o$$ zp(v0rpTvSC1+jI~cUED;c6O>Rl!k6{OdztGt2JCNPdL=|!q9L>6ZK!WLQpm>)fMZrQw(7r_Ha=8 z_FZ6>MQk-mSWg8YuY9zs?WS%}Af(1-z~{ejX;G-yhRB6Un}rit%e{*9O(80Jd(JU_ zCC{&M%Wi})5;es~LIff-lpAT(rssvSmk9GQBVSl=_w0|ZER;u$r&A}DvaMjE*3MkN z+mbVY;<0wN!6?Ng?)`l!YxHKVzk-fLqvfFqiqiB0@^h1-dseN=KcIe4qJ)CZO(ye5l8|r5F%mO4mC&1Dm(Ed z(uexB*{5`v^W(%V8}52tzpJzb+uO>%7kTGi*`h^MJ3dSA%S~Q!<9gW=_~t6?YHP@| z>mgn!MV6y`vdyAVXska)LmMrP7XLPi?JW`u?fhi2LI~z-*Esf*RdVXUWwYz~Sg3K$ ztmEeqt-FepieGUWK}UHRA27*)YejKq5*kP|yx$2hm9OmfD|QI^(E!ql^I10;8#F!{ z0pERzoYW`1u+KmD*$>aJWVYb0;4$C0lQ9lkp(4QV=yv`+cXH&0xRI-@p_r|df|Lf2 z_^0d{U0PjQ2`3+cKq@^D|IvCPog|TI^_e5_$8qEl=VD`+uA-(l-xgnQe8#ZfYHewt5<6kz3>7;K z0&*V96)wWHK;Y!k&%NfMn^|t+nwalf_FW*c*GO*(jcg0EgR5Wvt59|lXH_YXwcGJGEH$@S+o?1m^AbTgs2Tn+{ApQg9-ylD&mg*fDi%je{dTXz8IX~I1 zO|@)KH2t`;I%{m&OjB3l3{Y}gx!q43OHwYGvCne;ADo+4X|75~fuuVdhHALRBNI1a zC6ZGxU+;Cnj*c|afbl-U6@mq&GtM}f8R}`jH7b)~>*>GaZ2L~CyW7_TYMW1Z<{plN z_idaoqjr$3l;|Vo8L@dJbsU48O8~L>(Z7Q-?irKURXf!fNp^!aYa}{X%PxHJAE0^U zZH`M8eGYBN8(@716PgO=k;?SyB zCp2Md)ispMBWJ1g9hX@HeIe+WpRS>=RJSd{1ymZny)rNl&l#eER}+0T>i?l(jOyvY zJq`?Or=3V+?-zpItc;Co{p5E&uwK2L1H0=m{O&Lb(CyLX=a?`Nl$7r?-6ykK{TLs_ zRKtm>wEY`i6-Tjm1MSL1lmMy}`3l&hucSARUNs|WjQZ7Qb6A;=qeDTSez%CfA(h`- zwb8L+>$NUXkwF*9lF@u1cBhe8H=GnL6QKqSk0w&91HF02iR;kBga>%qHjaGVE-I2g ztym+GH{oaQOf6>VIN~DvFR~u~O?j~LyBUJ%a&5GcO(`I3jq7||d=TBqm`+KHoBh>f ze-f=w$t2&RY{3+!kA=?o5Ae0XRnP%nRY_N~7xJAYOIwjSOnc^s51r3ksjq-O@4y{t zoK(L=7m@H;W2Mwvv`V~HOA|lI?Rr=Lb&T;oum>dz#*lik@2FGRNzP-~TtrabIJp@J zI9_-X8hAO%g1_HZwiH@^>QlyhrJP)KklARMyg{e%cj-RPZ09^b^H{;GLA1ykQFFYw zV%Ixq0AlX^dC@T8SNQiug+Qyt5jzEy+vr>Kv7}wY_GE%Yvl{64H_K0q4+Ic0R*Km+ z6fs8qla)gmLHbsP0KuO$)@a}{yv{kth_xK}R`g}N9bO@&s|TP7DTh+UVOTb6u!lDQ zAZJzuK}7pQpDsP-2+qsuW;|Ib$?c?n0715rgUd*WxEB;LZAT?oh@A~xrJ1}9rO6Z` zAIcZ_LfSI84o&F;^d^T4$Ja8+gh~0)di=-|teEd69$C0)b{cNi)HQlX*Q(@XQWV>j z7+F4bc+Au>P7@R#j^lic+1zUhN8O$ywK;bH&%9%qZ_Dc2G%qaX=x+Qa9DFk%4rYxR z)+}dDn!u;wouNfJAG(tP^N)DR_Po#q*)(e;lt)0e^F(*Rw$1wL+N*bgo#o9H>i)lw zv4U-Z5Kb;VUk*pW($`9QiLRXR2H zJjY&hhV{vImd>{Y7E`%hI8a73N@M8Tzsa97e~n)g`R$`j0(rT=rSK`-3NFc_x24mB zqiXhQ8yGkV+`9v>?>@!c?6&ZehAZAAv|6wXzMaF)3I+(sCn2?{9MvVQr6M4xMmJSP z$BTb=sb`ud`cU4+^>D2ruvKy#(2~gE|FPHycpG8y+|lcZ4+j;8_W#+sH4FXEFBJLu z@t0J-gIY<{nnZSlq@iKf=>92Je{j0E1=q3Nz|xgSYQ_`wS4vb|-+z}u8DTSuW1E!n zzB@GBKpwgPgp=oJcpHN3T8m)J)v`Oe6kbGa5DDl#*g1CG!zA@KN#4}X*X#P~oy6xWMP^y(n6#Mw7Ux&C7-F z4;SN5UxfeuggwK{zMAhLlXK9Bm%?fpFZnigMT^AlT3$1E$mpXQt=-R`5+hPSZQx-D zW9bB8%mnaetw(l8&*=hV1^29|jUOLTb+gk)@W2BQ|@x zRlQH(cjQ6HqBy@HV$Kb9AdXWuOk6>oKmCn+%bD;a_2$-J$7n9%LdYE?mI6O!YT&Xfe!SXmQ*3s2B68U7F{}I_&ds2H6?&kM;I{RUp=Lu%praS% z@Ph9(uaH7p-M83T8phyf()&3D@*RmhJcw(K(lc059}9tajSJzkqGoWGAc1Pgj18-_ z8hQ%pKBHvep|dutd!p0PYXro3fhWQ_ilM$YxdyOS=q(_{UC!SY5RH}ltNie=1U^Ij}Oh3&&k3VvHDIAB#T? zc)7Rc9|=7}FL@qocK_GjPQE|wzJRq|#(jr-aAy85-nGJ3=3-&g@ht5h{D^7K^@%QO z>j{z_{|*}V56!6>89(Mks`kqe&ImJT@Uc>+W|{SNMo%N$<1PE2%`5u{ri*7qd_%aw90LkTE2*a0b3>zb(|Kclc$KWtee-I9;&u~E)3sEZ{XUxBF9=|$@98;dWvVTchK^OC>N=E zs|IV{B;3SO7~-=}BgVB)<%+>O1rXS}Y*zWT?+q=L!baN3J5|t}yJBaYu29E+5DQ=B z*DN>wqN+-`8ZJ>Q&jq)fc;wUeair}+t6QIcx_it?#K#eY{3lNp*e+Mx%R z?i4m^VNvGcN46&{x6=wskdRp&iCO=5@~!g)q$X^%i(5zd(`j#RgPhQ4q7@M!lvOH@ zvuq~`c9?n?_d!QVV86M|)j?OIa(&AWl9ac1fm5K_Vyeknxqf#n)uFaM=Mc3x!004V z)WT>gBR!N{_P)#ved^CSplv%1xfG0Gu7DJgaXj;PsdlrjbWW@A{u#TjS3NN!Xnq?@ zP1sL9Ud~VhP11=r@^>U98M`j|M%k|e+NB>F)MGm>i8`DGN1HEUYA+25LGadV78tKq z6k}_FYv0Of|57Ot$Vn;n5NjroLo2MxwZ|r+2$e^a%WFrK_Vv)8u-$=^zqC zrk_M(gBRs<1Qyl|lgrYvv+v!pG{1P;oa-hAmzE49jVV}OH#*7$MQ9Ml_OoJy)zS{G zK^|gfDhK-YFjl{FrM12R8Lp-8~W7~$G*C$QPv)T5#vvwYpds;nVscLVo zD%s_(<4(PgDu=ojuNk>kow2hgRZBX(Rj&y3;*}>6y!xM;H~VfRLch_VP%5F4_gsN; zCRo!qy3FZOn}u%IgNA8Rl5i{Kt$r|RXDe-LI#w%xqokcuPn`D(SvVelNXAz9$(f)r zb@$B0d4XX+hJ z8OuGbSrV>qdHAiE-*Z`P%B9k&1WHi&(kem*{9(6T7p>3jLWk{G1&hC(l>-*F6Bdxg zt16no($g+UXG`U#9?*is7-*uqv6dy_tkR6B|e3) zN&QTS(J$%LCAIVo5LDzmziv6Mc>-X)u{8U#g!*B89ktUvF3k9dfx;+|Pe4 z_JY_C#3EKAu1@ZJbJ{HBG@1mPvjG+LaR_-Lg40`r#KR=JIQFmLVX)`JF~7&U)IhriD`Z+w$?%WH;*9FYfm$PD0}bbEzI5`*X? zg~j$*#2T7z!!!#j688+H+VlkLUULq|B%D0$tauo3 zaY{#LhSfCGgDz<%|Dy%BrWdebsnTs{H1aUX+IvRT0WrzN#)64NlTm`p#kyz``y|Z~ zofB|HALJy8nv$M?aZdTIbb65>3Bx*DQif0F^~YYafl~p_gHE7+#u}_?$?Q|4Jc0Js z7pAFk6fOUshEboU9}7q&DZ3Q0og<@^AEd>7o`KvFR^wR1 zh|xS!0z%wi=rF}&x>GN)CDVlNy&P7P0zO9DF?eH)WJ&&<5}LuRxM4U-*udv;L&z%2 z7NKwRUE1Z2^)mZ{AIt1KLvVXf+&L_Ihx%`|8w<1O5=0&jLBz064LDCY`rH4CuRVSC^tsKWfCQ5Bh&2}@E#g&)|<@v77OI_ zV1hzAZYI^lV5a+*m2?*1APZ~a%ORHb`Fij4P^(zS!{J9rggN#cN4`GYxxp%^^dNaD zGkKXGUg}bdrEagoAe!8+kVId+EFoK|Qp%=|^L^46ttr4Wer>&$CRL53Kl>E50bZDI z0qi5*PIR!X&6v%%iih}=CFAfsZ*&1g>o4)>)98;vQ0cbs7_jv?jGVY29HhX$gHGRP z>%UgXn8^bC8L`n0MSy{VOH?}@j~}g7Fl_JgFGrQjtMPXAb=21(NaPamZlreJ(Uk1b z4}xmT+XO^b5>wau)fZYdxN$FU$%JPgZne`aWRmB|swvPer52L{7D2^-LEM6?jnu~q zOu?D=_FY$FU4QI?R}Zr2C|kCvhH5C?Q5kNibHYle5-6($lhab?=G4O)8_nLC;o#<1 z-z%*BC7f#i0Vj9jJnDezOO@+#=gO_p+(h#ESAadYcOhlqjf3L)i8tULTU-K25d3#v zV53VNCu!LN7@6g~@KzPXPJ%sW zJtVqLgis@+tzZGfpy-+O?73;iTM|Xd%?V+d1_>vh^<+`}(I0~vftIwbHq;|2zbGh2 zQO_~SsHBIIX#Iyi-I#f31w}xQ9hVOCp{+s-l}0?kuY$iR{N}ZHG|KZ+HVU_(^KA8~ zmHuRWjgvQr@Xc&HtlF}{3hGoJc7#4SDMWQBa|nIse*u;hY3q>6;WLfUnXFx3zt+`& zi#|@?c9;)dlhV-~`fhn4P5V9#yFl3Sfsl8psTNG`KsY-{040KP_79tM>b+c`_GIU4I6TIz`45F7GBP-hl01 zhSdsD9lWPwZ~c`6zcd(3#jm6_JMWZM(tlYa?wo|BnqcN2V0F>o_s}e2(blhzfOi|v zu-&v@rIE;RiB>xzqno2cYnXj9)@XyY+dQ~px@_8)kpVU<%(IW&27dl zY0Msv%eh3g5f(}cvmF_#wDu5h;+>n65{1I7|Lx*RL7ypiuilZbTFPyMpH}Ymfvc;L zV`q2gtX|iQuMktAoCEJ|9 zz%u?v6eqiT3ArMwph2phSH}{%;Rq4>{3?34StiVPfyF#;Kw!yR1kCOFaoa3An;JF; zm6R0Kk1Enpju|M!!&8TV`1y;GTW$!a&%cScLhS&f(cHR_WWNhi^dfu=qOTc6E!3Ww_Xz+2!Dt4C zCyqOQFV*fVc>7zdmsnD4N%F;Q*Ed-%(PT4jF`mVxec|+R9Wb24q%UkN3Er9?y9L;# zOlcs{CwR;+XlU`V%-kO?;#@spsSg2mP36@BdwZ+mdrL@GSJx*mB*`-_uM&A6Lv}!I zk>S#D-9*9N*aFUYOTf_ul%1<4!lIdo{56-<*Ixp?#=iFc8QUC0RYq&lBgA5b{a6sY zHHOh%5NNqo0yux~UzSsN$*1GOey&aY?7RwsTOe8Dd`6=hlP2SG%%Lfq2F}!bkUkCmlKt?f9FZEe_rqxU#y` zi_7+BuE!d1S&ZJPh5Tl}wF0D25Lv`3G1h{K`n%2??!ktxk!=Yx>k9Q$8^Xs+&qi)u z5+C?wQ8#d9S0*THW2X8WPlxq+Z|~6i<0Y~#!DDF!Ihu%QT<+Fr=5(b^fPO>NrWe-% zjTPmkgZ3Y3y|P)ku8suTS)=(ii=lgn^tM`wWBnnE*f#b7AlI^cPUzZ~+%5xQ-17hH z$kM>3?K+bpZjY(P_js4x@Kjrw)f#?W8PEyDD8%A;VAk{p@85yXJ113&7NFs3e-^SC z^H9z7@w}tAvNl!x_G|B#PR3NkW^{L+JJVQ6c@8_zc0`Sp1a;!;VaO@7?pm-W^DAeNWi{2ubkx4E7ftsFz_LO1B zH<%;2EG+AOn^6%@MXbosP#4a~Qc9}gmRNJxmw&n|Mqka7OB;^~DGb$YuEHf*f2RGNhWe0o z@qN3>IzmGH8SE_UD>(OZ1<-P;bs|2qel!VW*XGjx!!K}=)XZ0F%!!&HYSs1@(Bww$ z8Q4@?4*|&b2fdOrZK)0d>U6amoYew9@X_zsPJ%_2BSc5TlnjZc)vo&My>(+IQH&FZ z#xB`dmI`DTjb;@PWHeX#K(g1XY8!5IogF=?hc&-6%=_t|{)H(qp_>_`&8PB!p2SBQ zfuIrSmvmgVmJh{9p!&N<*j@jv$+YSd)j&zlyNV6cywKNx$bw`3xC!eetH-Y!4Kpm6 zMN#maEzd9ac9s;E{(t!WA5JL@yK$2`5)a1;pi9q>?>WCeSJqXY&WyYhiKx|BVwmx@ zniW1*r6~$^R>a&4(A6)owE%BTuGJiYWQ|pED;t-*qZ=}x56lk|i%0QKF&0L{h+cBi zxDl5?pP*F;RGym)_)n|3`?8WYWr0=~Ph@@pY*JhXQU*6(*xl)4$b+^+)2}rtap@T~ zJ61%Bs!o1wH7eoklwNi2upF1yb&vEOd`Pc}}E72DljiSy1TtX~aYkPqWr|jl4u(C5jor2r&OKBgq`wX=!Bu!_0bOwXZ zS%ejJb)fz@@Im;F=fO!$RMoy?!?zcf(hl}BR$MBJAJ2k;D_u@F@cyZVBtH875nwpw zX+PY;vb49gTC;xv7+gt zlhzx0TcJV>3AV)Mq2L0bu`ppw4EWg<#%^eARcQVmmj+21p*&{j-LKO84vSfKR!QAP zo1iuP94P+CHxD8r{YTRC{lfE(W+!_?WN``sles<5=hu9$QH8=&V+S z*a6oS)jz%}3j%UYYKs^U_o>xDew6%`z&)D0LIE`oWR+2Fz`RYCRC{ zc+VeXd)rtx_$|a%G;XVbtjoU%&Wf?YOF6d5AtKGmHFB!-(LI2&GNb~Rp=6UeItS>n zntL{Kzo=xfA|WYLk;x|npgkngcdf`~X(%`hDD7fPVXoI!!+$je*}YI!i%&&vUw082 zvg`_{0l27BD*%mM)rH&g!cz=0l&Kf(*oIGq{Hk@|%M1P{FKVBjgWZ{dK9JR(?1*su zLZA3@%w-+?{(~RqXulP*NI{d`9Nacjal-gtqP)Gh(@{eQs+H zpAc}%+bdqH+MgI456<@$-!GF_N_BiM=Ot}8UhinzXz9^{(|g`7G68{oDl7LX@Lf&C ziA}cifCbjsCM4I^PZAkz)vq`K?Rx^G9((23?`})EP zt;&slx@hhC#J=^=fk=g$@&zAz2W}l7nWfxMIX1mBO?>4UJ|%FEI6C{r_al4&qjpr8 znHC1|^Q$UvcA3pBgao96v$W9OngTo-Vt z1_%sFhjo72r;mV z$cL+kc1_05;(T>wMH<)!Y%L4wtaM&}ucQH13PC@7y8yQlh1!<~MAsIQm&7BIisYFz zzYk7qiJG$b=zO%RxE$*W_)CaMYm1)l>Yi%X>{kv!uCI5|s_#5VErpK64qCd^ulKJs z0zqmop9WkiQl|%S%NVU$;X&{JtWZC!Hf-b*0{6TL!5QyM0f}mOb`qEVwzedAtP&UB zH#+diO?KjT!F)cE`^Dqj#L@^?tlBLsovf&@wi~ks+5CBv8bfxRUon4dU6S2L==>7jRqR7KU{VJmz=x{yK$R4X*Tj8>54HXaKbdjCj>q* z`&ME*kZf2wQ-Mnm4IO-J*84UQ)iHRqJY6K^ev?Jz5Y@rBR&;rJ!RYsjLcYyO(v0P& zGeFN|R7ZV`hS5%VrEiJ@*3$LB&&&4(cL`-sFg4y70iy|n ztHDNG2Crw5!~<-q`6?b16MD8|&q+Qd@TnlVEO++kt&)r|JbJwJd@OG%0%u+zZh3xs zQ2_VT;iB_lTynXdKLjRRsJdcB*OMX2F9Kc)uAGJ34Y0e~8U0*B__u&!m2J6t1{eAH zkRuRd39s(4;u4v~XK5bs@8tpOcU3bKE$34Lp9+hFFnRUV7^)-b9;98-hbzovOZIi=fO`GP(lDO8fiIM3r2`BU)s91DCP10*BX4 zAb#B&O4ul=NW&vWacl85_sjFXE*|0m#|t~ghc?IXDS=PTRW&Ee*OK_3`7P+Z8*npN zrKkA3n_VoKEFhoXuwb4lS*1DLdS?)q57rGi*`>rSY9Vk9H{Xhv+wdZRGRD7N|_H1hbrP zROIKp4Z%H^MwfBfKRGo=U{WP+`NvgKT90@!au%0a`NiEd$Gplt+a=~u9uT=^yUS->tjtp6jPfag`z$%@ zEx+Sm5_{g9!sjLWaptT|K8xL&;EkJ3@iiwdySs`ZId%ZI!HtGAT=f1X#Sm_JzZm_$ z322Ju9_hi%S{|hJ;j?~Ml`NJ#$EO7D6IoCiz`scJs-%q13+w_P#al8C_la@q>@iDL zagin5hX1RgAGd*B(Zjg)u3W-H|JNrMxLZ-pJ@MCOU*kdjBYaL#ilwxUPYK*7oiE~M zj`%G;&tZh~T@F}hKUs-ex59$QSZo0YhF5V@p17Th+wN~I;i3F>ZUA*P)qL!4+OqkV zZQ5o~_46r#f3=WF%`HA}iv%)aE8!7^ItjPj{gw?Qxa1$aOJGrNDsG!HhIr8F9a8=G zAJ=h@jxXfgz>UHPJ|*zK;Gh?uxBhL25*<(CqdOuzWL}!ef1Uhl2TndE@UNGq%IEWD^q{nSs2lN5#Utmu(eE~Ho01RoB(1C9Pss48Y?&+P zUne3nkoyVz>jg;i`Mi&6pkE=9@d=g4_lG06O#-jQOaq zN8{2j@sGcGqmDmCAE6aj^1nym%TnP3s}tG*KC!RK6nqhvp|1_z%+9LdPkO9#BmbKO zzAQ^m1FD1rd?G<(8ZE)CIPzT3o16KQ_VT|?;LCEh8@zUu_VWp0LM-;hC28Jq$#FTB zuadx*rTkSs<7T(^ni998$08&CKz!N9%=lGBD_X2#`Dj6K9K%QrpQLA}p*7 F)&S#l2m}BC literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/black-wallpaper-charcoal.gif b/public/images/skins/textures/tiles/black-wallpaper-charcoal.gif new file mode 100755 index 0000000000000000000000000000000000000000..2476bd16df71ef725eb24967a6a07eb2e1d2ba0a GIT binary patch literal 10149 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⁣F(j{%~0V)}W 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/blue-denim-1.jpg b/public/images/skins/textures/tiles/blue-denim-1.jpg new file mode 100755 index 0000000000000000000000000000000000000000..c0f51e142cc714633e837e3def1447e77e273d96 GIT binary patch literal 52474 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

      @!FCJy9ZLf#V|EC|4qY>3j7X3=zo(p` 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 WgB%*N^*)$4?E%%3nM1_A_x}M_Db7Uz literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/blue-heartflowers.jpg b/public/images/skins/textures/tiles/blue-heartflowers.jpg new file mode 100755 index 0000000000000000000000000000000000000000..689e4256c9bc0550aff77f0ab9c23734a67965c6 GIT binary patch literal 66663 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∈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%0DKtvdF_BaAJR?dY$USq|-5;HD;<9Ydpncg*<;Z zCpmEkit&!0OlMo&zxZCwFV5DJQ%j3p+eaSHUcGN)sokM(AJq?x$c&Mv-<}PGR)2#%@W<+ub<^G3au@52X5QiE`0Sb75DihjGc_yUR^=<3NkX+ zPX1$#&IY=j$ z+s^V!;hekXB%3qO)j*dI``CnHWPY(WVuM1rQsu+DGA{kTAPeD-tc~lLiIWofnuJj} z%J}7}plX0=qdV>LvqT+;OLl!&&)GfqFIxs&UKA64mZw)qfnf`8vdBDnd~w5^Z37fm zXeE0?f4ddVN4c4)hy_On2W3G5R(m*GrzBh1f&WxOV6Q?gl(>({mXtV3Tj;n0I*@!F zwRg+z^4I&9S{q)w+)-lw#W}iQejAgCbqNxMBtm|H_>NQQhq6gD!NSSI0Tt=_kiB3a z*+FhP%v5Blm*%-nKyOboz>aceh)DB8j=ABa4r1|W82?`V3#QO^PqIPDQy^_2gy2HP0B4m8T=xJmPRAhK5Y)WhwoYr$`FZ$^-+-RXDe z@+>xYx^^QF<9N_ZW zhcN^wqDFP)8jE`Bdv|D6u#9j1S_)vaEen0YlgJ0(!l-tQSP9aDO;iPbxi1W39W24U z4n$HedU@Et$U~yv)oW6+s>K5YtvwdSTtFI@v-6D?5A-xoQ&5nIXT%2rKHRWA}9^|9al(H5n{>r6QGS5iErh=T|2JoHH3! z!yy5M?s+dr2bF#6pp1KLNXD1sffIVD^aCTE{leHVu^}zH6`9@F+HgI6`ri570r^IF zno$qGTI&`6r1Bbir--~`K(nd_+v2L$2lnNZE^U!gw`XClo_%G>lg&;CB{~6+k{seL zu}HyT55D^srVFH3wNsuCyt`OBW#5~wBpjQiN#0FqNM%h}ADaZINrcfKPupLS=R>7ya?3@p;(K3ZbgtGu)5i$CXk2MZ`5?%VjT*H=B7_ux5aVO4uj zoYCF5%N?QG?DKWb0(8-fs~~r*|E)FPr@7uCG4!{S(P_I&-RW{O6?D8cy4-E&@csnW z&%Rr&;Vx;W_E{wUU2-Jv-s9ir_$Qn%9{|h|0LS47qq-uado&DoDGiL$eKgeDR~kHjZFRXkG-ycNv1sd>o$XJ2W+qF_<1zbm>aEy+8sv0 z6_K%bR!#&20+2IlzTX1j&()+Cv~rAe-FW-W2Jfa62(4M(EhTRFe+3~sLcqM&6p{mx1Jvjy&KU7e<8xeqOSVt9J5;E42}#R}VN4 z)K^64vI)17NSP>f7-^c4{B6K>{~6x4S_0KcYB^6}RT;kc0%5uMP_lsVcIe;2 zv%>f*F@&%FIaFha4kt%r6kN#;DzCbkX8+E58Z5NCX~7_yklD%1L+#W-Xm6KETya6m zUq_xL#r=!6qan`wtxJFOwCdxwA-JO#unSd^XgKcGyyT`hBUepML?zD_ zlKIJVzb@THTpeWJ7|cVa;WK5anC)bCm^Yk9odZ!jmf^VQD*@Tc|sH5!shx7 z5jT1;m)Yj9F6mvanO|-#YK?C6juhqAk{cHl3@@gXcJo&X0nwO!PCc76BcMWow9dqT`tBQwaCM(&d)F{{l zNE)g0kdPT5Z8;!uX5k>%M8r`Pu_#Z4^SP+}T7AHWw}?jxpI^4@U-xOsCdK?MFRhh8 z9_hV7$S$*5^zRFz6*6ZzM!A|3;r4Rn$q&IDRnZ66XGn+ugpz5kr1k(Rp>0Vh@4hfX zQwXW6G36v_*mzDoP*RWVroRh&ac)$R-j}2~zEqnw!HY+U1JU060ZLAqtVC_Oc~8|e zzt1q{5UZpz%;axsJ71i2-)OrDW7CwRhi3SV2m~3IOeFLAYpZuiJD1u`S60kUHHW^7 zo+}H3LI8<1z*>uQHYkxCA!!I&K1C=Psvq`{Lv@w z`6lP=<0=R0$~ZIktCat|@pqNiMC{ge#J1j1C5^vpWCdgF0HLGz2BtS=H>8A4nH&>2 z4j~JH-TfGi#dPt#_ci|6&ul~rh4Q75xHgagh|<);oj5#fMp`1B16-Na1A?+kydKO> zf%nv*G#yUvC&`OzE#75kyH(warDe_S%z0=*w=)VJp0V{5R&=xxv3v{ec=jrE)BoO6 zyrye%)K)>$?aeRv&oE>u=m`nTA^k%ud*a?U06+Ewg3rk$B`M?`b(_g%9nT8@Y9+QM zy=n6NF%R#onQhRB17bN8&0rh%eXk`un_UjMPDxz~f6W%Pu$K0qDZ7L&5+khzCtbyz zRgj$kn*abXVsWIHfK;QjvUXnF81D%$rm}XLGKFsd4s!=-thpl=%c!=zgEF(giTFKm)SHKjJ5rO?gr?A+F_`_#RW%Sd`}N4*kZ4P?~Rc!No9xCM;--s;uzFc;&fo&ac<;fw8JLSmroSK zhA@(6GMH_GSK}_1F~@QtWv$WnGR6$4W#mfQ9JV{Xj*#(gy5ARFX!mEbMJ z4F-xGSnl?Z7M^BgwFeZ8{x1`=6A~W|MhsIaXEI$qB?T#y&Z4qr*jTY%beD@m!+?Zf zcGxBxuUr(4dYBkhGr#m`R3#+^=a2q9zbpB=T^PT3c5oX!dA9EwQRfSd z-ZizibImrfM%|TDoQ`^GV}%v{seNi;!KT2Y?{X(tgc5s!897k<`0}Ha_BLm0+_uqm z<-ernpiL39Mez9I*vcvLJXi45WbWNoi`A0z)7c5h*5oI}=Bw5_aZZns0=-LYyxb7x zWc(B_ z*+piW7Y-Gh2gxNj|Ji6mMC7x4CStf4B0MO1Ua<7oWf3;Oq&|2vhEeOxwAH^fzeIKw z!S-V~`&li}?%00OSSdN47}%BH!w}diXuIQ>wj3Kw6JExYZYz{XvC?`_$@xZRjH^kd zO8DKc6UFmd0bygPvt*zqs8RGO_?X4jANiT^y7flzuwvb&WSbfcPGFBV%B@vtr`#xBvSwuDD?Jy;CGrt&Z1l_5F`CWX~yWaU;4r%nFn0%?EAk zrmWw+AN*+J5$Q15E{t3UadI&FH0i{=uHnnW1n<{n%mn34vdJ=g#d|=fYT?yH!T>nt zcRpa5$9A|njG>Itu|j1ntMR(@VK$Hh=50cYGw{AQKMM`XZms2u(79pCiSISPyBi1K z2J{8j=pgp@CeY)(HoCB)?tUrlgkT|c?BA>7!Q4U zWah&|4#!PMB&z5!X8^Z-x71{&L#RPg+g3n(`*sw__Q5Ngzc0U@=U-j5!%{TbHolNQ z6`FFyX*2TiXrOY+($CxJfyaCI`|phSus2{*ciM{t2U3SJY`>BLf$q6D^)$hn9=lp0 z?50?f%6p^S%zNGJ*FFo)Q-<*`l;CBG{tMdL1kDw|9oMBS=!v)8{IPP>c+A&oqVmUl zwIKqKuf2IgroSC*1%cL*7T$>@!HiAV&PNt#fd)FPDxpQTcy>4mLaSBoLj0CH-$ALwsa+o6~>3vt0EWgBD9ku5{toyA-tZgvJ7s9L#$ z{wiX#x3(>S=-JZ|8`l2izGLLn-Bv^^aYF9q5x|!o))x` z+PyE9pn)^DPinmpdD6tJ^(wnTa&}J;84#}zp?(*#})^x z)DfgKn$X~H#W%tdA}hO#OMi~PIZXCIi@DJFlaruhL|vN8Gqpy~38EeEZMgOJg0_$m zQ%UnVo72Z&7Y&hmSVY~ncM{tF=!xf3abJ2(;Yprs7qYfuJDcMCq-bVu`Cj_ z#5=p&pCM{yLFtm~{$Ypqy06`Mt+c*`d9}&R`nh>zu$1f;D%8OLtC+TcsyFUZ_y!*G z4|8+s3%lF-zJGByaC-=0b8aZh=~eJw+!BfR@Zie)sT&t;dwmR&?Q$R~n`Dv`V;^Ok zoHMiO)S3P6b7zim(wZN4z02yFG>P+fqTfnl#=vsOd0on#!rA=8f*;Q3qrv(QpReB! zUDd&4z~sXxfj=kd*>7&x?+c?|=t$8ZDpA>Op*z3DK9F)F;b-yuZlP>ej)de&140{T zqt?~1@3NN2zq6fdWdF;3bcMtr&G#;cw*|B@$yGvzXMALE?q)JIQ{y`4|0p`ouqLv< z4WF4w&jdmbMF{RWP}G18u@I`*)_@KBq!2(rgB1iZC@S`#sMv>UP}HcX zvF!#y7u)`^tjq4Q^3MA`A129M=UnG^?&p38;=~PWvv1%+aZ(&KVo+qSe9ljRlcK~y zkN-r20_#fylQ8Vodqqi2jT+upNkd!ib6Z=)&H`?+caPFaXh>lCi^{wNR2qp^y;|kD z6K#Z-J%B`TpguxJ>*o-?Q_DUbR#6GkuXrkjUN`af=lQW51~>7aG*~*+s!1R4o*u%n zsNBzTcRKG9xlG7c{fsIG$oo!aDA6Jz2M7_cCJ8L+XlW+tOHDd_Y9By(a_H`xijZSm zkcC^EyzrL`2}|pe-cw-^#}rc)T)J)`3mhDMA7kYs4&GF&w5nF%1^!D)AibUx8(VGv z1G`zx?guIC%v8!<`;P1zinIoS!7IQcdi6W1m`EIZb5=Bk_o>y!(!`QbHHX{|w=I1l>f zbKw(PX$T*vm!V2Tl2P(xLQ|=CK48@OBP60WgMYde>@aqq3&Uqe{pl6vW839EG>b_` z`^i`6b{{4ft`&*uX@Bbx`$)NxMS#R`-|{Kacx?DxCQLL-bZZ;kpO{GQUW3OLd3+k% zTe&-8rt(e5P_hbL@yKI=P96T{qxB{pmm2!2mF6#t_+13q!%&;`fl4JXXNvE2cUt?5 z3a}i~_SM(()V5krWu~bs55}#v>sqZUcFn%T-Eao*W#|%(w_7(+8;m_&u$!lzUkAUR zww0f(Yu@RyiKDc2I)8GV$TQ%q6c*AR(%I!o8-KkLim#-E)p~dKO*dMF0L1S{m(w^l zY_r+3e5t^a-Y)}VdSi-XQ_rAj7b>T#KA_ZaC&c39+<@m{pM8PG*UO}&;p!2+`cnkc*8c| z)vqGNIPw7~5yy|ynNk>aR3O`GJ(<@YDIvnaJT_MD=#GP?e@^QbTT+oDzursqFi@$Z z%dL9(8oSz6sw+G|ezaivN&q@-}(kZO8kYVj7 zhcibmB~RIO3Ot(pa&5FeopZwe`s)k(XMa4l+6N0@mJCJNn8GLDA1sFUu~AwQ7drN- zlPUyd5xshH4XUE&aY(cI!JLN%{Cu9>f;4*(5cWeS`l>H|ezlmwvI9$#c1( zhNf*ka%ISzZ-MO<-PY^>_%`s72c&uxBCphvWg_N8V$eRJRmn9fi+&D^2}BVP<;I+m zhPXR3{bW2;^?-W-=h<7B5wo%WhUa9jTOmbD^AaY<4i|yL-0V)ps=@dvzMa3=;@O(p z3;x%%IHSw;U8vY!!MG|Af8S?YoQ>YX$2$su-ayxUL*}cYB#{6SY{)SX)n24X3uWI^ z(iCp=a+{CT*4JnAHC*=u9rMWS#Hd+18&i%@^wvU2b*PWf$jR3odCJ-1$Sf9gzMLnQbKkaOh| z`{fVGGY5dZ0lhZc<(dpG!Kfl_ z8Z5GXV3^`^m_mgoAp-cGZjn|89&y=YB;czk?huy>InAO!3|5Cj$M(=#tMY5u)*%?g z){_~yMqLbihCqTo;X34x19D@PC@H_2YCR;7(c&?v z#zGd#p#lMNVt?=&e8tImY{HwCpa5p%7EVDriC(Cg_Ha&Nt=P@8xg& z0w6#s)H83%;koY;93mDB1fyr(ra^3$#jY@F^!PeH+1ekVfo#7E#WwMwXhEFQsNORT zKoiX*h5{1GNzabQo#1EEGNI1~`aMB0HN!euLE>Ai?c^(HU+krN(j2*Ug&aBe%yqpO zS*b@2C+t42CP{VH?cP<)e1u3t&3>*~Pb!*5*?(su6=KIMHuy~BQtv*Aq<%r7MbxCf z>keIl5)>pCo%M2<oQczj{y z0jGh`PT#OF@3H;K?mhSJ=RJ}+H+(lzMnDjy5e?<@0@ zVX~mT^7cF@(r&WoB7?AdJ~LSnS_2O*ixiB!FYtBQPZP)xwh1*oWNJm!>=@SKldd;S z1W$Y_GUHgUh(*{*<5Ko4-^k7j2MO3d=v&%q#%|B0$Jgb=E(2s=1@WUZtpxO~iEOJ; zB5NeCK$zq0`!`9RFnx6q5HbBWfe3l|Q^o#gabyOzFW%m|fVgxsF{(CjUi~=nP+-+R z#O#p6=LOPnFGBMhm}gu{Q}BJKo2dQ<>if{pBkiuR+5KWCOaC`>(vkQr&2UPdje8`G zZJ^8*&=+ASX-Ke!y-wnQ`m(8zfviTxOn+nrS1#6@Cd3 z=_v^Yv`Inobp>0p0Y%R=$~jq?#{^v35(^|TkeRa85q;?6p@=}m`kMxLWnyLECL0=< z7KmSSR2~*Qlz17a5&u?p$dd<8*xejmZg=<}<_opWdgK6MigwB*V&5z`J-kPbZUSgC zG1O6<=}|aaTyOH!@EXI;y=Cly^_07^b?I-I!CcZ5>Dg9@S<@`|^bhBX92r%R+VW#x zI0`Pg*nOOXn&j|fJ^mXB6&N74f$SlZ^z`}cBa`RsL9DpeySdbBNAhPI$Zh~~6+uG1 zcb~%sN4Y#nh7b|LCZd0|I<#Nl_gPKiZ-!ooU~fHn0w7;vpPP)J?RwoN8ET8=w78aD z!(mw8vA~fzuXM_Ioc7PV4r?6lSESWG%CUDwE?Q3LhP@{D*-lV;GKT0f5faIUrpbt4 z8)-In5E&KkT>2Q*8X&0wnR}J}RY$jHU-C+XKlhb8CGW7pJ$@-OB9$N?Bdw>g`U$lH zO)!0-T{589V$>f8x{ulcBOCplkbzA!SR>3uTx*en((8aeIIukjFdY<8bRFbv*tsR1 zpz_b5L(msJw6Ja8&9`b?VSUI#tjuTtm)38w7R#U_;gK2d5+42B4L zsdMuj@r(x0H67*YIJH&)uli?f6V5CIGzib;JY41uAkBe?w0uN1sz3!Y=n3}`)Xxk8 ztB#~H*K}PNzbKX=fRF#TrfHw=k0HnvhkS_;f~9u#;hS#6{xp9@faW1#Wm1T1WjfYj z+x3)kP;do0WIz*43|BVj*HaG3p+r5|!@y}e<9_v&u1N$nrFF!%+dU8*p7!Y)_lfO$ zyJ@z1blm3&{GyX}e?ODl4c(ex?p#|QhtX{WL|-12OlC3k$Io~_zfZW81@K$>!;dFL zHn!D2-h{rbemN@mbwuZQ;*4Xoh@3V=cQv55*)K;A*914g580qojt0r3S0@)R*rb(7 zYjR{1tq3f@1|}(Bk`7rjr2GpZiFMZBG)B+SuUjD*Vz7WZL$|818N$a}4P1@hZkqs* z0*urwqqyND>oW^d|7Nblq?2ctPXEFG>qZXmbH@Vz-`{^4+ayExeYN$7pl%Hy)(@MF z2Q9)TG{r=Y9U_rMG>Sz$%AMh-i}f{C9q)B?l%Ey7?Q^q334K9=Y?VC5$@^+y^t0~z zvv1~vA`xH2H!DIrw-Yz#36^FjeXcIFMnGcH2{VpK*~n2gEpmvN z_O~_RIG~l4aT1aekMl7=d{(JW0Qbd zD0t9kUSAg?-qOTOup~$?zya!KAJDL?7`4qZw0gbGpI=Vg{1dj4!m*fDq@KBc^maB* zfbc`~L$i-Mon@bU#CUfVtu}m}g)YQjl}xVZfAzS8W?N0!2-tj?LEV^>?o;|1u30$!Q`WT$d#bOYyC`EMbEmpYPz zp3*OZ=kn_%I{G#?1e*SbFyx~s!}WI+r7Yix5%aOPLw72N60o@Z?RX48D|z^WFXOkL zE2C^VG5j{O^H%mXcqHxNx!)L&?dHyL)w6!TpL#8JaM$xy=CaJ2sZoXaFZ<&bk8|f_ zWq*3c%%SYQ=N$j3_X2fX;oe%L;zbo2CmlnM2{L)Ou%+qbfk z#B79W)KusD2a8sJ-To*(wHu6X1%WAzIrUD{?2c{5iV4t=;Td} z!eQ#?-`rR(k5XIMnxx&FilDFX)1C49P=~C)>tj#JI@_AIM~r<+nQ3(5O`G5#I+~xB z7QeqL&+Fu+*MhHP3Z(k*yOYCq@w@7bq||p|>5B_Rq>REsob=*n-%+aP?8eSmuakGW zt0$wfHU>@5;;GEtxZ!>P7qAo5-aGWii|oFC_1&M#;0zvGG@B+K-A z54;;ZEda8J*u-nDbQ!ly{stxoa+Xv_)cG&n4=>pLem~nB@n!sk|8;~usBMw7BDCw+ zoAN~N>bvgwkM!;CmoUBLZudsNHxvn@iex=)acUg&4;o3)TKUv3ahOv#OXP6!*fGUSN|k2EhP;mCX~jwS`w1qZG=QFX%x@d0h{u=eFsa*nvbJF*x=zh#7oxa2%$su z>{Sty+q40S_lGgJpKT@kb4qMtp!DsfnVz#|eIsnLX^)G@YaYxJV~evAwNB)uW8Eu? zK5y!4)yJge`uVk;2ypcKQOE`98XF~N)$3PttCnsK?sKx;zH+s97N{4gfjv9BB=8r( zjJsZgdNspu7nb2n72;gTs$3YO3}?Ae-<9p4%Xby;^jRDr%kx9vfOjGvEPn@-3yBL_ zv=DFI?O7Z;Y5$42^0~UrX}{g}@EENM4bT-kMwl``QghSvo$l6G&B_S=uhrSuyOPUG zc3VX$DJUvJTxcI?J|(2FJpK6Wg_5i~GYq{FK-O;1)ayh;lDh#Vf?-x!SZk*2+ZjKa zm3ttkXWNH()JBu#@|UtZC`n;g^mpbe#fRJUbI0tKxMgv=N{T`Y`z~b>P25537}qs# z%bJTs8mIU5O45*Ok=v1p!@_t$$)2&B%vo@>v{lF#LF5KKg(1=&Fz&aL%hZnA#(7`3 zKh%jUxa31sVjojB`;RqT_hl~g>k4hu=_09<`}3!-p0-FQ`{~&vGerFr!g?L(G}*9t z3gwG3P*#vEGf+qE^@dv|iB!jIO;?Ea3-D^l04@qG!~8_MNa4*|4dOupY=Qx}Ff+cXIby_SSa5&UZ3B_lC_ytiq1$+VP>NK_xC@@ao-~9*e}B4K`#m zH>e;g4L<#FyZs6|A~j)g@ARyhqzi&~OdvG->rwIY)(+4V5>zmTxH^y1jVpfV+E?Qj!lOrWsk~= zyuSzfcFVe$d0cqtJ`Vpt25^o}oiQK21l8sSn*@vis3w*wv& zD7VFgCH$yrg)^TqUiTF^W6k$M0*9dI?$E|b^p67WfQoHuP&CE`{t`P;J-u*UKxm2j zenIf;Z6g@6o3kuX^zg-}jCKmUmbY0vi_s!_Q z$o7U$`F@wF84If##urj@PvmRiLG*C^0YKSm0j`9Zf+6fuZ+X_`BG)^gCG$JS8L*iR zI3+<8V-*N0A_j%NE@qLlypMj3kDuzbjnAPjQE}Et8BQ~PsX7(LLPY@FAbb_7%AL&v zUX81|$?Riy_bnXAVg|085%?(?8%uzFWuE`D{-Uj1B(Q*~0xi7VbBdo#VtvD)-03S~9TFRL4`d){b1QRk@2hc1W8!TdSnbR?1B!m1L$P6;nwN1_%W1d#8Eub|g7&mt zSw8>ux`VrEvJqfEx?7-fnxKR>i2CeYu6-ST$HtbLV5E+BdG&U=wbDEr1(@xviw)Vj!GH&tkGsgP7NruKrkI?iSaA5gV zrj=|#-Wn|KKi=-#@B{|pOM{^bPmI2DBgdZ_n(Clu+X%3Qf%C=3UcKK^GWjCG{I^DUNyLINZ_+UrCWt@CSn*VF6L?LRpp41BXUo zJwmulp&=DrN`y>{7@#Kn&e2UZpyzJX9Vq}p^-KlkGKevTFs9)!GZpiespkcwu6LnL z0?qWHYb>)<&mH~KRLIW4wt+6Zw!09)DF%9qytkxWBQwW^6 z;+F=`9YSm=x8h+k#*@Nh1O)sO$0)h6yakKVtKhuJn>gS@J)A1_u4B786%zCnd)mL` z9eO1vl{hv)o@Vvj>)~GPvn|lYtkNQoS~EI$espF#eUmG78!ck3M&(_i9wXJ1Z7OpH zMVpPqBxA7F?04hd6lA9w=-bW<+V zw08O;E2A>ZQuV9pU_EkZiR|R*mXmD?N;-#XqgS2)+AM{yBU?Lb#Cnb`7JaQEwMy%t zhY%x7c}d|lV)h0QsDma7Nsw9n>ol0bFZSmbGxdnfs9e?vT=g+W+=}Jfee;abOB%x4 zKh-Q-!?+SrVY%usYL|K|Re0{)9q!Bp+H*kbJqS1}0s_UVL>eW>|L4LUmf!AP?x( z)AF~0WGQy*)QJE*P*{UG3ROJ4_G+G>GDgb^u1=S0 zmKt=quAVn{fudn@R8=XpM3q@6`L{%Av^BlNC{Be%!Hva2Tsd6k9+4*ac!g!#+1N@#c-758fwpJ;}JlYU=xlZk9CiCg_-6B^2h`_VjhNKl7X6bL&>eh799i zivvL|lWm4(K9iw)F}&sdzQRbx#B9bM8oi*6HQKWM=>%Fa;hI}fr5!^%5LN>s^zhRU zfmSpMA&Yb#^ny89h>qfeDZPg;?_K6?t4Ef4&*~m5@(^eOhDZT}*fP1Q``_Y*HrA5` zz>1c*3B%ArvZ$mKNrehI)K=TsuctLms<7ISSHxc+9RviBr%qH%iF|CHiz$td=@Xr` ziM6qpyyj0Iugww&(;n*SR|K_k4Ltn>bJD!B!h3T~su?=vSc5vKN|VG2gd(UrD)eROOEqP3K&`MAME2 z#)QfmTknlmt>b{`Som?yi3uku@KDo}gEyrS_dJc-ZNnNX8kWQMdzqTNtdYXRF$ytc z0UFoWy?t>lIk@Eym!^#zJC|jQEE7?tRoJ!uxp*v-}0|3%C!v&KU) zZv&T*AOe148i_`YRv?bXpp5y1qZy$p@e}gOY%b&^6qXqc2hWuLIgK^39*QDvZ{#ow zJ4v8zb2&h)$7a&N3O?exnHk@QSr1V+4U+jfb=i1$6i7*t@<%fX>GUGrw`7nyqzaCE zuq~>$)~B4JkNE0_;uT0sj<~^T^;VkLFVd|PK{b*;lnNU+K9q~Xkk|OFa#SQ zn4?@tA;ZI1A`Y!>E*_mWmE@yO-FE;XY;o)BZkASSTpE|~bZu@z$}3}%M{DO+)46oT zN42)y2SJ~#&U(+%a$b^TQsw^ui0Lk(>(xm*bwHjf*$|S-6lOS!cXcgJmjf?L$((Y? z+cwUVhW%o(kb+B4J9zShl3ikF2#*s9Fq(mc0G~9$vXmFffGTaEPzmdc{7o>;>=oAj z*tv>4#-Q;PLfd4oChM&QwbW98WL3qP0Lc$8E3q$uxEMShibri?^S)U9tpJk;dr}7ZRxG0+9;$fs`9t&Sc#AQLG72+n7PNarx-O zWIHtpeI)a)IH0v3rb7Rc(@JY>Lsx2Mxg8XESn<_zGlW(_{zb~ULgm=>veGZ4#Zjus zIiT;?(%pRCmiWeaM%Netbt%;EVTbcUDY=VE1t8$(-0v&=Hl?yjBk^>5Y z%g9@v7iBkAWC>M?IFLxOAQR+d!gzVqTMNn#6hV#K$$5ns>m@6vrUOoxLmPi>=0(?~ zIq{B-MW3&P`N@6c97-%-S@at@${05lDAyT_p4L>3-6LMA({``LxEK}+7Y)9Emg?2c z2FP`o&~zx{+3MsflSrs4Z*)C(ZN^H{(4|bqf?Us)J!fP;ZKe!+UZ175F<}g%UABb0 zl7_7_%v!&WS=>ODErUQ6L^V=3G-3sM?ODc!hV#XJmFq48V!cob^NOvjsy9m^IltIi zPj+oQ7r@sfz8=GpfwVl$dILQAnL^4lcC1};LIEg_0%czCq(A&Oqee2%JZpNu=D0W) znvrC$-^sOwM&5mO{8FFTaqZBSUB?${kLdSS4>?eVuh1dHUJtDqSGq6-bK;VyxC#bV z0WlX`C>Ue}n-rn6VZc#kfZjU2vM6 zS6wbA^<8Bz>aNH!Kw|krHd~dqMd_Va6v|OC@+M*}Cgox;)OX#$*W(J$_M$5rA!F>4 zgmYf4dH3*oQESUK_h=RBSHMf$h0Aai`?TlXeSzt1v-4I_1b$1>28MfECAFbz1bY%= z@3t4)^BYIWRY($Y(Td~Zu=Einwfp4UbD8%}u03T`&=yDKwd3>rck;~LFD~>{(_MUa z7=!Ik8+}ki>FyB&fCHJb%G8f;>E`btHl6%Zq#+-{oV_;QoTdy!jyk9yKqbHBQYznZ~nm$lzr;%<|H`^l3o6tmxM zmJxD5=`4h?LAj^L4K6V-*QWh#+ZpuVh*#ZC&#|+5LZ~CQ&vPpOyr2qxNV7rabBl5% zUhGfoq-_CEB~1&=kEaFd@i%cZ!+}5yYbS&%xeM$;M@UnZ;N9x+*}h5AzK+cDK$Q1w zrvH75Cl+X4dYlvTxUl(dNc+g)_9^aeM_S>H0mzK;34BrO#2TK=b438Rh8Y?IwL<(W zW<=v;{_<~u**n98BbY1ok$rMT;6&7m<`61t5|2`Q%k9(mOIU_@~|deKD5c8P>sHIn#oJ20@I2piuKAy5BAMwp&=1d}q^7ff`{)54<@L zeZ|6JShataU$DPhd-_Rmuc@Hz(4c|JJq=tbDh5gLn)$NYnLJOI))GX7+L}Re&vz6bE`C{xs ze~=;+BjZFBE;1z$8lICU9f^2u)xSQBYI-?=+l5bEO9*v5SK1 zKCI0fc^H_?LbUugx!CB9AYB^NAst%dOk6mFJkkhJueh+nHCMHOZsCi|V4Fkij%)B|Xk= zP=-w}`QOesecMAv7;r^L;QyIgL+d2v_i4@R?R6q);=FNAvHei6PA+{1DqfwL&fYPV z7Mcdgqngw;gymD?nWuERm^_PjZ2=bbDY)mzdD5zTW|%rorkp7Zw@c?zT?>e*ur#zW z?LQ~oj(U}Y3FjnNsp&6TR2c^K(f=;E1ZR4N?)uc`oJ?2<+vqbF8E1`uT&T1)C#US9 zX$3!fJ9}?7C|%6?&V%pEth|PRGcP7EVRG-As!CwBxebjoscma_-(pvt=H2ETexFTl zLa@{0aN``XOQwFzIZ4wSvB{6thHWCSbHdUP0vqP+YW{(a6OYSRnp9p2+{G7bBNHhJ zdz!@=7q;1)|L5h$AA_@R>SC;a=r!r7T}K3yQW6V2A(uvM8Ag`aYn50IJ{npM^Sp!p z$p<9MmW9Bn&7hxMfZIa)#vF+0a zJ5dZ^A$$79xN;#B*Z|w#g?FOgbO!RUVrrQ044A)SPNrx1R#dWQQJ|Kdtt>YBuev!u zzf0(@2mIn#jt{>)y0i&?u%`iUS3E|3u$hEpV3p`tJ6dpr7Ho>4cA3BOj*jfimbNC2 zf6WM!nUv@Xh*mQMJ2bPYb(wPHEy0ku{a5Mm(;FJi84lJt-@d%C2Se5jD?L}_YV1q6 ze&g2Eyu_f{vuYw8uMh6nc%VPsUeUt4$zNi>Ymw~|oqW!Hzgc+~y;e9FzpWgb+{M)P zJy<#|r8Zr&8}RhRMa2N+^pClLQ@*?862odzql8b~`d*eQukU!*`M+abd-E;l-Bbe2 zNxP=<<@jMp*1|DFt8Or_*P~XyTojZERLnxy@rOAUikH0yvN%7S^S2NdvFvd`Nf2+R zbOnD+pEz>4?Ohy58j8(Cvz(XxN2^)778U+}fs?7?WyZ8!>ug9st_kC@K3ZN9xw4rZ^OyXSnl z-T&sgKbCD6AB7#Q+LZ0qYl;{9%*f}wi%Fg^OuDMdDDhe$VnL>)z+_Ct^T#?}%|vPv zlnvLqk!h17Etkh}zFif8jzVYTd%!NiL(JyBPvUxgZh3wqaUv>d0tGGZMywY}uIGX5cRr!S*;DC`ZBo=xU|m zF;)vfxzS@C-8BRs#hARxH7$#~H0|z$-lXxFv?E4XBFf+p?niX31_>kDc7?B{LWDe6 z5{OkuhuZvJJy=cnA@_(Tjv%R=cAGtxXo1Z7&730;@+=sFYDLry(}GZ(A`;h!#RhTU z@!xSr5%Qk=GEmUAd$RH6ijIobS7exorGWr+-cM-0jQ|N?1 zY@8+FQbZyK4+?AOBg5sz5A{Kx=GX?SD)-C-Q6RXdm8#X4D(J@zKp>kwwrD|d0Kzoj z$agI53%urHk85yuV0i@_Rl_}X0^vsrr(T0l zSv$pyQH+NKQV|Nq%r!6aT5NFxHV(vX#c5Z!9W!67Y-4d?iYbO%2)~^DYjWeOU^9k% zSKR}^4hQXiUhn-8f!jmpB2B3O%b+OYM*8rH;TTt%lHLGMsh($@*~QS~frZ2aAzq($ z&LQ!*u_;5}caXlzYfs~0>_eg4c1EnEa2S3%fluSo?51F*l_UOoVH;&{WCZ4nK;N93=zBAN> zK9SilcHuq7M<~a3O2V3?;oIWIeDOSu|~oIx}OQFjd}ug2!>R%Gnq*{(H=;69IHH&Slf#iVYJY5;w1AVLSj?Ok8V@t-K z-4pt$4FbPK(Oom5L=THJODk&*4!t6;Sx`Fy2m5CSV~}^DYi@0hVu!?5&>CTaa@|v4 zS!;+ehB`puo5a&Ek*;5C3n?7ME*(tkuE*WD5|C7PZsij?fjjlZEw{CKsRsff=2?qP zc$14dh@E+u+Zv2A{4Thm-Z=$?)8GJm5n_Vuh8n*6@B=LwC>KYC}^8*&|2`ST~Rsyjef#$$iFkY(nD0%^|mQ zS}>9{*`5ZnW+0qK3^eR*3BH}M$VRz$d{s4mP}3eV>~y!#ah(ya#nm*ac-CmVV{kPEt8FNKcI<%vz$m1 ziH`c=e_UsUoMxxg%9ia5#0QVqci;?KE8-@yFF!nSj0lL9uI*@p%+H&~^ogh5J6OVE z@RDgODA`i5wSsi{OhU8(8!CU9Q{KKneBg)GFL#a4<`4ow1FtB_>iXwTfY3CN5_;bYen5Oli7e;j$1cpG5GjHaeGLI|NAOW zMz-3Th~c%UmZ+zyDE*GlF# z4W$j;;vqpv$Y)+KEBV2r(TvSNrT#3~Nd zo{#@B$F1FF4Mci{c|c+tDPrFNL9((x%3p;q6tNcK^dpAtA-Jzwf=BC+;Nr^%ZF57- z68IA~?jd9^8igP>5M0Jld!9hPP7-1SF|GQTYa0`oC%gS5@U%1F4W0G z1Py|rwyD;xlDf)&{w{;fqE{SdK|b)8Bjc%9!8+Wx1KCkObZVT4DrzNhp7g!OQB-VY z9}_N;e3^~Bn=OfX`zU_!zS}}kR0B>MP)991D~TZXRI!y_iy;IAtVt^FG4#2Ly8ZKK|(&MLWWfW9+DJoOxz48BdM=VZ4O3p z5F4MAr{uE7p*SrS?n#j$=o&1_k{Q?cFrWMZ6MFb zez-CkU^Xjo)+a1=6A0Lh1(gHp2(GYyZrvP17Os`o-U%FPTjedG^D#zjE3*nPvpFTm zj{{6RD@x5Y0Gn6{EtdrAc(^9sDG8ev7Pu&{#A?5IQUigyD@lZ@`^vIaUCNz*#t2Z{ z%Bb#J+fNcG1NZi&V6Rg0mc4y=h&zB&Yb9RNlL%j=S-n?auO>At_Q>iAifwl%nmi0> zR1{$9zdd53kiJdmt~l|1Z^L?2vVTvU{OISJjj^1+zO3H!^1hN1j!A4$ zrDv1oelwwA#@W|f4_zNP8wl)DGZ?6Hakn+T~eEiI;>d@HrZRTsgoH{;r zbe;d6g=jN$K+=QIMA~zAe%$PCO{YX*!f0CwL6WSUdU*hwZT#UHPKIgyWpxN zeRmIP#T@0M;Ae(3h#wM=cP)BEIj&)s z@DAjc{8&hMd^sx5a#7S_5#tkHc6EJ{@K;h}w#|*{n%Vmw94ePLw1qT_Kjc(rU+WRX zLLr!v#{Q3Xeh;1m^$x0NNw>Ggwer5id~LL!@Bear?7tU2$1tpZxw7{^ezJrD^?a-VemXj0I&o~)+lAI(;)JXY{Yi zhvs8KnD*X43Ca#4gA zDG6cSNyAQU>q_R9h6%W5TgI$@&a>Gl=N#|!EcJhMJOYa#FtVuoynLNK=t{g1#_?5#oTOvNBVf#@(lspLEN#;Y@yAzN{{E9umA@|* zB9qs>*E_KO`ER+iPl08-ApO*4aH+b)Im_p@%fCh83pczVS3Sea>p7%fT#Fy1HkkXB z-nGvq`?s#K=?gLF5`i$X$!~{*JYR&v`KU6zF+*u zKYjO;+Kl=!@W}IQyG;gMWuKyg;F9S+I6x#=NjoI|9uTrGn^ra!IK+xf9LgLy=CtE4 z+mEz}K`vf*94q{)8O$LZo_%?Fthl&+g~kz=2(E@1#1#efBc&dd53F5E~^4olx?_ zm}WY$ak}{1zH#^)o;1pmA>>X@jFS{n!sWp>U-(Xrw_tSHbu}V>)BP&uLb=mm4E0E= zifzy|r59Q&j(>@xkqnply>B=Ru0Dxgmuw^jzjI0+Dq5UbkKQ*tsN9+?qM}XoZE_rW zYX)GQ4q`}^R%>YTg2;v$_H={%xQ{N?AHvd5#&xX#?EqV8AOIfDd zXgg_>0^zohZd6D0b9%p(9-7TIZk6dhItl@!OLHE1wIcZQCXdt=7pBC|Js+eUr=2(~ zLpU;w{}t~PZkJJj$S!|(N#FR&f9gX_VwOO7WZoP59o`*W#+*420~T2M@g@8F@Ff3Q z=w=3wmUMpb-ft!{Y6bcz`9k@^9d=YE*2ZQF5&NqO$kAO%Us5>EG2Q-fzGk;?5UeU5 z_=+#h%dm4&bOu_Tly$>d&P;ZP&5AFjLY}Dn=U^K(id*DO`$RJpJ}lc2Z1sN>-FZ|K zXWItwXJ)b|gaCmgtivJ(LxAaYXc&pQacG@6*ca$Qaga!)T)h$ ziWW7jq9R767MJ!7f=aEnQL9y}<(uz+&f#z}hdgsX*ZsS2P{3zD{(RL}K6{`>)E!d4 zSkZWDtAIA*9H-VKZHWIYtT)buoxQZk@@%WLv^sPG#(vNJD5OIXM=PGbzV1$qF&8N@ zXqwqf8#4ppH z;J(tFf(0%5MNu$0PSFXoEE+0k$5Gl~k01&s;GK6*B_LkmxrQOv*?5k7*1|8M53j;T zS)mJkon1{;ewOwr$?pieEU+_XTD3SV{>iNJCcubI5?x8T8w{f$h>bzI+jA&D0xp*w z4deXDZCr2GM$QAk*D#?GU0dAfb$G+YXLJV!AgldYS0|5%YgW44J5s|#yjx`&&dea* zQelhBgt>b^uLMuuaAtp$gvmRL+Be5Nre+yhm)l_L!kl~avIvWnybhd5ZA|Ci9jKVKb>ed={V z0jco?f1lhyY7$@l&I-i$wV_`AP0p>TlPhJ}pb4mFK%}CtNn=QT7}7Dh_GPgM-aWj`8XFzB|kbX_vYRteVmM z7TT^vvCs;&CW!V}LMUF$b>5trgCQBC?4hIY5B9? zA-jx>HWHcXz1B)+Q&S!eaCz82c_obkZt6d>#JeW%DD9+`z{e`QD@uHq_w`7&k4OrA zrac@8p`te>J6u2cxCqGT+X_bTShlr}d(rZKi;G zUkrM70OmZC=$(dR9$^_3$Vbb1@c=9%d1oqbhRC3%iF1pwn8@zvJjPFt*udFEHy7_vR@OxD)x4KzxaB!}ceditrl%0l z@E_Us9`=Q7lldf?;|RIn#}A2lF7wEsvfy>%1HwvJO58g(OjheCX(RamXh`FL3RnfjFM?rUjmYjdox=VQYVJozlq^9cj>O$7mk3J zXPz-J@|x0PQ^=l1=%1rocQ!ga*5yf#S?F(Rk!jYVdV8_OF=*xW%^fd`KJXq-Y>As( z?F}z%0>^wsX@@<(#`v#BLhK^MC{6=SF`1;xZ1j#eJnmnG*C(JY9Q5?0!UZH$W`$>O zJ(RnRGX_2N*EsHE(NnIJmOx1PX_wDmht%F?Ff@`V9M1r-f2X?oSwKBNC_{^~0+T2W z7yH!cSkdSxqY+9p$EN8hyL(deFI@A&nZk5b$8sRh3UCH1lDms}O}hnpZWqu-tLG zWu&AGzsoCqvV{Z{W^kwmeoM@qv?p{4#ykYL(-i!PpRXrW6C7OO=7L2pNk)WL&iEuT zZv;Nv+O0G*pNDkQY`ibOz?Yu;2^3BE>3#5X+a0W+9-CYu1S ziC01(*>#e7)WMxZ^x#{HLVYK2&AgMk($DS{1eci^d`@lzDk{TYxtRY~9w${3{6|wJ zlIHz0M0;#&5WgLmI_k%Wigz1z3eq((a|n@6K`Z=1$w`DFP|rfl*+j^-dD$08&t~5Y z-=94>)KxVmQn&m&?G29(oCRMbH+3a6YHvN8B;w^EcYT2Yqkm^dFCpqm??AXd(1YYX zfsxf{ZMpNVS34Z^c}){WZ%@8^(gkm4I80(F%oKP%Bj^&Fuj35#Su!*&Q(ce0!#i5U8&X(+3 zMYk$w9rYq5Ik{R_|c`8yGkVIru;DP#*k%7(;SHnqrJ-1swG^KrSTFng-JO0 zJ4`&Az0B#lXPaUod$Qvy9owf?zNypmto5QGX`9w1cr6f`*%fbmCggKP+rOw4SQ#0G z)ZSs>G|Ngw9*fj~Cw#C4M^uVWB_jvwD?fV@r;(Xi6V<@`N`y>|+4_1)Pf?$&K3(IonG?g0)unXHD6BfEqGoy~%5oHj;g zT(B~+gx$jAZQsJ%iV5R7Z}Eg+hS##x!;8nnZB|}}q{sT$tISICRB>@!(z=x+BPG|Y z9>&ti46chSR=)O+9f2pq4&9ovOGBex)5|+WN^#n=fsms#&s7S#8L$6$)TNOrHOz$=_&r=-m#>pO;AQl2;~2upvfQHS1dV#C#|hoTQL%&sT$crjY_R< zYbPDAP<)$C@oS?oj_@?FY3o-_BK}L}Z+X19Lgs(xSob^O3>?ujGQN2o_uK zmafCLR9l@2?|U-Lwa05aGps(}K4M-&0~cJFU!J#J{L9$24bhYSe|6B4O49^8VofAV zj!RaX;d+ceL7?B)Mt!}->OCF&ckRuTJq-v8hwisb9_nX|X|$UZ<@*x;bR;Fb&gI>y zrf2|nsrSsU6x~OaTXr0%xhImY&4Sa$T)NNe&d+Zg0ks;@c4*q{KgTv{?Z%kXHTa1` zK3?}n)Flx2nFi)iNcV{P*(5O@_Ob&N3!ln)-u!W@rDTM0?H)J0m9f2vg;K_|c^flc zvgHLU>&neC`1q4eq7)Puk9{oE+!-8&c(@(M+z$ax1r9I6otF`O60pKhdZ1PGpov~+ zDwcg+?Kv-6%Y)y8Dnn7UqD6-6vgh=4}P`>pn%Owb9J~_WH*Y1me-JC(|bDTtE zXaEP}K2-7b3P|UC;;Ux21(jh5!zXq_z1=h(>+Yl3AE%Tn=sH}|4%y=c2R7tODmq2M z2i8j_iTrUe)a*WnJB_2p>u6>yojOo(Fe~qVlSvUkY5`*iN8AZMAiQ{`@CB4xf;XH6 zcV-37D$DC=s$csgTM|4fj>F)5GcDJ=>i84tmdESwB@BPS0=Vkph$+ zOpsL!FpdIjM6<>0dhPA|?Y?U|u%U%CYdHbd%-=~9cbRDdIb5A4>ojldtrd_{k(rWf1HSmP@#;K-kbsbx~)y! zN!O8ata-y>)+R-G=oK$OoY;bcL7dirt`w9ymZESLpl>%bSY-L+rZuOok$;{Lj5TH7 zJ;i#s9UjCRO01i2PCBzeAr@fJkXym)PCH{FBXf(B%3JW(8=2i?e}Uj<{S(kZ(*0W3 zk2mE7S`n0RX$1`JTgC*5vW}hWG4A4IkHF*PlT#d&_~e#iB0DQtPJuc7YW#S9I_>X2 z&c$IMk2*jdR4cgE_3YtMYr`#%N4jRM(5pPdxc8yM{?T2~MnO0~(r@+7?)jVxB8-0myVEK7rS#2B_aB#(z+kFCALl5O<)y&08f_YQw7sT_ zVb_2?RwS3&6mIs%l{-0?atxOE5Ej0ZeIe~Im;009YEBS~ddEZ7CA4=T{_g3u?&6Pl zZXFvdPT+Io)O@DYy+AR=^?v1T|5BTvliO>UaYgRxH%S?ENfyQno#?X=HEv-8KtuX} z*f(b;4VbR_CDYWjiWyY@BF|JI+!g!R5Y)?j+Ss;)Q7G-Y#wu)E*Uh{9SgUc7vi7Ws zU#C*jpejdMf}J+V)S#aeAk#84gVzn5dG0el5Oy6!ZiP6#@x_Ff1QATm8?{;!TZjGR zSa;%Vy(eRaUvZDT$YJdMR=X*z2G}c0IWIChNZoV6$+x)M|E*AwY?tbHi$i-mj8LN` zSqG1^n`#DHv}`@u>#>G~9t|FS-f9WH{xOcn^%>&sV2$)&bq@)&SmHyc=w~B#nL;HI zOR{qEWx1@l8;t6R)7`)=$K1nr`uov*hgSwcr{_e5yhUJiWMKoGVDW2$?~tHHwoLzf zp=s8@SiZe*S{goIk|xF1Xuo*jGceX=%YXm4gLUV3-gIMWyZu3uwaDRiRwz7WVWCHZ z!&BMo2d9%&mf-k%o;&;KGLpE{=Mb_^<9e|NBH_u;(0tu)|_et3gauAOeAPDH$ zT{}x@mA$i`Pe>(DX^>O#OUAYqj9F5+u1Db6?(Z8p9K;7wq(ZCx?A1eaC)1OZ4a%dt z2>1Nu`&=s?vF_lVAqz>a6DxkjS0nU;hUpHW5VGmUy+q(?hSwS}5Fuki3)3NH?P2_U z3Kq@6e7fHwIk#=vjVbXAENCKr?ebTN;Lxdko6-+wUeIgoOEj&Dy(w#EnXcFe%j#&< zJLP|sjUip>+Ux)f9>O#(>4M5&#}VOfY32Qxb9FA527fER!WsvjJfXL!&hpzA)JoNV zvD+({J9B|}pMLdv;Rw66R!~k%eC}qKE>v)X?>EAV*`j718=05WSZnaPI;4avHmeU&1#^bzTib&Z}4G3 z6~Y@8t-NMT@z4hB1wl9ZTw(!f# z)-Q1%6?J2bu%0o0hZqyeNkKdeW+-+2D@GlF73ZhBZ)}97Z5Ugjc%s&=9P{;jkfL!H ztmmoBI3(}ywHwFnviEd5ZO`kQoNeW<3>tNc{ypwG$B`No=Ee5bDh$?B+JbjM-h<*R z;nMOOVw+EM#&9>angEdYCWo+c?JQnX#ytK&?SI1%l&QR@cDO~{lAs{NDJ6`jqh-??ep zlo`W6EY!5}7O#e!EUNu79M$CojhY_N_p()_Hrt5#2;WoB;vX`4eR@TOG%Fn1St-8IE=_82 zSne7Fb2^8AoU;YcvudC8PgxNl%lY0~)$<+0lya)vnLLX0z%|)(Un6hPh9$LR4fW;_ zvZt(J#_AC-zWUkhdO?lDY65(-WmZ;fwnJx4ab)9lu@e0v+zU1%3+K_y6|E5TN`SX{FLQfP{u{5As z8g~qOag5y&5B=f8GKvLNc?qg(?}DA}FrW*HKPM8KAfEA7J?$_MA2b7xvpsq>3xS>s zGy+c>fIdEw1Pe6mT){+@*v!bKDyfcb`Rq1&Jlb4jC4@>6@}FV|SZ57vSoXBRk=HGT z&3huQinw{!5y;V)$Zqy-svkHE?B~r5=tTVR={^C&7d{B`D~vUd*t=W^U2Du9BY&N&8i&*yF8*(fj`@lsH*ub~M?S4_3JDU}ZHV90at`jZaU%rKzMtWFmPK=(a&Cq)uP7G|DG^de`=d!PDu4q8NTv^+ zrLNffgqMmaTm^iE3E9WgwN0YTJt&fZPqnNs?-9yljPo%&Z~IO{?7gutnk|gBP^Qjt_fY2VOfyT_Gz(%{L?U zb|y18ve&od*0Rk$(EZGm4&}u3#O1sr`M_x6-7!z{P(q*Io^e?L>TvsuO6W0Wmu;a| zzdSG#NLB7SVH6yMkr_(Bw(tT^vsVCQk)9zPP2lWD7V8sQOCb@Uh%sgpjrXX94osoc zh$8}pdetj_)vaN@L=zT-blc$fU7ptD5TSq_E#Pdi(9@VZ72}Jmtoi9@buY6NrBEg% ztcD1X=VtH|$vaTVlTntbztjoPdFK{{)+ArCRFx9Wx~r+uM|2udD0>S! zB?Bc{KAor7PWsYPHGFW4zJ#30J-vrpBDgS(_ErrS1}vtj?WkM712US)yd%-<`_@W# z!f9rkuL#gnY(63xtxiS`w!@cE`gJnAM-6y*Ils7IMxTohSbL+1x3!SxPqOF&-VIB| zcM``NRI>gS<85Eo;VT$Sa)WW|p{2gg4|JHgSILO`am+hR&JCP3@b2s0(*fB4YE9Yt zS48uPN2$ja39Agg$u_7BCi8Wj+FWbo5422ln#o8WwADy zXg{Fre3V&ir7b7cpK1YtO2j3e`?qLnsfkXNr7kf|e1mE!ebFu%9L7TJ`tg>cXQFi| zbX}cEza>nw+5=NVHAT;w{0?+OB2@`OZfwCh|B*t_h;0e>d z*=81X@#_#)&}BQq@Lu~XC6NH0BS)Bar`cc4IS9fIm2W(=mz^NvWw`7}ZwYSz$jgiw z4aWr3!N%DFXo5MqdRVk5#)9&^)Qm_I)MnnDTz}YK>m$IWV?Lp0U%JonrbEC^3b<~9 z=x_Sg_3HhdJGWh{E1(45Hzr0H#+_qjr7EFlH8O)*{Ws0lQQs)2{eL!n@J?>2n(=u( zvdP79w*!bY(`MhBaPKnnrwEW&KD@v8prfYZev6hC>PtW8Hn$3z3~1kyjClQWpFBHv zjG1Ijoo;G7C!=K&Fh_~(SJN{eHGI;4W+ua*?{7rBc@VnkzH!%!mm8m4fj3)tUYs9W zyI4_J>CnnbAAp$6+)E~I>ZoWGkG@n12?X|eS*n&)yCHq_kdoytGuT%8F-9A1|7j!RhWhZYul46qJlYEQ%FoS$A9^!?h(&3^7Q2UM!;_T-r_5l@llToQ z>g=G13&4J}6`n(#5M(v`_j9YMwOjqR!_4IgB*?IG2W=fk4uc^9m&z~rq0x|>No|wK zl#pm&du4(BvgD>%RHxSxSK7pwF!19p-YBJo!Q2a4mumU5lSaJF6kC4XT~fb*lt4D?uP(!O9`3Ku9NRy)5oOK!V-;~#ixCgN3BaHa9g{8*z4l}<{zvnuMLYRw))zkC4|wwu^z)~X$XW~FzfVeDCa0aX zZv*gU*@Lu{taa9|fnPl>YN*%RSp##YlJo#QtH_4jsd%{aV{8m$;?MyC!IXwlFu`3g`KO~|-CZT?gf;TVxAu>c z5XK+cL1oKz5)Q&EyRodyqg+_V3o>_fPoYQD>t`3}`jt6xCMKlhS^I?jN@$jaM^!r9 zriQ!Zyq(@2%W?Z(Y!oJckKf8ua~Tc#f(tm$-foLC$9xBWf;2VN2LXGf{rTSGsn5JS zO>#RmyP^eQkR6R5fz*6v>2L043x^K>;HGDAl}M8L+k-@2cCJtRzxKcV^Mbu=*=^Uk z6M9}U&YK{fpK%4;w)uqM=Oayyi8lU^Ft-?RJ(Y;F38Jpz{Cc5cjGp_#QFADDx)rzz z5|38#K9)Mzd8e=ccibQ4ijGVe?)G5fGjJ;k>%WJGqnInG2>1xkIO)V?P{_jl|8nT6 z+5}yqb50P*pQR;iY#(A~_$u%I(aJ4XTBnYlZCuiKM`r2_-174Y_}8 z!I&~2Py%-oXUivEpB3I(_j^R}UpG31*D?5#m953-;cE~NJC^q5dpFoqI#^eC8M&h4Y=1tpNx~!nmav*U1)?h}Vb95Vk-rEq>{>%HEEo52*!R z#L+(4ljRF5)-FkRN&fxA*fMoly1jCTzuvlcUCZfoUhtgamKPmdJMId=OC{hmbA?h3 zd0Kd{)DtDq7&G1s9WaHpZQ2%?!n=b(^#d;5vXow8+uc2{Z~yAm z({kaEp7}3MfBxf(t*H(!JNHij!N`Ahepwc)LdSLvE=*D9oLvp=^M)42-;i^;F2d$B z0sCj^y%V?lExJ9Hs?QyFm;7RRJjW2q?Q=YvoN_S#RQdO$x5Cgl!%TR%O)ee0HRBG< z3xCq}JEtJ(ImYsLOg@=&@%gkV=urvJm&zAhcA7%lsxv)GP71aUemx&HtaalnJ zCh~jlFG#D`1_aYSYR@(QFR!Q0{zu}wIp%ODN3rz5nST}^pLUtXl0gH%T=w;Jl}m8n zIaL$xCmhiOF3k9lUFXZxL}U|BRo`HM`fJD*6Ex+ZytVafqIutUWug$GKwd=*BpO+d;g>Ub# znw3}nvR72Z|GW3{k}|gKytZ#e5%hVCk<@a9hGm*!S~{}luc5dV36AO49@Cggz?kK- zSXZ|nc$TBYfB8zE`kM^cAJCObD~sy5&r1>FO6vg@PZ<{L5mb!8!*M>K#&I2l6J@`R zz=StpN>12$^0^i9g9$ZyDXSbLi~eyuDlQb3D_o%J^udcg3oVbK{0Z?QDq^EAK577O z^|!=A!Mo)L98?;BP&#hXHi;|wNEvjLVD)NECke-Glu5f-c(9`kmH-qWlB#h~27pD4)+zTN@T; zOY#wJ)(A`s{h-gQo0rr?=gJO1`8{57K4sbk6Gpj@9m{{1HtjgpdgWWLd%E|@CA4N2 zNr9(rMZqUsIzz%vD}Mql*|fPVw0w)Cy0*ZSc=Uf#n*J6|6=7TE$a@}8P-E9Np3j}C zdYQ!KfpL0mLfQDF{rIJ}lHIF>f+ro$)!v`C|5KW$pgpVJ*i>jJTg16(%rQK1a%;N< z4y@5-A0V59^EE9sMeyjNQnix<95D*Cg!w{>y^@rk5>i zjO`>{Lhn}!u}YY^8b&4?Fyy)#=80is!bykGr>Z*H3E$5iFesv`-q!nZ`kMvy%qTOh~L2>r)*Vhm8qsEr4{`ttD0Ln zqK&P^AjZ&~Fiyl-(1FQxJNF(cRq*nKN2i-g8yZwNn7MI&QXJ3;Xe8I6A%sz-OA38T z5-Zz$>wFJ)l6 zH>FpzJF3DUgZm3p6fP^AJHu7V?O(M4X zlxX%_*ve$I<8@!+W-j$tu#FZ?L?$j7ROy9nZ|!q?sDPV+k+5-`mn)6uK($@av%;R3 zdvA{U*b2W;VYP6?4bKzfX8(mMdsY-#GNau*bsV*qVoj28fzI90!UKCW>@{sp6`91Z zF_RdEy&Kt+o9=sNub<{E^9fw|Zxc63hi<5SU&T(jB62X7h#f6{liv^9cejOrKvauA z%M@RTVi-cO&al2>oo^6or&M7f^$K`>q){DvW6DkhBQ2b{PJntw6NL!LzIH&klRRM;wW*2YG>qYF8< zwlC)oczVU825-SxOx?8`GWE*~&Rx%ACwHS=;wQyFraF1`nUDRJ(3aoqQ@NnArExN; zbq&+E=K_MCZP7l*p{?@O$*#GEkfA=F-RZ#P_T|}~p7{FjmUf_%+wVq}wd6KbJ#T)- zf9o#3uU_5DLK$-t*Y3B!^Rs|(+c30Z8v>EV0$iFZX488L(BpYj5rwn;pfkB=rK>xP?N?7LNc|Eq<~+^A~Kc&T+cyO{1P?zDUE(7>iJ@Ds8w z+J!p}sjHiuJyG-I?4~|1q2|#IGZ6ZbG?DCA*+qw>(_ZIcytc#p{BMyD=mPEHka8pc z&ny3SqFT0Z(lI3Uq{%*hyR)+W>>s|)qi2f*5pc9v+z#-Ue4ZGnpZ%mW(Ic~}UG?99 zEMlQaGlUZMgf=w%qT}yX6z~{JcJzp=nfeQl@5S60-MSp;))C-Kr#deyh$7_KwdBQOFaEUR439NE?7?Ji^q2g`$IPCNyWn9;}X4HT>4uqK+n0=$rHEW$1XQOskDl~L4;I;c~ z9M^J44|ZDZ482x}d-+jlAgT3MSEUhEZYf)fj<-`9sz630SL|TQp#Rh-*OofqluE|B zXnZ(5lD6B6tfX%3>8#m<1t77-SthM6GHv%oe>yp|Rm}ztR;TCrZBD~9U?%*HS~p`r z!yK)zOzTz~5s!i>E8#9TdJof-?+CB{^LV>Xu7?oSzk@CW~TPY7zm0S zlWKj$nozSPOr{GqYTSo4VbAzmtYD)_<408xn+Z04A{Qm*_7fXy2qLbgk|YA(Y5o$i`+5JGenBlQ4 z?#9ao<~KL1vlwEc>X-35lYNPA-M~g#otsp98NXh2q5pI^!{;{rab{+vg-yNd|Iuu5 zwm?&)U|k@*(Mp77(fMY0-D$#IkN6sU8^dXQmY+}$OR?@8DK4ri%>HhdPg>@v=u4-zbTPh0x=Ecac(4p#LfC z|F0k!Q8F6+8N8-_-iPDWbT!BtCc^unEE#PhF+0VsZu3MJu&wr5npGe7!q;bIWrFk1 zI>Gdw71g?n$GwK3C<84U1;gWXp1$&8_h6;`c1-Gx`d?$d8LkqKXY9??#+u%m636#-u z8d{-;Lj^_3>J^Z|m#irYtogZ#p7(3kPFBAw0U>Yte2F7gCqQ-LrZ#(T{gRDkRI&lM zb}?vKiVl)jR3DS9`gVz(188Jc=qSw~D|9XI8t&~t_id(*n_)=OK_N=P$2whUH z^_N4NZ7|QEo394acIb7OE@2p;5^djB|JSdWQ{`?2hKu>~YNi}c4f}?%n72fEdu{Ix z%gzf+xl9M5#@`uw>=Wl*80CWLia=$N(yzBY>e3AZNYMz#!D?0L*D^t#j4ZP56xZ$- z$u!g6G5v6DgiTjK`J2Pq{45^?NVlbYwsMdTYRm z%ct)6&RcSLDFHbH+GD?jf7i^{HzGH4_&-BQF86kN&45>8iFA|HMNY`K5I5e9{ZUJI zBk2Ch$^r{xs+bmHx%ufion-?;*6i6)aHsjCb1kFHv{zA4jU~0KEt&hV19)PV`xbwY zqT?Gi2fxvINs+H8_)xsd>lQJ?N)Pzb?-X~j|9|`HF1S;C_yQG?Q4WV1Pn^)#xEVAw z6p3SL+4ps+Vhu-*pn@GVePysgzH6KwFQ#FDmf!BXJmtX_>-|+*{C=ER^hk?O8%fKk z46ps>UBN#@O{{?7FkHDrU9HwvB`&+L{2h~K?1Q$$Ywn5*EyOe#6f9@{RDAGrShvMe z*-1i^EOb{wlf~NQXM{GJ;ol1%e_GvItiE_)xN3z#dphnm?GC%FoT%S7VgRC^t{ugM zCVV_O3O${FNSrweX1sG;R*OVQVL-*AQ6jvyhN~W&p?ttR%{96#xTLNw51o$MG|H^X z@IxT-6ST1w5oA@alaD${;VD7dWwigNkW+zn!?WpvT59bPT570Xp+dwey<5KX5;Jo8 z)4p>zF6WN+4L@8Ow~tT@w6O_{4=+?Pbr-l+&Buv#bF0=m;Qg>jU74#QCX*T))%hx` z&cHR)8df~j=bBGv8W`Nw8W>P_FnQM|Eh0C4R!N+s@^?_#U41C@(}?WX*Hvei>E7$v zSgVG$vW9Lve&VcG+Ch-r4%gn(@ND@u1Bl1ToMB=`Ib(@~kL$f<2EA0M9-^5+lt~+E zWM*5LEMveody(mSD9ixGm#f#oRS=21y9>{JvnQWTLu@&D=9WTn%|+wkA9Q{{`_(Fr zFYUFt!|}Bf8^^4Rp(61Cq~c|5(FK*fT8gFA{3gb!jSh9COr>MXY1jVPcJh`cvK*eJ z*YKoZVJ#30Q@>inpFjaD&;^MJ57ifKDd0%I{Zc*QIDRtu8M91W^WzUw8upF3crPf} zT)krW*Zmg4*Fa+hR!7Joa?8=}V=E|wbt#A3i`?KS{z=#h)vkId~dgS#g7qW7D zFW6{9T%|sP)~fbpk9=7md*I%mhz66@OnqBZIknTpx+u}AbpUB#81`@foG*?2N^mhZ zr72wo60AYBE~zQY0Nzs&JFioudZ`sudrvCV`@#9+E^*I`V>C<`IsNb^KWu2-N8@}3 zd5VEnW`0@y^5P^6MFhjl5Gjba!K>soWhsci9LZ8?I5;dxA?)Wb*)k7uUcvg>R#h}X zI%WG-AM=>?dFQ^`I7}$e{N*|2V%C01G7C@93XLd5ds8^R2MvVi$uKzrt6Y13ukvZv zPo4{3|EL?IpHs@lwPfZK-CVTSSo;#_WS7AvsDnsu}%?_JGW8H4+POCuIv$d2+^vpsz}>(Uf$QVKCo23#%lNwpOM8zg-PCxV1P7J6n+@Ly6~Lgo`vUmu317>r`&vNmt)vrN;V|G?&gBv_qsnushhigT zoXWLXs+y1PJ5Ly4Z;R$o`{u)<*()un;j?umE33WQp~>S1*NLG>q!vHu-(QK5xfg?H zseaztJwR>OzX=SUJePCm_sk1%VC#xYhd!KO8}^4W9J6>% z7;nX_{Lr$OuOjXG4lRw-1#u@Y=&qJ8-@Yfh(p&u7aOu{EQnUu+MAQ z9`nf&7B5R2_<@Q?v(J<-mI+_p=J$ptQN74U0U)R1-eKKvJwqac?P_JE5|6U@tXi*`Hw$@M6P;e?-r^y(4*v3YdC;k- zKxJj@;vT4q{%wvP)~*ljR&bRSwyQHf9v*?1U|?@QZ|(=DG|5(}z?lnG}btUMA)a$ZEnLg@YLWLRcvY==WHuxxWk|De-Z1?vVN9%mY^ju+*u_E~#)x2w;5J5J-2IrXuA6e{cJcc?BdQh?6-way-h31P z)on{C1zcsRk$dDjkdRxQrPncj-!#@BEFXGcAJdACrX`iX+L z>j+~0J2yIHM!P97q-Q+^o0&tHAK-#rbQn?Pg< zITP-_RbjpFnj6C6|ME$c_sg(h*{!rMmtUT#ler{73`gZbTBZ$l8SbBFOELUe`;r^& zfzdx-m9?=?qn-NqF?N_43$cARE%#S~?~G}v4TdNWk5N{pfzXbZQLny_($$(c{{5Xq z;0P)Tw_TCQaYSfZQ=By9@XO4Xu3wG$h@ILM(b?F{fEm|3J55aOGMPsDIDd9pqfbIT zbyOhLRTJQhfT?g%us)CH-ND8~>5?ijXmGPS9jLhYpmJUJf~= znPHb&j25g`)Xi>-vHv|^>?8!TuR?iCVl1*LL~`KzVj{pyMqDzJ8(}j5egF=`=?q5# z;g2yx&a09n{uo_t+~!+%hj8^b`<>RWqQ$4^XDzdRL!%8wySEd*LzV`*)ZCE#@w=r| z(~Pgxy8C>)z4#onir3TWc~H!ay?&d!qC*q(`3H!GYv6U8{9Jl#;jZVC2oThV+gnqg zca3x$thKJ6eQUQYzjG@+&^IoS^?UG|!v4J8S`TJ9_UDIC9wzP<-%zp<3`> zjh&1OSn$)|`LNhp$#2N}v4G#bf634EtU737NB)zxAf9Y|LTKF! zPxG4PH58s!8M#L>?P9w^B3Eks+!a+@NAJT1#iiWmIJ0nyuJ$Lk2 z?r93w6pZVjLwR@K-xeiy73$y=v}%ymUBq`|Ml#H3=y3qsp~NKYZPwe{Q$@}xL&gT9 zg1INJGvk}gean=D-Gs9HTf--t0|$aOr*%PYto+rF!@k!vV2n1jThgYkq>YUtQ&axh zyX<-0mb*Q3Zck!=U3P1m*Zzd|L4*xf{k>J%Ge;b%?A*GE$1~2|zrAeFHFs**sys4C zb6%%8(4eSfH9%l8m42)+)5F?`-QVW?xM|%^a4`wJ`sU*4u1%7v8Kr#^S#&;-onmjq z3HotW0>g&a&BXA||2?EJ#?;%EZ5qylSWKYiEkB*c0b&y71b)gRRsz>Lql?E`swKf% zCAp|#@GC%-iyG%H0YS79o90yS>l$j+#v^F)?j@j`u2|w5!q>}upRS7I{M$>Z>f4KS z)`@G=b_(V>Cp9c@s4Sau@9Xb`01-;pe>NoU^HpI8b_-)C(sj_^O3vgxom}O3GVLL# zpZ>+BV^SJ9ov#kBu_0RNnGX5X4>s+mkRtwvg=RVdE1Ny3!4Nix$e z%dI3`d^s~MTBeLjiY`+^h&$XaS?`%PNf^YW(jHO{2oQ$F_s}kAv>smt@nYms@RZs^JG`~nglk0J z-7aPWSlGcO%cM{!&hD2|B~n|K-n|{3u8~qi$%q^aCTg)p+$k-IoIH%S0#;7AhYQl= zQACYq`;=&xpTKAh=+DD~suwC|50KD&ih}mUVMT_>)VB~Wv1J>dIRtgL8xmt96+w~qk7JVC+w1;|)VQXt?h#NGB^m?vo&?|AmlHB z=8`MpWk^&sBK``f1{Ff^-c8cYA>lEJx2zMeNf_&<(4LUiLWux(=|?FpFlB9542*?* z4FeNo+gn;i&ck<|<+PxMzb8a(y!7YA7uKR^BIgKx*Do-*mN`6a!)k z^faL(apzjO;FE4@%qqNVdOz6a!4EhWn*F_`xZ~RLpIzf!5X4y1C9^{=KL2mww6M)( z1a0>3AOIHV0~~8>HTjPrz)xcc4u z2c#0J9NsvO_s67!!j0y# zHk;ttEM(1Fl4PCKxxWYza#*tNxf6GmwByV8z^9)mRv8cWOcMvh3i^x8B>0sQ;r>tx zy$4;?_Se?`l`%{AS@>-CZYCdN`4divON!)`P=XO- zr+h!Rl6c5I;jW}ZpzrY^M;F*aC{3zpqiltd{%izbJldLhpa}K=b4~kJ0{qxIr9Y{N zXr{2v!Dky(!E!xkh`7%51p|O&dO++H>`ck2y6UgH*RZ&~I?wL&pDMwi=VIlb4)w)M z1BL{lK@+7E57cc8E!#Fl;!(sgLbM?8W$1B?lgH$4|63e6KHCGZ9=&`D`uv)me3BmT zNK3Ecc1zkoLkyDXQRIDitt^zCQ1uKcKce6kL1m%NY636Z;f+Cj6miDxlD?^k-0?jS z4|2i;`Nuau22f$xj+fc-!YlQwfn-n#r*(0fAWN)uZkzJX_aX`jx8_Tii`HCs1=SDc znRnoVv`}(!H`N8znb)&1;+DiMQ0;Q{AjzOS_XVyGB}WB!*MI7=a?W?oE4T z?c3tLw=tNIL`g&&1o}!d5JW=P$0O4d!oU+$GUWd3X>V%`AQ9lO7%NB=FILj+v+fe| z;_akEg(q=DhY}UoNpDom>%lz2P0v>E`*~bR7fRt)+`Mhbp9IWlsQ)+wDXs`xjpAx8s(Lhu*>kv#BG`_T6Qfq~eIB#8j)Kjqwf^x$_@I#jqbk5qXXU6b3x$G| zHpAW2n7tPJq4pTndx-c5FPfJn;Gn14~5gC67hZBJ(`x8lz9U`WT)=|!Y6 zG((8_;s1CE^|f#Qf*&qeKA>VqP#=#^zCx^5^=l(-$s`f5=-No~Z@aOORo`b00+E78i9*)PTh0kcMgnbUIP{?x# z=e7|qh;HZqy2Hj`N*eJ*WqHrX^Bi4#JF&IzZ~GKJoG1C{<@$q9P|Q$y@mm@OH9$6+ zF0%w2Cf z;nl^T?RRpe!m7IHM?GG`s!6!@ed-@4f!a^<;jMqGZ`wa`H&KM~G|)1m@j=c)wj8%^ z)U|g0(ft|Y1f%2Ye;WT{Az^phUqop=7(FdA@2Qd@>^6Jd?>pSZrKzmjmoWbPRZL7f zC`5(BY0R_^o&1F_aU69w!p|UO;IL=^&xlNE9RzHyQ8qO3uQUd52MhuqQej z%24;#T2e3#usU|dPlQfLHRoDh3!sVjYTw!`G)BmEF+$sJ&VFfUAB^K&!!qC2Pmv%Wszw zQ!iLu|9uEAnw)UCTW2qlgwp#r1T69S}WAMzvtS_;=doCm+nYacOtvD+2*SYCa1+--1&4ireh;M(iM zS5RKv=b- zNsYTS>3<_KFNMD&K}Z0OlV#ftzp5bJVb1SZ#yqljvF|_rI?<^w?^(znc~qAPU6h9?sN;`x zy{4wxG_3EhCYPD_l9=XR`xz6i=pXjv-llIITWo%O@-yzQZ773FiVMgC!^{Fcx+__~ zp4WLQbca`}S6aDlysMY7a{WgAlxUCnXHzaT^+wkZ-uF^m+&XRgrM34vhYS89=>m!Y zR)68!$5~25_**VsEptST)W4Iy%NMrXnQcChVOi?&8i&Fzdm>qminvir?iTSDsWAm7 z-?f5cMAPkj>wmHN;b_+e^Xb<8DV$v^%pY|WTP(4${sV$sx%XJIuvjXAO6O`!`Y_jbQ&i}ij#Kt=R2a4P${)|VDX6S|tSZe8fRg_V0s zqKqyUEBDGRrFjg{U@6HeJ?rq~l$^RH$S6AZB=G3^#)Ol%`VjYwAO$3!Gn{tri70^_ z0&UDy2$Bo(N{g-h+g~-NvRbp|Qg)>k_aDuRrwndyGA}JzwM-Q0n<`uzme5+EY@T~8 zsArA9Lamv)bis=349hUNl2YO<>ugoi-6u`QA8eb9eNI-7Z@GE0b?YuCl67f#jpC%y z94!W0dv-p}Ir%I?FwOkqo>A}7Fe#w24ZV!w@u1dH&od3qBST z%EV3C>74Yi^UrkBON_Aw6Bos8+OiKXE78tup@>=ZjBw|Agv{Fww4+6~Uh+{DuS0v# z?uR+kl{dxXcJfO-rQ)kbdeeJg}fV>b`OAG@MDr+yv;13h9+!{bU-AEhE>(; z8Wh*J`6z^|>Lct5x2H~XqfmBCR+LhZtl=J&-Oz+3FnMudrPQ|gP*<TGY1G(`{?} z$nHTDxY&nXF{lrfSCH$TbIGYPqeE=nE#a5Ys`QwHwyI8aW{sv~=Af1qDKEXCQbLJZ z%=SaYl_NXdm?p8Eli4ODog7%wB zt6sEFJwOw1x#yiJDk>5vcX*io+2!M21i9xZfBotVdS4zYWp*YxPDQ~8R%{!9VIjjo z5tr1b>)QX3?`S<+nW6#Z%oR>G_ncMf;?ylScvIsFPgMreM7HY{O48FXiLtTN#4 zKVtwQ*(kiC0iQqMToj%79*PzB^%d(6eCZS|Zt$Nt41O1X@Zm74w zV~^_gy+F^Sm4_JJKd;*Ood0jp4r(w?4#ywH^{tlB`Nydrg(-{uB|G#nMoP_E3K)x} zv@V1h8w-IS7T&Le4c6wPx^yMg84MO zSfCI^#|riiY=+V638HSY)uT6zdh-R&pY!Ie$}>t@e%o(>jmYNll%S#V!lA&AQ;9iZ zWD7`X`A93EM?EZ4#Zp|vBA1~kgtXqU^xT79o8zgEk$7F)&S?>o{A*hDP1gDA_fBD? z?5#hVYMurK(@8I08F4?#Q4p(C;`2G4jwUphvcG8}$;Sxx2M;cojDyIn^E0mLl+ z5judu+#nRoC~S`39e2a*qM>D>e>WURj1U+&RWjuR1+ga_f-h@Ysah28E$dpW-1}&| zI`(XoZ7C_|OB|)xFY=VEl)i12I`D&mPv&Z+R8=iIj?_;ko zcd*PqW3Lk=D_WSA)L$<_Xw&#zBwsFOvQr4=O=@ueU_EITKeQ%7tSZ}Ju6EE7vDYZ+ zbazm+7~tKdStT&3WVQ{@^~Z}c^qjx%g07I6?K47aydKmFHoT+_h1~D;X_;wdJq~%r zDms=XW6%B9V78KpE7VpEiPNETr8g)kZ&@{OQg9ll+<$S69{f0^kv1v*%ZvXc=XQ+q zqv2(dEeB3zMXo94!)0CBPIGcv6a4n{b-uQDc`o0%#AVJrK7~yZLC`TyP|OXDNC5O!@7QC*svdE4v99!oxKj% z&Mtbib<{Ipx3swFOJ)cN-uZ4=0z8N+@9Y~BL;-(_ zYnh7aej@i!-Q{0y$eM|)werWbMC5K(iEzEde&5;Rj@lQmNFq>~jiXTaOZyMsPq72# z2g!84`D#mD5uD~kx8j4-Qzd{W5>diWzIh=aKVp1$YI9J|u040UHKFZ-yX~gD@pccz%ev5{STGnc28-~10wy6fPu!}TwI z$<-Zv>t+g1yJ z$ei-x-(_7hXvPk$78+A9PeT;K>FiSotEC7G$UMv%(+IZy(!CyI5VhMpz-ToC?Fu0* zzc##cI`-nseh*<DJ(qY91q6Hu9$Q^AS#m9``Tg%e-hX{V*q2+0DiU9rjzr=9ltkyrhx6bd2lAIzJ z6zk_j8Av-SY%+YnN|Eh0C4avZD%6u&axvMO78?)?;i+5MEI>tyC zntOB$kV=KHa}b$pNC-^jhl?062DKe&B9dJ-aC9UhXzwAVjd;!qbLX*GTwp6{v-!_8 z|CrKxOlq4K)>CuJX1tjd*bHaODcf-SdLM_201i}GSST#=o>8}HZGcvg1zBTqOQFcd zT12l#5zI*8^AO>rvAL&WpIS;=FF9LW`POUQ)J=Nsx%oCJN;}pP`Ufq<8xi;e9>5ok zMe?~KYeKg>{OiohaGP+HpEJ#`>?srjPL5SniRFj{Yas;KV0qB*;>Ja|y+kf4zq3l1 zMP7)F_%3FgdG@qF`}>Uw;v=RoF19-R%%(*_P7pETi=kru)XK6ExmyO~g#XWu0c#Hj zbf)oBjpX>3Hru2jM^z6i6t?cZbM$G#^Abox#0}hC8yx4p{L8gKbg_W&1AujFvrU7- z$HK@~;|B`R=KfUJLdme!!d{{&a}==fW48Z1@VRWB`X%qq9NZ;cK+B_JXrKAUN(u#PL$GYug71ObxaXo4g3sYZcmoit+ z^}#qKDYF5xPITlPj$Cs_Ljgbat?SF$vmHr2H~Fkd9NH>^PotbKnU=3rWP7}z zv}Lex&Ad{`oFigX%bosfFAc`I(VjM>+EqKXggDtVCgtRX-aa!P*&a&TOdV=ca0Wbi z^x~BveVba)eetm&XL?UOfs-6*ereKzbQ{0@&69l|vHH7ywx2o!7s;0gM#h%`i74aS z2sH!CXl$0ossst79-ebYp1!*RtpUahD$#M&198(s6x{yIZHGKP%|dTqQ84!(z5OEX zgf&r4)>;|zY;SAR+l(|*Gq*q7P?NK;e2?L)^%YdM; z`M#)|{Z$X@aL5*q9x(`brJJfI)5v^Wke4B7HCj=tZNqQpvXzX9bWWR;Yx{>om*k#{ zr;uYzxcBbX(^t;6Q{URwp0hpk?Do*^EXj%+%Ql`{EjB{-WlDY>ah7hAzI0Paf+&G& zU3e>keazb?N5nB)ai9>8eo^I2Q8Oydekr#YSVJxNNFwm{i4h_?K-lS&0Y|kT4rMuV zo?=Lbh`+g+_B{`{jr^ff_7Z)s7FxI-qPIcxYOU}FAh>&Sppr8t`cju`Ie=LKCFRqP z&T@Hf>5Wz?09Z2wQW!a7FKk(qiJ+IT31yxG_m_eWjPxm7PJ7CNAv z)%-W5yq|M-yzM+Oraf(=RPK^GLg7rF+cgJtBt8QZBx2TCQf9W?bGp`U3|PAxXCG78 zic#j6oVHbD|2`9(G1A;Iq~Iep5$9^2?<{h(KO^Ugfh{Z|TWkNvPXXJkS9>`^niH;@ z9U%tB5i8F4Kdr56UJyC0V$*9It#V2@Z&O8nK$+3~`91iC-r^pi6+wIS9Yt#@=8r6| zfJN4An_LG_PMgAsKoc1_Q?er>8*KP5eeNeCs7WKopfDe^N&Ge7lXljQNk>Yy!q!E! zf)V(AP8nXBSF8@=u>(&?1#gTa1(tVp`T+Mii#NrH66!;bg;aZc7*U^q__#wqK}Jde zZaW4%Yk@=zJLT;jmW$YP9LaM=EPb(v4wUPGBdlzTz!Ay&5khWstd=rb0X8I}4xr4h zBU>)T&K!r}2}cVjd^!L0g8s2JyO)x)l}TSKcjI!wwg$>~V#T3g*~*D7?7jQXI~eNH zkJkVb+m!`PbxU!wCS$^^NPSr}6&BeJi!WW&&w*c^iX3A}F50ma!INSH^b*vsiI)F8-wHg4_9BV!a zvX+bJFPg~%#y{3xNQdRERz{?hNS$k~GH`ngYL`eKKnuUlxhB9qKp`NiPbLG?wLhDsB;^YF& zPHQ1y6y33wXlVoj!cuTA8ZRV-+h5fF`$9xcGYYF8n0?uEx$DsP8$Y>oJ2^}JhR6xZ z(op&<0GB$_Y>gLh(>8j)J&(-*hZWRW`4&D}qz!WM2lPNKxj;^|^8ngGySozIavm~69 z0?z(2dG3K<&eSYQbRCqr%&h5d(TXxPIT>HHNk4puBwHMo@%6)EXla0{&ZbFWd$Dc{ zgG={Czs!oE&48$h&0Bm&u3zj+St2469j}ybXb9zOeQQb6+O_Ms?nZ}dxzHW7v?<{{ zIn}~MT9keTUi^Zor38!2`=lI^oW>Y&$U`~k2$I!Ip@!SxO3yXWc|o})nD}DhWN&nt@1f|D z3x%KG2YB`|R`P!MkZK%X)t&-nMGO1-4>2qmeA++HJnmiHE#Ce1eMt;lsrY?uXw&D{ zd$3jK^VyarbPv;dNlTB6tL+K0U}+qgRGX8xXO8xH&US(#d6rxEl%z6-jZNU%?HXNw?nV7S?{-v4Ff5MJ8OPN*0enl_p$j*(#rn#^e|oWCzY!hA1SW}3x0;S zWb96ffQVUA$|KvHf^F_pcuqOfRRRgf@rG$S!Ybn3DFrWkC#k!DkI5pTh~xVk(U;jj zLZam5-y)J{!d577HI81R`{5cgOD4zk)Ya&z!BS4&X(n@yBmYkZwZVjYyNeI<7JCiy zcSU*VMl0u=*&nU->;3xAlklE0-L<&OBuPvZd=anoyFjZQjEi!sQ+r=fAMBD$gt%0a z9C2+|@@ZDBvrkXqq1~YSg=#-@^FY@T4=;Xd%rY|o_airT+!7cs{OlS!iW{ZyjIox6 zx#enkk#(+%34vDTE0k03YPBH1fQOQ&7AcLU3CM)OL|;{Yh_Auhg?ph z2#p#nq;B)SN_Zvq9kL8S*4RGwg=zH*{5*T02$(NhuwV{d zjm{&F3QrBXXz@woZ}2^T-BoUUoq5cm^82+|aPpw!s+qoU58&lJ63yh=p|ObNvjj;G zg=Da}!qH8v+hap!H3N$PmPzX5DXC5H(hpTgkr9+SfH?UJ6B)FJ?o7EUIq-vA#8QZm$cr+HZz%Zn*iaAZjY=yEn$=E|^pgvs zV)nu$MVZ|Pm0&Iapu)IQ(4n~8L;Pz#) zcB7kPiyh+K`LzHB+eAD3*Mbc;;(4~uK@k`u4g+2QBs&L^a;a0EiF>RmKp=BDOxxF> zoD!c~-M<{zKCUEt%j+ePn9_V{O=A?%ZA2$3h|zLLH?CCL(!|!6!Qnw;ZxsOq@I$zf zY--RB=Xe~NmlG?Ei)53_GqG4__QO`&bS1)gBckhk%nAfdPqFa_ z@-S*mA!=A3RB_*Fr2!eba$*)1|B+KSfDIvvVs!hf#`zw@BOPWIqkv^qs(wOM!Nc9$ zJWStL2wnc??igTkuOcm`xC66T{81eysfK(WR67Gk5d7nePZEXyo9yJ+bqh;JD2_Cx z%bkXn`6cE|V&P!*crxe#)843Y>brMDl3f(jXJn#kgiBiqFDF3;F~%(xtQB$O`L z{K}9vwg5<6`qs?s5|>&dht?HQ?Ya2DkRxNXKuws}#I4G}@0g&tibc^H8QF!W;uCck z0_4-T3~B|laiy@OJWW(6wGC=Jv-|@0+^DmqoOPoePapMGSgHmgCq zDHG0-vPe6){5MWuh9wSR((e5ZBtDeYYn{L3UQg2Blzgnq+E=ecm`_<9{n9yYfGH{- zSUx)n=lHY8L9=cb&crZBRREZhZ-fITu#IDyGFAdk@snMeTOp^(T1C`=D0t;MCA6hb z#6Am?J%Z&_d$p2zC`)Dk39X88dF?=xNPR|YKm8ZcvoK~+LL+Fg~-*_DPs>uyTR=>tObDsI%VU#KzqZ)_HOo_|$xR8c5TLx~o zTCT7t=+pQ;d?xGKz1%O1GywSjmB1_C1%|pXV|A=~icLxXY^46N0K%0e1KdrkjY$@%*4+_A%PCL+iliiAWtzeHi&3?Eb6^Ta9ff< zjPh;N&?$1dxd<%F;iSqqI12jZ*^qq6E6Cvn4p%SpHgz#S`mFL(fQ1H-Y%rs68IwBJ zWM0Z*^N~4cGPZ{layMupdl^fj6}R;giq)wIq+QLsWnN96POeyRgXlT?le0hF34CtU*bYwkcF zP%1qKo~D7*MF|n2n&SwGkPdTmAPLGI$|2clQgg9@1WKB91u=?W_2tUh)l`f zm)0Y3*ZZ9Z`>bziJrlS$2sc=>FVeAcR6`2GpbPJi2qW+_MtMc<@_KG|O%EXe%m8&{ zIW(bZ*(ag~qEypQh)xb|O3>sIU!T+i$9#O4fIUS+%hOE(CNy6{+T~<6S>*$z%gweV zlHw!C_e^p$)(_yc@Msq>{FPMne@ex!ZjhcTtpXf z;AH}Sn}e?IfZn0(l0erojhdU2^ZbjXaH_MV56exnmeaBZH^DvHWJky>{#IbB0?ts( z#f{c+I_3pzZHfzPJ5-%;?r_KRxF}0E9}#J~$?WH&Yi(uh16b{#fg_WX-YyFYTeAH&&t%a|MT7K>)x{MZl zXkk)xlq#9$cN5g6rD1Z`8oIgkAT+%91jUDa4I@oKVH+I+WQZ8$Q<|Z9*m=qnJ`Rx2 zPOwuJ_lAU%(hR>OANr#DO^px6NNxp}V7 zm@{lFZb~?k*{T~DV2P}fM)G~KPOW&y+I*V2MMMaOu-XL2YT<83EPJutFMTZk{n%)B zh;=-QHHw`h9|n{5I(kzL^S_tt&*4#Yl$u9?iUxAudxZ2ALX3=w9FoukaZrZr-uiNg z@df~ys5ZjD^odw zV-PTKK_Xzj!+ib(qRe?6qU;1~9C z5tkp#vu8E_c68NhclhJO4GcnJG@32?FQxn)qRz+Tbx^|}UFEl!K{BvH%l`c|YhMjt z|0wN-fMsbytW6Lh?p{Z0tqo~rjm%m=_6{8UWMHk&-(k(&e9n|I6nJ)bN{CyAS+N!g zop+FVOy`bsmJ1vhrzO4UB`b(Fi%ZItQKsnVYyeXv=jtAsg@+ZSdhjU}j+Jab6DR#! zk4*WMRU$)FGQ{?SYaC|1_Vg99ba5zPPqct;(Owg>;}QlP;zH}R)pv4OrvOVV0hY1^ zzKnM9*eZzz5?fRqdnhL4?Vlf+F(2wCwT~@yxTI(5AV66D!5>9Kxt+7{vcQ`34ww0V~bLc+_t|g*3pkW_t z1D5}NLnY7jzv(EV#GnYA&o{w8?K7Y0!(o^>Gjx2u5xQN*y`lx4I;0e3iX|tDommXy z(C1qZsneHC`UmWMH3DZDnQ|G+;WaC`l^4_O>Kp1$=(FM2y=!IMi#a3$louw%jqpI2 z478t*6za%tP-?kx3XpFG+`)1PBoni@nverB%H_;ubP?6wz_<>x=8I_3lG@#&A+ij! zzNcoYfzh8Aj#VnmxTu{?exg`(Z95Z@NZOwsWM1LA!VA4WpNf6QP52}OON|EZW3xD0 z<`pfRZTIL{r#tx!GZu#}8n}1%sk^|DQzosyoU#uH^xTF1CgAM&m#vN!a*;pP1ii9T zGQqCrA)LqmEZk90e*Du_FIwa`*HaEwE^4g0OJbxx5v_i;W(ZL1lzs`SOOumedo&kb z;=ZD&nGz^NIh0hAg2|X2;g`28@VRpK<756r7T<*XhKW+qPeozujKTJ$;-RYJzE8&N7a?hR%j_A`2cx;_ez&m)^EH%}1ZWGmtWPG5*-P;G=z(p=_;eJ^)G+rM zpeY(~9rOUel*wuM%ckF@Pf3k@YRpq>l)YNR)S{qP_h!?o5P(5J2I!?fTcW)=*Ae=j zzSv~pI>f6OLs^r?FbTLyXw^wvNcXtH>6U#L@y^rS{$8Cu`!R38KnXQ5p`3kxDXeD6 zsTcO~XK2huPXu-t2O7Gbm)z43JE~8% zlyFVq>jY*izs2kiKNlKK$UG}AC;65ruMQd|(eC70MaYiYlcxw(WL;S1gP8IXG3$e=RS{Drsh=t5`B~fALoMbGAAl5a zDkE0&op5engAE+wpOm|6K`BZ8eYsnGPPp8X8yP4abXfKqs;EvYHjjjui!>c&cEK}G zA4^!>h+cI2!3UVrXEFEe;gk3#@~Vn+HIWd^%}6@oH2REhwQQnfc&N-AFX6ZL7f$~z zxzM<$@jLx(LtqOXZEvqx{+u_>|5G+c&eLWY1{Glw^72Lzm9|aumRav?O+tmbWsz8LiraF>=oOOw$={ i%(-FCsGKhFSL9Z`zT%yLv*}Ig#m4TD=I2~4nEii4>z2m= literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/blue-illo-waves.gif b/public/images/skins/textures/tiles/blue-illo-waves.gif new file mode 100755 index 0000000000000000000000000000000000000000..e49e22b0ea32ab2edcf838d90c5746ac237baa2c GIT binary patch literal 289613 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ℑFG%UH5R~8@7gU#jPtuK)kG**Y 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�rrw3cqI^bTKJo4p%-QT26T}J$+;$Ho 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

      keMpMJKzOsM)+B(5` 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 it*V;_-cvRczp$_X literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/blue-metal-grid.jpg b/public/images/skins/textures/tiles/blue-metal-grid.jpg new file mode 100755 index 0000000000000000000000000000000000000000..52e7905dba1c09307585268f2524fce2c24c4959 GIT binary patch literal 24353 zcma%?byOQ&)b2yE;@)B*Sc`jcE3U=eA-KCcElzMPR@^D>R$Ph(cLK%T{qla_TKE2Y zPgd5-oJ?j;CVTci=l48$U3lF9V9QF%NCM#A0RX0N55VgY07u*nY~uxh10VnZ0D-rz z69A@&se_3bz_k0V2kvzl@Ew4JfPjFAfP{#Mgo5<;M0<~f^d1cz6%`E?6&)M>e;PJA zCKfgpCORG-K0Y2EDG3P)Dd_(;IAmmG40H@aY-~be0vrP3|NF-O?~B)N0M2{3w^72w z;Q-#@z`^6dz4ig(0B_s>wYP!(Z-YlbM0y7YK>nZJ|JVKYJpk|E5wHR8-oe4YLqLQ> zc#ntxhxm3O;1O^D6o_oNBFdC_#_Xc_NKQfVDpbE}dQ3RPs0q%df>pmbCxAa~=DCQg zeZcweRPX-xl>d8hI2@686l}^)#<;)YgI<>a=Y6}}d9XzGs*`D4fo zxD)%8?67IUqb=_7wcL-7OIK?P=K)#K*9WO|x+x9K8ECBBwsFlAN%uJA3iM8yG5oZa z7h5t$o^$j!AsjNQzY~bR&|rW{ZfQ<>X79SBoqg@9==ZDHq7jTe;mIwnIH7&dB;zw3 zCE2f}jr}--zlbOm2)DMwCnN5+0zO~6$1`;?*;>mxirlL`q=C5`GsTAaDesK`r6uq8KQ*bljTAsngY!XGk) znGW+H-@N{W2uj*l5*@vl_ATg-X-bAF~)4N;P1+?SlFMTZ^k+sfO zc^9cnhEg6L;i)414-8JES-gAIh@=6XHGL8nzm@0r8;NnssM=foA;qy0=D;qe4! zt4xSY?8lGrIvr8$)A-yJ%B)jTTBXc;wQs^~Rk-+rX#sRXJOfL_fIgo#Nbis}mesHZ zY;>UFP&bh=eioP8Rs(*QyyXuCay=%j(^WU}o9I($VOfesVcDt93VfsV4g%L24WEY} z$Kg^K#;DWn{$TIr$v5d|{L?@K9Vy-`m`C8V@|~L=Sz%^xyV@E!vSIK7cdl+fnbkPi z1ER)Xp6@5y>nPd49L4IrQmB15w^cQme2S~~TY64H=?K^D_}JI|obb!Z`PxK2T=!uhmOf=&YCfgOi15=vp1MER zJi)NKfCuy1=mx4@>4|yO1|kY8aO@15t#Kb}7w2TbR_dR>4m)*9C2mN%`S+C&Ta1AL zy*wYioB^YU1gNx7IG|hYkH5uBB+j`ws{XrI*nuJ1?G;eJ3xxIlyBzhe6Y%tY1;i`_ z$`F){xkx%XiXd;jUx*PRn0lYHZ1r|e3`IdMp(TVwLOj#7uK5jo?LBi1JeR8i#SJb` z4A44Xz-*qZ*F9?8SdGf*k;Ji;=_`OWqz&;wDsC2|+RGbh)kq1B+UM8ho#huy?u^GW zs~#8Jt>7j*8|K2Dg1+cloCCH1{D20J0}D0>0{)E6>a&#)wc3v>$5`k?JzE(xtDj;9 z#-sUgiuA84Cal{HnRMf}Gy}KaM-TKjFMD1~P?6Tl`+^fk_wAk(Ag&V-;a31Zd?}uX z7<(q`-PPRpuwU8U;or(7Rao;>>)cBKbi(MCy+zI0qIA32Gn9p%Y89!bi$bWF94o$o ze5Hr-&L2HTXV(i1Ta0nM>)g-LuW>1nB=Q+?X`jP8bb5j_0O1#(_-3)Izbw13n z@GzUVv&!{3pMQDME2xiWMu;1cM3}^zYV}}|A_2Wa6Y^2n-DI};o*I+oCn|f1<(%Ai z|2g`~cxPK=1*o#uNf1Ez6pS2xmYI~5WGiGd{uOKh-YU3)h(XR@0h-xzyf&3vDchUX zCWclp%cE``x`(HYr(PZNOjuqAu8*aGDy2sVIUp{dEO84dAIqn~X7JTN!cv?Jek*6M6`{pk`c`563ghwi( z;X8A!*t%Jd5fx;ko)3QcYmD!n--$*K02nUDG)P#h=b0KC56h1As8H0z#r`Y~Jf9v$ z)A*G2r_MGzN#uh5p7snHqf}__#$0F=jE&xCDp&%ypWvMc3Gve@m>o$ulrQ4Z8j1Jz z-w5v9O@Hs9y!oqsTsOiCv|iQOSs`#0JbN}}N zOiExyuAZg+nZyGloJw7VZunHSsAzlbvWh@I5Pfyf$e%Bx^aFi;c-@K-dE#fpfnYF z>HaNW@7&BlgxqU-r!YgDF6FX_v-WoMqV0y&K+hrMdb`92Pb)l=hO!TouGQv>tu=vu z-I%g*01Qa;K#7l-v!QHKSLVBV@(Q+F@5P^eUM%U)OPJecrrADo@^gfpm@oR?06q*x zok?g$yK+I3;X;83t-rai5q2bB*3;l&Sp(8-ZU@NM&9AkJ-$cW$vDcZ? zDasaZqc3v_GIvPkIk&BA$-9i+qPH=AH*RwTAYToHl+G>MYQ6Ik%y4A!9TRfdzzJwy z(w1-YtKxYd%mY)Z$-7cB2n?_~hnANmO-ZfjBB)8i*ZWR48T3!|mYzXFy6h?^vil=B z|4_@-mO%o&aw4FdQei5cD+wd?vnR)1D`Zo#fe1CvNN%bhw;Bdkoa_0Q2!|ED6=mW= z+P<&Xd%bf@8NSeC(iQ9yyei zMJ<3Q{%Xh%ioJ52WOB}9M->Z3j)bo8J!+m9BHNrF(U_9y-jmQSX2v4E%#>rceKd_9 zL8mq{1M4S$Jp)x||57}c6Lx)WW zWDc`|I6ArXvLpGh@aDynD}S7v&$5UX$sep}he&a6I?0OSec zgiLpES%QAnDA&6Z9un|${>=e@wpRH(qt5S(;RM2s_!;=T*ud$39?`)(`FM+>$|9EF zJyQpOujrE-Zu^ga9gZ9|2l%_W%1zcmlh%f_<3c0R0u?orfq@rngN_rEe2EVjYQ34M zpJdH$Ev0CKAh=$g9>;_y$Jg%Lcc#aAWb<1Rk?O}~5jCW_LF>_EGh42;GmduNvgNm2 z8WT-v`R?$|lFdqlkPgm_{keT1)ucb2f($5>=E%rZ@35i*B-4qG7vr|8Ia{KR69CJ( z@J9LSSY^{=AUCer5JdHHV##y$X90ymL+6jt6-oeXJ7SiRsCiW3rf;~GT*m?h%p(!; zq;eOzLWY-9R>4l~>QPzKx9{otoCI6gas1)?)9z^3wPUn8WDXFOm3SlAvyZ|s7~tD} zJV^EGnu$2W4e_2$s-8FoLkDC&nZ>>=kXUTFQK~xqo_B^UgmRuHeC0mA0O7h5YyJLy z`PW`Py255(1WJGJ-|3x9jOtYOc#DGlPLwh}ofLfo#KKW3dUNvED#+*q&yDoFneul2 z!!>~d-4d;MsCv1s@7N;mU@%-8P?kl?IqUkg1QJJaj4SJWVPtZb%_eOp@6DHbz4B8;NTTN^(hnr3>M|5jByt?{6uEa zcg^?X!XmP2=EJG6N|FVKcAU57=0DvH?pd{{8udaeVtXF;d5vRTYWH+UB&{Mv%aidh zHeP2T-@d34#O=W2BsM8Bx=jxcY;?Xzr1S?*8sP_V5mEKs?af`PdZ8xMt*K|47Z6%} z^^r?(Byg>>kL}s!1s)wc&_Z0ym<>C`0O$n^9CYS1|`By6qChMA>(a<{(@#|$GJ1p!41g-J^p zBL}hnbW96j?d3as;J3o*Ka65&EUg{rh?+tD6#)Q~`MHsotH*Rf72a2%5R!Z}?y`Ob zSe;FUNt6zhmu3$iRka)gi8Vm7|MkvB$?Mg9nuAo(mlJQQ;4fnPBB!4VD#Vvx-9Z+p zqBp`MPmG@H#c#XnZ{J`6QnJl(j2m^A7YX<`pURS7*Tg5mHCmX^c65Ipm;PxfZAVr zBprF2O!i&*qU@d)n(=<>P(5nN*8-lz(*afr+Sr@krLGaxWt;nlj|7``kkvk1C3LA3 zR#?f=41JieUzpdX{U*7py@n<|r5$TUWxOO6N(kiRz-4yQG+ra|+ZU&- zBuxKa@Q8g%M}qe}I}rgLE$3e9HP$2qmLZEv?3HoSKU9;P<+ORfOyC{&KFV3p0K4_zeN&*Kb9 z#!~U37<8G*)wEP@9yB;Y-gx^$VC}|%B18L(KTht&Tjq)lO(@5nI|%GKTL{;xXEUcG zD`!!|j$5n$ygs`}Iasr^#ng1}%5m~QAz2BhCrp+R23J=p&IRAm-H8UWED%0eG;oYe z3?yXwWY5vK}Sf zSZvs+`UESU+R%?@HaCA2D=Bs_-tJ%EMG8cs&t!j<$D?}y4)`@*P`ls9=Pjd;pkGxg zrRZqB0^(UwRhw;`77T>s;7Y^8N=!H-Mu!(M)$!f)u2DM;FZtpw^qO41$9QAof#|U|l}o?0b7NqU z;o2Z~YOLHu!>AsvGzx@P)`_sl=`P{Q=6}v&QK5dMl^!5t^)NUxt&%1~)^6+7y#`&_ z6F*@~nY(N64X2d4f51X7&om?TyuCC+)b<}H4f<$RP<_(_enTOHm^T{*B! zAoSP6O^k`DN}o|on7)$EtW&^|hWg!_q_X5aT=QdPj){Ei*$(fE_IOXt@;}KsyO?3d zuRC+n1vdpMDU`wtUZ6wb8G_P{R{(YCglcT$?q{6U7!4ue^rVvl+uw^c|Dulw#t&ip z`%xTYu31g}4Bp9QbHs(skqTjr68xkw*2*Rlkk8u{-K~Z8CmZFLz?#IzFVRdN35c~_ zIMNQja!{vTgFYFaa^-F}REfGp;{5oQr$qsM+4^@mx(7Bl_1)cG!%PLI z$~>O84L+IYp7U88o!{UKXY$~P**?jg_iwE1I=irb^ZPq!;DGQoh|PF|t(oSN^xQ&~ z=ZQ+;Lvi%Zj@us?WE)evto0ddHUoK2Y6j{VlGFQOQn=h;OH3L_XZ-#c+-x==g8U1e z4+Nx|Sux$>8Rbny!jh^eNFmzVL;CI3aHJZ5vGg`fvs}1%A=p7_eB|}q+N00r-cRX=8551|`lvcs-=s)8%`lH-)qkupLl}jpq zt7sA#sh@v(&|gE;UIEN%d!x@_WKDymitaAbrzEB1a(!iC63glpQEw!8G(IosoM|pT zTYYL(+z>9ivr2%vCib?q&!gjw&{$&ip%-FM^(6&jOB+z+gP=U#Xn z^Pc9tJ26_=y`+HeN%#ErS0-#k#UeAk-@t`yfFoaw`7-h09KlmmY=eSfV{QKGS7JKs zP>8s3+)yt?a+oOBEOXRWTK?G74qfkn%LTh%nUAl>=kir*`29#D?gY5aYno80Vo8gl zrpTY8PNcDTw!LPeZM2>RZ&%2~DLH|ggpYMkGTmc_%c3#yeB9RgdUMkYLKX>Z?Y;My+gkZnx0Iz_9Bj6+Va8Shh zvh72_k4}VrP`^Jr%5h0GyZbjH`kuxf605Rr9N=?0@lwXxpV;vA2yyv>3QL^TXYA+B z5=$y)*M;hrj;X zvPWFg9fdDOUng6=Ve0BeFyT-m`l2*vF23Spx zRH8I{eM*FES77pa0HLR>U^KidS^6gbN;L&hXde|DK`%o{ zvzeo8ZG1ENp~`6yODx!t^oc>)(_Wiw9eqsumx|!h$+FLEdZz{%-9;1RF?w`1cZDV$)xvmS!VM1GDi`chP zDqLXes%17Y=yDDLp%_LY%_@IJxPHFpsuB%(`fcrOG=+vY-t}QEN~b5#vMB0A5!P z_-tkfY{=lnq$~C+99alNbYJNCm4$`<(@u$h13j&|?MdsxtjcYoeGiiX2l_WOH!M4{ z+n)D(2Hq#iW1dGDlw`aFfo5jLQ1&?2e)T(l9fsu1jeBhb*V$3k-`yXosUShI_sk2Y zhFEEy+v95YJwMkWltbsdH&vpJrr&-`X7PsV9N+78EFv`i{FjFA0sbWnRAJDk@;HWV zagrZGVJ8u^{cd#5dm9oMiHnHesirl+`%*wbQ!Gf76PR=K{I*m-q2b_IV_OPWjQm*0 z4>QLfEEGHSuY5HxQ<2@Lbg)6ruW+}-mmf{eUZ(I}<`3gX}15zA=2C3_*H5{xh zhtaWm?Kr<#^XzcOKK#@DFg~CVVxMmCqmysc$p}}ImqIZtG&C?aWs9cv$!!=JG$PeO zQ~w+6*QFJ1JxK3(?$c_GBGGZXOxL&E>_qb_?MYvw zSA98&?#)F0G%!XI^)ISWM&!{(R>rz6>$zVcIySHti)jGn{1ywJ&7SPJy(p5fyeY-l z8%16&vcH2c_zDEo?HK7W(wCetKYTWB{t7_LAq6Y@eKDo$9)I*Yka_ACZjO*%gqoo& z!wNJ>S=bZb>Vnz!Vgbz2@3*5tUCl%boKS8j3*lmy{*?vC(s}{!3DPS7&C4hii!}06 zu`|^wM!4=y!sm0<9VifjS?Z=8>ZxGR)kK3g9DDUai#3s~`SSomiQ@D!3Uc^eP}#HU zE~=*I$VF+S9(U7kvzOm)q^PaL@rWs4YRiCxiP^6UEJslEs0enZC{^NXxHadFqlE`$ zXMRY2b^Z>+8nsHuVmVeGF9=DSW42(hz@i&72dKgXAD2f{dXzZ%pmmKbtynlLz-hY4 zt2E=(lb(X@=Qy;!t4Z@qSmnxi-WOY|36GbV%Rp%0g9xVwqxJGvaTjuvj?qjIM$djl zuY!|664D2l7eHvl0<#u2kKTNIi~kD1Qn)?`;Z$O6WoCZj(g=1&7;#$bYU9(uVk+m{ zc(=0EEBTJP&$taAQ099cgG(aQYu(>_@+C?q+5%VM5&fPe3KU2*JyGX)K|mcpm+PX< znx`#fK~)akNA9-d(@f1}qUj)damG^M9=d=Ahh#vWY40Fl*XS~hZNd-Pxfr2DL{=1o zYG)6=5t;p6DqhUY>m*L)ioxAT5H((inlNL06EvC+s5Fbo5hv$16S_^URyDDzF_!ZR zAk#STX$@aL1T`sMDgFS3)|(};cO+1d$Ic91%>?UAo!9BUpKuEKn_1s&lnLOzJN{KF zyVPteZHoJ-B)K7DlvV3(gq|W?l;T&Sw7uJ5`-#h;A%uR0r&qe*so$eV2%bjF`5x_} z>a#Wu6UA6OqyRj#Q^q`*iZe3P^3BsgU)`!AYf>NWX{ktx4CXE68V_^M25JtaxDc(; z3hcrJQa_qjq`9Jg3fY z!*&hZDvlU3y8az$jomZ9$h8H*v zRyjmm=nWlu-*OuKIZf5Ktq1=R#OqFgH(P` zm??IEt`@i&+uFhAP@LI`oF0*LC|;Fe_Pj&0vyywXZCU=lIuI$Zw09OqvhjGtdP)$9 zzaT00{S4J@Vo<5f)pe&%4#n!tZ`6h@;O_z5R!OwkZMz_IAu)hu+;Rbv)1jH*tY88p zTks91$2+TF3K@J}VA5*pKz&yJ23fnJ$#trW1-6Gq^IbQGjfzncq;M=rrKI>)sNQat zA(jgM346b5f{zaO_~naa-`L2U?L)a~1zSi672LB}-@Y01YRgem1*C5;>W!qM<|}g! zsAOpUjrc@R@~ccLRU4{e;Tm|hrqxjc4k%ruS2jAdzX;Isk<~%x+<#(U%=08{r4xZ295?1`9Q%e>y zilLOlw-K=x-dRYJ9m%E6{-g#d3;6owi_UeNBA88D(;V%Rcfd#LCW~qT} z8HhXEX~~7;a5+*p+$H@hKijEjELl*axix_^i3Xxa53er`tnC-bBc*iL-tbAB$( zAh8%kF;UA{;pPO{nE0p<#{VS5mt4`YJhPa{&MKG>z(|%lE14eYLSn! zl{G+<9%cr~^v&HG-#(={Mfc)7xP&Oe7PTC`?#n+G**4$RPQXh>WWXnMQHdH$91WqG zUBs0uk%zk+Cbo>AVZ)Tw(4_2UviPN6l5b2JuEalLU^0BbZi(oJ0!0WlkuC@`Qa~XX z^vPWg&$P)2K*#Wg%_Bp)F(~B1iU|XCw?PZJ#SNs)24eF#RZM}Z^NAC0qK3WTUiq`&if*{O6(pB4hBlXL)!L{ZJ;%z^o%m6>_@e(g3aA;d_Nd5 z0=uGf@3<240tcFTgxp_WJE8mg#@u4B4N-aOV~=F6NgkDN zuxZaL04H$5Jm9;<_0+>WENVR#nkCq1uuN{z;!btr86$6ZNsJ*`UVWU5Y^>z`w(~&$;T(T0w2%qtaA!{{DEt?GcZfLpd2XMZ)rsDQ82A0;kcxxGI9<_8p{}*_=b88~HA=I`Im%Gw!9(w^h_Uv3V`(_kxs6nT z9l6E?QsN>T`O>Q#gLceLxS zP?XDkD6K5dzVzirjWu^K{3065XuWT`-C_DltQI-`e#J|^Z`k;A4Tq~PDqZp~640)%au z)S64l`=uCGiXmB;8ouD=zf@rRLB>CC4Kp-gsW4nPgG}E4;TeP3L@1qd#Z%nPi zo5Y@lz?C4q7^ru<8Dil_PDk!@QBp&vH5F^h^XEihVEe#eZ2rlaKV>UuTUK3AmT@@# zV=JW>F6HA*>dg?*l#lT%fbWO<_8c{Keb6*HrS`|2<8P@=n}r!SsLB$k+Knw5yw%9j zfxzJl#n=<5ywlZYwc*KeiFq8JPRlY?ar2ri)+sbh=Z4qD|GZbc8B@)!aZ}wF-`Zel zrxM{Bhe*wx^@NO&c(e*3DMEfjH>Sy zfQp6p*g(T|A~U2LLHf4hU=5FCEo-?~ml7%ERIgNr5L6O#cVd}D8+l=1$Pw@?XQDS! zZ{2$#qAg$yu2MC&e-BB@+?`xp;Ntgv^giUaC@Rb@;VRdvM0V+ZQFQcl_$|u0@>PPJxH~ z?tNwqd_l3o?9IG{hm~$^oY|Kc{%rR&A8ld{KshG@o+G_>Qht%l-e11vs7W2h-c&uiEEzhv zwJROXrp7jWLc#LQTAduvF8LQ8s3LA$qoIdWDOWyiH%=ypXKqE9%d3@Y!~xBsLK&5< z)Yjjbs3F6$eE8Ypatoh(Gw~{g#ih~oGgEy;9GIzE=|8$Xl-(i!?NZgd)AI>_t zpn}TBE&6^jx&8gJ&Y`=lMO*d2n?nmtL5L;|0}Rol#shQA5YgOQluI29N52AQLZBU9 zk?s@t^Az|iW>W;+F{JtHh4#SB8a&_V3S`Lvtnl;wGJVZIYHBtH+d4L5xSvfl5UJ@C zE8lZ-V-ZP94nZUWQS3L-lyH~E~k|!kH#XV-DL|C_6u;3s+cA^2)yNrP8`u`vEO|6 zpviL}J~Brwkt!L*P+GGzTN@W~GfoIJgfFK-RmIKUK;f<)O0G4PH}H>ey+ z@F?|uCQ1s0NFW2Jny+ee*ed0!Jd1lT)v7+(bELZv@W}afY#Z#`d`Y|SEG0+uP$-}E zg*YtCUz9AB+Cb{9bpfMG)ui#+dpj`$D$)zKBfXBUqvg|P<3vZi9_byweG9<9g03w{yaJAqp@c|&n9&~jAqef96zl-dNnq=Azo8|b$I%O=Q<&z)Yv zMZS7*vK5Eq$F4kPcQK#H?0J?O)=gB5km=qpSeYKG7L`PHe%Cw6=XrKxbQ|bG<_reVT5cXt;(Y_i$BFxwRN9Tb)Y4CRl_Tvz)z%<$s1`3FMGz5s1(%U`FxL$8 z1p2ypbCpTuIFI8K)b11Q1+-ZIUojQ7_LP6~&x5xdfTc2SlKOqkFruwrAA3lQ!qB;} z`4(cSuulmhaM;`Pm|-qwlZ$*xU4^X&Z#zQ&#T%f2$Y+1PN%8y-TBOpQg5EJ7yk=NP zL8<4DlkG)LtJL=5fn=THpyQe1C$-_b;m?^e<_3FItHxvoI%0~l^=y5_1nM!VMq$8g zAZN-pYDYFfWfO_N$lwJaQT8hR(F-0UMe-Fu*VcG4=#Wm#RO4wb{JGS-a^3tGtTVmY z77MLxt&NZC2^ylRYGSPNScdTby#3G4dm*+8OYfzMPiJ7WZI8P;;8;oT^>5p&OKiv8 zz8e+ro$_EGM&J8XYR!?9z%d!}kB|LYwPu#N9Lvdfny_ohi`y)B%rqkOUq>haC3UcV z16djB0L4%jD@AOrO)EYi@j!0T@?@nd5h9kvm( z(3MI@M&fu&j^-$noMwl~=k;>lXQ&s;W(MB$jW=&gxjf1`gF5g%*iSH*Ut0fKs|gS7 zFN7XaM<*1CghHtW*y)ru@-aF!NZiQy%oh634bC&CQOor;(V>uLK{vUweyl;>$eU!(Y)LWV zKq(+E750dX&@$dM9m*@9;B+_dnPW#a{kieTDO5i)>vLX4^3qg7@0TFO3m8BB_O2Y# z-LkJ-1kds%8Q)>EwQtHlbYL4J?I`Vplpd_l^N?#{UazlusCi8#rmJb2@@7XL7B6iY z?@Pw5S6=Rk{T4fQDL(vnw;VFRNQHSxCI(m;&?64A^SNHOi4M|NVS8(Yc30YOi2gv6 zrC)Af4B0V*h(DuY=<--Tvfn2zPCydYt5Bf?yI;E53#h%=$oQU84Cb}2qy%-H4?kPWG6z=^Ow6em)7BAKMrUsJSiJm6;`IBxB`+F|52%9`r9FOg81(Ov?lv0qkZ3A$9>C^7u8m5;8}71 zj1PKAc(fby6iQcGjrW&IcWZ_cb6W7>2jo;gR(Y35uz15`>dn#&eR27b8eKyq^?`Ol z^%KbuR?`cqK_fRhx}`!>6f*Wh>4p`^~}Z;_v=osViUYj*7_=wD2%2P}H`N~VG)Mfa#vw$OO>d*4she=qk7DD!K@qi@eBp^0zPnEQt zR{*|sEMla~^E%LGR^g%)E|7=5ci)YlJv*at)_Zpo!jNcIE(|{mXgI>&Ke50WL7JA@ z2Ia@zTh}GC;Fmtx`3-|>(VYkSb&&^U6MEzNDFKb-xa3Zv@7b~ob>nU`;6>=iKNf2Zt^m;7Bu)B>~0W!*qE=v3UF z%EBO8h}^nvJpGM*t3Bxy z*RDeyE5kA$feF`>TABaJRHPG!CWif^FfTbh5iw^Ke3)_nege9sA_q(*p6ijd)TK4; zqd`BHnRp=~l&_r(&1$$N zzDKulbXgB80FPj<+u+IFUhm5fD@$jB{(=fCG3Jq=C~05#rm*rVz_QA@QWxdsHs|-U zk+I^bALK!?pn3UMYQxuwCtbOL!)^l3x|-G>+VB(k`?+sz0611T-s z8I60XzMydfk7Q>VgXp6P-+r-}*47+K&R=^w+zF_a*oiCRi$phOhMUNJ*1h>6&hTgp zDI%mOHB8V(E+wR0VGLQ##Eai+U$1RYuk(PxQfo4VC)(}EaqthW(v{!Z^eYCVbDTUB znXZDGg@=hNc|Egbh1<6Z7zZ-5z)3NML7kyPz%_Kf`?tw*wwLgsF#I-^ss>$0(WBR> zU)B#2+%UIwvclzN8y%Jq5adPqMri?79qKQ1kbOP;qSx(Bqe%I_7hLj;R0n=D7y#=; z5RjNvTcx3a3Ascf8)9BS29Cw0#9j;nskAX}2d@DVkV1g@((eP;d1Gcy`!6CnQdZfCzysO%5Ugr&ydB4UQt7DkCv8r=|!y$7J&DV?a; zyJyD_4AP%YNMws`-wOAHM$Tne^FeV;(TVNH2=2f)*Me_YuN{UW3TZ4GQ^D=7gY_@r zkt)6sso4GOVx9P?W$p40*;Xj_S??f`Z$_agUt_Z$wz7XZ2wPKV*jXQxHQn#tlm~Um z>@d#3wTOby)|oJ11mP%0$;0|Sx?}i_%jgQUrnFM0Prk zl{)U03pvyk$iz))f+UBwHaKfgbML-);VTdZi7#=#=jSTA{p><ao#6xkf`zrvb zmG@r@ z(YFsCBb>N#P%vniWxK3N#i7*(ZRhtYztjs@Rb+alj0F=TPwO@@_8Hye-DRo$nbr%2 zUJy^E9nu|t2c-pVEoV)19|UJP4Cc2Pb~P=t2Rw^`H}m@Po|vR6qv*d`jA}H7w6(Y_??316&q6*xXUVNG*Pg^? zNNa;D%Dge2+Br?86BkQK>37hI{Agv~sTAxqK8PF^Ch>D+_#kdy`~L(8f5)OI0aj&0 z(ad{&)YBe5J`JbU5nEjMHCIt$=%O`O8R%H_ifYjopNJCoh3 z6~@Jee*|`@zKWuzSKP&#Avad>P-CRSSYV? z7Jw5Xvrw6zuO2onvBm6J$h9r&M9m*n(b*{Yu8FJVq?2K5#-AemCz2cd3<9cMbA#hb z%^jaySr7$$z$*cIfxy*p!7|-DDaBZQTn2v>kI+gdT$ynZJ;@Od!n5(B-)(cr4D>|u zFLNUozCBVRk6#9?T@$ef#_o>7gYcyaAOi1~r;+vLixsKovUcKQOKu&m@k*^q?)HpJ znwa7b-`oz>IjS2cf454X{fQ&^+0%CfkN5QhMSj5FDS28GHw-|QIycklCN+)|tdQj5 zT8`C-7^Qk01l4+zD^+Txi_xUCSqZjzz1|-jA&KsGV`f{3_}NEusp94uUu8!NihruPE0)k65Vve=faN?2Ty<~2bJ{~`eoS(b{H}fyR2hN4vOdt4^ook zbXtNDfi<_J?P-TpcbKpZK3`YPs^s=3H%fON(D`!1GQn4)f8AzFygbb8g`)jo2HbX7xQ(8jLrb7wIS`WYN~YH%*X?N2wV!yyx`i& z5IG=u3r*It@+mcI)F*z)WJHK`I4vEVG?5pp2Tmy!wf`xkY~Ju-VtuY%$GSm+2Xm^F zx~+s?;O9-KkX&P3jD4yXRnO3!f2$~drmu?pg|vJaO@qrm{AOXQ^E{-2@^AJGp`?~5g~N2F{T@Cvx`B6bzsO*lG5cY=VJdZ zkYD4=n^v-~TpFNpN4&*Xv@K3^^tNtEDM<7VQ50_Z5f_?+D&=OubhoKx%^T6u;wU1Qt)DU zYj+=Q1KyE5{|mJ;QfVSgYoyHMHD>@Y4!aACAWHWj}bSiax?Du-c=aw4u3 z?{P+b2ltRA-z=B7^p&UvwE103UqR)&JbHuRFf%yiS%8J9nwgPc6vUkOY8bY5lTpbMnYhUbHZAh*64Cx`8bjWZ*} zC!Qm{RR0uxN);FvfEyA73Gc!XUH#AmL~yKcj1Z@4t(Rt>24PM4j_2oyXJ1#DYtdVv z5FV?OP%i2y)A!m6miRn(WN#+Bd@K%=zueDykveO`V(>@xAwPLw%V zoSO1XNUt*EAsS5o04?*d$n8F3S+^<8jMpbx{X5fDy%RxpyA+lu7+^=A?9;pHoL}NO zdOW2B;(5tTNdk6poR;j>4{>hCQMJ^ zW>#In8rJH}AwL|}tQIWNLJy%=pa;a`P(3AD^kNgwkGD*BMlqH-^nv>7(}ZB-u5*@+ zre9{GHZ#x>pOroXLX%hR)~i|tuA|xkM`#$waOtWwVr6OgYobmv{e#EeFPglW-m@bN zgq=X{Pgh479$xaW@-s$NOJ2t^S&6zwswl=pIA<6Z~7! ze8#cb+4$+#Kl;pmQ&!zxN$XsI*R=udWN#7X4~RYlYg@6NPjDR7NnwYJ=R2k1<18SM z4(VyLkW0i4?uV;KoOp~LrJT=ec&#e5RppYGaG6J{3sHmFG(_zp6M{k1+)U+#bl?Gf39b@ye;*B>-v9<20H`r}IlWaKPgV5$h)w{I^6Ux3spm{p=w z1JdYnxbXd>Qdr<@@YbfAjODGr9X)_ePD>2%caic~QI=KD)}Z`$-&yUm(|v5^-{n7w za=c}gt8zHukwUz4MBd^{pO!>%>18AMPOiPB^t*MiZVU1^N=^9ZIT@dek3E14%~hD^ z-mcw9-_;*R_#O0KzIJ*>71XcQc{{Uu_hj^hVZU3EmbLgA3$Px^qH%@?uKxh2)4v(d zs#Q4{Icjn7yu85-OWDWrFS|fS%M{J?G#+2U;kHJM<~1)BCfz%fE=gL#7_7p3T|5uy zM#K@gBd(auSmODJ?ZpQfafD%5B|9X5Vef2|bB*I9ll{~1)%`Q#`W2~KN>2_X$?kE} zIp06KQ(n9$S>j{0WKTPnjX>;&qL0_lP#!|?z+%fpsym@vVLEge)QHr%#PS8{@|IqQ zAcqvMW4f~`{{Sv^9;Dx+jQl|BqT3Xb#7<+3V zh6I)EK;6+z6O5#Ye3*D0$3wn|ZXAP^i;&~fin;-0C;hs?*ud;^Q$8`sexIec^V9tw zz#>a9O3==POA~f7o}h!%TVU9#wr3LCk)(`#kqv;(hO~Q-$J(fh0`wbrYE;h&7X@Rs zm5U>etm^(^D#T6Rpx3n~L9EVwTaK~0IU~UD=c@fu z@T+RP_2g=^WV}R%Q@-QNI-0Q_&lW6LGEE_9hUpUQKWWm*s`X)1?Fb_n$C1>qYBByh zX(i*VS#CR+SwGTGG5-KbGB6}8k{|G&I|4^mb-w4fUcI=b zzcBo6>&jwiMLi(8#1umYh8P2@6{iN=Aty;h2=?(66Nboc6!tFEDwxN z(Z~Hm;@QhG@lIahZ&H75!WCha3^CI^K^;b^bl$cmT;jd^C8d=62nHijf=C`GNIO~R z@=`Y*EF~UQSc=AT+XUd_wSB|sjrxyP7vrqkhc%bvs9dFfTDIY6ZA9I&#Neq1uS2Ks zPaf5Hl&{RXRpjoicU1PO-JG#l$QX_}8*;I2+n=XCTCaqg$Z^;B+tXFG8H&UQwn*E@ z;yl3{f;CUDS;bbPVh(niaaP@8y8@Nst+_rMimrc!kI3Ii+o9P0wLVn;0QSd`LdhA5 zRLV(_zDJ(4%+`mG_mZevFYhwv`G;ax;(i($hEXIjd&`$Z*q=Yp4!Vh+Kak+LXeFa+ z(Bk=c8@hzj0BYGEO3MELJ8_t5hx+3oL{l z=x2!LIZ%wNqj-Wp{OO9SaMobtP;j@qA~LZw?6AW{V1feoZTz_o181S%&sF-T#QFG- zXtZ)E6GxEi^rBE-H_wC&&`jIo}=vJL=i`Cj@pRaY`>4(N%;Ok&--5{ z2>UB;3ssO2^333q8Tj`0`H`&KVVPq;`3*bNE*gA=b6(7Tr6+L8cMOa+Wp4sD)3S`G zIPPX1MvPoXH0;!&IH_$%eDwj&$-k~FoV0)YaC(`{Tg5BPa922q)fk6Y0pPHQG0hSA zWJBT(nRHq7*BN%dBw^yYD+06;tcgZ>2384VA%J7lM9vO>hr2#{sh=z7;X8ZkTaVkb z8x?ZBK^=Y=(lZt-{l{QSQ#GeW!pn>v&;S7W;10SPbueAkPhWAgdaOE9E#?O1C**QN$>x}X3B_<@ZhUP~xf>^(`_ zP(tRYyq&fp87tHcET5yu(&uPJ#q+cKGS^Wb9m+7vLxF{c!RpX?9;yETr)_4;^9;OJ zdhI*hb;)YZhAR>JWKN)sh#>SJ^#pa(_`g+ZT!)x~9y;ue_t3Am$69U9*b81lPs#iT z>FLv?z4$D=6zu2SV-u+=+in&EPg-9RJR!7IVKAkV)Q0&@+WSi{{Td!VEG;V^2EB7~L?2L@0E4#Sg9jY<=_8O^z$#rhT zvMe8Lr)5PXoOlvXQgukJ)P6>UrB+nm1mO7onwb-f;8#k2pRUZS|WzH80YfpAC14k`|ZM1%wk*w3+thh>`;-Kc)!k4##~ms}=Zea-H5h z{y)sWwN2mLrFR)>v$s>`Vw3A%514r5zV;dNmruvLrJ4&lj#yZumEWh2k=BHV?=62B)u3_X-aAcA}TA)3p$jcH2aI4j{tug-KB?~+iB#N=Zqeyb^ zfxGNB?mOUg^U)2dT+Kmc4cGzhPy;WR(hODQsdJR!<2l)cQ^LOAAIvx<;@@bj5DQ5U zk@=IuE4H&{d4^sp9quoY<2eZ_TZqMKBZfnQ7#+ha42D)4s||?NFTvaTxxn&#eaJ@> z%MQsw{{ZW+ADSmP9@M$(6L=q_{54ZPQ^)a&lY7xzKE;(J23@do{Uc79)lqEQuTQg* zvG-yji0oqx*aj3f`{NySV_WqT{lcTp(@x&iRUjF9lki3A$4j1x9g6oqpItqq04jz( z%-Gnwd3SkgA=|%FX?wWzWUbrShF_Xq-m-R#_V;)Uolslx8<46TnW6zC2h|t^XZm!r zrzl&e%TP`#@%Fh2;Qs)&TyGKo0QF_h(tpc8N!y{@E#`)t2%0YQm?a)R9cqZ6O`mAB zxdYFVWRo8@`N{a5QBsrM!1pCwLBF*h)gc>x#q&Cbqco3d(P;<@PDmRl9!fPWYG}MI z54kL>UYuT&Gi0CZNP)Mzfj-2yVff~UNKSpNVR7#Ih@YDheX6*N+rVO_J+ zODYsOYCMHB;W>3F?UFdly&AlXca8Jb2RonPJC6~p-+K)8l%)JGw_&T<1tpA>e0UM9 z46#B^M$KrK-Jjnv4&L_ph#dhwI-#DL0*^v+l@D zj80si9Z711sCxvrSixT>weU%7cp~`!09VIVQB7=CyrydP{@xFkG$$-T+qu8I-A*($ z?HiKe+j%P??j1n!2TM5Wk2G3~aD1T62Y&dA4_#?a#z>EVZ>@SBy+(}lrcojMZ!^7F zhw~8Qxld8%G^sAGLB`sr0Tak(RNvfecLmr0PmVF6tU|eJCYRrt354W95!<|v6aC!j zVvzfxV&Im`cSg8UpkQ{6iU)wy8dzRyk*w0nlsMSf10(e#r=fQ&e@zYh{Cu-fmF8+I zBGD)LKK=}>2F2SO4(_<{)VwqNha9EM)W$~r$>ohKsBqk^YtW|^%Q07k1>)^CGZSb0 z843RYDZD>~{0Y{78lNhMA^6l&p;;kl=3TqgVC*ydMx8j~JC`d(-EMDvk#Mq+hV4=5 z?(-v74Nd!}$7+Bus=f%LP}K@Cg#qP0 z#YAOUW^CYRBn%DDPJ>l4Jggv*13Q?i!~in3dsjXHbw9IGg32h_{{T@?c0-Vn`=8=C zQM<4i?aOo;p`>TxtIYWhQM?^Ti5^<8MQVQfM2lgBu7k9)jAchm{B$%IBP?!`Pa(uG z;394dx#%9EmMr+~B>I5B$B-TXcxnc#amtlN%LCF#HQ+hSp-vf&IxqF=MP!w% z*&gF$3c)a*YM(ZpO34U+t8DqCW28NE^93 ze8||6k~#*f?1SQZe@?XLYddP&%`q#4O!^RKwMUT7jW~ae zi`t9sZ31fV*%276Qt_aD<$G8%ujnpB#UPL#_9h{?ORZ`8nSrMlxg zYJ}&uJ4&CZZa-ZGA^3KZU+2tBN>5~1z!~%N(lO}cDVBDXy{b@*%Inmhr3b~e3{B)O zeayK)5fpaDqois#3c7}g$J4H3`%_|R}d3;+^4&=5kxWED^LF`1?6?~WC zd`Z=dRQUM_fn<<~>PA3$N!WY_Gn4virY{S;b$OtHkva#J+2GoqZNCuLmq{d9tMXjOv4H2GS~pGxB__{dS84>PHpBX^Or zZ!FE^yKDl1fT}!(qxxrypmy96x-eu%Dnoq+n=z!vL)(^+qH zt+mIcL1IqBOcg548Ksmg?#49UIKGjQ*Gn!%dQs+iz*u4*;0=qv(!ZyP)G;#E>FqN! zw!{wX3=Oux9$Ju*#S~Eqrb1zFk}cG^2M6{K6RA0t+}2yP1psV_Hb~dWMx|Cbh}G+y zy4SA}0$VN6XMAnB{RXOfnXzt!wiY@*<5gcwZy^fK{S27LrC9U_d}xN);R%&YQnCRV zB+I!c;G;Okl$pp-lEjZBY^s^hvb{5mXMI>Sl{&C}z&5+S-ZT8byApbY&xUcU7MZs^ zm*;l_vLWeJjCQAJ*;NLiTu|fKqgtF5sT*UoY|=10qW=JC@YGc&r^QEIWtJvVS24yj z>+Lw)`FWj7B4qD!{D`FH6xl!+jR)|qpsKU9b%Z!_2?4ye>5nZ(Rrp8ZE~{~}Sz5fn zd{y_)Y&H~(s)-M!B+l4u1Lxta_PO}qT(LUZ*@on>PLBfb9|N7Wi){RAV~K&UW=ggrXe^;U@i@Wm z{SLGdt??$sqa~S%kAH44unK(ivJ%j!46;bx)mqs17y*_iQ91= zEMX}sO>Lx^2oa6T9h7H&#UBkx)h;?TiLBaYj=t*|Uz$e)AxH1r>OZffl3VkvaRD4E z1|m#^PY)jx;&lZ>Rw}WgcK0`!@fwaEqBu@WeVb1o7s{hz4|$5gIqB(R;@7iigD||Z%H2?(^{8Vvl8EqmO}WHb_3ia9y!>Ps1L?HSf+oy zKj@*_LNVM)=&C$PKf6_3OH0VT+1YX;gq#T1WmPBTQT=+Ac#n6IlLIQ7hGEmUIqe?} zMQR!dkwp}22WMSJ6*#xxF8iESsgj2#r~M?e99Ntkiq3Y8{5@Dx<~56KZe?Wu045W| zeXH4ltJ;IpBu=GB@f#m8zO}v>&n8!&{{V60Bc;e6^%ce`@&kEQd?A}B*BJU(`j@8T zU`fnZ#ZV1?oIxkVHQXsUU{~ zaLB`ERvUsgBTn+OggbO*l5&$u#Z>Jczypk6{B*MVw;cesedhM-M7`3Ga8Hu2#g3tc zyDV}RTeE2TZL+G4ioXG=G&LwCbW~oOXC5cRLvkIhdx4%i9B&~jalD*ox`po2@JghA zhbUaKHhM4wdE>5&r(-So9}CLycg#2A_NDowkRIfb4@Ql~Rh0Mwleb4X8M$FS|8$!bn3h8OF4#KD$gOt+~Q_PFEYA1ERfiU_r)x2^0aO? zV0BBaS%}uSww~9$B)!n*D*(!jFOJVPPr|pQZvhMl&}>P z_NnYrGD0Ca3Nw^j-7JEKgeOdUi6jkS8CSa zIAn2xRP-ajf;thVUG&BFZkHv;^3)fM=Ao+bVNsF{yr{ zavXimGW3-#CuGr`@Ixyp-CY=L%ENF+T~eDA>DjBxQ(iLkp53@cILnTGDmOoEA?w)3 zDfEFZy)aI8$!Ddyb`JgF>`^xRx1xs2!J_3cB*m~6%EN}v@d zqazH42cZYR>GsX>R5;Flo$66>Uy%o~Rw3C^>ThDMaf}|a#6RtxpGh4FoW;CUugExw z_^wHz$Y@19%_ zXkdra7*BxPLs0J>$nZjEr&~n z8QYaCS)1Ewh_Bz@?E&M{B?Vnv zf2Ej^PiwdNZJvbse8|>shNaeDpId1G$j}hU6}gN1J)Q%Wmx_8=WrlWwW$kn%I-fD9 X;vL!%iHVw4XtGK|qX1{mOEv%5O)Naf literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/brown-canvas.jpg b/public/images/skins/textures/tiles/brown-canvas.jpg new file mode 100755 index 0000000000000000000000000000000000000000..f9467090f1ef58d737e675cc34ed2075bb139fad GIT binary patch literal 53224 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�U6uXHw9&FV07X zae5pF$heYl5?Eop9newWhQYw(1{UVaYnqIzJuH@=Mo0Ala~6#WZ@?u_%NjhlCHxTM zljik40EAbP&0k#cj``Z$to6>h`2vr;kzI}xS3*bt+xf<~i7A}ob) zBv1k*fS1DPT+*DJFj8@yeOsa7jXdV3{(+jZ$R+zdkGnOzq;6Oz2Q)B`9F%;+SBo(o zSAn?E4_(gJlM)tAri>5aGUDO(IGTZVRLyGgy8(BN^G3aYdNQq+cv!J1T2~XN*|t%E z`o7vqhZ9>-KY(SkCw*DXBRZ`J8PsX4jLpzNRe1{ND9=B&u*r@jmFp`jAF3@Krv*vI zS3m154M`+gfgZP)%TipQT?AfEGX6A|9F3KTXnhQlxxj>{8poZn1j*@#pEajMi1EQD zyFF|KQqAe(#;)0ePv{zrCgH6`o0{G z4LbA*^39{ke#_qrhgiTRpZhx7O4%e-`gVi*| z!W~o?|HwKY%6iT;iJteN+)70G%+f=+!Sj-fVb#xFY%+smQDu8ypgXGLkuu~PNMhp$ zKR9?04b&K%#C)ej7S1S@p0iFg-M|rX%0y)by2R%23&V*j?6K3gQtw)4dRGC_E#@Ba z=CTb}cxAd^V6lwkmW0G*&!j=~{{qm@8$YO3=ZcCpw|m2nZk=0_$`90=koAhRK(P|;aUQy`NizJK{W25xk z{k|opZdjLz&0a<-Z~Pn(QK8q{_HqX%ZI-6z;4Ryo(r8-S5f5)UYXq)kW@f~s2X?-H z=WVPk5>*@aBoRnFH0USkVA9u7MR%QUS!rt?Uq#gL`8iw-7~H{!Cvw7ZMWBu^i!CI) z>+kcuH@r(tq-_}2k{tO^yC@+VawyQ|^eqqSj-;>&B!2RXCmRHy$&4r=vMhXZXSXmBgm0B@YgnRIzQnI3Twvdr49+do z-#3d5n(QMi9z#Pnr){CdOj{}Xh(G;NyfyuSUw8r*KClgOqD8rzuoHVen}v7|L7JdB z(hqT@&js)~{QF!MB^;TBfc9j!Q+8+yhrkWrT!)k@!uIx|^?@Lfyj9CWuONH%%8$yq zDH-w{(|UusxkmXuB)%JImLI(O{2OB=OfzPLB+)dw2KI^)bMxHSmF3vaJ2om#CK|Z% z-VF#GNAun?uV|b91$b(lGAt;A>*e|6NOOBbmOkt22ghDU2AoSL33MgQ&WGIqw3qY= zV;3Opy3SxhpOFQhCX!+Dqw{%v8W30ys&6E!$KQH*@7gu7l@D*xehrjfBbJt-G8@a$ z82w2hNngSCu1K`yRh!-Cm!x~uCNT!X-NmD47fbrW=hyV(Mf4CG2+$Fv9!O5QmKxio zJ8NChu?RV?4-yE{$UP-fKcif#^Wqm1&=2sO=`YOtiqBf29xKt+<6wASYbWNG;_ z>D%8@*7xc(aGGV64%uOLcU@F1M?B~w3TzDUV<5gbOKe@CZ=%>LS@cs*&Nqy3_yWa6 z1bE+CU^`A{WuDnj7CnU1&&64-@XuNB6#;TWA^6)Rcm}m z=0_&(d+Be#PNjGS97`-Ck}by?oi?L2w-xjNR(JY?FS#AWwdKw z?KOr2i?SNhqpn}MFzXz^?@6E+p-v9PQpn`O)Im&wD|u&~bYwheZ;uTX`W6}c5hb?x z80V|d5h{6vJ%5L^^Q}GqOgN!3$TVb6u%bhM-wdg>>y8YUb!H!#2LFf zgi;PqhiXHmfHs^doumX7&Ac4GbS&OI60JR>K{OyV&@zxA3qNPzDqBE8qjc|&ikPa{ zoNRj3MldF+B^EkVnlgc2ULy1-yOr@XOD$fkR?2PAXDvf_AghS|x=)+UF5sm|o(^ZY z_)rzU$D9M7IrRy)jHFdBU_@^ADlOZpNap-M>lr&4`ya}$UXYKG6S=^5*v(RH+$Al_ zdz254si2YjmQ0E$xtNLfvS-x2cNbTk=#El9P$4F37Kws{lg)J`X{o&T!DCxqsh+|ocQzCs0(|FNKc^sQ zQY-+L!c-UuTz@%80DFG`9tRJTwdWtXoT3Nv1`T(x4;nvf>RmLD-1A{HOlm_eqdtAyL@Z|lGoe}Qi?_`1s82bJp0>~*VIQstuz{(p;a@~B2 z2_cXpvWSyVKmPI8C4jj<{XSUQw&mwX!kKQfjMj_Kwi}BX@xB^}Odkmv3W-PHlMI%R zY$%ITyh=kBwOF^-;%r@3@6E7PajNPwH=afxrrM;{GPHXQrpPBOXAJ)Zybsy%HJ})x z1{PY;9%sZYdZWoP7&$6Cf1{9-g5kgdI;iMYr)i{WilM^CO?@)_1v^uqhZLGl-iv^Y zgJNlAJ>u$D$fiDtLd+>_JnEad?2PuC8>WHuY&#L+T)S>|%1q2fSd~uxFw59|47XXJ z#kWj7LDj7Hl5UE6jpxM}v!7D9XkV9mrWd>uxL7XT339}U7stMkN33&uEKu3xWxm>A zoxmNT5<6A;hS2=%iNvonFJ5iF{pt^x{jE>g6?l2))g-k+vjF7JYMz#N3wKtCE$p2q zc%L7dfYx(FC=KT+Xxo2Kcqus}oY~@&@zK0jJ`SrFOGlqnm@=}%5B%whECV$&O2*1! zm{ytO4Q==f;1E*qrGY|moGIelNf8L68ic(n2!$|hq-W- zk9A6piG?KTY^Vz5Q=VMkHq|Q)qN=s3RG`1ypE= zB?|P2?*@K9q(TV{BmI|5^UETI9GEV;nfM;x>WlVX%-iYwWQ z!{bZS2>uccGE9trn*Nc)OJiigT@u)$$)nz0q>*4Q^b|W#xNW)(nY!dEId>`g=rR3K zNWSBlpettBb~=`|#$UksRd+b2^nnYLz;b49G0WV@$%?6I{9gcLs8K%fB~~tGH?x$?Bjj0GH+6s&++tWO zBnje|=Na0y5}cYlUwoFnVTB6bvryd`()jl&n-TaV=p3xPPBmv|M|ejoZcQJVO@7GN zPW#{$B>N6b4U#IEg?6@^);V(BpK8taR#)!&HP^RVeq z0N70hGeyrYgui=Fws@(IPQJ_RVNBzAfl0C$(yK)zP(Nv2=L|HR5$J2b{#BhMJkY?t zq|W_E0oMPYt_v`a*sbDJz*=)u6>%iXb8#L-Sx6LBa^{im&tX5K@<*FDckBi==!a#}ZbQ1#DM!1@mF`H{88bm?t>vojwi z=YLUQD74^^ovYGNZW5-E$Craayy!^nx!6nM2|@cf=>_JJd)(@bp#c!RW!w z2b;{?mrMVmLQv%J=$}`cN;3id*A#M#Fhi)|8iC7Q(*Lu}O)E>Ak7O;*-%Q{RkUId& zzE|@T?|;vi*6l{@W0~hF%D#u^%PC5YbHS4`TkQiI&+xIA|Jhu4B0$ojvf*3mzWyN^ zNJAzA(mJQ2XHrhXyIdSq`?+x=W$xRI_Ax!wV#*)|(UtIL|76Z&s57L-$Lx5B@{u}P zG1AcS=WBYoVM$<9O5Th809ULmFY^+3*TEyn`%!=)vC*+ZI}s4Ru?vwsQsT(YfAR8G z2uSedWOpV)jP#&xWH#zz9P0nA4m<7#7>jr%Vo^=k+yCQZx7#w^JC!uHPp^DaCU<46 zNQ&=>d>)HoJyUh_J-7^dDV#>Ez3i>pi?-sxSNpD(EUw%IM}U_+>^%dmmN~U6+Js+y zzeYfXAjg&hZPS){0DA>|@+z*jy%k3pHRh2H9Wx~H#N@EUy+`_A0KLmHG$*)mfNM?* zfe#>Em%hG4?fo{585Nxa*?G`D_^9ea^4r*?whb^mzcid2z9{PUc9F=LVl6^&M0xYg zmcR#m;e(LRR0$Cm1OtrwQH(5*OfiossSRHefhIlt>w>6fthJYmNe&ghAr`THkVhHZ zXB+}=^5ovqbr7{)@P~%DfsG0oxpYh+x{oYO|V=nw2fiV{^b1zUp1MyFHeUd_U* z!_2crL_MO9Iys}JI7ia(C;S}O5XNr9Dy-ZkT~DQYjInyn`380mK=f2(n@s)gY$W!= zV2_=RQ%$3LTYb5^+?}6WMu*A%(VIkvNChpMNN2Mcq3fE_X5E0WXxl&}VEDBUrXRFe z=IEBa+kzxU_r)Wc#3bdzKiHQS()2;5!w^lP^ER#`UH#3%jH70YFER4`0T+|jCsE)5 zy(j?w=Bbh8QVPZewJQ3Rg;g($u@1U=!%w`6a^CY6E2RXFx?5*@Bqof8LTaPWFVzHO zmKBrM7jYR`5))R!=gbxU;fQXDmG$bjgJkhRpX|PK`S0IF`kc z0!-~11!A(IPw*P-_x zMxTvyR`hjyU>h!BeZ$*pY|)dCXz@KWD7IE(*L;j6(0Y@SP#$znyY)3cXA_FqMLjWM zWZ$2li>r-!GYeVTm6He>m4lR=EXA6XWr_LN7#g_eMf7haTOcRaBbe@Jx+QQPLX00l z?=K9nWmRYD^lsdA+M!G=y$=D`HQ)vJ&%d1x5T?#%qyf4Oa7 zyyf?XZ>=;Z?>Ry{@9QQ8CT^9DwOYsfe$Wo-Ipkue)^W4!QsEN+YsYbL>VB{J@sVnO zW%AtEBa30Pn$JUjV>_<9!kJr!3^{(rCW_`A zTED;?BTHzbZCBuobuj}Xdp6f1!Fy^UcppeQ zjxo;~{edsEJE`56klz^IJJN|y%HqJflx zWp0TMWcyGuDw7THjtjio#21vAZ3VY3!K>G4L|tMUE-Z8SHp8e^mOSeZ`unMUJiyZ< z##*XXH-%LoML)%9UrlSPVlNTs@%H-{S6d-<{LCkQ!eNTqEgB>C`P5}wHt?TI8bI&G zJ7FSeXa}Njh)fe%7PZf!sMmR#8Xwh$MX66ZhOXr)o| zM-hC%gSqdh)_*#f`Qo1`59M?8{yh1I@OYxBdH7(n$y7bvF+AHHCB1m{)L~^nWBc!x zq!8Q4Wj>LvKO6qOp?gZ-`j=zObdJsev(D4VU%*o+XSStk>6D)NLZ&Z{Dto3j%gK3m zzcyWe*?Qxww+|2ooo4~cuWJL2$3C5Gm^O|hlYwI zkM;bKcnfOtdM#<<8=s0|>`{WXBAnT_-GK&~Kx6Wab@O(1NHTd3EbYflGi)a-iof+& zOG2R+0Q;saA?nb_R9G2_OmoL> z_?L9@9R4E@?50Q(LALo*ic{9_j1SBQkmnj!C)%y-G4`S{KFfZC=+WZ}PF(|c+HeRCbH zO$)mF&?Bs7a5QOS)Lg@6@UE*Ju+*f`An5yW8~!E^;AHp!oD&B73*eGOX}4cTsl3^gEdl8S@Lwu)H?h*b3&M@&U0 zzjg8=ac`#>xx62XepQ7;nG!HW^V{4~`F`=LiHiN_hSD-2FuOkjiMfTZ=Gv*T*)?xAP_~PTXsI-1XxbZCF0Zb9^nEOV)4K3KB-|gQ zl>bwpi1r*~XOwayL|}UM1*4+1Q~eM3jWA{Ym=53+gu$Fgj&bZzh-h<7?W=D$XNWDe z#m1?7LDc1{2M26Zy~X^Sou6OFa&a2kEp|af1=W@k)PII1s+6sWO~U|DE~{)WncjV3 z_S3cW;X!222EdB2@_xl;Q5{En61f|pj~`QB#h*~ug0%9G)H7WB>ZB#DO=WJWC8{oj zUqb1$Ekf*7;_^=~QP04~vg?D<9SRA(7ax5QI&aYxviIInzpG)Bt<0 zD0_I**ul+U$#t7A!3%a_3USn7PN(*4v9+P>x~W3MM|(fBhRm#gzl!8i?7*n(w*}|j zdUz8XD!gJ@*8Rlet`J^v%~-3aO?n&iLj&ZtyAr`yoZ|yjYiB8_``}TAnxAeL^g4em z>*8M?x5%W(Aeq5c*;OLev%n5W=zSq!Zbb{}AE?2MeLnA16{L9mfsUou z72MMqgA30<$9YXx-=7nAy8TxxkchY=E z`kQb*h{T~N!8IXFF6Xc5K}F16$o9#Xzt)R)h75n=ik zXL5Q%S*Kn$IkO9SXgqIXWoTzFbs~s-rr2O8Y&aN^26-q3>R7MJk+N1~Xq|k>sZs;R zt?qs;)gzc8%zl59LOB++M|iYttwsaM_AShheN7TmV0Xu(poKa1km?*NVfQvUcefkX zF~EYraY&>)ssMHmwE8s?6x;pX z#_ff2jqDc{wpWMPd2e7%wVl%*y+ma$MAOd?4&WmvHC)rP1E6`rfG3@4lVK1lF;vn+M^$GJDcsp=l92?qi;IH*Cz4L|Ut+>4JIMQ=X`M40@fs#ZV#x4S$ zUQYe?6?^Xj#DNXHE9v6u=mI@$lX>l=Lq-6UmQ7k${~ zaq4gLXpOo)czeY(-2nQESKjmLM^neOS-;d0gM^> z^_TZr+n^`OU=@bY)Zl*-roVZ zR8PMB*$(>hza>l%rV)KCqF652KH;oJcKR4b-=2F5J!p4T(ojxx8*4j_-S`4_*NXlG zPg1x0#v9BLe5x%LBl)e0xI5hOoNY0l5)NhJH>U~!(EBKa7Sk{;D=K3i2kQdIJ=p+n zH%cS2jgx1((0Ed&xh6P$DxkvN!av&vxHfl&kyIbUL0aN2%iYHrv|;}1ddk_hj4p8C zAKN!{1k8CF_P{7na!rn#~fcdYK0484P#SoNK18i9LP# zxhX}=t1W}xFDhNVmBKGX&{CdEKPDtAboAN&H9mB|wzd$ZsSg#n)?yz?sCsij=K=mY zS?+D)`Iu}HRq{rZEH3`Ugn3}eX!MTPGunn(U>|f<)5e-IAEvl)a0DHbEuOeA^V;VG z$8i+^0AqP1KT>v0$HU|X*1T6ruq<3Z`T!2`MeqzTE1H_SL3^1#oHmGoJo?9szko>O zIEqM2=syK3WDm|C@ts4>an~1563(VHM{hq=1~_&@2DIo<79NG%!*&9kFU+IA;3;J% zV+E;A11Rv={s#cFKuo_h;k1lP=|xlbzH4k|;E4*#r1#`D->#H1?`*3bD>oN=+;I-v zfL7R$M2RD*(xKqnf%i@Ki`08}Dxy8R$G2@u6d4(nGkI4a2f0cs1T6wO_nDnv2I8z{ z(!)6&T?_Cq03%|fmfQR^!{D^IWS4c$ndLWQw#P z=4MrjbD*m6M&iYnZmiM7@2gRjwRrh8VZY=VfoEE5Re}K|$qV$E_4U((hE`oBtbh3g zu??I;n#&R#@5%?L)Xg*xd(mb}S(=ci-YXErW4!yeC#I-6ZsmskHO9wMyQP5?d`*U@2(cc%N_2*Hs7(EPT(lH7bTaTI*1X zTf9NrZo6wXH7c(rJs>jKkBnI*+s7wivD;(lHKtM3YSxsFRHL~h+SQ3*#!MAEM_u(b zaJ#cIYkX^6u?nq>Tbgdl!UO^a^S-r+>+j2ZsK;flx?bYLCyMcPBch20W04 zRW#&tD|b5(({qIcD2_l04XPM%ylh>wF|EdE@o3K>h138b{c3k7 zR|{PD^yYYt&01Gm8#pYAtZDBNvGmlJ0p-T~Bq&8B?u)kigNkH39#4vZR@|&05O{R<%!%!) zjA}B=rZZWMU5!}?TmTtUaj+xy>83i&GhKM-_R_2XPa>x#Aeq~L`szgvK&q;OSZaUd zk24M>Oh@hX8fhYHlOnNVt<~A|@Gb5TM@`{}%5`*Bwq>P$Gkteaa&!A>UL6kOmqI=# zS5Z4rlH#|gEgFh9h6=_~y2la6sSLy)Oz z&%=F9F@n60wzOT4ibC&dB%?f!ZzHtE{WQ}7PIGyM9(1nKo7v-45TmasY1nktLQ2!Z zk0<2oEbKzqiNS&~@B3Thq^ny-RXDi!&T8D#6Kc(YhQRUwjxp=kKwfmC?pg9nC51>0 zQLsc$6F)!GP(3WF+v>OPLQ>#@1z;Fa&~f@fCO%p(!Pyq$TSXR}fQGl;rLA~O87sG^ z$5t{*wKn3LlO!rvZxL6FqBNh}f9s`KruDZZoQo|8l!Y#7Kom0WOt9(F4zv34X?8nj z8@T>JgI^QD>k5Z`)%ghc>qt}KU1j!e&pH8>dg7dz38?@_kz z;^u~U5+*|`$$&J16$DfE`S+^^eXd{$RU31Z+#iV=p|~_(_}nJ(=PqNtoU5561ODIF zwwtIYXG?tNAzeDyIDiNvZJIQz14%`*s=tpdNNxZZf+)MAqDb z@+FSn1H5YQ6BXv+*-ez=oOQ@#_KSIYed-FSGrSWAeN7QHS%~!|xC$vwR^I4l0oiMj z*l#0OOd4clT5hu^1U@1a2%-yx9f%xuKBqxTecdg4kH=MQ5QeBI49S z_k#ZbkEPng;s>$-F}k^qhg2Ypx5`0YB3q2L*aI@CU_j#*bO(=a`UWOYY|1OA@u<}z z5oMm)1OiI57&GzI9aTBjVw&r!no?MRz=l#c5C<)!_0|6XMG1AURkhWMl2981z>S2* zuKIyE_EC)$wgp?OawCZO5U83(s~hr&rmU=LELOAX zS5^b{j-#&HTtd8g*sAmt$FNywCm`|R#1aXT3=36mmFo3*zOc{d% zrmn=q)C~Hp7YD?AHX+)=sugE`yD>UiW6?He3x4Lm5vZpmRS3#K>-9$yBSlGbX5=3v zV^>K+1M!Cn2J=5ilfJ4Mja`_R(~{XVy-vPAXy?aosI+bAI+o(jhZeD&l2NRu9g@a+ z$%_!on&7Wu2VisqbymHW<5)1n5eBdsnPYj6^^FC2-;BK~uKatbw$}#B@vGoUxY`F! zk08H{CI`-8CYGTy%(lSw! z&Oln#f?ZM#u99V{zOiJlu!tvM40H>mO0y_qEvs#|ql8jZ9g;!hu{#a=&VhgUuU$7)mr%8V zQ%Rr|E4VUu-a2Yf2=!Y^akCuU0}cXHp@twq1nP_#by`}q$*B|>Vi(y5_MTx_8PpHS zzL&=}*L48$9$OVcZhfb!@1T~I{OYj*&?@?iZy4Tu_omGRP+TrV!Js#RPDbsc_)6B+}1Fe`jle6!8eI{=_W zkN*J2`{)#M{{R_~Wht}(40_M_odN(`Exx01 zYF4nU&QB62v_L-*rh~g8waR*Hv6b&Yp}2cjg7pwcDtR*+G_yw zQUM^7JY*3%2}KxGAm&oVJJuct0K3lSPs8D>sIrB}Tp}Imyrc3K?gEcg1nVlwa9{rb zGP`psw3ZE80LcJu4#oo!supor9E+W+H5lTcGN_Kt*RQUosiJ{h&f#kbWomfVTiH8H z5J@re(@{-7iMK2O?T+~7zDl5bxcc^9y0+j&7`3&54RzO!veyr!lD^o5iRq=LC#wd# zT~@nmrnzAC)ZC^$XOGqM&{b9~SJ{0S*3m--4Q)YqN|Umvk`#|oriNLLwdB~S^;YXq zV$fie-0dW9sXt=_QlP4vT&mhZmyRcXlh$<85-X{s+-E-Uf0mov3kp{?ko+hMVC5yFtLT~N0E;7>2sHE$|nN!>6$DkA|QdtTkr$zRb zo%hm`7k#w&)LDAjVhAOIl@YW82Krh-Vg0jI_F0uxAy}e$6N<5b+`qhfXeSScU6w9I z^;2cGNGOX1K-_{m{B#rn_|xXCa%oGIRLiI&$pQ;}ei{T@Z{r#5$Fjj$n7Fmz?2#ZQ9^Av+Du>_utJ#}>r72D;dZ2XBL)F81{l?QM~ZrYx&godt@ z9Vii}~8|Uj9R22!0 zk&#hM#p6RuV-Nr=yMh7u9@<|4)c$OW(Q}FWcAp;=;wE8vM9$sx_yOd^w)~&F$!n$7 zYXDWtl#V3vJ8AG0k!~hM_EGmw=er0G&*t#o3m z*nE}9VCsm{C*9P0PsczN2{#9};TCTpj)K<#ijzn+q_35e)3G(P%Jad?~L-2R^G2+MSSs%Af4a>?} z1%PLdeV_&Li6kDr*zKeV$gjm)T~=z@Q`{Z-R$#y&taK6^O%+vs9cp}8;9eh_+DKq4 ziB${KM*HdE>JbL#y|PvLBosWCVs@47$Y>dF<3Q!-wF=NlsQ^AW8;?_Zcv6R;&kUWizoO zxQ$9AZ^t#Z*lDO$Le^HMOHaGgq5Zme3l|?X7PDa$(qva}Ibj_`0Vn!tX@=EJgfA7W zQpLkq3o|hh)X3X?0)E2EpB<@OW~0i=;(h0gA3+1%-04BPEh&*hW7k`j2im^v%mP35 zItmUdSk>286Kht(o1P%B>}QmNsRXABjX3`9X#dTHQh z2}U;Cb+nq8MQX@*LALGbJqgq(at39t=Bul_4MK@-C8`JN0fy&SNDM%&aI&_jjB4R( zBV)7xLHKHF;FK%)?`u_+gONj2Y%2W=9kw6aSE;}QdNm1;Z9$YUtrbZdbZ8{N@37Fo zmpM1Pd9mxQlrVOzH!a|ynC=NWx4~9bsP-~fkc!qJWOaa`q-+Ft)Re~L@oLtaa#1bF z71Wjl1bQFnx(20|`9&6fK`CwlYjpq^1EdihH_#|omey5SwyIbb4qu6p>&AKx(W_7` z_^hgxLAHk+i<{P^BrzMRtnctMsjwx9rmBOwCAE@L-YLn$blHL4be2-eSr0(6%PgqZ z%(oX(%{+Hg$9SDh)yDD2rz0wnZatS8kfM>|ROJLgCw;Yk50fdf^~tLByBqB)3+JRE zGa!NP0!JSGwD9y;^;u?0im#=W9FU^0B#&^~dPmP!QwLw%{ot~`3sA9(V>cbww;111 zM`j*&Zcb7q=oEm-TLta8l0nj35w%~DWwy8BNv4%|g#Z;&0g^`h9^2}`FJ@4+CodYS z9UF9ufBL~22)*qi|~vo6se9Z-+7$<6X)+iGyH z*-eRAGQf1?0ALiIJP%xR#*TN?Z|mb_97$b{d(H zSSCkq<5g7AQrAP*PX(oG4dM?5$=ES1BX5R?1TOXNfZMhJ3Go%mk(yUsXepv+|t&a-r9ow-QX^g`cQi=C?-1xW*8Kwd024`cdu*#z< z+-JnSmm1PT0#eVQcaTwx{P^gRACADzwxxA*9G8aP)6|nBnHy?rMy*h7M#rV73K^7= zleDSYIeJfBDmiP(Q^@00;(GW}wVn8{NiYESXcbfC{l#=5Djyp)l_ZEefy1W4p{ zQDu197v8F?T~;kzYYY*|KjaT1xjS#EYztbyC?2USr~-0?xUNp_7pi zDv1U`8k?%bcEx^1+8@dYyA4n0r$UB~+O@=onsyvNtc{LJLq5^5^0$>ccn zomor^-&r(d+`J4J*#3VKBOlp+78+v>hOTd zMQ#)Zw#6(={{V`f`3sKLQ;l+#;b4Ntm%2)w_UNQ}@kQdv?e$FgDqC51{ zcZ;7Ocg`l+$fL(%FN*shs8Q2k0pGUTLafKg%D|>Q0G}+AGEM(kTyFA&=xhr9V^AVCmyTb&tfnHkvr~S9b7?WSCL7}dtR&R zWdT?KIKhxq4f=X&Dm#AelF0W{YA{tmY}R9kEX6DF$F+{(VD{g(idlTqb92K>tFc4{-GeEJKAyX2{-OBZYbvt4 z(}gbPEad~;xcBeGdhe*E<*7^UZ?a;kK>-K6Hr~>Bo&Fs(l)`Vry?-4=xZjFKps1~p zoOvaIAhOBWFx>Xl&XHQzkVx?31*?MwPip}i5~X^98h9al@@QN@KOUt;oI+LuF>b6} zbd9vnxUV2(*NFQt@5bf1d9BGRJ252fKC!I_BHPZ)flW5hU{_Q7 z__FWL!Sw$CZDtf6R>(IZND`X)MA|Cz$LfR`7~&@oW^8`z7(y?Xws$v7LzANhC&r4S@He z8nJ3NqZc%wWFd#PARZ(@k~MV$P8D>Ad-0H4$aw1>MsiO@Cy?R}@z+i$?5&;doO-cq z;-;3iLYrnjkb3SlICYic=AmCDD7MwLc03ZzFgUL%Kd)_FhAFEb5$>p^L9VbLBfwvG zQ@JD8ZS^!iFB9=pWi2?5%&!%u+h^R(xfTvVfL-*sP5DNP;kB=Sw^lBEe9817g0wK) z#@lEy!uc{zP^r1Hig!F?>M(ZR4^08tQYA$)Zp13q22$gX6(Rr;Jx5(l6LG>-vimK> zvF;p^T?zn+x)M)z9aqy-HuPHT#=gd@!D&iI* zoJV+%hNddYLqT3trDVjXL$N;HqIQF-m6-Qgkwas(_{(Q7O>P3Cl1Tvs`t7PV+N^7B zOh%&__z16v17JLWj==irenO~2jIWJh#1@qxGOq33OKtmfqn+uYaqCaFc5RJ~u?7qi z%XS^KLzVHX3XNtW*yNRPzVJ^)h?p(5qPLxR)>5q4i*134ZXB%K@_;*m+kGe|OiXas zn(=RU9IaNWLRd^6^6j9V?8jfY6*euEtEV+p3Se$H6Tf{ZT^RxLUdMb>TUJ6Ps7VXB zL(#S*Y2vC(cfN`*s_brDzwHG)cJwhn7||2eTUlMpW^Ov4DdAbFB%S#g><)&C*0Hkf ztY40C{7M-OV5uNMB7bq!q<7kzZdy;;QalI9MO(dV(MXMtP3KKVSx15Dry1+2*I2Q* znJF6v+yZAxu)KB^Uqae(?c`ZkA%R!!exHwR^bN?afki80(|__AlgPwv1NQ0=m&C_g zGG6?Qb4#MNe3m&!`@iX`4?7aNt-CY~TM>~0M&xvZzohgU1N@#HmS0vw+l?oI7A<6e zo%)mC;iRJ~#mBPsN}XDY-PxLlL}2X^yAj*2ngx%MykO)SmHoVUv#FQ@dJuFxb}OZL zw@|g*svN3TNb(+LNj;);!1IRq$#zvsm*A;**ky-xJ1G2r1})BbK^uf>y+Pc zJZ!dc;Jl0z#BLz^>4(XnW{oE6#KTMeY$~IrIF?a%^^7m8nF(p=FFum!^f`5 z0B%)+5Ov}rW7B;p55^45MFCQ}5D|KEgFmNPnUkqS71V`MD^NgU8P&I9BY$thuKEPN zDZR>3QrIfBSwcDXi6VN;`uy~OcpEYvn(M|7?Fbpjizn(QeNfz=x1%Ps7E@sovd57= zkw3RdMA(O&lveeivytMK5EUnI@jVA^T0IxX{90dHCD_?c#Duw~wk^?@c_mebvOI9v zR%6(<(u-A>tZ;=KRGxg7peMem_f)myE%_$FPl-na9Dy9c1i^@&+Mt&X(M`{8H4c^( zH5MqcBX$woj{2H4@R)f;=8N%}BEByqL=niqKc<_9pnPobXug3%)CTnz9zdi-ND8g` z>I}uk%(EPt9*klv2*I2=-*E**gWGK)+9#^#doihGQeoT^%odm{zfxmQx(gzvxvrGP zseuQ^$BQYB-~uF(subRPoyr>Mv?1V2EsDSZ4DLtzX<;j9ACfr0Sza@6Z)X-wEuSPwG9N4N?$i$9^Z*Tn$m!UU4O$k^FN#S5T(1|6_(;axsb^SGHATIHS zwu))xX=QW9XJaeg2d1L3rn;50myOoK9js;$H=e|H?Wu;jl-$=F1qJ|DD%=V{1Tpv( z^wo(^#cYc0Ops|@Vt@{Oc?F38zr#RvX0_PpOH_y$`9T6C9=wM7U`q1Ip_y-_9%Q!0 zIL}%C0MkV|F1q1$MJc7#eahq>Vs<3&8*ir(*y8qjvFa5gaPgpXvF=(ykO=9klB066 zmW~L?N?eE$8HjF2v0cRKH6mbgS*WZgHCA$Bw{ip?Tk_&}J#7pmRQHqR=n98{ot(BD}rVRCAvGp2A zx-`ScOq#Nu$}dn6mXs5-ZUb^L)Ir-$L(?(q=GK9WSh1Y&de%ngqA(y2iS*C_#?7wl z1@z=7t@(GcN9cwK^wSMD605EmANctW))C{ZyKYXv`e+%;AueoTUBarBt7^l*EkE3Y z@zXx3scz4{n#DC?UhGhpYUPBVY#-N5Q|mbw{kzwN;tw85!w|%MFYTF~w9GW+^SxA} z;rQ#vAs_j8m`K>h?KAr6Q9ql7c2tMVyLz7^)5mMw6&C2diV81OP zPO^kb#g-*pOBODytiTaHC4qS?6EPNScIi^dk8=7C)+=!qL-7F zYe#FTr^f27NaX@!ZQuz5wwQyuoUN=B(|vYTEE|a_%X!{33vAZ4sv&4v=^{`lATg1= z{UdE$4Evmf#fLA8~iko&|5}F zCav2Un~DRm+Be*4>Kl^fa(K~QN&H|%KyJcGkap>(r+~%E!=)OCtISoMg|z_2 zOr6G;NYt|2Ybahg;UC(H6gKC5=Y76nf(vF)HdD-R`Lh2y`p{ZqcI)DzoPb>DMeL)&F&5SoyV z4uQt!d7k4;8CCd+;m9vTS7l_1{9~l?JieLL!$gyjO>K{EKk%^qkY;1p81>T)Pi>Z6 zP1IX@HC3?XAjt&%KG>h@rUoM8-^&pmn$#yLWg-l20RI3V*HYal2Fz%akT>cFO<4hPr4g)KDtg|z3Q=7F z2e|p@7m%o7s>nvB6@_B30E6xuZ~b(D4oyryf`+jxvPh~Ht^|O2M|s~%0Na)K7F%6| zCah;=AS-f-`i~+$k|H_q;5a<)EwBf)=iaC)>thhTg;aL#4jL6PmZrcSmq^mu)$jx zu`ABdT_<4DNz}zI<9nlzws&h%NOzy5cRsW78Vtv(+A%# z(8XN4F{3V$u8;LIDv|)-+xtO1wFK5KTNisVyp$A`WZ!R66!!QHAw+9FU@gUKs;<6b z>f7m&AeoK9)d68PwM|wizYru`qE=cWL~-9zEiFK;D>(lEkNzWEDyu^lJwYJvA01RX z7ashCu9J;bd=^MHA9HQ(X!V(m^h5H|*wO|TI<-y4$^JfSzUU!fN$EPCHRvtJzKZzb zV^Xm3VGj}r*?Aaij&2cGTJ}uO6Tb7fQLyF2k+?gE!j{2Z&Zv`|T;<4*# zvmgPs-8-JTdSI~wLmw79-(|j3wDC|DJ<+tz+s1}6-^S

      &(BxsK#cu2#Od+@duZ9 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 g+s9_wC_NA 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 QzFh1+S~S23bHDh1064ocasU7T literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/brown-handmade-paper.jpg b/public/images/skins/textures/tiles/brown-handmade-paper.jpg new file mode 100755 index 0000000000000000000000000000000000000000..351953306a6385c91b28d3f7144fcdcc1072fa7a GIT binary patch literal 33337 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/brown-hessian.jpg b/public/images/skins/textures/tiles/brown-hessian.jpg new file mode 100755 index 0000000000000000000000000000000000000000..cfd105f72781147b0be55f344ca2f8844518ebaf GIT binary patch literal 58626 zcma%iWl$Vl6y+d65`w$S5cI=c0|d9=?(ROg6N1AG5`qSo!QCau;Do^71cJjbB)A1w zc58QQf9~z-s;=8zPpaSTd;6U8o|m7u0Qf2j$_fA!Q~<#Cyng-W^=lk_ zod0F`IJkKDc(^!3M8w2IMATGNRMd3;*HADqG2i06CCA4nrz9aDq5Qu${(mo?2LJ?E zDE=sEXea~#R00$<0+i=rKq3HuhVo)Bvo=MgWio9BCch!;SV6J8wkUl)X)u zC@{V9Tn^m2e+7PtjT_B7OcWPUf~sFU_iIk>Ph+POF7$c@4T0Y&$Bf_4V1TrhuPzsL z%YHx?o&nNKlivQxCD*&Dxh$mQumAa^g-Uo-1T-QfeTJBu6`L(ip8@Vn{O5LS=(|K6 zw1O%HlHo=IaBlcXNn~#w-|$HwHpY|=&^6@vGO1oAxnNrf3E}|q4vJKG~Yt^7jMPk@lA4t3rzM7wUjKQ8aHgqLDS=-1AEhazh zyc9on`LIFLX^!26csh9pNG2Ks++?KP(n@8+p8=##GK+qXX(!JB+Ko@Oy0H=^TT>QP zq04LkS}vrm#IHzK=SM(+(iGGW8dX_d&wxWrOWyz~MY#S^^;(vw_neBRlvN4qK?t}I zQ~kb#`aVBgzu`?hXOk>5{pegj4#zW~b7sv(zD)ulhL@+44 z)=*e)zJj;qnd$eB9^R0$gG}#K$rS^2Qc;D;>32LOj@Ked+?#jiJ{6vqkvJ&FFu>=~ z&Mfg5eHtl2-)5ISey&M+3gl_Pq!-&wZcB5%>+sOM(G8l^Kg#x?JnQ0De$z}1ZePp$ zb2XZ(LZp(fVpgnnvzLQS7E^UYPaPt}e<;=EA2}agSt5DIDId^J`n@9SOs5N2!ruK-%vmhsq) zA^1s+kT3m9z?yf+-I~femw5^FYn^`Z6iYMtKM?18IRXmI`?^}?lPlrhk>(XvZz}0* z;|`t*q-S;e)AiPmDDfX9xWes=^M`84q)GW{l9G)Ak!G>CS*u5hjB&+A5~_n%b0$U)toO#JF!* zz*A{>w@w?E{P_J!l2s1w*Zkwn46aod_l4@TtG{rA3TZp?eWMnt6|B4?cljo|F}EcS z=0E;jhK2-HxKU(HWsOY;s8LWTQio1xf_I&sIumgb!4vTPR+BRT)J@G>DIS)Z#t%Nq zC$+FUVmx&Dku~K@uq_J(jtSv}ppw}@y97#4x7rsC5J*2hWvq<!A%HN@(i)^NjeA>;lVc~ ze)#$u68UN8`vgIDmCkYh9(1mu3q0t>IcZUMlO)0oOwo&TYmy8V4E0%!tZ=82rfODj zW;p{-mU>zCGj4j$R?RcR4RnsHrr{5*K}I>EL|+M|(?FY{DZd2F3WmPOwLw`-NU(!I zB#XaXis<>8^MsJQ9y?-9N4^hK6}2ZEH7%4}c;i5`fr0hHi#ZA4=9jaF-jf;*b>?S) zEq}~o2O4<%44f}ys$EthJi5v?n$e&-lBaSq8LurrP99>5cLs0Qmz3C$cQNyeJM1`P z7Nz4D%WoP;a?V|-hCMY4htgCa%1m_L&6V)QTH`SdhL?X8DL4x5U;|x*F>7CSS{vqh zv#%Y9hYDIO&yX*6IR=l{!pj&ZObMx3)w*_2H1k_nrER{Yw>FI$Bm^qi;Fv~|Q;ZHE z`)VqT7C`+3m9~iTnq_^}bxoj(ecMXVEI4E+=E9sQYGLBb{PJf3CRT!K@%8RAwONK3t@Cnl)U zR9pVl%07(=2Q`GCk^C9(AC--{dOM!dMvS+xrB#Z&95qV3^;+y}T+mEP31UN|qS>Kt zel75P6x%1YYV8W{erH(ssk|37&uyM6kpT2!VC5;HHeizfD(I4HvMcPWC~Wc1iP$#W z4L^w_%!r=g8Ng{H=2NBqYhqK+e)zw|?cPdWE0nj>iVS`H`5*Z#b~*gu^*<5Pw4MYd zRwG~aA}&%pT)mR%F7I4>Q-j?zA3XGwKQY~)f4h*#t{hd^p*q^)u5I*a?nas%OWy57 z@MPIzU$YG?@0@OmaUP`Cv$*`%fkWuW!E9V`0`>;5v+A6NDn^zMFCbZGe+H8>zEvU9 zA$H1Q=YIwe?ab7y3buFSLZPu0PGsh~`~<{Jv4Dr@L>pkzj=_Zw?&TyMxdWVqY_YQ(zAXp;%0`er|?p9CPGc>@98Y zV)m!1r>5zMG9Nx8AG?;G%Ba6ZHzVGa513@Jt;%0J*pI)-BY=&D<%nxo$Kz?K1P!YT zfECs!Iv)4_<+u9bo)l6ygB;`-&yq5?ghqvT{VAI&_XngT#Hy;#@k=F)8~_|%=%jnF zOL*ISte{4Md8b3~;g)PC`$ z&_0x!r=Hm&RObwc^yLBf2kz#+vWay*w*q#A*E_~)? zo3l%&;^-M#;9%^fcvd{ZG3@myJmlrvzx7A%*KC@<)*<)f#v)_xyav2!Q!3{oQn;E& z)nlzQ_0m(X#8F!fbw#M18str@sD6XS<|p+m+$+X_wX*sx(p_Gh9G?I?kEMm`4v@+> zu-&xx`b<xh<0a0FC&j2&ikM}maq^HDR zr#P)&3sLxMrEVPPO>L_i)ctWXZkFcLOQeq>p#msEd_9-Cx(tvnxuh|CtrdUTFEv6o z!lQ#?Z_>Ce23MsFwD%A z&@H5L-p_GxTKE@Px6rI@1$6szL(Xm)Kt4Ff&R^?(zU1e|@|A5EQ=~vZdkQqZe7jg@ zL*Mbm`eZxdlCB^f0`_`Om6Kwc$9qMmE;_>Q(wisg?`9Swo#=AI&7=2K@;&Bkvf1z| z8{DjOdHr*hQz^LjF7=zvgYx=YI_)YQxfPuli{n&_@7-B9XOb^5A@d!-GU@tGwchb+9p3qm@D`Jse>$UVRcZhDkaG> z3WjgZenRh3gdD$7D?b<>{28+_<1wu#D3!-mlTPB@yM|V-naA* z{%9W(eLGHC`)1fU{bWvOsta~IKVo4@`_Frri8fFCoiOW75aJ#d+cSLHYhY4O#rIyJ zI4fMz9u`Vg?!t1fP)j9Fy~b5z-Y2=70{>yh^ZE_#giulH2C(E!fF} zKh^&*HQ5Lru~@Sq+`)^E@Oo6JT6-Y1aT~^jE&ekzElfD`iJvN2r#}(GG@9xx*S5PO zZiDJTjNb^xeZjGP@T?#g8NHpC3U|(T^-tSq)xd2-!%2{j*_jZ<9^#<2sH>If79OL& zT`TY$WK% z-lIlGpJ?M*LH~0g=I(*6PHncp*hA*V{vpX+12>tTe4SNFTAgo7(BF>OL+6teY`u^? zR?Z7L)Rn4I*h4o>gVd%{SA>Z#49*%c8k6RKJ92cq3{@{Nz(qyt|tT_f#rqzu1VtIhMP)hy?rB+!)lk2^}#`LY-SCE zR-wwazs$Z1l-u3BfNhz>HmQ_pbu=xbYT`XAKa_41p^Ck}qkud@`dy{TL^ zJgH_1RhKR6fBDUVhO!HkE{H9aP{H@8KAm$s^PKhLpLO0=gS00nFuRSG;#kPPgY#cr zMu8(b$-`b&2B{H37sRk{cO#ocJ_>ttV>44_U2ERG%X?kdM%*d)*l9y;5OK-!q-eAp zN)a?W_UkXf`+faw^cYemioYS2Z-sf37TbTRF3-pA$p}p0Scd?rC6cn}5K!jNgJcg+ zn@}Wk#an|LRMdUuS0=!q`U0u0X8Lqp-}Y{(j}R4iUrQW|{)ks1CixZ|loeMaQ2Y3!lZ`S16}j!s zNsF|{%1zGq0#-$qv&_Y_tQsh0R$UV~>Norq+v-(RO1l-K#Y2mXd=5M+=8c~0oi)RP zZypp8i8Vq+gW!!o)EYjKhSB;1hWYBnly+OI!e(#VWGxbGt;`vtc)BC#6uSK42M5T* zwc_7ZbI!qd`wvp#YG9}rTd#^V$jR~~V+g1s`O|w#gdq~(oOgIJ6r4a~3wLhCol&5# z?`Ur4k=^lDz?B3o*vUTH+8W6t2Q$At1BQq2dxrMz9HfzFB`O8=b*GSZKey}3)&f4X zBAmfqVd?f6UZ_3$vf|iIvowe8@F~J<_hTUOn1!ibWBD=`6mwGEzYRI8QaghZRZ6h+ zr(uqB-tw3EHFrwxI@x9_@}J{+)LWZdD=CE_6Kt4Cjy6kAMH}j? z)+3yf>YaZHs`}596UKUjk{rJSqZ0B{do2dLd)t0O5%W=ip1jy{?9cU|D6F&8qIri| zGE#h&z?pWV-*ENkXZeJqn>MgtO9e?J*+j-f=uy zi7ZUnzvUmOu2F%>-XNXnRF4G>ZF~StlV9JOT%0?7XmQf%sHr8|F=Z=F26G`o5nCdj2pbH9HTlV$a(FSIcL>l9;!n??cWeQgsBa2l4CA zguY>MfVJIr<&-kBV&%ZSgIb{wKM08M@GZ<2@Lq!iD8bg(Wo@jwAdgjalXH7 zt8L3;dRz_B1NJzkyF@(Iy<4?O-&@n2?Ir8tv$?Mh`diku4++Hw;F){dnpJ;4I6voV^SO78U~^eX!c)e;bA-{{ic% z!{+1RVN>_dfC$>Idia!~ht863<_^C>+j5oy``^*2uPi8mZ`&yAYVq{N^j!Q7Xpd)9 z6W`Ke*-?jTR$a{p^-wKcK01Ho``%{8JZ>P5m79ttRk);>P;YuaJ-<}sUR&3vVcH4f zpgVQ2_P0=PLAHv~BxSH){(CE~wFFi$GLZ@icm`C>i5jFC*Pl)Def(;4IMMHLeLl0S z*0{!UpHCxGiwQfGSy{>nAGSzi9qZZeIISt@WM82$bJ)Jodk-$}7_dpAxnoOIfA8Ls=)lM$9JNVO1QVWf4r; zf-e6E@2ksMFS@N?0Sn)55F-rxGBb$0olv6dS}~ZJyT*5ts?dYf_`t+|E(&r}I#Yr^ zsG6&PqLvKR{mW@h2_4C0}09L8uYy&j&F&M%916n}DAfaefk#y^3G+DX|iI zbz0-A)orTKV6hf3PiF<(Ii*#kao%E7?mp(zi&LlDDe*2)o>56fi%O!=;jbP#HMryK zjdRYjgou28mrX!1RF7o$7pD%K8`Hb;yuN0iMSqOp)ufp6l8u1k1OVwo=Y8fSy?<(c zk-7c#H~vF9OP5-~mf`H`bW(I0Ub3m59U;-hwb`?;Vx3*zCxF^2 z8v_TBozNbHiJMV^6KrnKq@m{Lw$*17?+C1IA(>R_ki+9zfqQ42r52i6z6Ki#3I$q~ z!>n&1QPQc`TBY#Kza66!$5nj_QrCm8+Ak`qd7q@0OxoWb>kwBnXto+Yoi!8U9SfMK z1$NzUCQI;Ldn=3jLEia45THCPuu64Ox^2o*nA9PNYTpI(3H&z7(gQa$;CQtuX&vPY zeN%>CXLe;?i(~zqF<8Graa`uGeFmsK1Jns8Lp)yt;LCNp$Mb=>R z2B_|BUtA1Yqk8Lx<%vo-ynv0axKaut2QyXn95_LeNg$S{tiDT5CiFB+q6j4lkt_JL zRJ4BBFO6?dkZ0nYFsVF>jl@&^GvJ2WspFM)eV~TQxJ&aV>lNGUG4O5rZ*0o4gr^LU zZ*WI9dXRxlL8TT$mI6UP=Ls=d^pluKF@@C~NeV<*RV!s+Vot*HQ@qtU`$(*}7oz;& z-$(yNI!G66}A+GPH6Z}a*C_5jTSB&icI7pIjaOzkCc6lnl!iwAcJb`TItW{Vr zD?R0K-v@8J))XHY(^0YE+(sGKbnV1dFl(F=+!|sJduRKQvbm%?Z657hD=OyUai>i9 z`!`+3&$Q0J%QIw%ir~@k1r9}Mg?sw6UzsjWEk5YgAZ-k_CC!!F?At&S>vq@)NOAdu zR+LcChFsLULP}=#?)Vg2waQ_;$xmAy(+p`~^9T!Aw(B8OdIr=%FZ`V3c0(zSEz4NU zKM<^-HjT#0F^RI+0Sd(r^i7`XU%TD>z1qkR(5Z92!BAmKjsKkj%(DyiRSxB{;0Wf< zKto;1$(_9;QUDJ{;Jp)>F>wuYy1SbT$Zc$0@$1dBPle+5Ga6-ZdG?zF?+*)JE1Uqc zl5?T+AC7-Y_*@M7&sL2}L|?s>!>plnf%c`2@&vD5fpgeLWGh)F*$eAxerXxIQ3S2j zrZln66(;W8(SFzkNWA2#ehMG8d$^gRhtC6;de@rp^ifUFKZ90@2rv{VyZUA9z5^TOCqez%^UF9baMOX>qs8-oV$_#J6>*!wK-zA|z zn99TuFqY2YHlNVA9^WLlCwu`~lN}G&&^LCKRITtT;k?XRJYq?2moOA53 z)?O)+o|+&JRpPD1EP9=~-!bx9lg8&(O&FBc@ZY2r?E^9uO|PADEO>B9`^05p5tz^Bfd6BC(b)p0P9h^{nEp=N>V9N z^vwIVlpjJw>rT13sLRqG^Ymh~Xc^^UuqPH{*7ZU4}{mX|duIg7XzCxt&=kV@Lu z57qiNRrfp{oEnmm57I_kL61$fn?B8^_?ZpYqjU35MTyfMZu(rO&R-v{*}tJ8y391Z zF3yY69A|kI-o|q~Kp(1*SeBn(2iaNgOB8Y3;Ej=5amCo4PQJ*$+#}FSfz|X%$~R{~ zWG2^O>t+&3tTO=7`7a``Ar+&dCJ}09J%5RnfrB3&qWNjAcgZNHGNE$D?osV_W~GI{ zqL>|5(F(-xY?5=sDM9-HvfIjb_aVZ9yMPi6U`rnTpj#b|Vo`gDXIkX;r2F0r z=Ns?D&g056U`Js?B8c?x#E%EgpW{aT8+|>MMJ*3X7`~+G{8wtev>N`{MHU0#yU+(h zh@+nYqp7(GSD~kcb@_0)uUkD zoawygj+3n19Um!ZJk2UrhANbYx5Bk6pKkP!v(^ZWT$_EOCLSh{2A)h&@VOdoZpqZC zMYyiC{4_NxCfQY5I5*{?b6|K1VA9w`!|#W&b89$H2d{lvAUrngL)pbEynstJ-3nJf zyy?fyEvn8UC^9~26i7?*2H3E;LPGu2`!Ey6Q%6F-kz%HB;`qFclDPGP89^o%k09+M z4iySDMOH}|*E@O-YbnAKVL1+0yF{Y5biI5~Y8n3MpXcvLqxuH0(Z~8;g;+#8q{xo}` zVj}FF_^W8|ofpJ&@(TWiR~P&baw2J#(0EmaRAgZS&{;7wh1Y@R_iLn{0WM(-3mTX7 zNz1e+9QeB*BPXR$C^^qdO321)O_05@&^Jmp=mIe%mNqP$yxla?!=t`^h_+612F@!| zL7TYUZSsS$L9|P_ltv031hn+WpoTsrFyBaP_Z=T-FBz8K63#DZ&h&YgW?5KPk3Gq- z7i7`WW8y$>=|I{4wPLWWr^p!(k)B?K?+Nm}WrGPdKM z6?=7(B~kL{CA5Enn#tAch8v}PjC}A+V;OJ;jxfb~(&0#5xY>EP;CB0Cqcx{6Isk`` zR%1x_?x?tbZKd*Rw^?U3L#&0%0KI`?InUt={_lyn_RDUs9yIz_S*|9nT6NEY4Rbt` z=EYzoRsRuVt$k^$e1d#QHanXLSmtfxrr-R(4Q|jzp&qf8S3DG=^#a|fNO>xV1~4gF z=lfc;9Xgy$s$(}xc*au`K#F2dO5YlJvL1E+D$nff{p65f>aEj<$@%H2^K$M=I5te% ztao90RgrPnKA>h_WMW^?TB6y8(g*zrWPSS#uvukH^|Rw`Z-48@74}nAnC7f4ucJ)a zd~@{Jtko3S;(bQgT!BsSWfT|c&dDWq#h3y=d{F*KsLuf8(&xb**cH0Es6L%$8Nqx1 z3?Pr>pD+;9J8z#{ZcH*G1reI@R5BHm1G6r+f62>z+Bn7J{53D}}vQ}q)6*4vj zt*kYk6s5q{pH{$3@1xT&2r9(EQxKmA+3>*w2nQBr#7&t~o(;_2y@6kYkY z${`gNPP7$foZ88|f!RV@3Rn|cxA1ntoN)$rpp#upDLa+HJXHx6IYGxFI=4+wD*;75kEKSRbwl}+ z{m`KsAU8`t+qHlXkl>1#K(i){U!X{0BMfv& z++o$`$xulx5(U0s)d*9z^}N(OI?8UxW~_cpIRj|aGSrE&Fj|JGk~Ms%5iaa}KAG#vVV(p+;Eyv+$a-H*tWOVQ%-xft5ClY zTpctQi@ircXe^@33QLMwMt8oSdmXi@=TcL(P(##}$g-xvc1pM&zpF7s8QfN*rPz4P z3IgR!8&Ut|@&!?TS`Nd6ec93Z z0AH^bX0ZAguf#ISpKs!3C{leHzbG$)a8t*_KRhuYr^Q1nb}heh`*l&(Js&1<*5$?8 zV-4d=2=Umtn!Dht&M!aeni)mU$*4RQ;Q<*ivguaQC->0sdl`s2{qwkG`Y)_5&{^US zewIzrSU>0&w0x~7++p=7^Qrm&TgpUqXm4i}-COdNWMp z@r_5fC!K97m_CwdUHf&@P8=H?qeB>}P}WmB>O?K+v^5G3SirT2pvn40GZW#lE{c9q zkHKO0(M~+HT;O`vcxRfP;^B9^K)cQdMGN4o&|YIcIg)|9$5bXZ*Msqy z;o}vubanUDP4zd4O7k_bq9s}cJ5gR8v|az@c&Ym$S>?Xuh#Dqm&IrR0_s0q48f}-o zCaRPJGYP+T9TSN0L#QGC@Q~sf=@1vKgdfo{Tok)`oJl1qQd7us!-l7!nmcrwS{K0_ zsGgkd8HxYyxxgkJL}d5AC?a@6N#ktQ;2(jC7G zChHx8&VBi6`$0aVV^DOG=!r6{QKhg3y28|?`6_5m-70&Mo;D&yhRAVV*`*!cQp?^5n*cDHdxsX=17h?j9kv8uDoZ_QAAEn@cCbFSWaMc4J7#)uy-=6ajs}i%g82#J6xynevJxQ zye?%p{^!zjv0{z18|_uTVT`O%9MBSPRiK1H^*=HPoQ?L**2`Gzyz3^wPZ; zQ9I#nU=C~1BDAf1lRo{KgwAs|3{NsVAuJnm+AK39)S3eP~KS;h7Ke%}Xmr4%s?foEJ(_$ct6OGzT{cS)5Q>x-} z&W-6v>@+)9;DN(-n!^Xm22LojK(d3Vj_&U_(T4Ii ze0zUA%>MiiqS7tqG0DP-pq2K_Yk)C|+NRDMtx|VA187>Y^3$92U(ZDNY{mm|4QJN{ zJwnKejw%}Gl!lrD|5H$D;4IUiLPPVoKKk_pwisPj6<`V**Dg+Lj@a>BBZ}_7bNapN-I2Q4)I6w!-9@#viov(9sC2=U2B#?|PCWaJie_3)?n!)GF*vzKC` zP!)vO!{1*~Tx$(-dX|2UaCq)IIlJ)XrpB2*Zb=W~pi=?_@qP){q-4feM;P)W#*qGi zoqHeh*h|x;K`%$xOM+QJt5<^NTCA_;(mJK2?nKj7>p|vrpE03&uxVutDSi-Y!ueQ_ zYf57=anN=BQ$Z<9;rG;?9LDN^L9puqfzUU zg({hCVynU)y6M0x4a{=T?2>x(j{v{N&z*)wCvviN9oKniQJ%U7;xt6ZR)f<&ex)|& zAFZdJ$r z>PulJU%Ih?JTIHgTgDkj`<4l7lz84aSccf7e62KqhJ@|H2}Ku)36S_O#vykV?D4S~ z=m$+4IugTfEaui3Cs`&|BH zL>uQcNuj&waJ*SA*SE9p{rPc}ZQl%!AnfJr8{hP|4S;9o60xR#ibMSymP@*hgGG=0 z=CoR_X)VJUWryA%D_KI@$Keg{KOTyU*hA^8TpzGBWTmK1FK6nH4EcY81pln&h@P3* zK8=BZUIQY)C@-j%?@m9Sj&<{ORM^x64%3%wS>XpPOWssOtqFIW*tyn;%SsKm@iX8% zAKq9%K8UWqQ1lYcGhcShEfX|XwVXO?kHPJCK9x;zaew&qB};j3oLdWTXJZGI1I3bOKBPls$_BSzTg_(8b^{{ydRN(Llm(%PFr*4v_>eOU9cDM}O&NR;P% zS6zD&#A=URRB5BA#u`QI3|+f_ls2O*sQ>w1{0-{f-bl8}!b9Ba$tYFJ9V#33`z`MJ z=yHwn51mZQ;J{~qXER_-W0^Kjab6v%5$u;Q_x-zgk!*oV<@Bk|eU$QO{8h$2OnXl{ zRsE+v;h4Vdcm8HVqqgm}!ZWe9m@f!F#v+1i1^N=^dGT;HcfpX=8b)%luVU3%Wk|I) zru4TA7OkUrWUqOT4#eF45R2DWosD&Cw*iIZMwtQ%7@GhviG}nw!Tb(6OtT-Qi={-W z{BkU0b_xVIeG=>kA>m8LZ3q#m^lC)-Tl-o` z=x4M<7y*uGh zw&}l;q2Yc;G-{t6%&yt}+=imcmM*cEjFQZ%?9Qx6`W| z;q5M~0i?SB4PT_cEl>=#Uo-d=N@9_0sG3o$@hbEJ>R+$IY5d)MLW0W_(H%5373(O!Rk=VM-@oGZ=R}wr`*M z)m`qF8#98in3}DMdaT~BB(6Wi@`5|0>zbVuG54?X^SnV>(<3SN5UeGfJo2~a7$DKb z+JaaCxu0fV8nUOkcOUNjKRoC@1KKeU-=7sv@~Q-_9oJngbd^WxSOM8<^#D#h*!JGx z<;rt08AvwWgjw}lS0*Qj0>EB2kPCLXQ^g_7ws2Ym5u=4y&V$nOV#M9@+h@VhrK5Kp z8=;NMt51AJGdSsOydx;vxRSnm1;dO~bTogsKD1R&lg!$BDJ|@Me=Pgr_VRU@{5*p9 z3_y6kAt6)-!ylKxKS%*gsGl^3=(;tvU;Z&78_y1lVn5V#%1d9E>3ZX=H76yd&MPdK zCFr@tankM(d>Edl@zygVPi=AV&=hl6lHd?4Y1Alb#8+Oh;H?lMloxM&CHvGV6_z7` z#Z}kC#tB_kgYXAztyWSq8Rv0{-^yzy8J>Z4x}Q<#Jn@tx1eD-}p|MLCm=J6nHRJ!x)i zmXiQJCp;TfWO&;1SfWbin>u_3y!~^}H9SwG`@)+|u`$FA?1ETcxQB>}pEBku&DU84 z^5n@|`s@*eA*rSgy7&8>?`B7wUVTlqW8&sJ&BZ}^THr|4q;!BU)HffAX$;H%(>qAv z+1!YM9I*4Jb{nl08%z3YX|@Fhi|*&6n{T#vu>qr~051yX**fcnH8U1v&hu$wL~WQz zq|&~^o!j`>z4Iz_a5atThEvY#YYY3y%+ZxisuvpZt%df4weLw+3!%PbDb|;fU&R==etA_)b>OcR2pvMqGt~SR7nA zlzYbleU=mTfLBs9#%#GsX*ho(WX9PQmyW7Eg3QP(XudeOPnkLNoE69B=cXu`(z%6w zg@<_uQl^&wVTpA~G|x?_nP8b{d^_NgoVr9QRk0hJyp((X44|qs#8I&Y1GQomtfkxY zXIjI;Z4~EkHfl^C<0v?QNoq18kvAR%4=Zoo8iAf)t#Se11Qvo;u_XvZ1 zHG;$Lg74fZ*_?j1#U%m+B+P-loMayASA_>*J^3^+WVO1HEn@3yq%01r7X{VbOL(b0 z>b|Hh68-I^M~8S4Ix~7AqiM-4T5M+S`4bqc&XtZYZx*lQ&_U^aM!Q-cT(t$zigMO#L$EH;1yjx`J=qGE@#%mjpNFvr%dfUVgf)hNw);r zq^#+zW=7Op5%zCYnDNxvPJL7;O=nn}5h9xbab*ch+Ooo z3T+Qxv4()g`(1V0Ig7P{4Kes%Hv;aqMed#N;S|PFF;_&RHQN@RO3h=1>o{2YI!UN_ z-{2tl@A)pV)3z+Nx|+DKJ8O5qQz;D{A2dVQ?pR!PfmvnWNlmSsSX)?+R*9Ck1HR5G z4LP}h= z{Y6~CY4%C=MLc}EE5L5RftN0(fUx2QMO%oH}%-IjVc1W`=L=4iXF|u?_j64iepdx6MBTg4>fW`k_-^EDbd`0vj}s?=N3gLcnFvzV{**gU(IoVeXsq@*8`chX zG6%kQjJK#9d{Hl{es4;aDylUtAWdJ<{|=)L={Wxwa1ttDq|l4!w$Ky$3Da_7E}}CD z$^p=z5`A2CKmGtjR4U4T_d5|~Z!!#dTE82-g8!f)5Wu< zo}r>>K_~Oiu1gy7-PXg;oz_UE!7&a8w5fjIRui;j^m7q0m+CT>MC+9HIb4mVufR8C zjjh*Woy8=m*C`09b#;xgxRV*DsNHQVw3g2kOet@T+w(q{HBiJngb!J70)tipxM|MyGj~g_<+;q_n2CbWZbR|iU&YjR=6Lsiiv}b&IUgu*~P5{ zt8*zNs9BED41~?D)EIaWi(a&D%R|1YINfB`YdRNV5A*(m4tc-G@C>-MebsM&s;9){ zM&ae?xO}^ZI|ItdRTYqs?Xg1b1G%Cch%GL99)rZQ(GyzLLdav2!<`10o&gJ(hl2So zxWC^JS9Gs))0bmmG)EdX8;)Pqx;UWPm9b@j{-P>oWw+@-ig1QyRg49Jp2{i zrIAN|P;YI6??cvvbpVsV6|gl
        ^VTi!jUQq(hRGPRTB^V+b(kGpyPw_L9`?oR9r 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
        q<&I`8*AKpX=53k}M4^57&AK%IVE@ZSru%@Q` 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 NZTX?c4!QEl{{hkC%>DoX literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/brown-linen.jpg b/public/images/skins/textures/tiles/brown-linen.jpg new file mode 100755 index 0000000000000000000000000000000000000000..fcf4dffb938fbf7000a0375e7090688b79a1feaf GIT binary patch literal 44975 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/brown-manila-card.jpg b/public/images/skins/textures/tiles/brown-manila-card.jpg new file mode 100755 index 0000000000000000000000000000000000000000..71c11bed9590a5a227124a53eaa6f21fcd47f788 GIT binary patch literal 30334 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/brown-metal-grid.jpg b/public/images/skins/textures/tiles/brown-metal-grid.jpg new file mode 100755 index 0000000000000000000000000000000000000000..3c2ce2c4f080246b4d73beb2a04d65683a79be45 GIT binary patch literal 30296 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 CTH>n! literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/brown-planks-nails.jpg b/public/images/skins/textures/tiles/brown-planks-nails.jpg new file mode 100755 index 0000000000000000000000000000000000000000..77466f2acc7f314da62f045ecef9d18a862d0583 GIT binary patch literal 40881 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%0AA+nMOJ5x{g{7eeQ z1?5Qb-dUftx=E(;IU$(}s97O1AyC1an#fNe2&pGQo36-Jp7Oe?86TK;*$1_!IH(H#NO6;hF@4Y5`FgIMLdz!NbP#girpfw*2Xg65Q zGOAJsr@rSg3q?(YLXo^EVz`Nd$1{IXm=1&%r}pTqoI3{Nx~T0UV&qNrFt`>`G*5BH zY6`JW(trNyACFBcB759Z`gc<@Nfd1vkLTY)7QDSKzf}~?ClJyoEWiQRuT5F5d|;xg6YnvO1IV(v* z)E~q_1cCCdvtOW*#G)3B_NSSvje~Auy7Y%N=9V{RI~+NAWQ>R*x|p>-CxmJ%__H3m zb4*U0W^owOx~4Nw?0^+Ytw(~6WN`V*dud5yAgO5()}&O?O@3yYc=epXt3cwrDM8V4 z5tNcXF{_3%0}|O=^3K~q#IRYpD0i=?07wJ#&_`cue@N`74?%GQF$0QKgyHR?h84KG zf^_dL#E?J~{vc^nrhn`PLX8M`5PozI`u_l@a#U|1)YlpO1_~Z7@mnO0c!=dDMWfEjOJgjYuTolhHcvS2_LjGJjB)|O=JkMPBch~7pg$9=xwW8q zfCl@vch-wEIn}psp6e-VDTZ5Hd&?`K#R2Ed zHxy=OZMyIO01aqq^$#TER*l$>{xz4X(lXi6$9@O6TGb4b-@Eg;$uM}-2+3+jDYoa= zMSSmQ%ZlS_3p9);F$5+TuU=fwbk&<84a%M@EVhfTKqP!9+M?QoGy;13k2y)~1MRXtE@o>i+<*O#02?-%5HC{?~U^c6>M0T83PO{8wornMsqB zWQMH}003V@>!L>O2#YZUJPpdU%&peCOo|IhRlzB|Qe8$RCgw%95>Ts9a0BN`5Pmww zbZj6yvbNhJf`d&>%XZR1%5n)27}x|V!*yy3AD+8ABWZ5l+U&1;gN7BMX1TYvk(@$U z$ra>jR+NrD#|uwQXzAr=r|JS104qCD8}s^UY)KzV6Fn9l?m>8vTw5xlM?VUoe&6Y4 z;t%%dBUh;av}NWfpJS#j4>^xDr7*{hxOI}zno=1+g`1ZX^E4mv)npoy(AN=r?4v?- z;l#CV&X#8IzqwpApSnqHa|ti}*@{MZ{{R97AK9jKy6GZjTt|f^tm*N}@a03hZ*4`6 zu(|>}AKV(^o5b?fjR^jjVgUpDbUF2ml;$7}=xCaK8{=sKPURmeyxZZh*0%yXduFtX zMvO;j)ABvQoS36Y$k4E^+M~6v%nKAXHUxMM&wvWu5As+oxjI8-xjL7^RV zhCHAFd{cMInr?zIAbBL)1*A7#4d+>#Tg(3d5XoY^!fRN&m$+28>|J(+YRL=G5-C$d zr*wLKcCpzYdsKJ#8b?_^k4Q62$06<&&sXjD-0S;;kDgq2j^SdpOqNF@Iqk}k$ovFx z#9Tbj%cxPX-=?*{jOqoswFlG3^`KPRE#1Dn`?|+Y56h=%c{pWUcPa7RR}UTgf0D4U zWSaha$>)*GmyV(PiW}NMr}Dua7hZCAHP6Vx2m@ui!LL)MVU4-os&}EQ9RC1r=9 zBf4nZuu%+=D;`y$-0W+lj1JiD%75-g3EM^6{lCfEp-X%GY)KtV!PbtzdJ-xtUri=M z+D*r0G9_srr@p0!!|r0ZN#?S!mM{y5gwA_{hNqyX5^G%r&XAM_{{Sj1g|20RHLaE> z$1LDiiUeG!_Q`P3yppqqJFJ8eL(^(&Y6%1ZWGX8W!PD3P4%%^YAdV8E*7c?pc$Ji@ zawA|5Q}eE>-lYSaq>wp%1u*Rd&1yF0pf_>$qUJ7EcV9&c)%B<~+y4OHSBqC0oLT{M zN5a))(Y!P`ly}9e0q2%gNb$DiWE>yAxGm~S4u|s6^3Kxb$xO!s(KFO?rRu{s2r*Je z%Yc#M`2--^%uipWz&j&wT;fy@a0XDAR** ziO!bJFN~9ec<{%?Oi+}MgARwSYrjn!?pti6_RvO{mCT)$w`H8V-AgR3LD(A~PE`xg zQ${kpA`yiyAdHfuZ9~}O+?TsnAc;8wYQTRNQK@K<+>uvzrrQ8ggSWT0l%97i6Ob}O z38V4efYYbvu58mV>@^a>3&tc>gX$sgD~3mpiFb{~2eoJv9Wx8_gm3_ZOGwX5*pdxH z1B;))%fg)2@K z1QGuL9TB>eyG}GIG}*sUpe0Ez=2%_hhFDy)#T0?Vfk8^_fA4D9iw5z(Z49xlz@go; zhd6e)DwEvaT&!lT4#^)AS^ze!KOJ4Nw6!ol8!C>4z~ZBY4Q=9A7Pk=HT3ySIogB)y zamdK%pzXR4cCMd;TILmK!?N_0`WCz+jz2BcZl%TWxRWcJd6gqnlj;~V%OwJZjdvuG z*1no+QLog@(&xIvea~^-OKG$kO*@gTL&Fb)OnJ*@g2Y`(Cuvki8X}>MeFwDl+-x<1 zC3J+irE5Aium*r@VPP!ttnyu4TvD82loSaV*qYFgeJQ2hTPgzVX_(sRmn$t+FQhQW z?{8w!!yqK`Zb8@%iZ>)4l{!c5;lnX0Oc~}?00pKv*sd(%j(F)5fk;%44l6-Wqiu1~ zho2(zRH6Orn$#&sUm25Zn`DP=t>%7kzy*0b^(LWc3DbU@jf^toMJUkIDSin=JU5C{ z>L!jkB?tKg7G6X3(EM~}=)+QoHE%0>?XBj68_8n&iB>{DMGAe!yjTOrrFz#;G}5%- zFS>^9LrAgjp(M3}zk?M0af)t8}LvTZoRAUWvf->?( zq94^KZ;2k1HQJw+tS4hhL3-mG-j}sQ9wpXZ=#<<>>`xb3siCDyQh@xmKDZnY3ZRL_ zR^q)bCMe=*qJy;*txAgQPs8GMcLgi5xsD0OtD@M)a3O&VfflPXnlUxsUrO_d~{I>x`9A50*Fm!>hW#3aGaP*(3s<) zQrmRg9UZJ@+-MJxNa6(6gcDUCA)|WkkY#hcqh`*^5si#Fn$I!s zs@z!@j&%+i+|N{qJ8}$MicwS&Ytuz^akyBm4YE8flAas4j&-z{O&PP~p6=m1_8qn# z!NmMV)zZ?&2+E(88aYVwExvqKv`D69y}U5V*@aJeNmr7D({-&lj;G)?Ei7xA)`jq) zJ?_d};)A}Sn+&pB+Zbes$!^Wtj6YV9c~+x-pDJmQs&bGR5YRmqI0Kz%WQf?#W1d*m z9XpdU{{S&Q1yQy?KAPvZ)ZCO<{G9mIw-*@2xU`r#b({H0(K7-;-MgHkft(KQ%G zYw_Q{qCyOU*7&s#kjmJ@eYK%zZvbMFdt{&#K?<(tru%f$QIVBPl#F*$(m7m#wm4C? z*=W=G?Qbb`3mlWDCqhBmkkB^6N{8uWHbQvV(caBVEpQKY9WHwIYfI?W+%0A9rW+K_1TFq_o%4BCk_gh(rk393Id0x(jZIi=0*Vts*1HWF zDRk|*W;|(Gbo02NejXG%X8fi_x=WjgS`?F)JD^pfd^r#4J(KZ zemn0|CH7y63tX(Bxq`DWar$aYS!+n+K zF9K140jpZoim$g-jt85CBCO{`ErlnRd;5uaCCg6cUNgK>l^`9zRcdu&9df%XgIi!W z@U;;PZX%VKvIv+VGCu%8tvL#kXh%{tR@pwYurm( zR3;xYL3v|Q&Inf;9%};6B#^}-vZ&&MSE*8IK*p5#>R9HWWLE`s>Nm<%khlOi=N16!HtU%&oWPG*{^WMvQjV8LCxw z%3p7JH*qcgrJO8*-QGWFSNVZbDWaGd)}gVXws*bWTZ%4bgt;R5Vt^V1Simg)pBjD| zRq&7sA*R_j3ZwC$zPii*0C8W}U)TI!9-V$#k3su}6>qv`^Nl)?`1;%X7385L8juTD zVYkoYL8gOb-$*QbsK|w@apKO93U|1Lp=uwQ+eH-L-hk*1^$U)}+eb+9aO|q|7XBKyr?q`Nm-S|!X*g1wq?CvGSn! zy(OpnFyg@pX**8q@Q3xmMAw0XKhhA;eF+F*2p*G93?O)EKR3I)JJ_Q>C+J8OmqHY}I6F{ai zdw>ng61{y#_UV+3Zi<#gq?O5KMZOiLN^)b5vtcNZl`dLXsu-Z+02LG-gdG+!1DuVw z9zBayCRVjkcw6xmP=T=%-G<4=wo?E&$0>IN^y;-=o`tGvA0Z~(Q^ZrcSsq83pnvgS zogXEai_IhgEXUExyoq}_=5=FFaByQQT6NrMcDdkSNZP4WAyc^QN?X~pTZ<@7)wGMm z@w{&DcXRFbv}*MO;6DvI!mKI?q})-$z|+gSe;zkhQ-7FCSf$0b?F*?@4nkAeRH zj+KKeoIydoe;`d4Qu!LtLrL6;^)xiL{y1WjyOGE($pL?v5vWh`F5NnO^w1EX9#r3d z!j{dc#T~?XerrP5+E~cSw;5KqcPwmOqb|yJsG_Av6#X69E__JkW9@W1aWXsH3{_xeI3mK z!s~5|W4j8xGPtz)Hti!0`qLX@h8ZbM#&KFoRTfAk8w${Vo+O`{8XKC`xhe6D7)dG| ztR3URonEdSrN=2_S$6LCRxWg)t!PQ(qvc>g*C^PF^#Zfp_mE54hiEC{lssvTR#Obn zytLR`fm+kkf~f;tGhC-JDN_TO5eFnnGT7QFgpjXy#mfZv?Xwe4PmZ8Q!~OnVNARn< zSFh+R%ziXna#{u{9k^s8`Le4TaXo4d^&XV`v_`OPaL0`e&vpE#4iwEJvX$oV+*{j8 z8UqI)&LmEX4%G&gJJUsDV$3|kfu3;7G?BLqDKo)^Fx;DK&ND{rZB(fVF5{5)sS1BR zG|<&KjgsiL@SvAGrH2Ji#)h6R{-1cV-LKG87m%elrpm#28ds*e0sttaZQoR!IJhZ8 z;YwnQ2Ei6vpo>x!)nwt*t56eP%DM!CKzyc{YnhkK1u=kN*4_mMM`9n8i~0fRHgKk- zZ>q>0eBLUxFp*?W3ON%FuqV+?aPabO=qdoEMQd6eQNmODkP0gdWAxn8#5g~wo4k+6 sdV)n(hLr-V@#=I(Hbk+ZG{(4896W3M*6H*8Klgg-nP0qBmM%5_*`=|f!T|H8klW zRXQSqf`X{1m*4-K|2glyb=G}%-O0*Y^UXK2+w48_&E9+dzWciY;6z3Hc>@4wv^ano z@ZaU{CjeM4(la0i00fXXruz7Y|js?yTI;Zp8iAs!eh&yXPLX!lTQq?C*_ zKwUFB)ZH@x69M(W`1l2Dz&<~F1%vu|X~66iOl3?%buqqvhOtSg_(W@#AoUtJ;sG+^5QV1+uET0nI}uo$R< zl#HaOjG_!w5h;a~lUGtwLO^9@kTTLTveHOdNu-jhoUE#h4D>$>>=GN+%Ujh-Pyau0 zT|Q~R{*$R2H*QGXkdq3*`bZ;HR8;<4~lES}X{7+-`^>lRQWEJ&P;TsYW z67Cxk3e~lihuZrEdxhKx|7UXkgI7Ha)-MX5>g8oaos($|i_Wysb|6{Dz|Bb|? zFNu-YN*s`BrqOa1$&`d^BF`S4$+g9*O07wn~B{5=9N{!85fUc^fS1pZwHBmyYO z$;m0mDJdu@X(%uMbkvlT)O7T;v~;wz^vv}CD$MkZOw3G-^sKCGY^Nj zR8&+9^bDNL%$(d1FogTRUi_a{{t^LTYG4*H3j_oM$iP4l82EPpfCB*kDgV8E0LXwK z0Qvv7@sbNNa^}l-WE7Xbf3ZRa0s_fEU~+&Ul7&?pX6Y^qrwG%Dm(yj-Znd(mc`adyGzZN!P1V5yu;SPI z+j&EuxuCZ7s2xm&+X}j}Kj@tu7MZR(fHqR-!?M6Zj<(q`f0SZQ1&;{qAN^b`@`b~= zopRX1?@FdyycHX~G2kC3-wdVCemOPnnY=yKA@S>G?TPC4vlh0(@#{w%UMyu2a{`s2 zk2@`$tX?`$sEO?a#FGZeHQ~&4^u@w`8K<1I=rlzs6-)Fw)KmDmpC~ZaEnYmjoQC~TQHh*v^ zd+8uX_9i=pbC|8!budK%9|?~zJ^lKcN3843b<-EGtLjBHLn4^!i)l;9d{EvuYx`2~ z9o|OU#JAtoD-@`fU;ng(|O_RmslQ`Nv?py^u z5WFJEbnXU&|1u8TR(pFLpS4ilptTyi-fWSP#&$d`hjm7(^kW|@ll}s1V@t?l+;RfUpmZbUSJaERr zw`8qnEo8_M*|Oy7ZN#LeRLFLxYK>Fg3DH5z?5f6-rz__t*p-J7LI;+v-Id}E~(WI$i7F`dBsJQ!YSppmB2n+I8Xj$A2-g$;=QN- zRG&)rTiNo}jkgUrg5j;I463q4y?hqTkzr9bUd7s^vk!Gq<@Uv^FJv)!`aSCi)T8XEn{7+OFR7ZhG%9^s=KNne zz$%c1GxJFtw}yue19Xa?lOI@aY~grVP{?JL^ib1@2fi$r=JUFOTE^b>27$v}1xVW3 zZq16{>u`Pyb|fH06-hVz(gWt4GZ@u=@hoZFuw&+>E?aoo3HqvuU&tMn58_&Qx5(LM zP%{g`$miA|b@Dj?==&F76!z_yh&=%@^DT6y2zBN6mbkSVYvgWqx$`LFDdPJ zz=I)Q7Rx;Bmct~tJ-rvq!;e;b!zj`=;-KNW7wF;c`CU)hjBfByGQJL&5ZtsqyDtF zQI=7U9i;3YIN< zNKtz!%gi4WWYZq(hdwOsxXw78kV>x^LeJFs^82t!?AxlofIkk5jvOia<-?GH_zgEr z*t+)(dl|-V!S?)F8oI~4a#;m9fsr0-t@W6)ZgI3wb96)+!EDa8fHW%0MgMcg|K zyEa7#uOXwt>ltNc8J%WKS|%l; z4t)^mO$f~J&!T;eRwU6;qXmv)86(R9DQFx7ek_hy#i?6SWx7kg;CQ%IRTJ3TZn}4> z46n2mQOr0@wjS{{-(L|n)|)4RoZN)_1`(KhPx;0yQ%D9;J(+jv3mN@Dm4>6_BB>`9 z8KcVb+aQxKc8|DVavbUfQ6npP0!NbJ6@LM>ZgOH>sW727ph8Z-3#MjxS@{mmo0`Yp znPjJOHsfWd%qh&tG zeL28o9MXB`Q>I!V(Vo#b9$E*1*FJ6H&kSd_Ri7e_Zw%G%< zhq8%iCIJ#G+hKwp z5i5d|V>6#yIxGHwiQJ@=rxP;$nDS6k4EJH4ui)$xSU5Q3et6kPB!NXg<_A5Sr=IUq zO66egYQr~c`_ApfzBHV0**Qnsf@EA}#U*ofQa`9UBT6_V5N>Ier z0AZ=Qf)W=83r#hD7^xQN^q=F#EXi=o=;uYCp42gz8#5L)`iPJp0Yw!meeI%SW144p7M0`c^~M zSSqVB3)JnG`rYrPWQvX_^@r9xPv`&$AOH_y!xj1tYd3$$b8-9TNLBp~rS;Cx;d|Cx zPNp_+{cTrZVlMZ#feX-ANQVuQf79&T7h5*pK~=2}Y-_7W1U`XDOAo7DSxJ8JrORjs zmn9sXVX9Af8h5ip+wtmorheuIZVNWP=Z2(9RgyXs?6J19{tK`p8+k1TvqknRz@Dcc zCPxAg>85gX>#{6Chy}8ET*q_JW4$8tudkgDVQoVTHh$&2N@L~u?9C%oE=h8)nQ1%_ zrb2{yUq7cw|8>^p;DJ~&I5xboSV<}pLd>k z9Up$QuOSaM$7+PvGbQMuhNWpdBd-`$}{=`)Y= zgny}CmR8L+^}myacpxUsMnCMTrvyR(}!46;K+c zSCX=1Td?Lk3|SS8anmdim9MsYfusmS1g7-IolVWcEj22)4SpNrW|%)s>#|kXWN=-T zwftT&nbZ#9c1r;%YE+rAlUOb&c}#SS*%5tgT+qt$VFnNqP&+|fLnu69R9k8 z-*Gn3tdHkBNzI$o*ssB8z#Lv@dSU`XQ*XVp{!ZNMwB5H%C=i+^t6VK!WnkO;m2UUb z-yUcOd!)P`G*i2CzW1l<*Jco<0Ro&6n0wEiCIrsWnw6mZc>d8n(8*U)~YR)K%VcXw4Iu~Gv( zkUUSz_S#pcn)6Zoays^A?t&E(g}Qb;>_1=6b3d~%yLje4%@x%<{mfFzv_oQp0pZpR z=G!Y`-?C?)Rfp+&y3;R64Dx;+jA&@Ir^aU4i!0@mp^*|oU0PgVJxxLGoRxdC(AqbJ zz%e1Wgy%zSWRYy@Q+&Kk-|p|=cARn3DJw-AR&Ql7M}v75KkA5AtR7wEeq>_OiOn$+ zORm-4PpO3KO_%2^cl3IWYqo}#&p!tY8gTL4lyCjyQu%}JDo8jlAbTHYg_c!qulFib z-WR`fdv1=BWH0`WXxL9kWtKX7eCv5RQ|wCFhl|mDT#47A!&1qEn)3x%Jok$)9oR_| z%5-j%Y|cXc0=~Cz%)(r1D@9ie>GcaiNG4H#PAf+-(W(9@F@u_Rf48b5AvCw`;`qgl zF>}5CY4P8&>+xaF^UESv_Koil@RdE(Kw&=F1>kV3j2ziS@FSH8Z2n?9p?yAJmcq`1 zaL-@8vjfRz(%A_3G8s%A&n0BjAzYpI^x`J?f!?jqb4(5G1~k&93zk^)N99%dOxxgZ zILQN0-{?+w_sQ|ygtxv+`0r!Zbzi?UrTTU=DGF$IzCbp2Z*?p|D$9{m-|F#pKwd}Cz*A|dzQeU(jDV;TnPXtNO3 z=$2WzG#&#E+6Unsd_A8`Z?TZk^~KW86yieAT2~emHd0eQxb<>zxFWkdm z*Rrzi@}lbGkE#;tZ|fPJr$1D9=G`xYhV{B7mh&q-twlI(ZE?T2dTxGimV&i4&*b)s zQlQgf?`y1>O*4*925dB{YxqpE`Fh$R0G_s2nKo-B1J0XKDP9k@bq_hQOygcS+2vDb z2<28O6Y=OT4u~dZW2@dy6bAmRon-dm`Gf*9pXfA6Hr$$7?lk36DQ*^5pdKRzrKr7l zj~9w>|NTYt1TtVB);Cp2wb5QWMvPSau8CbJKa?kmMHPw2RXFSjN?Y6_#4pNb`i4SE z4fC3{>krenVU|u!61*R&HgJ1BcpVIxeit3zsQ**vmim#u0E>fWakZCg&&=hgpuT9$ zhk?7*jE;HyoM|6&Kcz{8>#$86&(MDds8xgzXXS8)wfh1bUaW78?W}W^=o(#}@j%fo z!jg{7a7gUyU<#(ESb6^d{e!ghQ0ur87w9L;OL@yt3ASOlBOuCYC7)>30AH6;!>UYg zyF!fb^L4xiGz?i<5jxt~lSt6Xz_qFh1;oo}`UO8TPUjn(N}4=kbwb=6Dc|;SQ$pCl zO>AnUW0S+(Pj7luxpzVQg|tF;8Kb{DyBLOV@T7&g(B5F8&0-W~diA2YAgWLB2l*_v zB;V~$KSE1qg!M3NOrhoTl5E+0Ja=^b7EX(Ln&n+^^z`G_@WSZHX87K>K`?7Xm^e$S zj9gq?lLh!xboCCNjD}#fvfoMbqQ|m5AugeN2KPJEE<6N8u>GznvEx|**wq>BnI-xq zC}bD2i@{Pcovvb@7Pk((xnv-9%ea)I36^TtXpa0L9l7YQtE}E~Y-0ce*03sD+MSy7 zee?vTc9p?Y?4b#;%qx$^zmWr>luUXZ!RWLLBs#UHBa5?#kz3ETEr*riUgZI$GCb&O zCmJ(1q&rT+q_h&mbJ8L&Lc!Y(ul)+{P|K{$UNw$-%-jDsC;+!PGvpu;YmE8)7x0_C zQArFkR|A5coan=Y?UEJqSD&iq56o{}edKtjj26ukHqbe6FQe$C@?U_Bk5Wq7f+R&K zd6IAUR+jka&`q*R(H*iU;A+4V6R_>~CR=6Gt$clv5+!j_dsVOZCTu!S$=6l_)WEX1 z0LTP3Y3G_ZAF%`;7do2NRCriota*%if zZr$J|R?T5!^WR?tw&vF5Q}n093=RiAVOk2R_4HF6u~MF1)!&gx}AF%O*-4K%lB}_jyC93vPGY#{N<(EZ&`E)|376v1UhHu^aIJdXEQ^FmLuq--ktYFpsKgzWv z?VdU3ZGqLcIkxO@0_%3%7rWQ_hBne&K~dWS{v2oDjZIQM@NU8#NSM543d!m)CX&9a zn2bCN?Oq|DjCK9cwPqV*dCNj+3%j;uFe=OXTID1#e^)E{c^7+wEoE+ZhsrJS@^yIv zyIqF!8!u561Q+f*?APX%1}SkW-Uw7D)(W-Vl9kirU>#u+dBI4AxS4HhKp&3uHFF*8 z<9!X1`h-&95<&#i;8h-A#yvXHb_@cZ;51FZ(_98e{I>P+gC~}C<35YBOmbHuOx@r%Ca*O!4a#QH?&pwHEGX25p7$ zhVvV9-RV$l0?*)P?ox;kBZBDgqQSznn)P%YZv9Aa6U@MUs7|`-#>s zUfN;V>_WRS06RlP{wLeq(ChVS^XA)c0Hhy3JeW-U>bPS73Js6Ur9M0oqETHC z4Iav%nR(pLW-sVXFph8IP#1tcs!C;xGNAxY4l|3y5bR=d2o7whn|}fMD?hzxRpU!T zdDAQ@r%7*XeQ9co7gI$#pqM|L01sbBn7*vK>+g)@M0xq6#Fmpmwmx&-&=$U$t*zp+ z{8M=Y^#j*#XiC$z1?YI$Rq@o#{MXG~$l^Lsg`Ug_n!Cb?ln8Z&jte#X2$zf?KXQVLybp4Kt`6^9#xP6D&z8Rh?SGY)>>QCd^`N^`YM7K)R!7p8Szi@-g5< z<<}a(r$kbN{|>zHt3&H=6@62#=DU)NqW7W2jpm12#YQHT4$WC!{f}=$15-#}&1#f) zg6WP6y2O8aIqf{mBFYJkjR=kPOi|y~0XnJ614WKiV%Ej(r6yYDAl?#30#~nehFE3) zDJuk|av@Q{{h{jbIVAYs>ORnMIOpES)eTt$h0}-6A9e*WOwBVnDIhJ(-r8l~W4j@V z&M~9Qn{FG;(1+?fH4?6g%-`|;0r+Ofz#jQzqmYxakklktsv=|yz7A~Y^J~L^`iJ`| zl&kX9GllY}Z#i0Rt`z&2bctS#@u+}qMQ8S~wB3~+es=44?~M1+s2-};zNHKNbB zI%>)i!QCNYVuOK=@)H;xH_g-%xoDbdX~&%Q3Q`B`&3Tp#?P@}ng+0TajJ?-x7uR%C z&<9=^0|irLK7-V0@EDnYpNMkM#3q^LMfPh&P026ah39Ly==cZAntB9 zzf4E5bEGsK@W3QD7)ORTCjl~?xL1l=S zhOc3b=uWf{kOqkgJvAu*3kZoS&Un>ufRlne@+k=$hJT4muzDUY`pAf>3}`CJts70# zovImhJN;)iGn?7fEo~EKT$qi}NSJ?z0$BljO{Ml6J<2P=#+PL^F-J!wu**;KS?r@H zDTDfRi7m-Yfk;*d7E?P6z?gfLiviB42D4}HDQJe;3R>Z z6D0ngWRCRKoEtdXO+ANUMu(o`nCT@u8#>OElDgTEMVpJo#Yw+0SKy(4ze08R<1*R? z+T=7kKP|4wV{Fdc&&?~QrZU=QDqz?OEa9k$yj|R*hrg=1{fau|P3!21d~4xAmF`VW z(DDP@LfZYgb)kwmlUdxb8~z7M)c#XxtZnS(qd~ZYSP6EF-dnBJWT!K0+9f(mh7IoA z?G)ZF>I5@X?`+DZnut4wjIbh7dAZu8m4?Qqb8${A5u9+tY+h+rgt4HU(`QmO5rpME z&}|kSHyAbaFE2BXr1}eRJs5g8^Db>KtZnN%ttAE~G4Nz(l+o&m$wjMWx!cZ~KSRCX z56)WOQ53u7IbRsi7P+U5$TB#RMmMFBe(Oh52CY$~4E!o)_Bua97^C@{SR;k(**wym zi@t}&F zLn~;hC^93y94;9O+}5SZjnWNWH!J^xnkgoem|6gSz*{<&9o|I$enoG^O89%$A#$)Ub{6$ z7JYjCK1?C1BmDa$=Z5E#A^6VwJE zWX4fEc3P?}W6S~Xd3Ww81{l7^z{L*l7o-fb6|w1OcW2LYeRBEf)#a|Aiq8`mBlk|T zKilNayZ8&Ze}~(eKxP^nQ3Gqwq<>UoKz>qSe!*c}7V*m&=wzD{{^ohun+v65o3|>s z@~mi|(zq~vs}UHNNq^iIX@>K0tj?lDf_?-QvyM;vS>8_cl!TN|*-UY~Q@+daF;M{x z$b?q4IX@BZCY>yG1^3TNMjCOgdq{;lgjAPacZhzQ%*dE@|1 zu^yU!`g62s!Pr{|PF$O`)00f3g{#nJErIg`bmR zJ_)O;8!UjYYET07Al_X_zR|n=h+ac}@x-@G{~&3ifPBE4O8@2sl~REF`6 zk+Nw1sC^Q4s(Y?Ojt%cnOs=C3bg}n?X`KtGN{I`qyLp6*a>hzn_gEA|`H+LMg z)u{hy+e>l1J|vWa0?L4+U+O$V?-ft$*^e5+95|y!MFI70RPE&yis#LP4O-06O$J~cWK0a5l1tx;#stl0DTy%Z+457Ui7j++#pb`RujoBKCWp_C4D zhwML4YFOu%v9t{hW3%|@$F`+b(f478X*ZU!l@3zOSpq~5u6FZE?whJ^%B4R@>t?k0 z(O-Zd?wisP)Z31CcDWWGso4~0&=6eJ3?-RL&1H%SO;Zv`2V>+#>OSLsI$;L#7EfVB zqR#q++x+x!vtqMjNsD$$NRp_Y$4-x=%fqp5?jf@nMG%_YgrJ`0nXu8R9&z!Y8jvji zCPP1(CQNRHhJgrlL1@A%v}iYzL_oxxgeUN+=g0X#JppKOehPra^4o!lme+gkUJLck zQ8A~P06PWJ!SYU;3LN~j%8JG-P2=o`K-4?@w)|Wj(YIWhK9umaJDI-s+jcm?V?QM-imkSHf19M{Vo+ zBOX;mj5q^@#l%VDO}zF9c#riGtgJj$tl2AilWt{1!Xz)Fe)%F7mT>P=A;ZVk&(Mph^^Vf(S!*Nu6<@Sf;RAZBZb zbN99%aaaE1XHz}Ey&E50-Zh$_kGnBqp*Lmio1=cRfS@#SWygyy6O6Tlx}XA4bGz2# z8I&*IiAY3U`rKCHoPU(8vDdgduBU*7kty%f#114YF%H3YiNjW+AYMooINMIA)hzmn z&F$RNk^Mc~iZY9#u%+nrv%dh5UR#O7NfR=py!69ok#33o)~+|L0(9bRxOZ@a>{`bL zf!n>w1zTQM6ty4d%pc8k(*=GahppW0S#qY`X+tSQJ0s8Sfit~^tO*UgGn5&fE*#Lg zCxp%-Hw6|r4Jb2fg(WnGc$Qde&u4O@YriZ@HS6F|g#pr)W%Kaj;8CGjxvmL8` z_Pa}L#@Uvn84Y=A^Pxo5;c*nzqzPF@?+lhG~eP^asOwjV%JU)F;r(m|z;+cVp zk^t`jaOkuFRbCxY1L8`=2Ewui!z?=9(q(D(hh4gar}-8As10|6C3*vR*Uw0*(3w7F5peKeyc&@?TteHV&n=Xvt%(mUq}Ja&N$3O8azzd8e83Zt8I z#j}H*n~d+)>zB!h?8U^K2hfQP%^ho8iIF4A_@N!8v6zIdV`Ov+$p^Q+_4@_9e)-LO z{L@AyT}A6T39yOfDo&6goD!#6E2@Vxre>k6{BV2~TwIv?65l7oQ?a%|pHtJ=jtP6mv~} z{87~jFnDXoU1m^6bPgkVGQU->_90A|e{j*K@$Ch0Ze|?3skI11S4kkQ|9LU9-PpmO ze=@+8hd0yrY)3N3;hYlMK&ZTcvTg<;a`_r;6HFTNQ%ZXiE~ayz_Iw{Vqavik^VPd6 z-D}JC(wCL&G!@Jj%4xux-J6c(Ybv#N)^ zqpqE5smH4YK8qz5CpWf`Ywjhl@$dQudcyr#O-*#aYexH3%<}y!8xnb-pjh zK;YC3gdllw(2c+#>D!hlrGd3n>_>$s$sja5f6WoBU1qFW3#sky(A=;+A?hV%Z{Zbv ze6=5LiKw>Sn(BxoQj#Bswx+4&Gtlu4DA9^qoJ)Y`)_ILt2UZ#eM6xKaT%{XOUC`nI zcu}kTs8wNtTzEVqpuUZFOll&?^uyrl(?>w^>(IN<{WFuh`zBzAK&?iT0`@dN9gPFe z4U>9RH#r_srl*H@N=Qf4TZc$wmz6=X=rl*vT-U_2>Nc#H?)Sd6+mHcr1QrIH5e;TM zh`Nlm($(+nQ&H&aWt-$MWKUdykR}&PV!c3vGs#|G#*MJRc~!gW0t)H|0a_h%AzQ*k>IG@#hF(Cv!7zE~dK4KI4O`Wiryv`0 z;=A7a>ouU9m4=>0@^QUmYvn7GuizDMU}--nT*9S!etGzWR@9%V1~Wx#53#d`84HN9 ztSk$XXZ$#HZH%02ignAVOz9j*>UYs1zx>9$AdNKW#S*$H$iyO?v2(efTdsWDfxM@z zly0V-pHcBNU7NFK)bTN+s}3Z}laPM_>RMOwy!@`@iScxCkor0(3`c|^M}yk&-1xTX zUwRyKW7yjza~HAeRqoN__rx%rra5Hxzb6`evE}3e&D5qZglsc=GM~qF8pw@-_`h8h zHb|!Z@H$vH{y}KtUjUyBR|{2mUwG5)ZZZt|dzD`Gi?PpLqsctE6>ws3GpGu$Xtmoq z82;m)#?-1*hPW)lw*k7MXM+P6_=CllmX>Yq`-PE9emIl80JOZ3ldA4Xi&fh3?;HSQ z?5V07`<(44L=i%5Ky0sUDv>VAu4a7`Q^K?33jY; z0S{Y;LRguY>WHkvihI`m49jF%kAK~4|CK2V`AVc2x9SqAuEgsON8S78Lv@)}J5y8a zMm{=7UqCJqa(O<2Womshc@@=OF$jS)HS-1Aj0P-#~;5SFCvI~nb-2Eol||(J7ooC3N)r(y)6yX z1~*p5CF-&rk*5~4Mm+orVCMO;NiK{hOoZ{1wlB~8cbFktd4_c251Gmb0d}gX$)|Le zs~yuzx&1a362$ zY;Ywb{34?2=giA(1-Po4)VmbZrr{v$MZVV@XEX3f_w?(ao*S>649$3-G{L6Yz0?%4 zzt6QPuKz}91e=F=Zja-=uUBaQBZH!5gmb(>C|eZ&?N01!CMYeyT%CMTe3*ZBL>_+Y zX|}5`V{2L7V-vtqhr_04Mb6fa22Z2VdL{(Esf81=>XLlQG*bfVm8HCUkfuT%VILAq zQ%pFlhW46r#_(!wdmLUlVtzy#<6C#iYy;{Q#ZI@-RAF}HD7-T`|LCaN$U9Z_?=Mhr zuSg`1I#%58$Yj#!fy`yv0||C)sU9P9UoRrf0-2gwx6IYS(Or4W%9$c+pWch3LSNR7 zeBjZ>P2_WI->~MD>vpb&oCQ-70CE+|l-ych(W>)VVR5-0iI8e5%;l$14(TFA$m*+; zuyMddU|*y9{xwSRr{eps$-VL|Cyxop3QWyzQt#zfDG0}8Ec0s|z64o*TJdp6;o~{L ziAj1&X{U*83%;BE{bJ^)gT2-}hMFRW=T9?hE)&bZKG|GCV}AkMZfX2_vS=Af<52iB z*Bs}P#JhD+H@T|XXB?}F`@NDqsfQ)s#kjn?B_bEWbkwZvAi_vJAfK|_H}%qqj+dDk z=6gy#p7&sDj5jOZAi3kqJ}y~#F<-f;GI=9?nLpd5;>dcP2VgAJW-31lOW5dcp1Ym# zQM6f|B8;*D>EkC&Ifs?JjiR`vWhr9)?aLtRO5*4hUAR*`2MJZ4FCv7vJA|86*S0Oa zjs*&xk)nWwWm6f$-{$Daz_O}^w5+nZduw=UCvb)iVI>^X+7nG-bY zFL_>sF#`&WcJf8vIIIb|-C9m}^D`Mgo6Iw?vab%KLLt(JvKj4@Vk9|tg%ff7ikAUg zoj1p?nagvr7hYA2!>aucbz-dn@Ql)W^rigOC9OZLHlxfUmzLI*znHrYrAc%;91-8r zCDk$&RI!$kov0RRM!jGc$b!t@5>w47_`*p&W6HRbOCy{ZRMK^@)V1~k?LxuQt%hS6 z38vG@y*RKN$@;d^>julKPmfyjxW3}RYTa`g0u#cxfE-LEyWacajm*z8cJ!}gy_SZf|*Dnj>vCj9b=QgMgjuM(XF#uqNMvP z+oFC{-ESu?RY2Yb%x|1-+az0c)>QkmcEDcv86vFTf8Nfn`+Prj%XQ0|pgp=;wRduAFyL4xir_$gPYthE(Uz)OzT#P{imQyTIR(gL&3 zxCbKGex?C(Lc1#q9%YdGnPJ&j09iS~JHkv0EN4pI?m@?z15&Eqtd~Rb18i4WBZ^l$ ztmH{&xgHjm-@j=)j|G0JO+ifONk9FZs0d=a z$n~WFA`H z?j&>8U&yEAJD!Ca&Z<)iXC!g2#5;{0f5eunpux2@#q^X_bsG*h-J-V7fAAa@K&M&! zQRexeY)`Bxy)pJwi1zl{j=w~;@7^%j$;7iD>&=j8jRfBW1-U&SYDD|@^}RGXxy%`b zcXe*iA8cF+Vwds7-x^`$e#*P*IJ9K%r=A+`06R9Otnp^iIU0g0oXe+^e1OqobFqW1 zuFi$hQY}?*Q>{>}V5?-8cCVLme*vN0j_`I!luv8)Y4yxsAdNBjS;%mzl17AVs85s~ z?akDxrW-7^p$E8cZ=l{ci}Xo5yh_IlC)Lwl*Q+)0plZCWpHP0=2pRda44cNz0k4l{ zO(quXa=i67LZVqCwB9~lQmW;zF1U0y*lpk?q8O)>A8ge?1h<|<7^vER4CN)0)ywY> z3Ebu%XW~q(9W1|F?f}NX&LV6 zx~5QyV#(n$b)w-_L;CN67d=VXi%=RHLHi1VvCXFc-lXq5^n5=2B9vkoL-8v7^-)~R zpJ$#2nH{U`(d%59p3A@NfSiB!wg$D2R7R+hW9cce^(=%sBr4iicY}d6k6s7>n^2XH zKGpiP_{x00x1;+{ z6gP9dU=1?+yP?m@pD>HA%I5z-%&eWxR|XYR*U@y;A~v~Y=q($f<$-5lN- z3#yGWm|AYagy^=Hr2wh&*7U8m+uS<|J!AKD#zqvnJ-Hy?o19^)M-nb%4vL9*7Kc8S zM)T8wwb~0!JfNN?VVEb#kx6=ZyI6_UGlYOUAt*ya^;8CDSi6}V=Lu^Y#$k2rUoOZpxJyjcM(}4u|dU)c%Skn zq(NAjC=Ay*=NiCOua=wRP+0P&n|4_!lU>{ZGRqaX?SGf|pk66kBBgw7r_M)9vbof= z1VBa6mu+9II@4YI#@=EAQP*p0%`~FdJ|TfBj2Lr)*d|&xke(BqDiMj8$p9#<{G$=* zQn~V`JM{;5J2N!Wx9MBJ_Gx9xpjJO#yMaT`Nw*(S=!U*kxtV*w*}@~BZ)%!Es*-bl z`9{z6F49#p*ud*8&$hMww3Z52o^s9amT8*|+!zt<(7bIjX#$EI5@dw|v0eLkU#u4b zKJ0n{|D5zn%6%3=LEr+{39`B@N&f|``t}bM<^72U49OE9oxlvY7kP3l#6@+l=;piX z6nG`yO?JFu^N-tCwa+@l-|p4iLV^-Rw?8Gf4r{&$Jj~IJpo)m~eMf=hkdj3Tj|JtS z3?MTf*5m_$_RDZCqKM#N9Mvl8ZI}LuP;L_cS`;CaZ%eBSydW0zj=9aJ&MLeHl%Sj; zZ!#&_!sNg7)fp+2JV$s8#|`OGWCyLJjB)*upDmx*P?$X?ihw8hppAB4yCk0>>k>A? zx4u}I>Vu?4oTFx0Tx1x-Dd}3j-{RcN%oun!f{k~_!hVPjq68dv$JB>iv~!;Z$%SWb z$}_JCRrg9&fv# zl0Va7rI%F+aGDEUA@fiCMjwE~2EH@?6=w8H3Q&tQpT1{ljT^FpqccbIP5ab73`NMF z9dXo<-IY2Sj1f-NxdxqyW+X^bHsI7&F?0gGUn*6RlVxvBIv>h^ea-jEE6V`5GOG8A zOEHgogeC}yGC&($c_h&(9cUUrzcqKSc@{^I1ec+fc_)S=(k(oSUl14=eZWTUh%m#G zCqh1pKREYMm5d`=Gd=t_56|<^>5j*a>P{Aw38cq6FTMA; zdNypWTxD3MW|6%cT7Z{XN$-ZR{{>v(BxhJZ8y7pbS!Y4ROlFKq+MKM^;tb_!k!0=@&>xtM%@Dp_%=2U~^NcGtXcr>Z+R;xKFTn1?6c zK-PhsG_0&Ky^}?5W3jGa)djJLuI#=w{kCjy$yfcZw+!!v6#WceokZwGf+!pxdp6oJ z*;~lKd-n7iX6U&9j6$pKqApi@qcjxkNr3m5Bl4&7A(}=0#DIKE0PY+08Y_$5^0@Db z!!y14!bvs8moG4suH8pRm2x;VKjJ-aHln(>>2+l&dQ<$(&KMZ_K0EAx#K~4 zbT%P^mY{rZ+k!rOxW;{UlAN8M+gkQyL;$l%-y`V0ES`CJg9xRExAnG>KukUM0ApM_!F;sc@jNj zj&KS8GF`UOYgeRGGbr}*&aIx~W(4~H3vSF~x5M{M2%Q_K(d~axbe@51He47^gxD(* zHDV@+Sz;@#P3*m?y=RP49Wjd%5~OzRJxXn@qV}j+YPEKa($b;2-Y?&OKZ4}RIrq4Z z0PfV@R4AL_XAN(+Lob+-jl^dj*?!}Qcbq!lQ5qWV)QZ)*Y|j3QYYk_ zje?DD$;p_EkXvpMLLqMBv~E*@2{pIjI&K0zsT=4EweAYhg#fHx>bmuah75-T$}MOK zd^DWdQdEF9n>@|Fe!>5P8X$HO4Z)WkcOXYNl1)zpH>S6TX7Y}W`Hb*x|zJx zo4>M9E_Gc2dOl@&5)=L~IfrtqAb=80n~Z{2P**Ee2U_Y3D!D;UX&OA>pkOu134krw zY`+^5vsDANNX-%HKIbP*YUPpMlNYsIbDR*AW9H?xu#e=@aRr2aAfUvDMU>*1b$U)$ zZr9o?yWl4Z=>((964c;S+ho+2G1-)}ire$OT5G$d3}GPOu8IlKUERuu$YR(EYM=6I z(TJkHJ|v$WL-V(5LbFG_jME4ucK`NkzzNc^OFI8_j#EcWq+LW3UC+FaJ4_^~NOqq+ zj`$D2JNk0&@0Zs90H(=6^fhTcMjOSZ+0oV}c6I-Ao}Rg%wg5ZCb67C6CoFGzeY3j5 zDLIK8lF+Ol*l1H{_#wHV&lR^LvY0D3z|X(C9wNN?`tlaX-g48gtfjP{ zdn&HV@4;4h;obJWp!puCv{Oqhi(K8T>^^Q%H^uSmtxjT3+J)Ey>wyJ--_k5;I^!dT z1rrbpEC-Wp+GrGLMWB@JgbiEEc8vqB9Ol+fy z!f5eRdlWCi>rM+LNHvye*UsLJi56=_(({ei&SHT&xh5{ki!6{4j)oHNE^e>e<^}UJ z=xVPVS192VtAw$APRP%b_<#xaCT^f9V>iQ4FS>Nmv);G)X1~K$x=?7jPM$T(`G?Zx(s>^T zx}z1KzGvPeusy>0`Lk)`fb#CI92KG59Uehn9i@I_b(Bk6suRT0wp6iT^!3w;v&K$H z_U=hiJ-TkrwSi82xZZAz>h*tsE=h;iq2gwD$(9*spEgJ}CsnxePV3@DjR9qzB|p7) zsLdzOwXfu?`HR~kEb}?()wjFU8AEkV(%H2NXDE_Z#2<$**)C0j=~~O0*Dg46&EVlM&TVVTcUQ5XUQ>-Nqkya_2O?Ys zwSr?FhJ3a!*hf;%@2H7&GqN|EOXi`9r+-As?H1oRzt7=HQ7fcvJjU>bX;GcO*QA7J zGnCys&G8O#w-p(DD<|D@{mH^}ri5yM+~Z#FUiIi4od>1(pLh&YGx>b>~=I@ZASYg$W<^5n>pitdlivuwPwA3HOH-*+jb%YK!3H48lK?0O)V{N8+)EB}GoL<>^l zp-|kh!kiCo5XPM>?$K)3PJUs6b&4P8A1DL2aV8$wG2tUr+rPMDbLAJ!IMRUyX4O%} zVr{@{O-ZrK<_Om%G=TYFOH0WcoXR+vCW9VPIO11NXm`ZA;rh{Od1%0AO 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 T!C0<=6yvyGM3g^k;IIGLa2$py literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/brown-winchester-walls.gif b/public/images/skins/textures/tiles/brown-winchester-walls.gif new file mode 100755 index 0000000000000000000000000000000000000000..6edfcb89f56175f8f21f8e353f7e1757f7e2012e GIT binary patch literal 7817 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 V5~W6EEq_afm!t$s2p|Xq{y$KsFrfed literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/green-leather.jpg b/public/images/skins/textures/tiles/green-leather.jpg new file mode 100755 index 0000000000000000000000000000000000000000..baeaaf8844bfd6e009d561b29d9cee9bea9498cb GIT binary patch literal 36776 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/grey-argyle.jpg b/public/images/skins/textures/tiles/grey-argyle.jpg new file mode 100755 index 0000000000000000000000000000000000000000..98bc839ead0c782cee67a01a71776f851513621c GIT binary patch literal 40335 zcma&NWl$VUur9o~LvVKs?ry;?K(NK#9hTr0++6|$cZbC_K#;}VB>{GU;4DD{gzr7) ztGf5^?Ww7nd3vg+e{@&(boIP#yzK$rsVS){0T2)Y0Neit;O!iMui#_j5&%E|AOipZ z$^W2B0Isa9hqWERcIZC@;cXib1wchcMn*wKML|KuK>crGp`)UrV_{=rVqs!pzr+4t zdWVgR_YMyin~;!*h>(zql9G~&_Wuw98X6i7HV)alcVraA_{0?dhw=ZqcpC!Xqa&ao z0FV&y0f_hrNcaeEqktm7fBXNT{}lcI2?-em6%he|_CE*zFZw?`1Vkj{cK}301SCWh zr2m=70JQ%F@c{%V^n`q}3`D5f{ESv|!~#rS;X3kY>DDA5T|s8>;(kPijlzGoA|Rq5 zq97vy5Rg#*S0Fw;BA=|bRrs}6I+%a~sdRXee;+QVV;#{7${-X#e%k_IBO&~!ED}CI z27uCDD?;#4)zYEUMUAgA#N)1tx&P^dtUl||m`1KX+42Z7G^&+| zNFILy4%OBcp4i_Xhnj)o;?#1zp_PJO2H6?3d7pZWtP&awDuA}S%sxg8cKSA7rYR%u z1Gq!;-G8~9v(=t@)sqv1Q?b$B(A!4&u^Xg+^Td$=*lvmcRW4Qe>v$Iu3s4kIWLjg; zi~Ce_Es!QUS!mDL&PzN5d;@&Gi{_1P+>kFU^2A%H}85FPJ@NPs6p3 zd~{^6Ipl;DUiFz08#Q3vBQ8g)xNCLuCk$aj3x?)$Wn5pzE1I7d2ZaqqhFgR9P z?krhI6BO;;?#@N7bh_QYm#&j=c8PBK|DC7uYFMf29JAAM1u$=MAF%C;r-ADGu1>+>q)8gGpcD( z#o{{5Kes{A-2LSNC#!STT6N3Lb|!<$cO|n^I`XWXb;!|A&Y#A~2}0)F0_U!krH-y; zvShZtk3{%+i;bP~r73$_>Td}TSQOaoJJ8cOg4cE7PmtU#L zs%GaC#bH8*H|fc&r*F}rs&%nz2P2US6yoOlo_#8b6wWsvzMQIK7R@`eKF`t~$~O*#k&3WwwUM<>=;$;V zje-EY`-Wf(p-GDMgVzH5P()hNe!}>pQ&DWr5!{h>jHKw!IySMb!Jcn4NaU;Lb-9hh z-|TuOW$>hkB;10gdW2S#otR>+G%xW=Q0Z){ZukRT&~+s!Y-vI@xpkhP75YtUJ-qAo zb(KjOO6A_Y2w95g-ej*sCmdFq!~B>q3~k3*!78%+)f&5o+MOt6hFg1V_2|&PPd?h~ z8e(a9Bf3;UTuP2bs@)-(+CaoA0*y2B;^yWqmh-#2&wnTk#NZU#dwfD!?{2a^+m`xp zMAvW<&D+rD%eN==c-<;$hACs96**K<2R!i2l6(j=Mm>dTVrFt#l)$=S+57OR7CU~$ z0yHHF@agd6@_^L_7s7S|U1oMnU_59)XIOeoC@shH3Ms9TO!sjJtyx3tMozSzSOIzz zP|1G|{W<_dmJbu#-V8_~wzkk^1K#0j#tO^>jE@^+?ZXFv)AOG5kTJ?u2vC;EwV`Y@ z7C-NU$M!-J;b9F}KDNgI{SUwSyEPwzApd{>Y)^hnPU?lxSG+1CP2bD$9m{~z#?)#r znQqP3c&mfX2Cy<@wU0|#51+{uGqM%D(^RQ?*_?s_*{&qJLMXuqz+inMp3YDgQp>K> zjlVz_$SIumiMqlJ|B4^Mw|}>MI|km-)ov0tCo=r*s=~cz*o9o>Bp=P$V{2n@zS&IDnXiv668hl*7*9v!jh@Y95sxz&^JU4qu{{tx*oi%}!d@Y5x znj=JrRoAf!cGMviQ*X0t>SXg7_Z&!9TK`4s$dA%UWoRxqrFMUhIbNxCRs<0&31V7= z^N%sArMLw-(e`b{Phwrb$?ZWPzArvJ_s31jU(tTC3v&*kSGuirapk5igxc@oin4gDQPG~Lat)L4_| zj(Mj_vXIJkmj_02^Lwv8@xFSz(801#s!xt~hdqi-yIXDA5gY; z==j*>yCvYFAB?5?lTuEof%9rreu39!b*8iQP4Cz{ItXTg((ixWBY0g%w@aTpNuV>e ztjzYk^Y$n$dVjphX28!8%j2ZB;X}->Esu_U_K8S;MbHm?tFfO&YcihP=1Rk8->S7g<0wZeP0282>;FN|{ z>$V9k&g}B{V9i(r*cYGd*3u)X5LOCmLTK|4d#hXE1t~pnHR@8|ndH$U9xw^##r!&z{`X@T^Q{&{)(@;ImR zlqi-Y$FED3!dCiEavs4b7|+38(DG#(#A1F@`q9nOaZ^>B4E9XzW+wL8{Mucn@>)}Y z!(P{GYVSs_UJIrU^tNf^gM%-s=g*ZMD}2fxE^8>h9{1-xI8-AuclvLDs~h#wk}KiB{*c#KiL4MHLy_G1Fur!rI1$CmpL)bEg9?x3=T6Po}c+x z1hKuiui-119bPe;6t5#*(&Ak6DML3B%_vR>$M)w^feY*5%N^YA@Ac`(zt|Jlt&j}; z-r(3TT@wG$M))`*B9pb^JA~Uxnmkiot}ojw1h>W<#iWI}%%Ds= z)&lDQjJ`<9^uIY;cb{JcCF)IcWv^!58y=krZCd%Xjl=oMSBq<+Cdkv6(^Gy+nbSWY zEIc|s{;JAv>Cp;bAAKs)%{*X&T}(mJ4lY)BETa-g%%#yyi*d_}m* zROgUfYJ2txv|&X~3#dD;Fl(a!R=7n?{y2L0|M}zGm~-zICvEI)R%YlM^K!Z1;-}vrGA(h0 zS`f5^KZh8dluehNT#~ZOGUk2F&bUy!-CC{p1o5u^7ma?ZA|}AYn>x)`^*%AVs3E8z@uTM0>N|w`EFPoo@$`VN?0e&Hj!vAq1!3c4?Sx zAt3j^D6{EI#VRmnP$&^U_1+2yQr)TGpTPx*xbt<3(a=zALv@xn=1y6@1Y;%l>FIV* zV_ey6!WyTx<>vXgt@VBi!PEyhZwPxL;W0xwzkoF}Z;hLPfm#ejelrvR{(ZD}GYPv@xxjXau;drpy{qrl)PN zE2Ml(_t>$g>;vHrrcqaf_IBZ$VaQSSCwiymt4e%YZ-#KzTN!5Dq_@`%1+!wKTNM>* zeeeM;-l(%nW@y-x-wz|Ctn#{Y1|%=)tGDxZUT)z>^1Mp=&`!$lRMVo6qhy`Klf*)5 zfir#3G|2$Ik))Pz-?Z;EGF4UU5({q1aRoWWPl&bHmIEAKxy&q@H*FDdu3fdbKkK_j zJkIJ8Kv6+si?tw^>rGisooA(F7n1NOXJ2t;*CZ;KpZH;{cG=O2&n zlROaS{C+1QZM}MHRkP^@FG?y&o2nzXN;C23J6b8dW&@q~o~lpP^g^K~$@}jOi2X~g zado;VnMQ|+^A2K&e7Snhh&iV>;5xf@`-i-3GZh zivl&zfAJ=Q11(Rv%9^6Vo6kJN2H(~viuh-a>IWZ|=)YQKO_ z&z8~8{loF-ImgaxV^J@Q_2(H(3(9&|d7*rr_F#|ReiY+|rl<>(XFn?$%IxR4;JZJe-WdV61hnwin8)&+YZy zG>QpICww&xxLf&Iz^&BA`@(bd21w(oZjYEXa>y~vn}|uffBqIEaVX)`_5yi43mVj{ zm<=7@s%$=YGEB24vuZEl%o0ku zhFr6esx>ATb=IYyoZrC0%Yx?}$Sq?Q;OQXGds`Cia!Z7CY77>HL5P%JX#QA8vJ9Ou z7WgG2i4>cc$$)F9P5o(^fB>LVy-d4>|7Sn5%%F0p4NuB0!d%GXN5(fFt`B!n9PD;*ezN%#}b_;X=(x4c5WT96$a>KrMgrd{$Ce5>Mlv;J2xaMY> ztm4jhTP4sTE8?;8N8$mem-@j3sR7^G)FBVHhFiZ6mL!BF3|qVD>iR$Uj*EwC5%9{G zap(t7e%@n##;oc5x#MK*LOdHz5Ko=U?~_YFPE3|&F!SiBPG|Fyl#t;y(9wv{7aCAm zC%ldL{=i4>CL>6jPdbWgf$CV-JtSu6CNh>l7wR-aci&DU4E4Qic={9sGW6*AwW1#3 zxq&pIxmh0=KaL`;HjrBdbD8Wke3tZzOl93(!zIsRA_y-YBS&_)GA+taG^fg1jD8Yf zHPt)^3U^K#4)7j{Sn80_(c5c-QNsxXKCQ!IzfXWni`x3yOV7erA}8FRKI0pL~JNi zA;_+u|AGHq*Tr~XGFziBjdFi6xzr`UD%9V+-_(_0pkwNX84-#$60d%7GwkN1fGWLg zyYvP}jXAh4L9!XrBW*?>yNaS8GsEtuLC3_K!Yf1my5uwNiI!3i?WIuIsZ?DbW$XBk z1Rb0(%n)lb?qKjsn;92R80ldTnKo!zPxHa~%bl7&;h?cs5sj7Jsw~zRmtgbc%*x4?B>VFsKAusyNf|mgW$W*5u&N5hsPmD13Q* zOlEc`oKS@zn5(aHE<16wsZLdVnX;=UK&)$gH2J zi-nu{(|I z>$joAzm~P2Dc6tQxzn~4nlyT#5&(4++7yiiW>$bldJVpTSl!>7wp5>L%t5QS?^d?z zsl(`YncRJfg%y8wX#y7&G(R(82Y;nEpYh;OCM9GgXJ~gK*~%yzbXtXx`%c2s zwSKKnYb_NAU=Z}7OycAi=BUxERBxHoL< zhWJd)&GaE*Nuj>o_wYk{yBe<wl0hkhhE_-QzVxZ9a1By=#xcqDqYtwnu|mvcW)euNsyvxD>LKuf8cnJYBk zDPo_c4>>Vj2G}SQn(Z2h9lL+$0JZZ{mdMep=8z*p@hrN~&gwhX(}m=JWdifB#>HaP z79m0DDHUF`h?(}o$s;v+DyV>pjMorX*;Bqso5Y+Yj%;*ET49c0<5c{RXv)Pu>WF1^ zvywkZx9M{PPVv{Dh5sFd_AZ^-AFVpA$FnVo2nEkG;vaTD?s8Pf&0OAbG=u8v6%2yQ z6t&dPrN_(iU%x*ya!hWvePdOU6{JqM_qBsjusK~4Au@Nm4I*J}zu zQuaG`3h+%a-v3SJtY?Uy&w#2>IM#ZKoe~z{ds>mcET;!Yi_3Z`86b{#RyU1>abg}I z`!k?}*?p8Jv-!U$$asG~DHL+GDXI7yZG8>*RUffB17=Okk*V;GjRb*8)K2zkpPahl zn6!F6E5d;qHyrutoC`_Mb3b3|`m1SU$>@qI(!Lv44E%79{968yG0q&oly9(0D45gxK|F-#EPLIQ!*-XF5rhYHFq zm$CIx2z-fWIcK@(nJE-`+V?%3VU3r!Rg#xkuFXp(1L|1fD}(GmZ_q*qZ() zrKHq4py12J+fSs$f0h4<&SfV1UPm6eq9E-58And9FC7s@#N3=aX= zpd0Efw8}U*9tCM3S(F>uqR2LZ#|>O0>02X& zN0dM^7SznnDKpHI=?CZWgD~`evSXu5a2HQ`vkUs^4V7LM-R7Tr6SZ%E!^S4_dG&F0 zi}rG}p?HPhz^Ne9F{i5rH*r5^Wzg8O+5l}C*bK6;DNQl{a$D+h8UlZG85{R%F#tY% z?S68p_KfuBHaY*G&&pkd8#=aoOTpt4@`&Xraag0sgKw_NHL(FLPhuImS31I6ROP?a z5f9USz(y!rH8nDugSag0kQRc0%kz+iP{y)wb92vxc%^pqcqIUha# zNYmDhK+<0DezniuXd1`T8F!c~jiDcBEbz1UzfWlbH%Wl}*_C8Gdc1n?2i12{$HAj2GbjQE|O(O!y7WIK6;qObIko=$JD=w6>er80;|$s1WwZreXA zrNxl)L-P0YqH>hr@z|5EJ4Ept1Tv6=_~$Qg08+|X@@=q5&&f<*yrWrf+>3rI-?APU zriF`kRLh*$;=AM`kfPMXClN=>Lfg*w4EvGX6zGN|rRl@=W6u+_(j?~Az?_j$NMahL zaGTkDI-FiD*15IBrYCq(rs|tBqt8k_?wZ;sP13at)4g29sd{^Td#fj!7TN`?4&Siq z=G3U3u;-RDzJKU4tVbL_VPc_ZDG4y?(|(rnalh$MpCP-v53iS{UukIf8#y}(++~n= z;EFs+#;|`JIuJA`7@=Mlp&N?BU9X!LLE1Pusi!FvjoOE_GDNMT&ruA1e8>gQ>Um#h zm^SJDlD^sS!;&AfH-65T)zqdrVK13uU$_sYb;K*vFfmHyOe&tBncCX6$%ul%K`a1! zPk_BXvxnbPN%FQS9_9j|N_w}o=gyljVjx(%?raqoA$GijJu8Z}lZuV)i~*m#Ue?;3 zCLFql4^TGKTrmafYbq6YlZ+_RJZvRWwX#v)f2!~NxQ8uL6is%FO~#XVec$k6<)j&)g_!gF0)z;g2816zim}1zJ;ZaY8 zWybk4MK8jWP34-vaDzXjnjqw4^=q{m$NF}+@esUqLlXI&*P5@EM`F>8Pj;IsjnZ9j zAI=kHr|%oUJN&RvV$k_)A_w5HoEH2U^X`Y&jh7FL|LEYBB9&HmAMf4w2eW~+5b0(- zYQfj->8rK9RZP=Xd8QS*Tv`tq4l^3ID*VH!59|iMzkiW*Hr;tk9~SPOSw6(g zh^Xd-hH#~JfwtPr&9&C!k-j!kVz%GZ_U04pEZ6NOm^Y&zelFZMhmq_?C*k|?dtrH9 zl8d^FegZxLD;<^C^db^89fWa|z7Bv3yv*PcI*f1z;m$Hlb=%e*Ny$K{>;RH<_U zg(gWsTqoBkM}95n*6*WmcnmKiQ^VLBfE{Ty-eSO~aDI~XKbxtF_(iCr_7SZMdK|Fqs}!adz82{fi<*%i0oBX!x`x2U>zpsT?Zapx+R{{BMhaS(ye!Z5<5%I`=zKa zgL0r|@j7hsxbt>HJAwAVQ<;9&?<8@X%PL%Eh5&kb{PYmUJGkvgGz_x_}6D;0oboKcNW?9CP5sh3+ReQAYV zVIR6bsZFzBgfIu+ui6bD(33jX@CYv&0qR0{NU6Y^N?6$Ls6eH8^AoySITi6=RlNT2 zyJ{EW`b3{lw-Eswfl5`Qc6o{u(n{kXxmyX&^A}c}qMzu0ojL2-&v8RFK+5sF1SmPH zpK|Q{&*hNZ-T((pVU;J+RpX>psmVT1Sb4J(amQ??y)G4`0jNzKm4yX`>BO@ENTH$+ zEf_4y_2j<=S(S3WzMZBC?~< zqFXOdFYq3{0GI!I(<7$aYJJm_%KyrdbkBaZGa>4-FJ z2elE)q%w}oS8F$a_C1xS!{>xR+poq~k6T6KiMe{S3Id6J)eW&Fr(`!E)RLjS9{0&3 z+yHgz_oCEO*#niv_)~7{oYOxs8PXcPmv67A{94uG;Y6q?&ZLwU`q;lti?v-#o?`;Px4qP4n%j#}O|28ML$gF% z{^C{U_=r981`sfWpNx)uLIE3R9lhF4^1%?7roE{h()$y`DqPe}XUr|v!t-^Mc>Y~kgf5GLp1 z=<@hZ_H$O8Ejyj&?l-_Lw4v$Ky7hAUVCpo)pvQVi9cv6_o5#t4MKDe!dZD%R=PgFD z+_7(Q@l}_eSI|01_O04&@a}TKvHQyMg%NCRu9cR3{}FDc&~|=^5v4Nz z^Q_=V5}VWlsko^?+n2;ak_gMn$|?1J+$BSm2y`AFw{yw@yhFKoEUJvv%;)jC#ZoQ$ zDf&;up@T4?!^tFoDaGOc}P0NGS z+BE(AhWSgZp_=CnrG`q);t>fAdeMKV$sT`ekzl9$!E(Bvv$Rj-Hv@Hm`nS`3r}8qM z4*YzKWQ<59*Q@o+;zwFFe*3{ptKH@v$qM`?qr&E7z7Tu5$U!VdwljcWhyG7$3F0{ z@Vx;;(;_x|<!wk+-kO)eyE|a0jnoJ5zdNNP5p^U?|T2U z)x+Xqa0Nru1ArUczU>rIf}(@M6C{W`-!dMwdoF?U&cn4F@5~qF%6?Z zd|7l}ZD_Y{_v&Aj=q%T^G>ZT6-BLCuKE&i#$ys_b$v@e`5o`jZc%y@cgUJ-)FL{e) zd~KF}gslveC9hh`@|HXvP?woXwcQc9HvqNa<~wQA_7naG;zN+OZ94xa7iLTba&V`-TvNeiLQz%{7vJKNSZzx z+ubtC8>RLx+m}qXP$XIS9Nk>KlQhz(s*S3`fQQ4uzHa6!(Sk9t(fnU8 z(iZyGz}8WJwzZvo8VVj`oj|lhbK^hJO`1`-K05#`X5Qd%9t*G`MOBv&5SQ#6LA4)&bvwQRVl?Gi8pG0}(4mZ087j{4C1NQk$YIE8a8RPktjcAF^#5CtJS-}z7b+Q*1ynPjLoG>t{D(P+$W1IWV} z;fR4U8hFx3vK0M|R>R*JQUVVeYtAMme2rwYqMS<11}1qulR~RcsxE3WOZvMQB^9If z(TGZb*~$<6>=TsjL&wgKN1pKKVsA9yHLi1V~p8YGP3 z?dE~6Lix``L&jKo!&C+&##rv_Zsm%4Dn-KH14P~2zXoX?(W>&B^uO?p5yBq0)`d}= zP3^o$X(D)Q(#zdFXS$zv(#W2mCZYX#2kwQoE~E}%-tc5HsU#hOj*56n8z!CC#r?qY zuAM+UYO4xoM>SZwvIt%0I9a2XNy`{|vW?xu`Nf>7KBaz&VQ6okXGsyWNBmYC(E0n` zDwq(&rM*ksSP{GMeG_-(uFj@eeH`GBQl%%*k9eDjss;zhxSsfly{zKUCF&&u8<5V+-1G3#inl+|4)P zTTjO3kHo5*w(Au&?NVf25`V?5I&*x+5ieSUR@d^SZKWi6dI2qopfl}8Sj7-)o7KL^ zX0Nu$<>{K8D|0!?q@7NuV83rEQ9yzR+Ry>NE^63?0+WD8{75wR7h)jr57OOQtwh$| zq5v-5qNv!j-;mS2TN94ElM-`?*e9vcV*BX}q z!yvvpn#`5`;J8J1iNM|xNl}csAB&1JvH-s>iq)Vj>22-1EbAwh^Ir|$0PQ(qRL!t19*t%9t=hwbUmrOfe*gV2XuHDpwY#O2rI%q9ngCr?fMR#V)d` zzgl@~KvC^M{gu9~j9rbe%$w_V6DMQXZC4h4f9i9FDxC%P-Fv`oQLMo~AbI9Dsq{L* z94N7UGpA{GR!qMR>E#F=Ibj>&mVdZdTF7u5oPy{TfJ5PehD0GxwN$qH9sUE06Q{3U zBqT%yoF>lmlW$pU*<*JP<5OGU*81Zgc_tnGt7~{U{FH3`m~x7_xqXC%Jj=hHik8Zm z;9Cz{uP5uIXGal@^N(ex`ncb#DOezi#nr3u)uZjFZ$Z|)lB6r2FZwV~S-_&lJU3j< z6EE}j)%2Qd)41DLDz8!}xEQUaA?(E;0%49|p7OI6VdBg2Ge})aVsbz;c^*e>6Y+4s z$5SQK!Ch{QExzM2zO`@`!2BB^byCUrZY<9I$GjWU8D%)PZl@=8jxf^t@%pqG{%IyB zj`J^=MLLYRLt;SJxow`gW|*&!oyabk*Cvgpk~mg-8DjV&8a2Z=QAqe zDLvlIyC7~`^ykx#-lGGZW4uQzqKf*$bOGSaWF=jxl@av`KM#J=>rc2a!L`6xU_ol3b1rMWAcz0%$bs&;Pc54 z=$90)dMAjv;aGt#Z1Wo}erY;A+g>p=bY;p-0gus$q3~uKnuj~L^1!P@#{S*A(| z>u#@M-rql(O^Y%#JHgjwr#t)9!2K4eP-j~9k$5%f=Qv>z0NzU^$oDB|CxQV`1-lSyy9C>sUiW_pT*}Cs(w!`HN)-& zU(4iN*ybc27Jnugn#}ErQ7W?}g7*Vc&UsUuF;S0>dfSEC+)W*dQu=Pol3U2+vsO_e zv8a`|G}TA&jgWD=ll$bvc6xaunuo0#rN85ipK2GX?0R#B3c>)J_7T2mr;HnxqcN%yNl-X7(2)eouuFIHBpKg495 zkDE1UIoTZ}AVNC>!*Yvd2FYr4#c7Sifgd@woqpt?8c`9Fx`n<_i6V(7{+9?&wHpMy z0e(~%IkwdJX9tKrR_Zlo`vMDXF{>TZzMe-u*uDzB0e*_zy(YdC1g9Bg#%7T13D-1I zbjoeyeZ-A37G(I*$ucK}sj2T>j6-5GA&DCBn0Gn@AN^3|E@kP$AJa(3E#dWJ`r-Qm z>d|#_XfIIwF$F5~2H+4}eeBK2&adV{dvBLOz7aG^ykS+su1T+K-s<1Oc+x11ZS$TL zHWZe)zZU}`FhuxJq(a8ax3nB~Op@B_%X+;$lBox+Pd6z^ zqlK;f#p+b4O{oSQ2A>k*;P4fgyK(KsJ}Qlp;b_|T2@;m1ul`4{-&-)3jc;+G8Ux8BX=sWGbSCY3eJUsI*ez#CNM$<| zhC@=5ptYiT4xL#s``$%m(AM0hD#g3QX?gPTBkc%i)zzof8CD4_eyK5|%G5Mj&SYAe z)-gM(t0YJy5m@;R(20Q%POTJpy7n!z+ae+H{`G-Nd?#ae`dXQ}u2Q0rG4R=qT;|e! zr!fh2>4{#h3c57+tX`L1%I}t(TjFnu&~l-XK_Vr6neRahFhr@b%ZyBTe_(j#d#S!7;9g^7NQCA{ zKqA){6dGX0n)-zkMa(EsKVfy%&i0;pL`_4dqS-K>hN}QSy=_GZShwuOuf@mK_h-Cu z;(@u6Dp|eFZKanS^>~vGLH4rvV^m--VO@t}7W2O`{YsW8%(Rvs`Q(<>(IxucAO}as zMOpM+@0Nc%rw-J=P(B0#Rgao0Yy}rT)xqPYf+{>z5iqE|p37flZqt{4 zDtc(0VZ{@20Tio8qX`*FxPN*^Al=wgjoD{+OFhjWT?Om(4y?<4qvDZWxW24U8#hM+ z6)4lqCo-+Ju|n_~J;hJC-DGgn7HBBWgO$ha1gJRsv~o`XA#L~%@Iud(xzF7+}hzv zkyTNVK|PlgmHQm^WlqGy&nj*7$wl$<@$gcK^wUbPSxE=P$P3%oar@A1Od`h7rQPcR z_n9rTm$O*DX4=My+9&%qm{Hvm_V@j3*Emsy_B67jYx=-f2g{}n0*@M{kJH5j!clj} zT9iGfWfRcMYMpuXg>)i8SfzniTw${G{z*bTc14rdjzmidf#hf7vw3~g8onFnYh~kU z)0_^Xe`*b0^Un4e-FA-mx%9VWWlYJi^pwO}@JY#~z#4ru&rAMQAlNXdSzqV3Fayu# z^bhoBI_8$9!0^*kp*oK@KuT0txfWWegd|y(A||G;>iLnk4bBN0(R~`&h{%!=J6e=t za_{e7(vrMtO>!L$Pg38KWnw3?k9dCc151A;9x;if7rtlKea#v8^vQc>J))z?nGo|Q z7q!XvIVN-@+gRQiLlVb-n@FF%R(#MDn*jl7kM+P`FkuhTh-qcFq>dj4=-PW&XP?S@ zFwgIJ)@jYmrnix+weypS2B}CK0ta#_t_E8754P0F8MjdhyPI}xhE6gh+lw!#V_GCP z3S`EdTgOoH8oXlOpV#t_a*EvXN40)KFmc=w|LjKFv2!yL09<`+rfuL;iR0(VPybPQMwXRf) zWzDJD4epZI-ppOkX>7}xqC@-SDje~cxuvFtfyT!D;y>_JMY48MVh6DBbRxS^W@2{P zPF|;H-qh>#{V^PTnm1l>Qd2%58{I^Es69*`z+p<9GbTQRiWX zt8@^uSLZ%)eWD+8L(p|BgJP6l1&1khoQO^6{sWGFLRn9WCy|{yV`AMb=GLL>r0?iW zOt!D`B1wRO1cGU__Wnb_sk=`Q?&^n15;1LIazulc9a}r_#-cVF zp@_*P%^y!?rl?jtpgNpc>^IHW9OA}B#st59CbUdoIFVq-9brEAIl*=Xo5v+%-77BD zGdg#~`>}{J4XYVsT@M-gINmjGpsmtrb*z`;e&?v`T$POPr3Q6wbue|;Qu(gdRAgYQ z#9AWzp4s(<(q>BAAVC!CO#M)`69Olvl?fH`D3NZQ2JZ9HfxNunu|n`VZ8v`38vt6U zAi7ovlAJbh?(c_C>X2JE+cnKQDqS(>FEKf81C4l%MO9D8UcC=%G?UMD^^wGZCX((h z39W{qvIC8q`Km0qWE>db9ArjhoY-0^0#$9$=80Uv1jm9kFqa>{7v6TMV1rSm7(b)2 z?#Wk2oPs^7@crti)9^>;mnn&p;Xhndb(xFi!g5n(WM!0;pI4dS?4_Mz?iJLV|0TU; z22y-xk?+GG_GJFwr9|Y$D`rtPa$N(LBo!K(Dc`Xsb`B*uxI6`%hPoP_<3S8#%rQ`M zbOnP$5`0W-Axps9D+L zDD+x5K5_!{DZS`lN))^V&*$SgvBjAnJHVBj0)Q}4;%35MSN-x0=G^~ljXMjWQ_zgL^2yx;mWdBW$MHD z#dynJtd$$TE5)X8x0{N#=x9xHGoQt2C7jInrA=gxPG0?UlDi<`hcC{WvvK+ke{=A7 z7~iE)96m`IJg)1_X@@iG=Npo|50I7?wUb^={#_PRz_>YT;RX8b3;tECQ#*D0*F_`} z+GC9&DRlH@)jz)l+R*It<=)5|L%#dUa}Ke+1gDy!<_}EPnIgN{B8EK2c-p+2b7@p6 z-N*8k?BAhPlqYYn__6A=deL6EtaJOHn~|V~?|<2{-IHRc-~UKypce7Ke@b0(>WH<> z7$kkEQzRwJ;BgC(K*YGH$uXQ8Crl_33qTD)x^N#fQ(R2hRaKMsswWDgtR~9o1Nrjg zmTxf?W5dSjd_^z%U4!zT1EFeHo7Y$f3RcbqIS#r)QOz1u%0w=92HgMw0e4kIp3Q$v z#Tt^dammQHHX`%%z=go7Q1_9$$2Uj_|KZt5=~*4opRoe3LgFN zyt!k20_jCxh9$03oHlAazliYZex021O#{Rk&JH}^Va zf&TyvDPLYk_zB59S?+T&-frz#Vx8wj^U84~v5P5Ya`i2k_Ni~j(wGb8;Mem}`plj9ZdQIVV^ z9E-%Vzy~EFOFK(4K_l-#vi|&^PpEX(ccOvn6&Lr9m`> zj_V-wueI{4=6ZN^(^a}Z>g$lfaAz)29GA%H^1MsSCj-a-02vQ)ol&7_7;J)B9Qx%< zmCumD`fF6;)}Ag%b#&O-+l0LJ;(YR;4s3H65Hf3vHZKYZl8BdWC74z-Ag*Zbv<7pm`%o z{8fWBm?JWA>Wu0bEJF@qj|E8s_0b-Dgo(UroQEMQ%_V6d;ouEw$4H7Rj2SAa8(?06 zdhQqp>!*_LFTmdDp7q#m%__wFjdqU2m~ku0n~4yBdop&%kCK{{|F%3b8C@P?=pEt-{U#oA?AF03)QkyMr?8X!n0A_x~o!d zf1x(u=b4?a+O-?T!D72wX%d(zJgie>l1L5!+734V0IN92(Q1XjHg(9$1QvMd7Qs>O zq-Tv`D6y|)vn0SN-o=@>u00AebR~!}3Q<8Nd86M5-$4~4U_GbgmuZW-_;H2H_W=8b z2C4nTheS~O>pXHySC3n@Wr}NQh~zP#UgT(g(4=Kik5%#1n$CfjMj$cVqgk?8CGta z&s7A0sJTPrr06Zo@)hV)UMXj4=aa2b8Z~e2VprT+MU(F%dE6r>(sDe8i&VMNMBYby zPXQMj@%r_rtuOL}m_%y^Ud$t5D2W8h*ka#!kpBSNqU+}A$_A~4$n>jj&n?1sQ6!Nb z%4X!P4CDsgvJ4z4j|Zvy+w|1YCOpybNZ`H4T%W$qoOQ0*k-@UC5(=_H0Sco#wvm<@ zKTR1mxF1efau;EN?AD97Mk_M^08(iqk-B%_A%gBc3J0gBhIA|!AkT$sP<)2`{i)-E z8?~B9BW0F;{ELM$qY$D&vpF7q8YOyHV9atEZdXfGVp#&o$j+747ij=q)@DYPy-4^Y zb7W;n8Pag;u+I45$j|WVwU@Y^>Q^I=wBf7IwC(ORgocalJ=9#2>H3{3p^&bs$+WeWL`;1wGl9!Ur+WQ zu!F`yBvx#NX&Nj%8#H4zD(c*MUj}WYpepg?c<#@~7Jtwy{yPV*R(VZ4jT*OF`B#fTRBCq5P(;aoE z#?ooO_>*#P#N*-|^+)*Vf=f0MUJ8ZjEY+QdY1w@$!op#Z2sw1|W&jT!r^#o#yFqQ# z?0xdPwRjE&9xn7!2`_Q9(w!BP`(!!%wpG;bnOLzZjo?Y?r}3{-m8h<8pyoa=k>S2C z?0Gn0SgUf85ghUXUU4QKHID<=fwhc>>=+s8jUJ_S(zFPLT}=&yj&65}Zbr1XRIv!Rjbx~tXj{jS(yiOp_;!L>-ct?5OK|OpT1bOPM0J_J zA``etpSbvFqEC*bG!zMBbMVU)uU(UXFJ7#SqClqua#qi(Aghkw-HyIGd4Jp)@ON!1 z&1aLI7%gvxrGED%ScbY)-Ih-LE4VVrkb7&@M$>_f3oiTv4;>3h%knnht1>F{P{6TM zluagD7{H2EVs^Ok5_HB+d~>BVOJL8EJ(wzT97TG3dPtM6DQ-F9tVNjRW(;=8APd_$ z`;S4edFs=LFF|67za3jq@b>Bs@mM(N<*@`LEKISv4I|3K(1C#69&*eF*HwH>?oGHK zT9VHr@nR>Fd}~6mtpczC4&tGnVb)a6HU;VdAoyrhyO4E2@B7LxJ!#Tp5pooTh}8D? zGleQlnF42J{-5YFd~{n6!Gj7UvG4fH%*~nYUXnRtRfG|>nY(bY^)n63>UtdX^3juB zfJ!R#V43@Gj^`cRYwn~~PSk`VtV+$kHruzz?itlf`iOeShCWM?oKHPCn%z0&m5@ve z%@H{ffLR^C+W!Ed)T|dHWM7t2xX|6=s{ zSow7F);1^fG`a!V3~X@-M1G5wmC4&C_i^cQBK@#0glES&CqmD#XaVWG&b8x1CAcWF zxiYHQF61(f>yn+w$v%R{A;pt<-2vmE0ns0!aZmNZDT1m3y#B z+JT@8)g^P(>}K4#8D%AONQL-Ybz|U#g^%9KY1w$9+`iRXeuh_%qX`jC0(rJH?p5R# z29DJlm3T=k$YYM&wCTqcnGPyHad!6vB%fOWmItI{oo1VFmRnRW&0gyBRPZ3KYjOy% zLv8ztsSRV?trj+^O~rkGv=NSjS;~$I%$>=Y>vJ4ES9qhAdy+hLZ#z8O13Cqj)PW3R z`cWSiKCkhsYM*R`@k7>YRQ_Lza{{#TQMoK>B*ff>NLP$2DB7-`D4lcudX(tGIqy}X219k(VmutN!bD%+Kp zq>4)P(Q}G+3sHvSrihoG-gVI z@^SNgfLG?Q)M#+^VKYXblDE7K>WZ3mBe)bw>(nn%^wXbBHR_=gQ+dxzRt`Dju@n*0 zlHFU7`g<8Hy2 z!Q)bUQPyn9X?RtUr|uQI8_vq&K++wHF5mX?jh{}sJyhp`N01mQLHvh1#VnD=^{Y}u zuLX|X#gQgvkjZ7+Y?AuFCzcQBG))ul*l|{exPx7JE?S}NMHGCDe~vj?2#iY-_ZUn^ z+p3276UO0yG;z+*v5xf)6K9Vu3ZXI+) z#SFYsqh5&`JdZ=-HLJvfj$V1IadAC5vBMmZK{CxD zF9DMTIY|8{bM9bQ%dRn}ZCyd&H_9|NJBan(3NhKPuQc*8hA9HBV}ouBVVgV49jk$< zww=b#?NO0O7u{g?edP7K*6bq4`$P89u!v{(XMdYxLc1Qo&??OBD@r@48;laB$rRdG zNdeDqr~@tiKlGAup1L30256CKx%iR**AnejXRSUYK;S0nSdqMLIA-g#j-Fahk=Pbs zINDWj%9kxyTa4U{(Mjytqx7g`+htj@@P&_X{oXx#>D=OrKuS#H)7RiRE8ONHtG4&Dn)iIKM z&NX-9g>DAxm}RwUw8yNodUfA(D@zxg8z|o7vYVvZNWT`A> zSnW?NvC>aYWkLkfkLGf4%mR^v=zmW^hw z9559TqemJjldw>32pDz$08){rsDm&x>_r{s62}<{VsNmPHRFu-jABmLt9(1XQLkJu z$4uyIf08E5g=J-GOqGrm$)t7g3Fv4w6)5++?49eB%} zAnJPkG+R~2T!T2h6d%lSRsF>miqcz4m5Q|DVb`RV-}-FhZqE&v8U00r$1b2V7NZv* z6uf6053an_Y(-%tkTmi$GBTMh0k%2a$K%_8zL0!%PHOiOI#}b6l}H{oYZCD-2X7!+ zXEJU--4G)81#$rB3gvu8G_vQaXgv5HUOoio?ZO=bL2|k@Fig;(fL0~eM_=kg>BD~P zjDmOLQ#9alQ6G+3V?T&$;iDG4pAUOFyUjG6609eHn9kc5oOUp=7x0I4jAUY$v+C6`G8lKZ6= zw=s7e&9Ao&*Tch3XrF$d4=q@((sDtpQ%d6B9xF*^86trpjwLPGkOJ+ne#6#4bDp{q z!;vwFEZ2MYE!t9%*yK`pmy?8*GQtKXfjlFV00xW2vObzkQkrBiHC{UOlazTLw8m~m z)bZGaHHfDK_PZGb=1lD%=WAf&O{sC%5sr$oLs{C%O3Wx3W0KrinOc1QKG@ysVbvYK zY5g^`er9KuCWvuv(Clf<6sxtMg{P5=jnVcnQZ^e`dzBl8KDrXGh-5d(8s-?Fi?>O+ z9zc!YG|{PuZ)^}+DB@-wo|!rN0jami4T#)~D5~;=j?6;Dj~c5@1WZVc1g=H``u^YB z(4ATn4tWTqww0>Dg0bTY%Bz^wq>rg%V+r|=KK}p$Mmmj5YpCSn(k#Cuj&(8htx+U~ zJfgxQU@&C_ZdG6EWcvKPG}r6m8H{oBK{OGT_R>1uu&-n>hY^5ww8$~O65gd%>71$3 zxp@LIUnpTe3B}rwq}`e4330z1!5Ok*XfU}^;*xy{*0y5Ey99OeEb)fDXd?o(^97qB z$w^Q`LkNtjKxEDsH;#)dz+FRK%{`W{Jk>?X(w`+z&iL%IN$FfWx!m)Hz)SjiaVSW4smPcUY8}5+FA$fpBA7dVv7xI<5u|rL~PEwtKsvYmXcgqRl(J zq>{-ZlAs;Oe_u{BYQ;H_{5pl6R-Ngg8vI1218vw#_>2d1tUoAUY zncPhpG~}X+wb<^o~$UE=x85lE|#KtScuh z?#n=Xa<*fPlibg(<~ZKT_NW-guUV`(%%ioEIb-2@4|odNduXp(yR|V3t0`terQ0P} zx>vvuJhW;*_O1yVPpofxdch?Z6r@AqzsQ?yGo(M2?+x6yDhE5F-< z*+$E0-3h%Z(-JZDo&HgBP7{-nyI&q_#BxZ3yCfixkOWXw+{oD9oCOW7pSG(wGsc<{ zK2ZaFbBczK2_Wu#m0%295pF2qWy~mWs1iwgZ@)c9>8tqPsmuQWBD#v1pQUp$*_9fk zA+B7O^*G%E2&XbCsoibJ{{ZA7qpBkR0P5E*wD5f`jaaR=y?2t~$GCTSc?&j7@j_xm ziV#b@fQ`>CG2Ix)?fo@M5`BT>briL$SgSMwy7A_f#&?bsih&!$G6Dc{Nh!KqdOBcW zXm#%^xF1}WH23W(jKY!Al~Q#PRC%IgMnrhd_|$Fm=kFal=b*CW8SfcpIXN4#*plK+ zXP1D(C76S(%8{v5jTfYIt_N?!1M7o@a-zckPQ0CPcP>FKgFDR;x6Mr;uO2STJECo9 ztFz=R=-4H*;n&MLFH_;zEpg&ct;iSS`3H)7iCdSsG_csKJ5>Iv1*!^$3ELwKrBHOw+`048 zg((hk7q05|URx7JVvCS6e{)<6kpy+o=(sf=PZw$bTJu+IYCb zZRtl617=*YSm9Lw0K3lSVnzmkO=$h9R&Y)%t({R(iF+!2DmJSQrI~O86Vp`ES5rb$ zZ5QmdgC`v{)ux^)`8MtuCB&vkvI3|Lp5R<=m%)#Qp=a2zb5xYqsb;~Q%$4kjt$>1X z5?!J}5`n!3gLoD>#)R?|1ivh?au(~flT}e(irJgg?(wDr6Ic_qJfi^mNbBdJVd4)F z-aJ@qvLrR;g7o~RT*V@X++g0(O5H+8pr2MpnAE&Bfv>qMhe_nGRu_%rg2%m*7+2E~ zk=T|^#AR3&#GQR!UOKykg2`6k;QKae%OyzogKj5z1Jx0$whHvgD&*oHCM2CHQ%yrI z2f5q)YfyHrURy8Qq?4`IK>$|T%ZC_eO~2Fe+B|%B}QRv9ueKebPo)^QWqshAp-Zu{;TVKdE$c@kOnr0}^ryOp6QX4D>? zt^p>Ntkl2yy@eOGvjrU&-I0&+e%Z1nisqKOGoa0TU_254TaeJ4u z%tbV9SCN7~Jc-Z?R}p%uG|^#We4d3zRB}9qibB%8gHZfMyEiXfleIZ9a%Li9u(oBD z)&rR4azfW~Sf1b;0Ngx=mC6?#cLZksOUYT`{u#u#4OQ*G%Y9clBIgQ&d=Co`$B}MTj$?ZF2*!HwsFheD26>k0Zi6lPQya22j~z|- zdZ_j4gGxLPeqBS4{{YA3ovO_}zAK1|B}^Z0QKx;&I#}trGviz$` zh3ou>#OZTarbT%tzq8SGMS zg$f1)ZOaVf!#XwNsR3u-1-mcqrHa&?eM2uG5gKsKD!f8Urz&H?>C>mD_0w2ko9aMf ztT(G(fF0(rrR{z#&c>lst7+za&ZQW#w%X z9a#jcHUoy+AU}=DvZ-=#Q$Ax(>t)7pB;gT0A3SR%kzN^KW=qTUEV}`FZNcHVpscXJta>-#9MIV}0=#HDl>>j-|ue!XB)j*uJA7{eXw#>1toON>* zpvF{`$bCJy0mzlN9o|D}=nj>xUm(>9e;~Zy`Ks9qU-R-KGpqGz0iEFL-B8{&}BNtavBTnR978Jk%k6yVt%{iXMF({_ldylOr zZn*ZA;aHqA%o&&+?#jR;GcV&lccKR z1{y}P$I=%V!40aSyPmifC%qno*_?#51+Jq{bTw`1E6X7oHfj@8R5URUmhU(85Fl!Yv+PutT^ zEvJC|9ivX1mE|3m2F(KvcpSvZ5&#=?;daWWCw_X9>K+J zkt^&ZDD!P}eAfGSz|Z4#HoP0Ud`QDAP|FzOEI+t!#Z*hQKKl`U=_lK>Z%62Ljo-H= ztPY+gt-{$cMv}tyDNO{EIFhK6R@zn?s&}-CGw5!JGuN(^%kk<*k&5Riah3l7b%^A z{#saJhIE6KSY(cbg;phKm07GvTz6q|zNQ`oH`htgF2Jg1>0RB%!fS|b)UU|gQqgXK z7=$D>h={`~soaP6cw+}T(W>c0N^}|ED8UB>Cm^uAkqT2ua?o(G$YYx!WMArU9+e8c z9}3F86EF4ft^x*LVz`;g7b0peX#ek2^h_0O^@qfrZ7OnWMpg&;(bK* z(`qD2r+_kErp*kH+p)yY+i2uwx}Y+lkjH?(YPaJaE8(Lqcn`tM@|EVV)u~yMK=n$b zP7Tfd0-09@OC7y&)elVz1wX)MMWOC)e6o5MVR<;a6PbA$qHn<7(Sz=iL;DwK1pUXu z#OmEGm5D17l^2lk)+BW%HHOuW>2S6E4e1g=oC%@*pn<=k)VxYq1-lT3jGe1IanJpm zv&O%j32o3<44E%8sh6maV|_`uCR$Vpzfh-Po2!8Bm^CNbEkE#T{04MMe3}g=LuBY ztr8WsC$EzQkNuSO4 zI6gi{$5!y2#D_SO?e1I1gw?Fnn$2lLrFOx}_MdKLWoEpI>3SyV+RY4WrHUHlC7fJ_tp434JaqlqAO8TCb7K%oWS-}J zo75ciQ;!`bhakm;xa7Uc!6eNTQ^ChPa!U{Y0AJgUnRY|8tE+Tijz$~&#)zWlxK1Q5 zms^hK3ww!4^A{&)UrtU&ruQwzA4WS=2Z8}-QWaf zI2QQDn7Ix!<5Z$(pR>kZp5m)+g?r7~31oG0XZv~&#x{|v`4l$yLbb|8vMR-7!)%uk zaS|x6f+|W`)g(l;NRYA>8)YPVfdd{I&$hi#pf}dU+~**&?KB~&P6*+YyimM_nShRP zd%KXoi9eBZr)~?7c$`IQDkGJg$c*jC#=<)aYsM3_yA~!wH%I1TZy*nzbVSEtNuJ{Q zc;&WkPN_LtR;Pwp_raZ@qBE>`GN-2@TRx$UYjw1OQz=x8(&DPwg6vjTkmKjv<~&PT zoB?1MRj|$j5gBFhB%EVX>hQshU?V~}BKXz$Y{DUwR;v-8qsb$pZOl-9*;sAfPfP%O z^xy1+us!9tiQ(j;f_c>-H{YM|^z6dd(< zB{A)jktk`dY{XO}DQ)8$VBEkc>Cm61n!}E{7GS5P6$xv!{f@C+kNAa<$j*{DDq3YY zNmzhlEOG*_gy-o{Y7cCgKandOd*`jjgA8k)jtI|gXZxh<>IWe8#xbE`$TCMd9-k4+ zB~*?+Ni5frS4VE-YbIB6u{)(wGNr%O)N1XkS`zSQzZkC_PA;{JOI|1KS!rxK;zef| z5ty^arBcLi+K3sO)76Zgq7i+k^cb5Eb=zkRcI%pS{Y@J zHPozag0ZgVhDg_}K#x{+5WO(BD>2?1hpRQJ?FEY!NAee|6qI+YNh7Nb)g1L%h{C={ z{o0$ZrwgVuh_|)ok&Ky9!3i>*xYoE%&na`*9L__?=6~#9{efZ@KdNRG70TyeuOFt*$+2)Embs@hETNU!uFadXIP6IHPcdxIY5%kk) zEqr$b>Qfe8Zbb|>8csHT7_D0Bk);KZT~D{nBavJ}<#SoqDmoNsQcudNm1IEN;nGFi3Kd zu{l;J!yB{LSzi+PF3=wzp40qdoDU4}h2w3dSQb6jKM}(xb+80O_ij6v!%p??ebAGj zTb1aJItVI>RL0z2zuhT@O`EzIu5}V@@IarbJw}plYrjx8_&dK+*YX^6h1$%k%#$^V zrCLrl$J<3^0EeG;0g!;8s^i4zTIl}(^!Eq%GlkpZUowlBvlQ@gT*ZsE>r0;9rBK}` zYU2vX&*}dFxNgR^k5#dnf-rJvW#gJF^N)2XlaJye?=vdQvBzbKDw<${94BT54&ja6 zdg~4JweD6)L8B8*#;v|W$`+1EnRg!i9d;a_#Cl@^d`>jti;$Xt<-*Mm zHBQXZd(K0ZuOu-^5V5$%k*?*AKlfEv(l9)F_-Wgd(Fx{p$3w?fqeJ;7lA(t6#!0V6 zvM`HlgDfRS-RcTcz%bqV=(<~RqQDm9_&E_5#Uzg0#+0(tvhc*HjX6oql;kUmb}J->qn?;g{!OZdl+9onS5w9rk~r+koVHmVpUf;JcB79OyY zcvvzJJFeKsbU87q`WLQrDyP_Pgv2qU(5^%xoYgGFBo*T_#~I3(6G}iNV;OPPdVadM znIU#bW=QEr*q?Pe(aly;Vud2_6)hCUZs`C!i3jQj*GmfS1j`K-{{Z<87lOogc=%?H zq?a6sU~>#*x)Z<90O+GR{{R!JRI_noaZ(B3dS*4U)5TK#*MeIK+O-G~=2x{}jP2P9p{*)sYbcd^lq>4)FvuRC@NL#N6i{D~jbq>< zZH%*yGrc>h#XNUC69yiiSBBj9`020Pka!$({m5#Xaw5Q2*@<_vdph9dfJ_fo?BMwA z8ODn>@7yjZe8-BDldUaTf=6Pr1MeSTa^cXytD8yE8^b^x~rIUS&)x zM=#vfyb1+Tg^y~Tr#JFj= z_Ts(UZj!VVrz=9Z-4%xJkpBRfA5OwD%Z{gM@F!Pta~p|ZcPKFYVmg=MYaC?DO7v?a zyK9I;E;h;+EWx)fKWWeS>3^wM)G|Be&kY~Q+SzMU*&KvTRb(MtL{Ugx#NnSL5ZkcW zA6*vDrZyXi8Ll3*{21Y)u_d!+`I6)+u`DYTFO^6b_T?%LW<#H#)Vj>=*WfgQfPZs# zoy844cv~^e$V-TJC}{hJwMGi2yj^$aJ}3OA1snBUNBAXk+}8_Jk+Tiz_Dr{UrC7No zb$KLUj7Q=F)eNMl3*s^lmafZNRMb~A6X3jeJHb)ps7)O3*^+8g-AatIOpRl1$l4|c zsn7L4Y0~*_S2X*DiK5p56?)ThFjR?=YxA;KmI!3`9;qQl_QdCMZwzwkcJyqXgHe5A zf8tfYaTlP?4C^Fn)TVAkS%wz|tBUM$^T@llvSf6~-_xcwQ}z@d@~-gwJ{uNxJY$Zk zV1{f-N#){K$$yr(}Z zv;P1l5|IAhXOi=x^vtl~_m_NSw)$Hh7}R96uVLoNsd~o?e(g1iYTTT>j_vgvF_*as za*rqbZjMPUfG}8Rrmj6nJfKqy>xiW-z9OV{8Scj|Th}Yq-eih)8Bhg`xJ`)rW?#7A zeRQsH-yMDdDiJ5SX1B-farWkGb(f7trx0a&-L_--eZUR6IN5RA9d~p-8qp-~m8mmG zE%P&8cy7fUrWt5)^<;QNg_I|7Dm;_rB<#LNYxiJ}^y@ofo3fh+e&knf)UNYcmg8~> zEx?MZA(ANfyFPKgZkbVxZT|q(rj#xLv*_zV?l^g85?iLWY|HK-0yrU(UhZBckOrCC z#zk)h^yr*JLT%QX8?{|5Nga4N*@c@bh>%1dqB2Lj`g_}JW5g4xSaK##XOIEM?5pvw_W152@<~P z(;nQftG6)U=srgv{WM>6;1;MUtruwK<60T%yV<-Wue?h;1dJ1ze`7}f0MtHf*TiaP zKE*(czTA9uR;_jtH9E1_rp`MJ&C(fOEtPMR1a{^>t& zQK35cgH$Vgf+}rw>`W_hW==*GX#o}^F~p&JP^y5b7Utdh=NgM9HKA7+?sk#lIW_qm z$)b==b?epR*_uWblrWLYgP6yZfA!Y(xn7eylsPn=zB=t5B*rAIJ8_Z~vb$c%c;(z2 zwpBN5KVx+({{T&8EjQe}V5ds6a@^l3VjzL6y;7WdSnXK$OaNwU%Q?j1&< zze-(HYOJ9`hZ8RwZZOb2R^?iMc}7mi+Ytfam;!$W)EiuN=z3{3=Yga^r&&1&tU)|! z3e`94Q}rx$%Apupl|JV6W;}UgciXKSkD)4~e1u^*6`ztwV-nM=9COHCYV9P7||A9kkS+M12wP}X>^KCO8<3kd{}*5x5o6V0+Wh2d35YQA?YTVzrlx`I0W zx=QBhw^9%k)<4hucB;qPde-hVb}rahW)4G1u}oyBAUMR0_qUFe(Z0jY257lSZ}C%d zAjfrU@-S4ZWAR#O;Zj}UjX_h5}lS!)s#Z3qDH(R+3?JqFQq%ubpcsn6dIn;&j!G+we7w!aPXHMls*cLp3 z<1ErV3A98Ih+@4Mup=OM5^N-oRauP8!H7bCU-aqRocMJhuott(Sh4Wyb|Eo|TZn}r zy3ETnJWP9vYiwZ*tFsLu{h@q1>8qmdMAbMbUrNwZ_eRh{*6B$x5qBh4NY!yAW(T&o zCFEZ=KA#?vs^exh4nWXylmra|B%GCyE5|ENwxDPWVP?Y=jO2DQeJ9nUC)=;&3@tiM z@Vju=oeYPXs^;eu9zSr2B!#NT))&&Uu0!-cxQ%o->*F&u?KBr5xBQPKBtf2ao}_J3 zq@i1O-Hgym;x=fIdL;FD`n8&B5l;}OhmV+&!KK-p$;&KjEhDx#5=!9D9L!E$CQuzt ze2>>l)#=AU#Nnu~#Uim@DEQillA(L6I>$F|2WYYxrWwlQ?Jclj*QTrF*RZY79}ht; zaS%s6X(SdnyB^$=646<)`DG{pZsIcysh_*9i>`;yBDGV4zEoJf#LFpFem0eA7UvdR znti8b3mguEb1Ut38?s~d4k;k&~@0x@WmJC^J$I=6+55rwZG6{w`P$luTM` z#jw^`k^_3%z#m8>1E#h8ZHJ2^7bw=J6a~&kSc=x{r<-V*Lp5ko8s? z$JIroW@!REeqtiMYYjDSoa(OMVo}Z7^`ZF0792q; z*`Q^H&g1Qrt1Nv~g5AK%$`c(kxDYd;IlGW}1G4E~fS4G^xRRU-@T_4isMK6)QL!F);K`g%?k{?r*Y~$Upe#EIDJb8!`53jYVqVHWv9s6 zc;~dexuS_lEg?k>-Q3$TAM9*>bnbAcVI+M*y3^x(q!TszQy6WuP2YR>%fwD_GCs>g9RLccZq zeW`CvV&o81zkUefvjj~h{_s`a@Gx%7Xj?5A{lw}mnszC`D)62*#}?KalG}@rnlVv; zvSx{vNTX@wRy$(BJ)!jV9BH>RjsU1;zD4p`{yEKY77`e2LgsY83ZDFmC19W}nHZID zxMaY>jD2;bmU@%x=tb8ulCxnrDzlza zc9COja&E+5Qxt_nLE@e${?^@(=#h`NO7~7O1ga@caQsAp=8xXTA0a%?WeK#M=5&!! zG5I5Ww$~u+%XHN|dy55<#v`x{=nJMmk12k%Xoe^*2@mXZPVi;maJ-BtF*PfQr8xn4)QWKR$jiW zjcf7T*N;>pR? zsd2bk;T}r0B>2^du9&LC)hc%8UATL!&VWY(9m^?J+Wj$s=etFHRM+Sk1HVl_iLpN+ zW*V5Y4SId%?k$dr$FUd(YK1yBocj zY1bXL^v)1IWA4f7-4@sMwtDm)S}k7bK-~(wpCde$;Hw?0BC6ejQC_?R&aD({*2yJz z$sbh_54d&ITWu#{wkKQ)+@Bne15FxQwPIQ7qju0ZJ7wD5r$4$#{FLLzP1P_N<0V?0 z*9T@n9U7@ld1?y4MHnFE=Gp$_Z0vV#IXS@lbgojLa9E=!X6=89@~~9mnoEg(29KX> z$P%T2VS!T`U=@xcH!G9+>twxZUj$F3(BI6)zsW4XzPOWsYfHJhaiM&uQ@6 zqF*%~e09(Md`&YF;jA-!nUu#hVBE7ZOJ+ZCdygI@Dx{%~!=^_}kFVROa`y4p0I}pZ z3pGir%96=4)ho%E;7?V(uPXs-nckz7boS@1WBe!NtQd8~VJzL!16V$mI{{T<$*GK7Ud71vtV}C|_PzhzSpe4R4w6INZMk>g# zHqO+We^ycSd8u2PI&8{qcWg=-#B-hBftPP^MtU&Eo;7Z-mDh1(d(OvE_)8STHd+WHpk-Nl zEJ0azcVx~cQp|frbA|r^4Hi$TdxOAlwXXA^T%w z{{T);j;6<^gSiweO<}%4MrzG8oxVccUC3+uQyWVQV0NDZS(%3E20cUd)TKw+4dQ3+ zS*ghK4FcL=wYZi-+(;2DN=euP`kW6-b@JAUG`ZxT!THA-G#n2%SA(fO`WMo$ zux~`AO`#!Wc!&dT-y(ce<6So|QkRL6ql0?~A;b!H_6@)Np_Yl{AR7Y+)lI0vw*A>X zP#oZl>z$`OW#nlq>IR=70OJ*8k>TWNTeyj8!Vh~Hv$>jjp*rqw0-4Glx^CL-PTYcY zIQZIjsl&=cJ|`3>LloYtNnsg*U`AEaZxtu)>JNsU`fe8LEq=65?QBZogrE>KVdT=l>UPh6b(htpd(=}PTLiEwTHOFOqJV_T6rM?#Q}8&MNd zHc3hC!6&D2PPKql@;5BqmOabL#P#L785l9c+cL)*t_V995qRTi z)kPs_DX$=SiLB3Fysr}pv3a3;3QXx7j7vJI;O>uc z#?1O#KjEQW?%qMF4s$kZ_TX8o%_>*q;juinY?$M!T{goI&J40XH+MSp1FojkmH>P_Nn3X*-*tex4mP+$&!JnOBiY@$r0Fmb!^shqpSW z(ze(s3bKgCHi*0e?ZXY&#-U8U<9KjmZPKSTZeCju_bzet>s>A#Wq74RPG?ri8080R zCQdqQblo>(YI*T~X5TYomgH>Mc<$YJ-1bWsRg9vl_Q3!v1=ycL29@^uVFj*bnyPBy zq=G7Pj%GXCBWRzvvr9F6`+E*XV=I!y^Y!bjpVA9oQ{D=#d8x!}qpQ)5zzu-Biq z+e|)E*_iCRdZ>eE$F<4U|hfg(~sPBofVtkZvZFF#fhuH!gA1=(;C_2%TPAx4t3lYPmn! zTp?=9{kfGV1U!zUcD5?wL>?`Vu60fo()B{c1+h0C`~lpC9kpuMjw$eJS5ija!BdGE zToD?m+&4E&4GBL`IDyW61Mzn%cKc5)ii^jIrCBR2hYDj_@hR%8bNZ_4Y{fC%fDTT? z@Z94k%_b&XN0wUnBYw>9R`Fsn*RGwajx+}R%%vOFD)%q<9vclxz>}3Y zG45FknLAk9*<+Mt`W)w5H8kG>6Bp*V`t>T_w>m$%rCP5m#@j8q)ukbEI{ws^TPf2S z1M8yKEiMGn*Zf|d^N&kYIPU)dDvd0bV`<%_2ud^zcOP+*Hm6LEy>X-Gqm6^(`<3{L zQs3ocr^i>awjr~6I~;tQWRcu4Mx0E;YBK^ut9_@{^weD8OW37|PAtnqhK3|ZigQ}@ zl9=|mmNwk3(8@-{1jIXveERw5y05?$5Wl&tcj6XO6ETfAy6b4p=@SoL$d#=E3q`-} zkIeY=8gUnM)dh;+`{Xc7Qk9-A=#kvdO5?0DB9`0e4LqtdDypyJ>(|G`XtB$cxLu(y z<}zDKwz+N+%*?!9xF`2BsE=gDNhv#cNbR@n$N2c_zBs|=E44?T1ztL=oL3$RG7B)>NY*SdW@kOcO9uiaJ~C(gymarY@C$Gjx81SDV)QeNap@&0 z^GVT`Gw7A9Cs`2g{+>D=HH|eBz+y`=jtXXu1j^EmIPR`MXX}8qo9vX1o3W2QD6b>P z7b5V=!Nq zmsD2=2)lsoo!+D3buH12Auo_}7OnC%Rn9~;8*EP7Y{|8Nee#T~Oml=#agK*oVuUN5 zPoIK-iRw)pHta2E4Z1a@%;*%CF$us$ci7&bTT9oN{USWVL&yIB$@L)P+PI-sTGcGk zsmqG-vOV0fB_@c5&$D>abTGF^#omo4K6yZZkxb$RX z?eosAeKt;H<8&JbUH9pvwq=gWaOOA|khAua(b56wLy@~-`-lBCj!(I#;3QSAtoG)p z7SAD83Sr%x3xnJ-+hSJz!>_L&ZbpXIcvrANPvX(ZWu%;>6WM-aWuZz}jFs%E**h@> z;gjy)<>BY3`98z9?l;EE2~~;XNuY}Dn5|i>A+HIHD`6#x`m{iJ6*+FGewtS=A)y{K zjjEpNDzZN|#2Vb{Ub>8m0#FYj)3C(^T-Qj{ZlATH8 zwIaNb8Cm^)(yEYBM+5RG`*xn4bds0j(;L90ezX+~HjJ>q4d_w`C3UqP-$O8oRC*v~ z9-?}Y^v0z*@Eav^jS5Lk{jg}}$s2I*}q%fQ_%aX>62m>kz|>sp z9g13?J)1W!+6~{pXvc8uU{X&4QtSa{=F z-Ag5AO0CdsIKCT?qhpE@R3+$Bw&@LlD7R$B;wNhGbi=0bR|lyLtS-5^;Iyy>$I!ic z?VEAR($B@wiU^@`n?k(pxU)s*0l@9&&Y!6^`fvtO9I1?bQ$S7Vx9#Ovy2 zi~3fk^oLAQKwKW!0?wTwM1WS9gw2gSl(4y#Y9i-_Fb`cj zlb;TdCMj6WUxbEXvE%j(YpRSv88Q@@ssp`bA7bt4`?TIXiC{4;XkU(=R<#_49z9hp zP8i$U7z5kjFGIWi&-DFtldn7gUPu`tyt~l%q@?z{IrmviA(BXsrV+dDT>9S{R^`ap z%UY{bkE3QeAg5tDStgRW8^fZbp^{`f@fI<*A_I7w3~57c_6hS3wkVc?c!Uw2K5p{3 z?$r^>R{}?2>nzyJo(ga?R7gsuR9TOyk~R&vDuPKE^V0d4{xXACNw}1fJ1AB@KE#*g>Lg}`_atc$ z?eCMR*vh|WR{M1`UPq8lPEX^wKIBFhvo{|G+tNlBz>JgJ&2#o1;$fQ}p^W&EqT0Se z(E#~fC?xpTA+i{uwL8}|du;N@GPcRHPy$s4`m@w{X!zf`b>bH)34C4z{sV-x(!?xF zGy8)xG>tRIxC4dUV_267xRHaMRqx!%w*+b{O+R~#hRkut9jdo$%UMa4=3>5?C9t3f zr6n7+*B%+xPd*I^m6hL~DKd)=&_M51SzyN3+5*eryapZbChPRZt>M>QiCC7Rf=YbV zx!{s1y`{?X`)5G~GOkB-!u=W49KPQI25>c;%HXWV_^WH~=Z-s~*lt!?3FH;Bq0ql_ zz7(vA&fQ`oqixc;Qw*{i4Ng~^ijEnrG#eqlk$adBTSR7Uy@m<3vc3clN!_H?d^-Zb zTajtU8si&dHE5*sM7_((O9f)lKIDm`j|}WjtdZlUvGME=0KDyy0FKf;5J;T7U|Fh# zjJrrfC5V_6MJtqO{4!fbi^wkflX)hKkhR8EuTs4vh3z8Srmx_ZAko9Eb6VI ze0BK~sHF3mCF2*cro!>gv&*FLjwoMYTt3~@8Oe9fxPuMfDb zTFh@8n{A0>R!3thj4_pPWnB1vqe|sLtVo|bmbl|NcjJY4uT;J)RGJ4XBv8)^$7U|+ z3+@nia&UZnG7hx(la)GuL|>R6f?1c0;F39#37&&liZzutEjbKficJt3rO3lZ5AMj( z@~L5Cgk0h{VK)soA!5QLRd}Xl$}-C%v3-Nvk=yQVUXu0nocU@ly0N)QQg$TrHY08Z z%z<~!H8_luC}TS^0!j!8Dy)BWo@xiz8nmm(o1y3Yha^(`YILnNWm~r@J!FTZvlW1s zV+q<|+tau<<9AIT5ADMh_zV0yk)tOW!AI<(OHtjF-kGHQmYq@39IzjZC#6-h_juq9 zKan|og2#bRkheSDqK9 zTx<5_kr3HUhdr>kKYFkAJeNOBHmk@@4$K$q{Bhr8uFu57ihFi|pqx3gk(fhZ;AG_B z=}K2}8E{bK+mp0ySBXn3(oshPWL~0GQDvQh6E^n3F!LGI+Y9Pbk=n^xeo7N9ix(bl zLcniE$Am*086IF%2_=oaatsAO;&m>IfXtmr)ZO`ay3FH_o)ojxQS5>a-qU4FTe2C4 zgLU%Nwdcr@NZf#YiDx#-!!3Gsp2J4o%Wtfhf@F~z5$HZA2gf~PJ-$81H3Hm+A;^4! z+RY|w+vKw>_TyP2aauKHXw+`Zi?`Dl8%QHg61RYvWDX|K;XYf*e2138ad&32^lr$p z&0v808?^|^_n7*3{?56^w7Gh%R;)=>a_}f{UizOHkH|$lQa2ww)YG<};i(@{B4_D> zig%w8;5m0Mz9_Ek*O~WZtazkr+Re+%Mz1xtyeoEn6BkOnGEc|e^1v_@najl z!@C0+UHLoz03#g52KO{*rCFZXKoMnTSkt&03MJo+D|qGK_Y#;fDCM*_LjT8xp& zZ;g@|!g2CkxfQb-F|XXPtd1rnmDu*wp4tye{<^20u!Ml#<||d6zY|_KX5tSV^)5vT zV_lsHbSY;GGC%HVJOks)LbbZ*Al^VP+=kyWZ9L@HrCPLYUQimbEbO}#(|cnlCBJdc z*G|<7xSOfl*yO6q$tB9OOI{vMDeD`ssEsB_!H>6v^pXJletids(Fw$863o4RKK}p> z^1GbRKGM^vZ7$B-gprdY*inL!C))FO8y!cdsn)Hlt&4UdACC7MV$x=CWZAw{zSHt)$kP#EJ@ z=t1=i1Ep>>)s30?>OV8{Bg^peShK=IEjZ)35)R;&Wf+X^JA0mkxOx8op0rQXY&>d4 zE>T_ufw{`Gq={B3`3X&lXu!Jw!?%6I_>Q?~lmZ8yNYp$hVzU~Dk+nSaL;%`>XjzOX zRccNnkVxy1`5W#Tlj?FjG@Y^I$mD%#!YVphK?F_2!kkZY4@kn2vv%b<-|Lqo$@SFD zd9I@pr!#-%M`7d5v4tQ zDl@w$q4fFcno~Q8ItPNyxV}2V!pI{|G<#%b3tKEomkJ3jy8w2EI`#08`@ggIr3(HOZrOk$Gn0=4z8jR5L=|Uof&94;{#Qk<@r; zUG$NlJcG|H_NJ=SsY>*t+{`DMT$18hD*^U(3YhzFG+VynXK)MrWm|I~lv<0DXrq&O zofgTA?}|gW`*{@@djA0ZG&paLyM_cS96vAe9tV!%>p=1uxj9}Ij!`9e;ZVY9T>a4O z{pT1X9(vQ%t+~C4hSUVBZhmi#Z;WyBwCJ@b?}e9i3luCF;wM*Zo?)L-Aj4+ zja}C#P02}>r-oOa)mzgyyiP6^d1LiGVLXRoH6lv(nX$Bez<|e4o@-vJHY3KtI`X!y zQxn5R8R^!Vz;&9-n87=qH5+4+M+KF<6|x6SRnCz262vFRr(-k{1ePc!YszbfS4kp| za=OW9{kQ)BS`hQ^v>p4nFbYzGW*aCENy z_m$ii>OIPsr{Hfxez>t-9x9!IRlPOUqRB@Ev7V<0ne#Z*+lq}?-W&__7I^znNjzfR zgpU0fsK(N)QN*kP43jrWn+i6zdYFWFc z-A-a2+p?Lvvo<8ekbuLyg}24G!MYxUL$x-$1moPz{GO*WpB0~tW|T}hsXNqMw662G zE8Ol4!5`O$AO7zRYhzxi*o%{nLwt9iq@NhQ!&#l;w^p6XH|U&+XOn*Tnkfd*vF9dK zKTo03zQ^iMu6{-87Fq6Z zaJuS1@5KH;d44-58D>O=DEVsfvds90y3B?&g_8iwASCb36+k+llJ)A9pzXGixnuZs zgP-CG)0?|5CtyUkB}lDy3O{hxjZdmYWY2eRQ`5leJyUD!II1Tiyf-LKStqvD>RgrY zNg0Y?>g-bmQcmIiyq{NGcnw}puc(fByA+K0le_O%hlWpoE<|pkP|N+UNf2#qp-*1} zqSXGqau4i%!%i#n7pzAmjfrZy+wB6=HG>%egeTJpW;s$1r>={Xqze-F#kgvI&x*K^ z*qhv2xbssFxh9cIDvxkWn6SQ?3m&7cv-vJ^*J7Q#tWuHVuiV>R&`IiU z;ro?9>b*T!K6=&t$U$h;gOB2G*}9RWG1Y;hy0VE?a@$-*0R_zLS8E|103>+nH!VQb z5vAtcIL<~o))ER(*yUnNEZg1*1d)RuZZLloGP45Uk<^i%n#$U#*t@8GawwtX_~^>Q zE>C95JXTwCIx4!y6Uv~nChn2-{{Xn13DJYZLN}*do2|wpMH|6V%#&7Zy~$X&QuhNl zZSbSBleeZk^-fxzygbF2mAeMajSU1H>fC)D%M^(fux68Nl5TUhN5YN&08I4o)g>6} z#15Sc$CtZ8tzj)k*-OGy!nrz8Xd|LdI>6?{5Gw4>@~3Q&kDtA zQEW;UvL|t}Y({arXy}XkvNU{;AhgBtcC36myUZfVVjgmg@KQ#8+6kUPkzoei+ZWUq z?QH9Nm#&&J7q+^I(Bj8C#n+u?H5Y)Zi&je)jI%%X>l%!Z@-}yM@+VE*>3zhMuE**3 zDZ17%cHt5W{CBo{KbpMDVImCBMG^F-)4oSI+BzL_r{v99=QAyOHn^H`*PSJ;$XQrn zvcarj6^ln3AvjXown>0k^*(wnti6HK4y;;exj1*c&`l>8vXZXNck;45Ud#y(^J4<$?Ie z8&+=jathMaJfkJp;gA5as%}NH2>y;^`T^Nf)KtIbPn;>*x!Cc*D*Zr|#@ ztxHjLH5#e~@+)R9i>&bW0iK;>UgvXsZml6{3@`@tOMpS?=>Yw7SiRhZ&WAj;s<)sq z8mUG*HsTvDNxG~h!bn;LOi0T9B>vIRc<8k?xG~u{)@kZjmL;)z-zxDz70I>~XplMV zG<&ccXGxo{+B}YuyUVZWBg~s)`E$&ZLRnJP9yZL@T6q=Ol_VvRPyo2t-(l+5I;9a^ zMOi9w-q>2?qn24Ajxolh)4{gH`H&8h#NfyIJtcq8*cywnyIr}>)NM5TI)b_(R4=;JW-e~+)Fc8nNlY}Ng`%u z%CZkYZx;tmKOsSeP9E0={{YD>X@8C6X*Sujh40EorcC9d*ttD^?wa4#>ZT1D#2nLx z*FDESFC>vwsqt!1q|xP?CzYft7>Y6CTxFSbKWmTqFjcOG(c`e(T2;bFPFvNiZF1IQ z?aLM)wy~1w8jn+FukG^IInKtJ3Cyv}@+vd5!YeUPD6MK{G6B6whw=}$EvxB1BXK&f z^2M1|;G{VYCJA3QEKsu(i5*R;CM=~`%0}4Vautbu4m^75CByDkhm+H+F0=*@aFOw0 z;SVw`(JVa!ET_;MZuLctyH4K`p*nI99u5);@LWjMJ=vbTl5z1!sV`ldi%JQ~XQZ8a zXQxdkbihC^D#e~VfO+am1kei>;I$GK>_*AC)Y?)(17IO``1Ay6+@;rUkSZcw#*SVF zo7HHdsN7_YGzMYp-bEv9(hjVz)2wI3vE`~**HT^we=ig60^=w0IIdZsQMirWR{-{h zr|x2NjAUr|_P{PG&L{pi5HguZAy`WCtbNv8e{N-2j>U|AO`%xjyvCtp!C404LleUk zXwnfa-*T)KftzX1xM|ADBiWt1K^_}?^sdi$RfYH+#oBm+a5!rlu*3u`=Kh z{{VUXfrwXbULMD{1i+R1KeM(&ynA-{JG**;pA(GxXjgqiXbvDlz^n$dN>cv-ZdMq_ zdxnX1?F&jq1fh29 zJC0-V!PegldajH<=6B$UUkKiKtHL7d(lQu^WZl2g5q&A#+n%g(x63-elN2j3KTNt= ztfKLOBd|F-KJrSYNg`w17$}njjbYFA0x{Pr-$rcq6S8Qx$s%c#M@&z5y&TN)L_qrq za3h>&{h+JU_3Nsyr+NwEH*CZ2YZ%o9&*Q+LwV0km+;==iv3YxugP$hqKyVHHRK+Nde@a4FG7u!L($R zh{%l=e%|Q=!}Zcw*FpY8{x}BOTUtK<0B+vR;tzAQ7wwh7+1(=>cl91w)4x6iX*##K z{wC0j#5s><#xpR@fe(4N2!Q-%P2XX2ySJPV4O_=)C176WJHNygUeLTas-{_6VRl{J zL~)!zvv)T4OioYKbvVx4c9Px%8zVflLKCuKez;>?BfENssD~*UpnnB~u<`5Rt5|SO zW{c8q@jZ^hQTKO)?DeU#BlR)vY?onPk%aJH0#8k6lh%c1iPMVT#n5UE2px-F;w`zg z?l&&(?1YIk^~!C>>789=$u9t0Pq!SM#sW5grEhT@8`THr9nV_skpBSPxkpU?nl6|H zh}53oC-z>|uO3Q%!J+A}wYGjj!adB`1y6x?}TPQ$)EVpq2D14I}6y_&IZ9I zJtVGuM4T1gN95_@*IHjB+E4!gkbTeoA@R{UZN0bdk{7x6w`;s3Kk5FSPlk107wpNu z1bzPi5_?nezmo&o6XqhaKUe7)*djxS`u_8~AbA}h{*T(x{8%$%%X@!#{>QQJ*7Xkm z0Pxt$%w+s#Om$2@h=+DgcVk%Fz7X*(lCB6(KU~hlFTJ^eNl?M=Fmbr#dU4e582WVU zs$Z`Hc!uN618SR05JBuOn-S&6@AnW8&frPi$5;qopaaiI&((GL1X`5E?ynirukdGq zhqA2RklpTq8CSYz-;&#aJG1&7Ld#!KUQi}|((?R=@- literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/grey-bookswirl.jpg b/public/images/skins/textures/tiles/grey-bookswirl.jpg new file mode 100755 index 0000000000000000000000000000000000000000..124cc84f79b259dc543e16e88a71137d53d8f7c1 GIT binary patch literal 45313 zcma&Nbx<5#^ex(hhT!f#xCM82ceexv*Wk{CB)Gft;qLAv*x>Gx!7UIR0!euM-n(_* z{qydwuIk#Sy8G;|>b=ied!3in7dU{UqM)n*fDixx@_GO-KLK1hZ)+!i00bZb03i12 zx&W}GA#PSS0A%3R1A5s2z5pmlNJz*?D9FetXeh5I`WqCKH|Q8|-=e>Li-Cjj{~8Vk z7B&tx76v{(0RcWf1vxo61@-?n5GpDvCI%)64h{(!Aub`={~q|iy?7Y_aNmH~LF|Yi zTmS(Vgoq1z83G~!01@;*_Bzr3&ybK&5D`GA!2jX;Un4jG0s;u(H4enrU=Wc}kwFNE zNXWQ&04+WWw=^Ar_6Huqk23V1bgX!ZP?J2uWDApZ!Pa~XmyMn&#NXz2isbki1wIez z3F7|$Z~I@5epv@F5J9igLc|3m0pm@A>!og2k>IY=bb18G8-01~q>`S+;)<18oP~<) z)4>7&#pgWJHeRr-QS4e4xsbX-o)1QuVJVRsLlM-2%85v|k#>Ak*6lECLf6WZA~^pB zkJ2|3sjCt$GO^dRpgS=)ZEDJ%T;k21Cy3bLH6RkYdr4w=fpJ04y3`$#>SjnqRI)3h zsCR6G4olElAEF+GmYND_{25k0$8|b9DRvv3^s+S&=}`;i;eIj-=9q!T4p=p1J`-7V z)pSUjOt+D+0C7#jto}~7l7F^o+)>~cyWJ9KO@7Y?jFo|UC+pf2v``Ejy6|KNT%&*$ z$HX8%Opnfseb|1rR+-KsuM~S^y1^4q8`6P6P)Ci>&!P!k_G)qa(-o*X;-60f&>Gk6K(dpMhSiAZWaQ>|8z zHy9alGNl~&K5BckZU`H*EzB$7<&F>j*W??lRMXQ>1|@DpJoOwmZ%@onN zR_Slx?2iD&uCiw2pt*6-38)Zc5B~=&>q##yK8E<9LXX;CfDY0>PE)SVS{dynp&r(n zhocmeh85X)rOFCmY6(zz$j-aoiBBn=4b9-izf3eRtYgR}(OZYAL~))3?$c{HlRdna zLe^R|^Y+SvYR!AL;&5zY2n!(rJ9XrKQSaHYw-Vy8rEUiU%-D-P zQo}j5i_fZl1^Yj`qnA(m8W_?CMSMM*P1-RvAfEpuOr&GNY)yRy2kN5=XdwKKaGnLl zn&joE?~_3@?^IrZQK;?~!SlyJ1Bx^g^mv#mm$H?NEV!`|57YZkw;#~ZY4JGq;ivU3 z3qMV-aNVj+l(yypPbVlo-)si7P2Scd@HCaFX4R>DGG1WRayfx0Jnva1Q^l#Uy=4!G2D z&4xklj~mtLD`~tY+Gg^3c&qdcavLyp@;jEK+D6;&KM+P9wSEfL^VF>e zB3^*XhyLOxbKSq1{TqKLtnS3im+l<)euwT2SU}#j1gf^N>|QM>+tH@vcq>B^lPr`* zj+&tM_+|awyZ%%NoHLtjlMLD8xqfkk-Y(La0(*>m^*7p+U;CdGL5r6;nSp#wD+WS! zDp!l%wEnP-J*wgso=BfGD}FM}AZ*Yt?_H)&24mKZcyKY3ihgd7OD_UJNECSjR|YWO zZ)@j~zQG+^aL%3BSFPQ)f%g@{QzMq8$A*LMDT#&1xqV)@eg5Zo?6AA65$5=#1Y5~* zTlCYRA4=YmOllUpgb5zk`)i`;eVyj8lpd!pjseG#ryxmzY$}8Re;(36VI_~*QQAsZ z)VlSM7->k75fs>@N4&43d2~m*Pd6pCV()1OlbkNd3J5qU>VjSVz;Y|DtPm@-CoIem zs$YN&GstS`xKFr-S@y7)yJ;m~u<)+$dm?o{9hCCPpvSkl|2~VmE)KNdvG3o%UAlb0VSqX?bgg>(qC(wtnaJ_C`el_H?sOQ7?N=GM+ljmS>hxmh zDZC*qtFCJ7Q?-6qcY+Z;dkvq6y^1=z2mO>c8P6pJbaf|XYPEtx`-CGqjm*H143~V2 z0E(j9F4M$SkdO(d5W#GFj;9Ue_ITqk6<2C2pZJO2{i^wx*gqBqe=W8WAWkOgoZ7Xv z#@}+DnUh85m7838TH?h!cOv)BsbB^gRyX^(ZY3YSR##J`lvXA+j3Mn$g?gs|x& z;rCqXF~6#OtWJWvtbWgAzaQ&FHUv$(3-Y2seC%%v9_sk5CT#RE)unQU+Q!7+X|N+r z=G5o&8TixA6`bk?aI3uMa+bEH5Une%HuN`&+tOA>lqw`S+1aav6YO6JiiUQ1;?5-m zHOwiC>gPSk8ci!P=(k>dY&5;jL;VD2th1S)W~_H#EiaQ>NXt!7Ws~Mou*gK5t!JvY zBp@GH$N-h_`1C0@?T*^kONgL3$IQNswnOQ_>UX z_Bpg2{sJtM>M66*BrB;E>(`s%_;jG&K^8uWwa&U@kdyvB{;$@$+IA3XViK||swQ

        tM}hN7SMfStpv~<%B~>xc=tAZ%^{PtqHf`$yAemfH1&e{=0w)h$D-A z)y%99lQoqC_s3o@VKyE4sCsQ7a0#+zYK|q@^u9~kw&<{DROqQCj8vjgD9sGWaKfB} ziFJT(R=d-lE#7?8uYvFwe>vG`nKcen%ie}z{iL;lsC$={m?kE;I7FY7v)e`>$@Q_wqrz2&L#j?YEy z8;`#I3}Hp<9XQ?Tjxh3iYt9t`k*8U9{kABtZB>Pve)Q<6xmk|<@r%j7X@sT>Cmq=R z0Yz{_=$&v`7@E}5Zleiqlg(o#ZWB!GcaRW@cYo*OrjUJE_Ao_{5}QqB^qFl&CF7NNy%tTc7!QYnFB_bd2L(0QI#{rYOuyICr3!V5h*3{?us$vVo+;BnaWTI+;vr2tyV|N#})(U#-8e4>+#Df{3_?}J= zu@2yRe$2vHp)zfB0?chtk5axd1k;ff5xG#GHuZAl6TyC6cI}mh@p_oFA$QZtebh2! zBQW@{p2mKub&1S8+vP*y!tf~QYsjx}2kg>VCzop?jnTCP;;hXii|Iz$EEyYP4Jj>^ z3je4;<62WQ-l3&+18ukZy*|JFc|P$k78O_3Fo(SDq5`%bPM4ym4DuP(fp=DkbRC#S??Mo+cNgZdh02_Ao7$f5TQQ!!0@R9%>r)IxamE~a~i%> zIm-o&r#~o9vI&-?LRemLQ&!pcH<{{ZT5r&A^F2no-H&S@P<{bC#OoUh#--pQ)qi)t z?;S^{x|t-0h0%r$zdL`6U$1UsT*N>;fUn&s9a0X`res z557hM9R9n3Gi>zfa)~WEZw?;#I2I8Wk(&z#AWbGPJy8^70P?E(F1q0)+BzzgOwBcv z2jM117QKEk|B3<(1BU(#a+Ul6jBBj+2V3e0hC~`oHMR}S)oB}t;BOwg_-XkB+?JwM+- z)hSthUd;b1=ONL8vd(;kt^ET|HD_+?ojXEK`f`9n8uwOu594s`nCO{n)JDjtzG!qY z&o7Ewia{*IPY#VFO199ktZ2b#hy4R^c&EP!slK=}-OxC(yGTN`I|lPnpc^l^t#YeV zx8|HbyMR8s;`5s>-7FL_X0;4h&fviB5QZO}zh@ zpt|>em|g&V@pi-Oz%QQPv0z)%a5DFpg|M-CQjxf# zGXE@bR6tVXD35R+YNUoaj(O?wcwteZipBfkDAw8{zPLiGnSPklCEzfitIimbk3~+| z(|5X)J*C(r^#jTEuhe@(T6#P-gh_7+ibuemGDV|mP{P2^*|ruXjTQf58ELERH+^Jh zwy#@}B(?yYnRoTfn|n9dDhzH-Bp?>MgV%I+mMu>e-<_Zo&p$`}I#KPPLys-b4;!_s z>?C7L^F<1pCH&CoEn_i#s|D#hcQSQVd}K71H(w3pd1MKQ$PB)q(CM9wi&P1+JgEYM z7G{rVs|;h?kzI;)s)RH4`^_?_;(ULa%5s7}Sy-5$)Q6sDEGzR1RcC|PJT`dZ3O6zs z(hx2lsY1+WGbSGR?>raJ&AUY^DeHs#CJwbo`kXx$)+54P2d6*44{UK50BXV|k z?Ggc^4sQ#@HS#GCRYZI>s7Y;a<1CE!(gO|gl_t6A3BmX$^NO>Wn~|tcq6ZKDjr@t$ z>}f?h)KfbyiC!9E;&6U+iU9m^neKky0-&$!E%)l^9)}3YkNUhBM+2!n9jmy`f5o0J z0P~7Pz$L;|E)1fcTT*pHOj|`)dDfvtXk0?oP}{C90bHW)^8QAtw$-$u64=uu3~z6D zBDGqK`1qfq4rN-aMZn`FrpwXses!HZeFBRWZ<}A04zxu&q>R!xtwq9I@)9lpo5^aV z5Oxk>r1&aNCg+x;DuQM5#m7%O^u1*wTy$_fFv+6%{+Wb)gzD=d4C*t~td^IeL9b;frs}x*5+NTxCrI zmyii;^Kvk|R{DS^a7AGKEi-OZcL2?kJf>Yt-KSU7fY3W#8InwtSTC5~5PN3<{(Ho< z+tY#RsZ*pE@9cz|TuZB9ld6%d5}|L9i2Qz^^M^_JA`4P}5Rk@UmbBN`SYYj|R8tHZ zhmaS8{XA!7UVw%_e3)0lDB-@}w=fuDozx>2r%bQoBzZ^r(y5#tJyCG=3ggdz_Btjh zH5n`7{B+UQAKj;4RKBJ_+9G8*H+zEzbgJqyb5o)j9Q1^6kDf>lJ^8y6Qq54BGC4_l z{8^2x#>KX1`+jdbdq=<)fmGp={dMIPND62?cq)pKEC$)ReR=^Z_U(f2?eq`z4_&4F zf12Y4X=Z>HNh_~fb!p?1RY;f>sWD2c1Ce#MSVLqNrLnkL|6o|%|Sgh*0>Yz=8Q{mznAw)#zWjYVUxlwHwv zST2{IdKC^XH-!-Uwye{=Jp9nbww=H}g9mIbwU4ks&6{Xp8U4Idv| z#*M24+r#ZwAdF6tL<&m%la!su#TEf4<)DFz22B?mgsW7(xp`Eb09+KKQAW|&m{Sp_ zx`G^YU@&#u3a?CaRbLo=&dY80$m<8j@o2H+DQ{CX59+1tV)bW0ty4$HiBFuvhuIdRdxb8Xt?f#xm?FnW zS*hi=o;3k;v(%+utEG7CK58F6q`0Mge%n{jWgej&B>edb&MORS%Ihmqp){gWeDGS5 z&cemDZXlp6%_fp_k>ttq$E`qF=gBl^AFR~B8vWt6CSOMPn#Ow*A zF^I8qI-Mf?S$DHp*oWkO#fKqM?v!iUb%-ECwv?|fhaTXuxFMLpHw?tYd@pmsl;2v{ zh#3GQ=V;Kud$lN%(?v$B)~QSF0bH=XIdbae}fiRzVi((WJH`y>*7eK zp*Ubk3lp4pcDi2-CBx`55T5#DcCD&rFEVSKZd`Odue2|cbfqI{2ON$l1d_htG;2jB zkyLk^54aj57^marw+LX|DT57ic%H4J6aVF!S2mMJ zwyW0|s~+o@FuqRZ%+7#~Yrog>#Eh%oLFIbpopxMVQ)QT~I$cd{#dhtl;z3O^bJX4N4DP%4K4YpI76tC25@5ucszE`SL-2LHN7U@r(d@3zKQPoCLT8y zqS{@y<(q+UtkOK%+`iXPrYa_mY7|#|v7c3iHFb?Qo`d~U2Jkw6xkaacKw~k`dZ4$| zW+VTZcpPLdQUx!l3<`S0<`I7Lp<5=<>~zJ5j6GGV!0m%VV+0Kzo_*UpE8$b=%iGUE zTde_OZm3db&Ab;`%hnh)xO-2o(L)7WuUR9kkLosyVe)}ub}7CsteFzoUTQI}N?4TT z@Rcy$T)jkC3q9S2hkd20F)~q+lkU}MbQBy9;h8*2ys<(Bc25^O`8xJ3GF(1*#jh)9 zY!DF};9O9Q(_$DURD^A_ccJ>68QE6c7@i(BsnHJ2kzu=$&KXJxvn7>Fj*E#2VFVU4 zn6|JB;8PO@rF+m6{nLP)fpwBzUMWv>$7o_pN;EjP(7&e!9kIFL?+o(kLqtQ$?C$wC zTWnQb9*_Bm_cC?(__mC7*M_6Um}2ZXsr13D&YIYjBza1jw0Bg9>;{H{3XAsm^%g#J zn)>C{AC#ZatTspzO8X>&Kz{@K-M1b-{`7jF8eCs_==9{O%eh3L{olMD>~ncSmV}*loFMWa=L@%@)4(RqS;6~F7{5v#SS8~?c$TT z-$C&xe_n1Pk#*g1v1suiDqUv)Vf^ENjdl%KFNrOauisqv8Q`Hut zXk}{}QBX@_E$nPSGa}3>fg$^Kwd>Pcr4tw^RY1A(HY_w|X@FRQtBn&W{_mgKV5K#} zh61JrAN}u03K7 z=P?a90Z*ARxO_b`j=EB!2(1)jK3N>}ULKbyaFJ^Y|gsq7CzwA+fwQ;mJ zEfc1^vIBERSpLjU3FGk>9g8dFsUH6P^(h?#IQ_3UT%V(^mj31jPH`Bh;808&aP^IX z7e|*Np@A_SQ*%Lh{nN@=>!!qePdJ|G0NPdaST6g#!8U5E`G_?3yIne%UWJ38z1P76 zlvA@so|5@s-r?HYM#aZU0ppUj6$-YK_*9e4Q?b-Do!bF?bdaEh|9hlO9_|8NK1Z)`=tr<3lr45{2v8UM(FOIz<%|{ z8PAHciup;Wij{k580%Sk1+k9TC7kD(k(VQ;nzAf_DqO7|9&=Loz!e=Tx;|G%W}AirbdZQVu~_nX*=uV zdAR&SfkeP1e#hB8^7_i&92?}m1U9H=s`S>`TY~khOMtq|5A`9q)`W#oJi8@rp%{#Z z2zEg!O=Npis;t|pFLqf-+L**!Ng!uyj>gxuJ#@BWPm620VL7FSe}=vSLxlq4D-3Z6C+}UZV8g}k;Ufx$rQZB+bS8&v44Ab6=@{28r^5#>n@a?+k zy6%><-+t$CGNVA5uhjxh9I;;S*wg6Z60=fiI7w}cwc9cW*;r4?fhx6h5z-a=bmJQ( zs@5ohZ&?x<*GDWs4wU&s-VvrxwyAL{q?Z|8U z3B=BP>V%0KJ2t^3sCTp{U1z%zNdvxVBl``nq$v!tgT@-V4k5ugVONvF3#W)gst#d- zey?TOYjnbrD;pQB|mCvlh}_xXGi5RnN-by{=8%k<>eWm9sP&zA~T*&H1H z;Ps*6nhENAUS&B{Ja5+--Ll)0c4#BOI{8CtJLEr2hLxEaX#Uq)E7!L~W>X3uT9aDW z$2GQO+ULiE6hXHXhVDN`UjXNt8m*j+MvcoB9?m<*Et$gA5WgjjXNYa9<*zzVU*xsE3E{pkl=H?QreT;&N>39SE|i}5~X8<*%M4|=tdC!rL+ z5-ay#C01a)QHUHh;aChh=M=wilt|<$>`C`z`xFlTC%x`B8Ka%AnIyj%>=g8{Y4gqv zmNt7-=zCi|fE(YrNuY06?Puhx+r=U)1BtyBHIXXPzdou5p7Alk0c%-5MNB*X(krMd zoTMo%FFpn2=ts~Ap1|CZG+n1mZi^=dORLkx|I6=Jk*~X9iJ}Y`14lL?n=8QmFdD-1 zy3aT4>j`3Okt0$s*q3+g+b@`OPm}yGkLLz_${3X$*3x26&m^Q08C&KMOjucNtLhIk zAN?KukZupA_T7CUFoo22*EKr3EX<-UhHUgjm=GIo*l?*^MLfvyl^t6x)a9_rCu~Mr ztf`tn7cy38VxG14-uHVec69&ysv~N@o;C-UgcDYBXT`Q7hN>ejnd>?m52D+>#oTHAOzhqK7zH;JGL*Z;VwsKgM=g1du-Pgj|?^idp}@Xz9v{LfeJ z-Kn*HNj&*Ak~kbxEFW($ZNa?bmCB^}^nxWdAS>GSk&mAT?2a=1 zcl8vJlrADz<2~IaI<>f?yIa~siak~=*GUjPwEu)HjH~F-RK<;#=f-z|cKxu<%MdW= zAF!x&3EIKwXfAx7XbGQbRz8iOBm5`nJbqr&{WXN-EDMPH6?|@>e{3;XLH7>o1r8>|gc2lwDqeC-th8 zCs$Vo^?-)>wZBTky7bR@vFID^FX!eZ0hCft#v~{Th?(FJ+G(p2f8-&ERjeX|XcS?o z{M(XD}G&>!x%)noL`RAx)gO2cb}K+U9T z@uqa{BzP^AT8gFu4+Kid5;{2l*vKA$K`T7GHfM@k$p^M(q4PEk>)GeJIs3E zd+S@eI$NRt_&Ai!p0jB#5G4{@?nSXPdOjT876zBV7R$cjn+{1<*YQD8(h!*Y`gUp)FrB0aR zgyA7~+B$tvlZ5KGpd%2+xA^FeZ{E$%I($8w|Ao+3lUE*R^Jg|IXvucvj)4NPoAR4X zJQYSRp$W4y&Y23h-ncAyGKsfGJ6TGbJ~RSU@1cstMW|&stnmAcCi8TpUSf>@PL=U| zasoXhn`?d^1#DjoUBT4te&w+X#sh!(Y_P6m6(fks9fz^(L&!e|nA2hODMBs9O;_cc zc}|ixz@CcwL#|qs400*flC=umq)?^_sI>0zHc19HcN-fvoI)T`g#b&GVx~*b`ZB{g^_+C4uk5tys34V(07XVXK zRHfCqMP}})r2ae|;zLc90{q|}Am1|NLH|-4T{c(5$G8>6hm^vXV-<(`ODx*da$|sn zhzIWuZ?d(SwSTIbt_p^oKVpd>VGZ3@X3-knJ=gOINHRO=(TM}c3xA9EqX=qu$6u>) z7&#i+C#r~>Z}K{%r?={S{7i~!fq3Gsz_aK$p--Q#Yr*>4#JQ4BV~$zhq0p+N8dRke zVJ?JraSOBlz<=zZ|M8Z_v6L+;UwnFJoniASFGu)z9n%ZWJAA;s8l-9B_tffv(fVH@ z1x~~JF13wxt3CCLf_A8bFRu=JkI)+${2a0>S{935dwQ$spJ{WdIJ=4>?^dJ-xGqHf zNv?lIok!Bwy6FCU0q9~HotVu{XxW?^Q$4fpHcjWngitWUVSUVc{Ye7N*6QpbsRjnb zw1!?DLh16xq)HCB{`gn$*X7@j;P$n^(v{Nw?Q@NYr8{rI+cvkOcAuOM#NMSBAUMe) zD&C}__RBtgEw28$;qNn+L{E)G*^V<7h zk~s0iOl1mqMz^9%q1{5WSwE?K0m_-F77dRaH)4i^M#1MKYjZwLRFuftSc;)+a zgU>5kVs4#fg zkJ=d;`J>pCG)-he=L+|$%ab47sbxnPWv20J=G*?HvVJ3Z93#i1Vv-!{3#Al7UY*SA z5tnS=j4S`16_8dlBB@i8eeBC}c{P{#c!_ns!=co7S_2t&kd47%GC>m#Fiw$?{v#!Z zG@^@{-%!+hLSLJJ-5IHkfG0-Uj!gCfWOaaktZ$$A+*7G9r441F{~7u~zmmC#xR9W; zk+A%u8Twy*kFmzD!h|q!N2@)2l7er>GNTCnlMYnBvRo0uGW_p88ar)o(T*%xBMDeD z)$`%lWAno2NpYpAv&OFBxI5LB%>n&hhjTw@>kToZPzwp(t+*h~Crc{S$k`XGn`(fz z85(?T8#9Wo)_cw{(FOkFxqSc!rsb0^s0$1!+qm!@4r&CU2-W12k}2#dT-5~B-mjtj8cMg2vEpc5CBPfpnz zVogSJphVe9n{>Oue6tjwLg9BTK@Z(%<8hK9;U;cd>Q887$W~B5$Bg_*qo|+ygy?}u z?$q+=D1^Pl-F|AEU6U-&PwM-V2&VAn$Wxw2SO@l_=gV=hEOhx>sa39DdA8%-GTM7% zCW9QQYc}vl5yWMq@#OOV5gRS=8Z8XOdgIb$uSMV{7{kuGMETk%7lV;99_Il&j;Ki7rBO(gL* z=j2ypU+#PpOs?q*#5YlApA#roM!VUNi3lyuI@9`2ZkRiUI4auU}9A)4Wb{0BGVPQm(5vY5`;S-)+gNp$8RJ0u9U&MoZQ2G zqm(mWsF*w?&>WhkD9Iy)Vw9G_pBh7#l-aOatCL_V-RGhjw(h~v|0**$(Jmi^KA?Iq z+e|*_RWL-iCFyY0S6ZzThAtnz`$6Z2nk8{Q&g8P3FH-2?>vf+-qw@mP>{Tw=AR2Jf zS7RzJ!~a|xIE-wHk&U;h-il2+n zpXY>JT?AaeCYO`5a?MSL#Xns^53isOdVvvFT)For?GBE@5f*H?KB-%B)2(88YIEIczM)-!l4ZDRf+O(eMjX0RRhn@7ddin| z1YEk$U>XNUo%|S*+%z1DBYXAgaV@p32!xP|y}K?6RxQD0EkCRfr^{J{$qye%x=l~F zTjMJs-ZZ^>JuL^aaOGHTgU4d#1?b<1nYke)+mtTxQ$m^*h(GF2^Dha%GoXXC0Y|>$ zw2|U!NSq8~2kg+oG%>UVeUM%fg^Kdxskaz1MO)&J6bgdc*PM4zJ0kq-cq+%w)>crU z-2Uzwj#3-m9QVxND>4};-W@So{!7ry%JX@$x-J)qNWlo7gMDemNaW{n+)sBy1fTuZ{+@gOUwq{&CitSLp4LoMHgvS zWT@UY+c*+czK*Y41Q;?r;^p7%cpCxh=KHMus64=3vldyI79C6S7Wt0I%^v#hl6xSg z&ydQr-C@8trV|A@*6)}RX3=x7@34pBFrdSa6Bh6hbJ9Cll`6mk&U`q&S{r$`XHy+( z>lG#|jAkMpwU|>zW0ba0b=rRdN4j`6l10}ao8ecgUFEVa6E~1Intw;~Uxs4@`;&jl zHJsFB#O@>@Xp_EQY@!mMGTXotUkW=C>{=|kuiR(F?En#aM0MMpfE;JcmOYb^ zJj4cznkq?U-+9_yVuh=jDTdhHu4>Ja@s*Si)2 zs2Aq<9f&(=8adR#3ADIqe34JiNekvQ7Dt zKfTrjx#sZ%Kil)UT2KM`0ZSh}#kqPdzwtRMwzh!n!wYV=kdhi6aW)Y#LW8shX9MQ# z_Q%eqcuRYb|)1N6{7g!N6txM+j(c){73>bF`^yD8ZT7ZK?sjn}?YG zb{de~b$eDe(aD+M+*Xtw;G-PN<*9E^Oy8>dPV7@Ws4nJ*>Ms4Dg3mBsl$MHdTG;k9 zuqY%IEGc1z=o}aGTVnD*JB6NWX9q_qIi1gihe|f0{_gl!R@L7ql3xJTjbu$s2qt5} z?xf_9JL=?`s@_-A>oU4#M%amB$wNt8XXZS~cd(LX!YjVFKx7q;K2F?a)lwWWu%8-9 zvrd#DjNzSPLy3i{63ucAU}GWV=R2NSlvDV8ASj8dT`Q&+>`GfRk)?2`v9GGYp?VeS ziM0gxN;t-$&v3+e?}fkNX04e+v(frFiT~c3UZVUCbr9P8O#CtMm&^U*-+Il^&92!y z!Sj>bE)lOMaY;qhK}~T#w7#PYV`oz78wj^yJ%PEF#=LEanj-DvCFuc|+4z3E zfNy+nhm))un!97S%@@KXWyui|!OOE(BG;EvEG{d*XjQ3hDL%WW@!gUuk^>bOIYN&) zMMJJFw?)Jq;jO#TFjb%UxgCp`E+4LNd~h;e-7I}wNlA70d&HEW4uq=*&5a9Qd3K}w zybtN9F@+v!QU9XS%+l=5dlb$EgM^TcuJW9&4Z`kuCcckWvnkSe>px{i#uO+W`k@Lg zA5_q#$ML5X(pI$=a@MUoGC@MhhE}o_a%VVxU;$>>4v(&8K_xcIg{&#t{P32#d5vZZy;;rs_;C8mV2pBiwC{&BwvEo^ zxi=icv)Uc)gN7C@#5&wQ|7;)uxg9$U5<=*9R7-b~G^I%y*5x%=SeQ{ziX%hz@z}FO ziA5ND4vGL66{$m(I-2;lEQoo;TImlN%E3R!P53vjC`-;oy?$SkL1>3Z37zA_^d5BV zOX`#I%Ti!XBO4T&*roTdZgbPne;0^mY0qw7DnSiV^xv2552Ar&L)kVZmyu@@RqD@z zKtG}{qYaU>y2daPt*U{m+FL>VUlv^2$fejntpI%!hT1ZOv`BJL>|>mL&pory!2@oq8Y|V?>q( z+;qUghcoW=`pJK6$di(*VO0qa>0w!CiajDf1oB%g+k(-WrGfi=oEX8a2Q%Xr|WY6PS7>{l0Y>AL3c~f>8y4_R0Y@!oXq1YCfK{Vlj7>V`bhNQ-vnS*r~Fv$4dh8?t;*N!GGg( zx}HYcH8BI8gCyNR45|zp=1U%L?83eul(CW3Bn1xrc3>6b`AR)nS3reOw8YjiVeIIk z=3+EjG)2JoUmVAj1#Ia_M-9SSwbP0|^T!V@^89|rOS?V+cPgP#dyP%o>erp1fN>hR zr_(Nj<+qlD0mE-`tzTj=W1BIf$ZXn`+22KNbxkZqRz-v!G&#*oKy~@VCoHKwD7IjA zi`=6N>EL7(Joc+(ilUkTmzAMwII)$hq3Qj#FZY;|A-kH%tc9TT@abG*g!vEe8FCN0cP zE5>~J?@1^4UaKDm$g?~HXlJqwNAP3bbEpPii+O+SIDX>*@j6jw4vWUjo~_&5mR>mJJ3X5@H5yMSH<)#WBbF1P<7$k&E#@c4Rif=j zALW}DW)x=9&)7&e&mJYpNBl^ZQV;64lU`r-WE4^Rtp9~l{tTDjjy`U3esM5uD{3+P7(lAzI1>+J!HDwcSc853ouWAkP3pJn5v69L5)_E@D6#&x z9{jUp^r{{bkQ$2U_^Jr7TVJi)z6kn~5Or$U-n#DKya?vfB6P8h){Dx#kW6$(f$(rI zpL@ZKD>+q&ePZZMibf5<&7f8FcCDMvO@35!Y@lcFO8m&*L#UgGm~p&UX@CW6qmb?Q zM(H0oDRf-uZETG(n`Ty_nsPjBXo-s>B3@XVu$Wtgfz?u)HWv5hXn<}!w>8LIVWP$# zBRQ~g?i-RWUFs%`-M$g5EX_Wg|AH z?+u8YJAMzB$r|*o-EV5$x-#$(Al<1Z;}V`!5V{k)r9ckhYKD}Wr%&r{uKPGRi#dKO zO`ERyc^#z;{zKr7c=+GB$@QCyqZ)&ri4&t*Wh?2&f$_b2XE>g8oLR|~)&m7f_gNRX z=FWAxE0iPP3uo=lG1=uC7K>pB<|)y;`IS*?v_K<&{*Ad!96r+)d*>T68WG713B>jp zvwyAM_u%S@6JTODKH2#zq%8{7^5=JQ0-vrH^AY9$WsQG}R&AiaEzVX_FHf?vW^0)z zfk)OPBj5PgSXcz1;zFEE`c}~@bG!vcoatn$O`7De6##yYPTvHDU$rf-4XcLC$ymd8 zy5IQpuTH@^MF|$jO1&(29X!84t6!JIHI(7Jecb-J5Fu-D=A3~PL#@8ffYIJRGYG07 zrMRkKc~0^uwCLNRs2x>9M_*cr-n@v%8ByZr5*6QbCiy#$D=ST)sZFFlz~}bk9w&qA z;rR(;cp<0Oj26s-gTm9Ce}CJu9h&y9?3Zi*T5#v{jINz!=?manACWLu|BrKPJ;W6u zgZS?TO#GNt`cpY!j4LiUG7Ur3pxetUM_00 zuKup;jS+Ner{mNQ_$XwCj3#mPHK|Oki%=PoDIU6zsPt{C`0E}QPf2J+xBuT)L3Kd; z>8lROR}R~dR+~fBZex_dlMfB7RpIsiLrP!4Dg+9Pdy-7jA5OpC|3O7{R32(t^JSeYHRQLXUN#gSYgxt51kF1jt z-K2B{)yOPr){&E2t>!JA)h$Mj#gtnW0 zPY-+PMjw1T8sv{t-Y?tg6qK8AlOY=IG~CVcR11{BRP* z9Ory2RRTH(RvCmrwy|>}ugH_zuyW_*>%R)NG{Un~W`OsF&3~1a)LG5A>9-~6#rP}H zZ`~_+kdyE@OcdUKxmoW)vd{?f-pK#KrDKAHs*>9zQ87!8^NC@>p3KjYG{hQO(^xQW z^=<)!*;LiygX=br-%!k}R97xow?HV5e+doQRJ#I>PUP`tbnA~tW^92K8 ztUdoxtRGX-o&uFGwA1{eBZnn1EMJDgA9n_MY2!Vm4^+!9PoqE+xM_LazLwQ{65*>?>Ii8-Of3VXI z{l)d;Z`+au;k2!XCR5Bxd@n!ZO#aj+il5{Kwwun^YU>&X;?#h$?2hQ^z2C9p?4z_V z08c#7w5If6!{JMBJTf+|*KSdhMEG|rAjkiY%-O(4Paduvu8lzx!wtG`2u%`6u)*8g zY^hqo;tG0pNwsUlOfjI|qlLvF_U^VlM3_}P^S9^_VJWlewF207NwKmA3+gbyk=zPDos3EI^?-shdsTRhhh1Z|~Wi^_S-XeMZl%WsqC@;VrdGEjBUr&BpIiWY3 zUDX*{*am3V_=UmED0KKr@ zem<>1_qjxs4HL1{)WYB)k2MZTTiN;?%-1cfwz5y*Y)hERg`>OGL&OY=038jPmj$H} zpS(um7j}v~Z;k2kJI7kzp6VkFmUPluk(8m z`E0Y6wK7`-GQyN1(*yda=s&kd1IAY1$w>WokIF1kA(>~2m~x2f!MZbjg9Z7YFX3p> z86Q=BA)O@EMmpFkByqnp{!H#kzW`i-rUyi_Ba_0*cW-h^+_mN-2}30TC^nV=7(1oj z89?5`F)h!nHwpAu%J)Q9RbV~*4qK4;G9gmT8h%MX3RRiV=z?Gn9Ocjx5FR#EeJ#w9 zvxyhldU%S+j~WoJ*JN=EHWe)@Os;Kvn*=Me&H55PnM`!|Renyb=~{c|5)Qgh^HJ#S zc(+PgR279ANId&9tW_zj=u6`1c(}~J!n4;OI|3LPp6Cc|IB?gmwP=ipt2V_ejB*}k zjW1@rKXvMG6yyRdRN2<@R*Z*Z)i+)8U3jv~jC>1(@$ihO_dupc1M+5r`zkgUo2Fz~pXcRV>sKG*UigA{l{;YY7@E#F`%-@hjnCTu#=(xfwgk zf3KERG0X@d@`oF9-!wu{C!oghKcj`7)8d^%Ecsmm20>b)JvN;eoph%YdsB)$uQJ2J zFl|K1!>=r^`nBfbE?dYY*31cBrwHH<9C@o0Q&2p;&etl1B(eqDBc&9=N$ zPklFoo?AC85TC)#-7nMZ&1z1OS3P`*-q#6b4ydwnVTg{x@leaWK<*tXbb(((^wDIs zZ@=NLw4OcPdQz@esU+RQL|f#s*fA7wKd1xAi#s?&V}4Mb@j@-~5EM5o_xpD5ZtT&i zdHF*U;VzkVE6*ho$on z9ICDR&AjK~%raU5XN zhuH5+prYDBgp@5$DahYrrg8*(*K5I=3FK3m;-Ml&<3~%Ms}$$f|>Ut-D=y z^eEsco4apd^O-r|#o4`u%q(+QfT9^Al^0<-nU02}z0RI5g7*4 zw@;qD1yPp7mqmDLh-pO`Xs1_!qSSi&QYyx!9axq^JbCHOxDGH^?3;A2=IKOdt96R| zGuAI0u$ZG~mDz`;MjCE^1K>ChUe|5rv#$d>WO4|PEt?m5w&H;kUHYkN^`b=Z(N(__ zz;i!u_Uz47r^aJ~PQcWa_fV33Py2O5piDIScl5#d@Ehl{cwAO{A4eftNU9`zaoNc< z=)_R}0594ig^o32wnaavzB~g;qay{|a#@)rrPJ!dgpKhxiCtHek+AhgAmqd6z(`xa zZyiRSMzkLHxpVrxU00}Jgr7>H`En!n`0xxyUgiT6?lN|y$z&}thA0GwY?BQ)MIOR7 z!x11z%j$OY0y*#+M@o3F(oEHfavi~K$FjmzevNAU`R);wP^qEZ-W-qDp*#h5aG1M> z)l3Z;UWwJD_t$3pTRci<%QKx_tp>+-OF1!OtB(Y|g z`;I{>WaA&H5SBZU^Bk8cjhBTu^^I1Bllxo1KKz|3TDea3KVWcI<70XT39yo zSsJ5BBv5nlZC_`J0B`~0GIXzZ71{=z_`L4sLmcuf^4ipDSzUlmxcZe>(IWC3^x!wL z`O00pCi#+VjI#>0twuCQ>bOOHr<#$ksYuijrvSFh`7C|b?XKJ_RM$}Xti*s4q>aq( z=U)JI`1uY1oR(JfQrGR=VS8D57p*jx4)Iz&H+8HA)EP?p_K~(RpbA@n^S2|T7jQ_6 zdV7~Dscf!d#HC_{9$OVyvhOF5UT5Y!I0toJt=!z5%Ejcu(TSnw%>^Ac<>aqvbdTuO_jN% zG@)Y!9ivut41SU3Wqr~&$Ctx^3A@V^YP-)u2}y2CFhQ{o`q?!j%nkuf2>ZIONZE?y zR${PAG;^P3<#gsjZ%Y6^1^)mJ1FVyE-E7p!KwDkLy_42}F!B@fkw46jr^$E)wi_KK zkqy8~wx z<-j(ct?N?cr(2hjIZnv8!bH{O)Dr0I`fOq9*{?4F%Ya#%80t3`^!A!d3lOB%V|94F z%W{)^Q5h9VzpG8-O-BLV3P!u!EsuP8qh9>bi&kKbP);PB42i2FG3LjX?=KDm%QZ1w z>tiFj3F6Aq*RL#yy>yLRZt}<@NmO~p$gQW+Plo|nH)B1X+~{1$jP*BE3t@H%byd+= zKCHcH$0cHYOX+VS0!oM7unitBEEgx*YcE1Pf`&=xiCab>f+T~P^+h1qe7-yb8}Y;2 z*o!9hi3ZdhiOnWoNTI-RqZ)V5LDG94%BDM;L{5 zc8DJ+Lue12t`En6>l5#+NALPQT-JHE*MxEcCM98ne(YgTyZ-zGR>dey?s_7Wxa1u_IXbsh)9fcq8z!(S1N z#dh7VZZg>EERwri*0WwTKH-Cg0c3Jxkz2(0bJu{I?CZ8W;}@4QR)V&6k|}G@#G<9q z&-87>{I))xOgWDcrvNu^Q--|;zm9_CYFA<=O4TImLLIpsp_wO#n9%)0%pOC4E~Y-% z#?Wc9R(2$>J&RL9kfilW>Q={ANYu8#e^Xx-`0x|<1qv3Wq8wPCAkSgrnT+vE11Uz> z%dve*!Te8v;5F^Mr1k0Aywq$|TupiBgC7FL84k}3OyG1#`XoA%r}5xDr`z4Vm}))6 zkGn1lsbQ2~jxc~sqf)XVZHmPBIyT4V3WLBj?*7IWs>IUDsb&QRu0|C*Q%_cfRI_vm z<~HhLJ|2$%TZ{YlUU@LN=uCOefwP6nM140Vt?P|sW!4)XPbd1mJO(|_+}~r0rJd8{ ztzU_4)9WNrQ%O8GOB`Ssq=~;P@&|xa$$z)IZhO{Q-?_8$C}w}=shIDLPQRN&)o+=P z;lMD#cEeqg4%?*tIOEn#owe}`uE`%?`jW6IAHfIXz&7s+y`htez7?~QW9j1m07f|B zuF_MEQR)3@fZMouc=F%@v)k?39j?_UmK(CqEsTp4^+fPP2#Os+{o^+Ql1%g9Ajr&y zOeB*eQQ3b~v`ea~LdR3lBTx_J{5S_Ij>BPlY8hzAA13xA#bfQW>-uuK$+#%dd26`0 z$Z!VZXw|XYaAV|+O3;GTRFY0=C5@v^+Ig^ugTQ?5-Xdz%GZ=ZHXzf<%*f9`yZVk3g z2bgWUf%)(o_Ix!Y$MkXmjUkb%?<0M7`*u2W2lAKGcgukK4{_%5xUS#I%Za##JPoK} zB5329Dd3qGTGDSE-Ue+o2VFTHd;*M)Gar}idR@-A_^Z=-dRYuip@az1Nz?Zg7-;b7 z$Cyq>;B@93{{Th*ergBS?#E2VxCJn`^*z zgQu3B_C8jo4F`>6z8*C$lRS#RZhd7RSROn9$(pm8z}k^(`zE<{ahVx`V=6-sGdV|X zWa;eHNOR~Xk=w`s`1@7+Une}+36{k`LS%8BO=ERlL@+w+Z-eBve_<%?%=~L z*SmjBmttKPA&%ZPWMJEb&~y4E47zw7I1NTpYtciLuSy*DF2p|0{51%P=70jolGby& zIift*YaU;-fHY&H?%v%5*{g=4&m1pNU38~Hu`SWlm+HwUt@ml=@ZbZpl*IP*Hv5W} zzpErzp4^Glj+JzZKDEDB@1XP_Kij}vV&}lq%=cbPD>P8LT8mkwIv;4zA*>V3hUcIj zCxH3otkqMT%;czvD)!}B(%-d_Iz~&$5kT7yhP$=X$6Ynx1OCostI*3`zj^k+1GL0* zVp=wRsyx|>=m(zwe{W5M!R0!+h)P?`TbR#8uIPjlF1QE6%z#3RTvFN)L*LeOsTN&U^>UyUN~BW+KAZh|sTC z2x?WYBQSMy$%z|xYySWa0@_?BM`nK0FR_}r#id<+cIJChdKCB~strq@0l*{6TA;P6 z#f%FzMx8PHBI*^1V&1M*$?D6=ex@LQ4*+CyW^onrd6_69$6PbxSrkROCNb-*mG-#N zTg8t7u3{w2R>nt=iECiip~*G4l6S*FchwIbkZ_ z9e58iGTFvR*6()oS&V;I-(u{=GRsOEG9Of%&Ws^)caX!(3XW!rf#wPf*l3h%ooldU!UjQVryy>|An4S#b_@!%ce z^Ifxv>$kX{FHh!9mZH?%vJFdGH@CzjDldq^8uRp44ko9Rd2IsFE2p zKac+acL815w^9E9wwLiSpqBng77B1T)2xM+ zcQrqCQptB+DC*Igv8`UjO{`C;-m(W)C!gcMXL?@a0qR3S47DOpMozt*g-?@4WFNPH zecO$ef`F?fci*#Vru&ZP_Z@vc-MPA6J33o6)8)WfSMFSWin;71Cu!qK>piQor$wfc zD-kS;k$y&`%Hvuw#THD zG5&I5{PF())QijNO%I4wV(~HKJFd1*84t69au+#;M&7Y3pGCUI{mSLEWh2AG;sAXM zFWQ)iAhnT$7fUUahCZw?$^dyCMxj`ZcOQnl2hXeICGSq&w=Zzkmb5U~jeX5%NCRm- zB!y4cA}c&>gHyDF`FH@k!?-ar+NWw-)9-=^;Kx_4cKv*u+Ql;4fK-Y_+V3Rf#qK0l8m`d) z0HlYQ@jUnm3}z=MkiyR%K)hbo=~%K4>TUbZrNWl^mjPRfp8P@^h=Z{jYw_R7q#P9*vuZhOfxq_zR3z=$C%3wv7TI5EKPT8JN3k|1f zRNxJRxGK}M_*%WM42w{h4b`TRqX_vlhH0eJPvT?1KdUT~KsMAX$e+^pDm2r{;td)9 z0Nub(_ZM-cO6&J3&3^`5!z(7qOfr$ENurllRwJ4+&7tz zEG8zCTUOaU#Efo(e<3QM<>Sck3TX;b+`{)RN~F=`B11JgYz#{zh4o&uc*hFL#nHbq zoxUTONoO+n)XCXzYdyPj$X?ulwRj|vn6oH=59Nd5@$=vZj}x5kJd|%@Cq#V`2qQuq zsQi#etuUjBbu|>wTdQchO>yRMIMEwiU;%B z2T@S+Wz>FN0>7{`k@q!Q501>rELLD%8&#kdHWA6gBL!f5HQVFB6W-X2tTd~>6EL+h z4#g~5v9GxZ{{T>`B3&c?Ask@0?{E{jER58tq!ux=x#A88R+sD`qK*wS|}D5GAGm3 z(39yr^wWS{Cwca)sbddzSA%;!c{N7cxRNymb@Sjj?Ygm1!`s2!{aRDBhB=2PhHi09 z6Y2RST|zg-5a^Nz<9^s`m+)r^l@=Zy!g7Hy5xTzvOfrAEH2(m<^E9<7>IdBAf%u%U|lC=es z2>og{CdW9Q27>td78h=;Oefk_HU~mZhk(jH+{fdwX-b+)LNM}48(t{4txEAU4KRow z(~bz_-M~**!^=YfLK&2-tsD``z8W64UDW;^W#Bf);VNga`N$`@DnWAfnU;P>ZpqOQ z9ohr9#(ekya+&Gz9l=tPCti%@;Uuo)lSUA7ADv3ZH>a3C9S;Ee3;n*bmF-DJ!pVlU zD~86nEj2mEq_k{#NEclg9XG~)I&csfY-Rq~%gG|6C2;*aFsb?*>Rqky{P92k0FME4 zce`=xMyGJRRwJH3kl(+LX!SDadQUtO0*C(&q7SwFn9)*3=f3I-lm?}ukW*VXh}(@k|d2Hh)6l85lT*j z$4|$APyJ6<6^W^wiya)6tjW=hCYEAR5jv7MkTS4#-h)x_;43dw%;xcQZc}SCa~B|K z@kQn)h#bQAdsKalk%Qk8gL3T^Vw;trE8|tb>xN_IYs%3$r-?mL87thMXHVnR2A5NM=QJU*uk56@2!cmVFf+gNySU7cDQPYTeSZTY%fc;=eciNaN-a^=toUcx}eUey@ad&3t(~dOtNZNUM zdFjAYTK?X4^T^PqNSnIzN$pUD%O4*{QM5mca2@CC<#E1~qTX_OwlNn;Vt zcBv~O9+)JdI%}^0^2`s6!%38-C%Ln2Vw%)yyV7{jZJA|3`I-eghvoxt=es~0V=(p> z_7;0RI?oA-@@pA+E9hg963UPE#@|ey8hG#>-Nn{Q7{1Jg`rC>XjrLV>w$%2fW@l}r z{**AQGknP482!$@9Ah>vcDdV$ayX}j$$2R}bEsyGo7K}k45!1ya^NDW)swM1vi27~ zjJS+~80MBON$GCg4Tz8LMt^AFEc19eH!|4H=bI-HmaJk+Hxtz!PMVFXU_r=E+qzQ4 z{9A_sKVp28xj5Qc5$Y-l9PbBg(aubZxcW)ylBedsE(08Od`&ER_U>v%b<8~bEX3ZB z!P;bPJVxNl{!`cu) z3GGvpoF`Xw=`tQcg2p%tB)g0L;r8?0r(0%jn)I#EW6F4sGa9$!>Wuj}FFpY-E4Sds zLme7YoXg}D`q-I3j0iOyRh_@u3P;p=tAIy71JujOi^~HZHC#$tlD$ZwX#=rS$Sf#h=6rQ#90t9yE*CwJ82o;3 zFOSJe38?crJWk3r(5~kH01bEm`=d3Go3muEWG#zu+iG{GUO*U`v~3TD{RW%@-q!65 zmQI@)?M+sMi@es0)Xazd$Lch3M2GjChQ3~^#i~+yIb1LOAiAu#hvT9 zM^Hg5ddUQlKY{e4pg)*$JopS`?fhSI(W?x%;Kwz48{v~~l`Six2iYOo5<(N29$@Rh z8DdOETevM{GBzGub}?sulu|OsRtT6uUvEr}C6Se+*T+pb2U+F0oUFaN(~I(5r88l2 zZKmnEZ4~JY>;{F@Ms$D74?hFIeAoJmxPPYq0HQs#oBi&+4G&kx`5S&6Pgeo;{^LsY zv2?Jw^hy*m0%iCHJd$_UEK=VNp z?uKfzxD4R=kTvqxQNVZHmukt}_pj9<&N9d8fzNd+z*U#=9NE8T0H3>UNru2v#^B?4 z-#pT+HX_$wXtHb(LjM50VqICt=eKC^;1mz-elERp4o5QMD1dvK^r_2kD(ptPCXqRA z9$;_|Ueb2oXj4NZ8HcJSRi3*yD5bE5FdIPd$iJzkqnFHZ4a^hLhFq#Snsltu!$EmG zu9CHw59$39px?_*W18wU00$|4y!i~C9^Re7ZWPfqjdn@(q;9MgRiuoOp&J{>>*?Sb zr8~VVX;CWTJBuYswV32+77_%J2)a4M9ENVxSF^%XpOC5<2neELFy2VQ?K@$wdStV-C3?=WGyYTR#RRX9geyzVC@P# z2E6_}2UyE=yGkC7Ud+i?rVg`PfJJDZnb_>-fEziEuX7=pzlyZYjqZv7iKAU5M}yH} zG$VS+9_4q8^DDc|4gyM8^RRZz8;0zZ6{e0-G&;3;Oi;GJnDkKXJ_kfTJOP-z!Lf$N zI~fDxe65s z2awdC{f_{EMO9)j*+Dcn;^m0})|vjbLN#$4ZX1GzU(5#q&Qk+o{{U`7hsWBjjjvi) zi!~D{jrx$jnzovJH*@jj&wy)-!`sQeDKOSOr5q9$qmi6wwydfYR7E-#i%oirK0LSr zzo@YP0CD&J!~X!~JH4OUv|hhoPx_i^(%b6le((5j17&VwtakI^sM`10Y%OM^YE(Lg zYn94{Q|Go=RZq>h2wvp>0JH6i*!c%iTD798laHmIS=wo~A2mi@y7`_0zXgw@CN_>b zNRnu+8%darwAi#zY>nh^%2rsHrhI;_JopL7{{XnRqq`O^u09;Zv{|ZSvN4(Cvn(;T zk%C}kX5A@YF5{M#D3)rxtNsfu|@z+7;z$ESq(&O_k zWL&mVrF|C0U)+{fX8hu+Z3w#f0#NV_asA5$m?L?lH?hF7OC0RZ3`dlRl1r?xxChl7 zj91V2fHG{FRl6lNn9Uui#I!A*MWnB_(_MTYYJlVX-?_jb5Yox6O1plV+EHHWuYyS! z>On9E;G_}pUSE{(3VU-i-f{O7l%kR`lZvZRNv79P3%F&G2>SN;rn~^wEwX=beV#41 z(Z|B|ByBb7Bxp>q#FCYfph5c)0dY3 zQzgo^vDmtK1dK+8e29P~)+LpW=^dHBP9!9f(mCK3!;{2iEac~lE?U_q9;? z7BM#2AlJ`pulYCzc^Er)Eo!wqwW}D)@D+5Wk6|V_?Km0P$3C1ovJ?8=A;s z>tXCH@nNT1*$lANVy_Y@8%wsDw4NFc0yn!B4(w=hbfwu!{fKPYnTCNDw))dKAB1Q? z{vp6l=cG$L$qtc}l*?}8D}6)6Mi_qg=>m8QO#C?d)GpgbTJ`YDUTjtVS|&;~(rBXn z^?j-&QOj{Yd<4ZW?gw#X=asQIC{pA8t+{JUW+d0m87uD=%GE&lCt%r)xAm6oj0 zKqkyvtt^u-RhLm#0_H^Cd`mIpH2Cll<35yfI$y7nqa3VEHs`lBnAmxik`@I&6fLL2 zfVr*QOJ*@$<_^;`$y(%vdeP3ROl9RyMDe;3y-%xQ=cpc#T(?KGmI9hw$FoM&`389A z(bGfm)-ki-NgtPhp2%Yjj8qmd((SQHn$|8v^y-rOo;CP$=A+2^emn+!n|~{kqj7RF z#|{l_$&tz(3drpe2I=h_f-|TmfD5yQjLexR=VG;PSdLQTlSd#eCiHJ2s(^kva29fA zspVt)W*JbN$JMVR#YvPU*_{cKchbtnPvI;M?qKi-pvc+7SBtl6Eh%F~y%jl>gm}!eB*`L@ zSs7#_MpMh;ya70Dz5CY|OxJG5?<3{z@4&J`!AC8(wA6gMf&T!_z%j=!YCmy(`yrOQ z9m@NWA-cujj4=9Pk|1F#r+`-A1pDqc`pf#O+PC!YL+!tH+H~K$`MY%A)7R0vP62(2 z9lc8_Va$?2mCtSls;0rdvFb~)2lC^RNVjU(9&5XT@SWKF7B})I?1pWZ>QtH7u+q1hLYoA~lKe@ho80 z*H~hQs!?Hp_>aveiRHj6tDMK-ux(;1xd|%ADx|j@D_>b09g7y`c;SQvKA=xf>No;z z_cdswS`*4{OOQY#mck<}vL`huIt6jLSZE{+3ci|-0e(9XdewR8Jgph3MEIL$UBIB< z5+C9~#D5Z=TJqpD$<)Z>nX{GRFI1jhELDKEY$4XSdJxkN6&`8R8nD=;V^&cNSp`AGL^0bnd(=l|F zjx)K;T6iiV1|^flxqVuE4*=?=F6FO_nvPYh*$hJnV@VWfzNI=9Ko~I89!KZEaSwG* zaxq#ezTYWS7m`euxw5Ys9dzE(FpKsBz%*&@=H!A}ozO9vR?|w9?tX^tH5*s-V%OxP zeg}YHzkOVNm^+qK%1;8Aszp)KiPI0?DvW2$4M!C@{ucd?DD z%O^dOTL6g}mr!K=AOfJ;x{V2Ld;kz2mRPi?Z5we(5xy8Is95J>bIZ&BoR;0edz@>XN1lyVZg9@_Yt&_3pz{d2pR0g-pUmL#(7sD6N*tZ5I;JM9pfZS} zIyCLCg2?*m@c?iW?$)v}N8BCNDyBLuKHZ9qLPmFeD;y(019=Y?@h5MHbCS1w+Uv_0 zImzQGR+#=>8t0Q1J^{ac{{W}r0DiBE%t;ba!%M!(dh9q^C6MdSR|>8WG3TN3(|~Je z=c-k&V*EDkTBJ4AI+5wS>jFSyV5d(2e`f)uPUUH3k0(MZ)vE~vQ^k15k}J68-sWQ} zw}+bY;0$^h>vx*ZZ1-f%C|;x0_YXR#9Q6p^y`$u>`0xz0%YC!oYX|iv@8)cq?fp$O z_uW30oqe3N(@lL`0xI3X9g0+J*2jxVY(qk{M^}_a=p&G`{X{a?<_4Pioi!W=nA+4n z@g*E=ixvB8Eb-ZLyF|+wia8jtE3TyH?u+zsvSMvpn=1@$TK-v4LRqZt zTom^Xj_ib;jzHId&pq26tzv9F3;Ag<^f3rn937%bA3+^xwEU_zp*~7990K0o$mB9HO(WKiAS_7mr56N7(S$QdrB|NF zwg*5t>NFla1KYS4vud1I%ncmR6nM+Dqi9yOgl0}0tTFFVIbF42SL^R#E@>+?5tBygFQK0Yx zf2;kj6yfbNV63`qh}c5tx}O-Ge@)l-PNRT8uy)*2jD}Y}xmyu`EI#S9)0omFFS}15 z&a3g@1juGA_f|@tB7z#&@gq9*PUmJLbhfN8Iux;# zP_&bKaY> zF%@vsq%rp%QW0k}ky1m&6a5vTf66>}Y54i@8Q{OR6Ig;PIU81&DLg{gwX9K1cpFlZ z+OabQk9L}c@za1V(?cyJtr%Mu>8g7nc5u>79=g2plsnw9AEX&}s`K;U5ZaQ|)`^yB zY1^03)UE|JrueK=Aldj2_;3s|SF!XhQpjZDlFj^igc`7+!K2n8urf zM;Jg|*`zC|T{m<5yaf(Rw{mmlB$M0U9j|IpYUVv7hkH$^E}=x5mN$P>FZ?(JS88D@ zXR=+(HfdzZ9b&CUSYEvKo?p`rQO>$U7VR`1I&cc}8E2)6hSV$4YdWqvGvbJYLpu+S zheRG;K0E_#6Xb2fOg(zD*+CVLdu0rZUU_#2^gvhFI>a^CkYEpq;0mco!IYX=^oJ(| z9Z_Z-%MA6M^ioxc*w9E9&%kg4N14yst!lMGKIcMh@j%`(Fx=rjeRy6$r|*tj$lyAk zBYll|@$2sE%U%|G4!}tweR0bJA5T_4|iZTlc9pFcVzO<)W37YBx$C)58O{7zzf}(Nv~#N?B3T`iy2yPYZORI$!@_qNi@yL zn^xDy%bx(&ulDMuG8Vj-@7Ze7EOXhW@z#P_gJ{+3vo}^_yVJQwn(!T6lXTwtop>j* z!bQH3Oo8KacJ$y2x*!!ti)hSsJOa#gQvKc;D_@jL6Nv;iSEX{hc{o$a)AziH^WZ(( zfcu}h`(l01Uvsx~p2w}$*|(>^O}$QfYo`F}DKZps85v;4smSgz!A85uBsL)qx=Ydw zW#!Z)qa8jx1`QNX-3?`xS>ur&^gBURiaENSHXdC<-X8_vHSEsw%;Wz6xEUONLRYfa zrIG@NQ?gp_!8R|D&}pXt>$;@K=J1V(Vv|W$7n3D^T?i9K45qvT^UI*;r_wxl2|P@c ztHUlWq>m+zfx5CFT_%N;>RF@w>GK{O2AGVV98T8oa(jDqW%p62jGs~hjO!ogMpL7O z=fD&@h6{1YcFo9P#$z39#|}I^kH2=PJz;jFQa1ghcpWv+a0qf<>ec)4@7Cy)<#Cda z0v)$HFUxWN00XZ8;~$#FPk>)@(-me_jT%oxkTS6-5?u(#d~MpEb|8QdJhfpFfxqLx9ZNgg6{<@dD~V!_Lr6qux+6Bx@ZbUaZaSVt@7rd|=Igk7 zmaG`kj8;ybjT=s*Cz9)@FD?R<)WT;eNXe3WRwNqQ$6H8MW&@e%G(aZx@m1VUmZQgj zSsh$#5Lm|5Wy$0qES0O-F5NU>u8Y)CkFmD;4}jg{z!xKAVH9G5i#=(QcE|$lI#Y87 z?TS?F9;ptDbw3UPHEOL^mQMC9z>q;{>ev7i*5x#=hxlVt8lREi7=La1t0#X0V-C|1 zW}B>wa#rN9G=bc^6Zv#+9s~D(!lN zjGsekz-+f-w;IoO`1ko}W~EP{g{!J<-6rNfFD{|Ro?}fscmx9D#+CAuY9_A2j$kPu z>Wm6asORZzt`7l0o4<~=RyZYSmiMYiW)3T~q0X`^You&<`nRDR`R(-`K~vwmS!0ge zs_-xZII@-1$KbN)@sap&8l0XAn}y2u{Q|OsvTl@uGybR^JwN2&DEoi9yJC&nQKlZg zKOHo#B)3*pnirB-j49L(71vGVbNKKSz0pc6ecD%|K$KNl8Fm1x8#9JRZ-8wI>+#co zlD=W7nak#-GRO9sa7|W9(sblrtc)9JITiz$<_Wud z4QVB$vque`QLX;ZwB zvOwWB24s|;lE0x}!~@T8-~`HKG8p-B^aU8Hu2q8Hgh$hO=aCg$4LJe7cANt|rdzjh z(AmvbiEGDbueh}l(%ri*f#!m{9eQYu%1J!D2R?iP7^z=;oIS^vuqopxlGwa#U?TJ+ z1bVlSkw)sr)Y`lFfP8oivD7fwyUS}KD%ZDYOJ8Y`_A-IdJj`2u4fT!!riKd(lA%`} zI5_;KH)Uz1i$p1AG0D})XxOso!}o#n;3TD~PaS^CSb+`M-gqp*8|+DpPEt)Ge^04T zQC(8HIuV1)`#3wLtkTv<({pmt*SXX1f5Za(oct$ytoILc@$QrRdhNoGi# zjT>%(jC<47wE8y#rvbdx?A4038qXeMr(>s*HWDePYTU!Bx%IS=qXWxE)1I1e3Ml2B zdx^1`F&sGBXsYB5phF_`BrT`FNPIW~ayg84Caru`T4@ct3)G>AMb~LztWw?cl1JoH zF9G7(@B&fBUa4B_xm%w1HWQNz%b0>}Rkn@*bK4hxrIhAWdjy%`uVqfMA|q^BwD>QW^H0EV3WhhlJ90KCg6=Q<*jM$S zW!IkMJlFBlfMl4unL3dg0R6iq9Fo_heyFC0oUumV9W`Vg2SPmf393;|TIJkShk8pB zvivng>Lah>I1i`yoA;fH7~6Q1BGx*(zFLH5s$_~(8)jIJy=v~fm}#n>M}SwDo*Y#w zS*&=Hw0SINR(c9|CsHXu>4lkP+MvjET{&<8;xZX4^(4N~*k!34mgC1j0BI#w5W)Po z)csD!>F^u@nHx5&_RLb;#jW{!u7RFuc7;zR&~x(O4U@O7V&;kCV+0HXgcBu-(x6}oiex;#9vXwdQU3tw z+HCuO{jScxyy_<3d8bS0*}ti;ufyr*uL0&G6+0kIq{QT@HrOPS!Jv?AW&9Z!YCJs0 z%n!X^-qWgV5-j3wMIMKl>2K8m`622?KW6}{m26HzD(!i?l3@C;6`|Z$tGI`k?52Ruun*=W0cR2 zcw&Zc#iN&L`10U7wPZuvUd}n16uB_1Jn8ic^`j3i-q8Dw+P>xGmkM=cojJW>Q!47}B~ z;5qNE<;FvYik(ZhCa#RKNYcqN#_bu_IH5`Pm+IzQz-ge@fSIG0Xz?@VtiYwKsrHe| z@;bD#{+wEZ-wp4}$Z!W=&E+A);^u-F6FYROSJ?`krg9v5UwGUj>5WhC9s-ZKEB9Tj zJUIFjmM>pR`KvN)3tz>;H;C&nF8fFF_AkeP0|k!lKHA7u#I=Vxe5T5CdRj+SutI|@ zd*X@_%rc{IapH751{pkkbh~zr1-e;eSZ-O`jEWw0M-LaSKvb~-mzT(J1ks}$wOb_& zjJMqbTh#i*wa=zO&+0{QA2H+M%olex0X@T(Q@8Fl0@zgXSq#V}1Lhnt{iA>tr^d(c zd$9ii+~2toXI)OQ6pRU29}(^ulR`d~EI0+-sZx8>SMDp)nX(euF=JueV~tD-8RT-K zlu-==qWJI)>dlH4S0NiMr>Ohko(lV)WJg9SH>`xi`@6NbQe`sEBMUb90-_z7fLrrQ&CmFF2GL}0$=z_{F)i)jBi!GT1VJk&C5|+Z zhGgmhx@{wy@C5fiZ+8xVCaGzSToOumkVjhOfIU(yWcX+{$Gm`%jmOV`^9G%#Y*_8g zYl$F>N$ef6O$!%wuHZ`YMoA)H6pcY6fLFf<_CIyI{{TS$0Lts6oqn#nI$JmCyHCx( zO*jU#WAc$-$t02vpGjq>A|2r-ERhu5=ACVlgYehSUI44s-u5{&6j4@7DxylS;qIdJ zv=9FP#nGex05Lv#a1z#_X!=>&JM2)fpidbes+~WN{wyaz!^~*kOL73KLv}2MoUSSl zdrI;$WN3|4G;*DFk4=9t+`4*{^3#A|rxB9571*zIa#5&_`kNz_faFrdGL?xIPoyL%1S}<$ zt=L9L+DU&is=G)6@<2W$a2?`nLyy2EM+CiEz)ad`diGssBbS&Fl|P37B`IaUjK(6c z+3#{23Gpm86xZ)yC} zlGUA~y83!$tbtMG=jO{KPJhbYdhi+d1DXr__}w%3oK0$s>Tjr{kJt28hyfb`=7 zQ>TXkMfWS-*Z%+`Cs(J}_M2eq`|US-e!ovnuSeJXz5f80U3dhz++TC{zi;P;SP!?u z`c!9T2dvK9$4DMzZ`$KuJ;Tp{XP1gRE_A~>kG1Cl$+7;3?7D(uVmt(^%U>s5cmO&T zF}b!|R$40eUNoLSp^{-HrWu)iJ7z)%-o7L-Bh+{W^>goz&azO1MvmlfAhmWZcC=Hj zn~*aN4x`}Q15DO7D@bxsVqw2U&e`FembI$W4owS5>xuOIr_xB^5Y(PrZJ{ndwq%N3 zN*Nx+Ky&^e2_LYI13$Iovbjia=ha0z(t%SANbfQ`wxT`2x~EaTw|6W@0Bm`P?`5Z> zS%lEmX0dw8@>#A~nPSmD@Z(o1pC29piqL|dHy11ozaK!zY|KubYgQPEosZ{=kgo{XKHr-dE`je(%Ob* z=`018VUzb(SqdvR$#vi<@SV5qDR(p5K~5@mOd@BQ6(O0UQ=^WeYP+0ir;h-ZDjmY| zM3nPbs}smHjUgntI(TS|$AAL#cM;`_HIRA2w@Sq-2rDBW9kbb#CohN_j{)sl7wp$c zxCr2m+BSuDyx=g5FOxCeKw#@L#*tgYU?rVSU{KuP9?vY59>V;Ukn ztn58p`FuDAIr(IjW3N{qTQKQnXHs+QdOi7nV|t+(m8eOJ9-(AX{hC@{u~DR9^SE5 zMfaE*`314-uYRP0zfv>ww@y%eymq-92G!dwQU-?)+g$-Jo6V~+bcxf&kxYAs$()af z;5Wu$jVZ2Wdxr6oD{{QOTTu=1Q>@F=mR*GB{y58!eQPSE#Yg{{Ul;jGxRRU9(I36l=f{R^Dz`ORCEjD!)kkeVbZ! zPD-&?=CMY8l`Ww^GI$2&Wf|(|ecD{bLj7?WBOM*3N0r)5y)|Yo`golVgMh`X+c{`j zo<6LIsam7g<)yBlLQ)&dTp-FN}hUf46Rbh-mzvoDK*Sh%Br&1)NO)V zn#6rfLW80PA3Z#{4YO<8a#V(EmSy{OnBlFDmC=|_?bP)w$f|mZOs%Hjugy-p2b87A zrZ~~1EK(AyYK8KPVhI)#(V1k`M4D|Y%qSp^0NCFr4l>3{>ei0av`|{EuF}=FQO?5M zDF~5eh_<@!@bKUzeV#byB&i?WD+mid-mHkSDjhV9h>-fvCHU|S^BFj%-;A@9j;-k2 zz$(KrkiZydVT|o!WIs#4sgHo*4X@hR+!-nt=z0pmS^dpA{3TGwC-kZNUFTG z*IofI!*_f+AAM@wI67tFf}P6|DE916>2wsGs8`EDz%sMipKz|NEo297k*i6&X!u2C zd9wTiukGM8z+)&H)+<)7WJ+q&OKAY66>Jzh&@32H$=h~rDK z$pkDD)a-W3-V5uIwDSYRjsfNc@K^D3TKAGkP9H|t>-#95V(xSjGck@R)0^y0LzcUb zFkYE_$8}lhP_WqSBs#$q=%FQ%V;s^wNLZ0nk3UG$Qp`Z$5AMF-s-pGWmBysB?W9`O z61Pv>!5bqxDBZN}(_NlC2XW(ZGt{SMD{)AuqBgU2f=m^w0{{X9isJi*d=~Ohuc&ML}dDb(r69s?Yl4F(dW3lXzcwG7q{JW14^wa8AaD#(nCBa}9(r|{qt zcC^x|YqZ|ro~tkwZ`hJJ5TbP+SyxS2B3@(`(_IGubj?@1uR%m*joBt5S>s7`X_-gY zD=crd5OP%kRev4>t60exUHb@I35`` z+_1icJkzkzw(0`;@Ezx^VzHgGfJ~)!%u6S@uTG#yK#n@o7`FgYMkVwd0Weg@YBti1gj0X(ezsCi9}Ntd9*qPThmL zGr1_Tm+X6ZCRY`);kK@l#&l`lLd?ZZNd^9uHa7r?i&x@ z*(lo|o5Dw7S;-j<@J5GUiV)FCx_vCF7cQk+h!<16ZWW!HS=_CB?^!%Ga|TG081>`ij!BhM4Y&TS2_}{@w!S zr)~DmJ!O_>dsEJO)7h~pVC;NYuAx5-MuULb4&?3ex~3x^CSAex#abvuU{8p7SR`Zo zPXL^?=U8U%5{>p43Z}BfAB$#4!Mc>G>JP}6jYL_R*C5<`izgL z>PI%b(U(x(16~6z<8I>1V8n(w(NvauPfitpm^y&R6l*De)?j~xdGG*tgt?BbS*Ywsv+Fl+&eE)P!Q1*v zBW`w;y|vv-Vg@+iE?p6txrB#f>wN*|rn>3CSa!TNs^i{BJ9t^83#<`AN?`7tJtuY% zO|jc^$O-0r2g86*Z~KRblf3dUWvI-UY^`YNU#np@NRJsIC1od3w|9>KE_eH5-IyD{ zaO~+M$YZRi2xDYt+TZQX8T3lOJvawlr-RH|uQK;G5i!+>BUmP$85xf+Lx)$*m^V7pa+%;sACbgo9DYQieYl&7k*;tn6z*NbN?5s5ek8DuGTmW9vi8il@ z07_YZz;FS!UmumLBv}66moHIAIc%gAs~?WWl|eu0UI8sES8c~{eauASeM8oQ3%>rm zZU*2@aKZFnlAptX4-ap<>s`B$%Si*W25eQ-(5$T5mV=g?tEvKI56(S4JObkmN?z^6 zTy`mj$3~ectjWkLGdEqN(_PZZI+Rd6d1=5u#dl2bT&;+mW%sopJzDh2q_G(e?Xy_` zzWF4RK^#PAPpI%7P@g#mar6pB6>v|u-pxI`Q~qZ3v&$SxNE)3E#rU2ByE9&b{kr*B zYPLU9_VF~0C7Gsg!;Q(_7@UPz@^e<2X%Xj1Ar9x9jvg2A zAv7AN(f}N|3rucyTuvrCc@EvPIh8%fyrj|C086BwNZRS?+CHBEI0+8i$@b56W9)Xe zSzf%0Jk~IlwHx9RxpNmkn|&w5ejEbd{*`zC0J{4pSpA!;)b|~4`)xcroh{nyrUK24+yGiT($G^C_Ng-)Fgq?R)s~FDrK?o<`h&@>X>+ zk00JTe7FWwO=*RB;-o0rwI2I*_CU7O09qZ57>QcA3!& z7V&+LPO`fCZQK4{pTH(DFZggAV{iA3S@wOB7AN!L=Stt=BX@-V0I4_!QFcX4pnG{N z9CfE2qrO;`*!<0TqC@`xAm9V8(zT$I&}!82$m>#RCsttScOoK2(le{D+p9ZiuAq%L z1^9fNn9ODR_^G6`Y=P9O`nKU{w+| z-78Nd1O3<0imL&!erJ~evX)+ZRHU_PL5=G~CW;hLObXhqca~XMH#UIDtGABLqd}(u z)&mZZS;k|rVXr}uGGt|Wr&A>2s*aNCRTFBn?*m?EfLED|xG>foGjzquQZqb^k%XQ! zB>hp5vPB;rWB7*v)_bsI@k((QJ%z-XY~t>ujT~!Wpo&WJF*?Q8MN*Hc8y}@p48BE2mvOu~?b5RIlIqIaZFb9tSo4C8@w5PhznpU$>#N}h2#kL6A z6Q;#g*MMnJ@%b9*?mHVL97Jlb4Y^fF9vr1;_za)8u4692f~nf~X=80LSg1)R<0})X zV6!C9pN~KB;10{;YTv}&##FNoKAV*l>_&=_s}~MUnBzW#nnh5vAli0#0C*4G*_o3C zg{LA^uak|ey%nCwW_OO15yQDAQXO@X9P6(ECl`LzvuY)qw&1$j=^RfrnWWr&(|bSs z2LR%B?slq1KeO?;xTPTLY(&zxKZTc5{{RjHdKP=S#D2CTm`$I)T0{VNST zK!2BS0LE^{#@DAFVjLWC*@W*{VxMHYm*BqZr?27u8~~SA)<+k9T$NX+Zu_KKEXyR1 z6A(;~vutQp&?^8vLAmNc;4-I|oukJk2NrPBb$8DwN&s7X(=9jvP+#mr*>jvN%HRD<4r+^3zTN zJMLGpH)BlwNVE)6JBX*EPJ}YB06a~h{Gbu$hk!a;UBML9^8K+qpK+-IL28bn#k#Qa ziey3Pn`(L_3+ftcz+rMMFMlDqj7af)-45e6JLrzi&l4FsdjA09@%ZoydbxjN_V2l6 zzTu|Nv*{+gyfps+FV9{AqbfU^zi&qeZ^I=?<(Z~zdXm_q_rBrC*eO!GNKGi%DRyb48g+_+xq^~DCxEP)Y831m*<18-Iat6G(vGdn zgGZ-5qBz-Nk57O>z#+?bb_$iam)hQ?Y0kzJXnPhQ^3;i*POryq&)PTvvbb7rn#b6) zB=XA|iEGf0ay5o;TCv=B*LEXWdYt)sNgM-MF}ERGQ*|PUjvqniL#^ zY0uAqUkIZO@mIEcUN~~;p`LpZC6um6@m)(I>*cRMmjGC!c6&vy<*AE^H&~F5cPbAK zZzvg`sSxr}~3AE5}`y8i$Yjsq_7?Tk({9+xPzRc&?R zL|XDlSwpY{uw&(~n(!NE@GAN0&lPC$FvHLi-;zTMrj4m708^=75PbL!Y{hKjX9 z6Xn2h-1sVaIpUIGG+3yerJYfMv0}`>ryO9nr+&x_J042Evw+^!T-}QJ$Hu*Ub(~or zZ)p0GGN#a_BzDj^U^)7D2bH^@xU4jEbM^7I2-L>=<$#0x$s&n5XYmWbOlLc0ycXo1 zfqEGi8oW@nQ==*8>WVY#L-7c|gX5A;g0>PhLa*I2by9|OyPH@)k3)?CAju0$B4631H3gz4vU6VtOK`Aa+DkjtY*Qa1FtcV9&Q8)6H~CLVw#gWSEXhrcefREmG!6@wkX^rD#Uo{rvU2*9uj~F z)@kFOY2>Q%Mq!?5WmzYerlgjR6houA(VM_&uK<>|0Dn^qrTEQ>;B-tqEqZYzRgXy~ znSdlCIvt3kR_1&-29}`jDw*kXIIA^l*s`jZAll{$On*tyix9)ZUI3}`Q+EVX!I`5% zdpc}$1g#9GPJ48bWQtMzJM|t~a1hgCO&R5U9k0-h_sLd6)qz+a5hP6^g@?y>qxZNB z?cAr9bb~t!)60ETaw)V-e|45s(Je3ew10yW%YZ-bpWN?b_TRWe>@?Z;&ZK+#Ur$ed zoqcuuyLb6;4kwVc>8?#~4{sW>yjv@)MLPO-B&q35+UUyXP-}) zlvY~wX6~j$h0wt$P>jInr+3yqo8l=l$dfbvXMKSZ$SOciw3W5w;M>ckiqa{n~L70CfrctO2KiHee<2;Xw^57KD zkIlbo<7;E36=29Ix0%U1^woNvtr@k{>#uca2-bC_MMSg)l(b%dWPMbD?h-Ev0S6?0hY?9c>LzSVuoKKL))kGw* z(VR4d51xdc0<$-2m0Ilbex+(Cqo$nNOB0onRbS%uM<4i(0Sb2>d)-e)#R%xzfC-so zCG?1ZK-#)$+8%uP1@PCxX6JiLX`#vJT*+QXNpu5J!a21<0P+$q0a=ahxpUY(uv3>a z3`7LIV8K}LBT=M#)+NM$I(T`iLXcG$W7~EgOGtv9}~r)sw9|bz_Dr z1{E8Mw#JQQD842m>RTQ^=z1(JU=1?;^bNDw76tV>mtQX(4*`yM0g}k(p`kwLJ9?(bX;OrR zmfVWG);PiQJhvW7Iq(=+f4yYex9ChOVdy9stFRCi_G%WiEO~U4jjQCuG>yP*gUaI} zce5RIr`r@uYzm;g$y4(Z{t>5}w?8l8;2Oo;Fyq+wW?XwFxgWK}V}wRoW3K$!*GV7& zpXy`eG#mhUMeQn;n=y!q5|wfdlE*|W zbutk%s3}*+bUU}dEAqh0gBmhPVK%dWh*4pLktuW@Q~RGhSnQ&sm59N$*JP-qm5tbvKwfa2w-7p`%2 zTEo*nZkc2Y6Gs{-R&zN!%6crZS9v;8}}7T5w!|x<}{_%af+pQ{oSY0YQR`vU1qguiIe2&?7aB zY|31K<44vvCwy{#U=Et|8a9W3mZ#fU96nVt9l0j7<(EqsmXmaIpgKtuQa7S)2D(Qk z*$2abaoiMJ2}>s~8ijVq(Ue`P(?VonMsiN*<8My*B-MO50l-e;V7G+E-|l?KX>%6f zX@W|1kzq%qST0Fs0!1QDvnl{r-JiL6k2i>Wi zhzx>O#t*yKt1NdbfHyU$G}CDs>U??l>A)5#Nq-sp?*xzMH@!X+_ z(EjfLXMSTnre>#b#6;M;^8|NOsZ%UMJv1LuzQtfi0U6u4iZA^!kooCnjpcPU%AAgfGO*0dO@Dd(aCK)@gs(HH7>SrEE1_ygn5fCIBJUBw?} z<}3HoOH&I132{^0ZMJL5y6GfDo$2MLJ^^)n^?KOaxm={Rp~%{U($^wnuJ4oa-Z5RL^ zt7>7H2QAOYuP5c90X^Ftm6d|Uj0KBrkicDm)gqBVo{Y}BqM4v_cBwqNkrq?&;4|)8 zoxxIuIzHQ@94(R!Lm<_nKJhLlsWb*cSfam((@jU80KYYhJ->vl+O(cIZ{;Ty?AeU# zx?{C$Z6n1a+#w(9`0x&UYq#+gRSyNU#z}(L597jE+HdGi|Q|AAw(A zk3L)gSokg3?OPqmSZ-*YA1y!)5@^*_G^y~AY0vkE;lMtZxN$%IK3J$zXz}ykfoHI( zr$VEZX57QTeM|7>cnA1fl>X)kUwsvfD6XfjA3&C5P`Vh>M%3tZ=g)xGDOVv=v@tgGu50&%Ql)zB z8;@~35=o(kUAl+S4&$z%5%}-|^e{g2?SAhc?zif;e>+GSZ}fu!E0$+DxSx-mW{fM<`#cOAS;)N+C5wl5c! zAVV#Rbz&3lEICMbGHh=WIURX$3MS80Ik5B@vH3dWHCfmyhvmqr`bc5RYjR=B$3g+; zytSI@UBs+aJD9W3@wFGb!P2QMH4a~fjgG#xXBgo>kAw<#75&{|D zML`=Ut9O?H8+SU=+{pJ;wT&j2bTP2PSjI}G!0Wq0bRU~f4g*i^9%jZG>)(a}VrgBg z)QFuo%+R^!e3ed&=g4plv3=nWZ_Q5JD;>c#=bG+K2?eB+Q6iPo=`FoSKMgnnPI9%I zd24M&s%7GoNn)iJ^h&G-$Qn_#zCS(!qSZQ-t5D4bcgWvgYe87+98ejWR+*6fWTP(CJh|`+Wwm29 z0$ip&v~bxeepzH1wQA+YvN_NVd3q29^3#Af8;rdjT!i?0ZysAD4AfDQTFtvy*rY8e zRFRkh03JL8Y@KU{DjAFLNhCEWLmaRog;;J}UaN(S{Q-iY)4^EiG#&uAw)?I+R%E+@ z3!|xAhAP1H$q?j2px0eIokpwRL0L0U<)gKp(xjuHC zVN#4%VR)gfuBE1x+-=uZEX}DW%Yai>^3?8r-R-6ZwGmcm*~k00tt61Vt^Qd-UI51a z;Z(z5s^U@wIoxy}+SC&IQYj%FF{YZdg~-)aKWQ8X&vNz#KL#i{{{Yl746|JxI}kBt zLGT)%566J1?W~A{v2Nm~e{CI@Vv_y0AIYlj;OXbST>w$=)bIskJHBcc?Bb~7;Bxd< zI4a0Vg1}96R?|&2^(g#!41V$3(RTfNFu`fDlZ`B@GS0BLZb)Kt8^p-mwMQKEI&&Nb zwj#Mk-ZQx?hwaZdqFs$N*_pVM*A7r!yYX$L4qf-VALr=6Z8uuUG~u*=H$j3$XO4or~yC z!L-+a`Cr<*lkZ(!vwPohx8CU5b#>Q%{{RmTd<7+5;=Mim?i|xv6=_tHrA8vo5$f4V zq<3cK?`)Av_^D;1ZQCxD*KVsX!Iov0xSPe!E1Sc|-Rde$j4@E=Dr;ouXtt0sCI6z|3D zJDQS~u^1esP&YKu1>|{pq($-i)68%H;BxcVx-q#W4Js8_n6};OK7{HHVEM%$=BMSr zeFj?5N0h{O3%EfHo;@_mFZippB3)Rvh__%Q+jrm+~&;s?20|=9W^_(@EQ}q3*3_TI$7M6qc&`4 z)-22vk_XWoN`Fj3pO;}j9e4#4J6}JYysJAki8ati5mH9JTfH$xK4kD8M8Dg3{@cP; zSJ>GL7OU4lgp`RL{{T`r_2$KwQt#*Za0v08qwKqW@X4N~80Kk201$dAbSA(RtPHV<0kXMq`9ELt= zCCG1=s0?wI21P=#Dv(!ptKxLvJ)1e)$1N-{BlUkFf;To!|g)D!~%Yd$} zHJTXKzi!%!>U5q?uwfZ)U#g27!ad#|q6g1_Po1AX(TgF2Xsyd8qu8@YGESZ*N^_(2 zNnZ&f5*A)WaykG5p^5udn~_nPXx^d7RK!bSWQk;j_Fb&$uBWE{un&kl0(@R>-ftON z_0z17WG5088b*;cNjO#bDkKav;1^)zRl-3egoyN((;*s%mP-aGxq0pNAIE^Co4oR| z<8u>SkYsCPteS9EoM@uBXj4Qhp;jI$-XQP|vvxaz#v7@Pk*!!uhReZV2KTVFNY|js zyq(cJSM&I%drc#VQz1=D7i`C=2Kw))|}9wh)~srv4H{;g5$k z^B!CQAKZ#rOs{Uw_8T)nZXyKr0SG3GO{}}lnjb$N0$P$~V5dgVH7w=POhWRqmySXL zv8lYMu`!H#_5uS9MyyC7DVROTww@|=;-y^qbgQ*lF0YHf?nhj!iJf3O9>9L%7d8z^6I0bgG zuy);ieca4`?rO=kO6tD94VwP|6nwS$a1^-wi$#U0K48U(7TyC=y*MKhOlAjUmMjo{ zwFOwH9Qp7ZNsyiF+n?KeF^RRM8%;dR6pbZmOic1f`Um<6+oqc7zy*xY_f?AmJcdd+ z41-Xx^<)}(yUQc0BKd32fO&57)hi8)u&P*J&@x#jDM<0zF<948@DlR)a0qf|CsNFd zaF(#I z?Vm0KrTZ68ANRhm^$yhgH{17h_iOod^z7>E)7{JJ)6=H`JKw)(>&emE?ln%IOHI4< z{e7B$wZG{3>!+uHuI%sY59sUN9+sP;-S0Mgex~o$>verQdRlMOp6xvMa18OkWA}_t?WI)+xFePA1(Xz{XO50tAJ2`@%=j= z*fxEeb8P8#y|4QA`uF^L+`b$Fs=s{PpK$wEwcNV(I(zi~4wtWhqsRXMM}5W(I==q^ zarWJAzfZ%TORLNLI0~Ac>)SWH_TO*Szv^!3Yx%sj(}0rgZl0MRW&Z%|{WbTy{{WTl zHx7qO{{Rzb^EBnRUIVVp_WuCTIepu{-PVu8UH;GA`t{SE-J7?3xD4ojQ1tR%+g`6l z{?E|cr(2`>c7M6Ee&3&m0Y%#%)n96l`ltT@+1+JYJv8U1 z0WsMA&s?6He#P$(viCae{#3g7bJuTA>F2KBJ_4&d_uslT9OF0yg%()AfC~vD)8h`+lC&rL_C4e>YpFuDic4ho1pAQ=|4gcHMS# zt8ehv`K|u|`8RMBJ+b{Q_Pp2i2G3{j?t7j3?cdgqr?+pb>C;c20hWL6-_`WK*RQbF zPYv68JyE9ZIqvE7wrT3uO*!xmXn#um>c`jjZIAs+?e+G3Ek{?Y`Ffl5+tcUO`gjN& z=FjQ~{@MQknbiA@bkki=*Qcj3JyR_%C-1>C*Yrs$Uzw{UNbbkK;t?xQZ(f2$4 z-Mdk<=>1Kbf9d))@$=vU?;q;!w0m}YeS@Ly_37=?)6xF`^tyaD^Z4)!u$^9^`{%IP zx1U3Ix$yG#{{TJ#?l<~-eZRDS`-aih_g!A5zms04uV(;fa&`Xzr|f;-qo%31>f6-Z zH2VJl_S1kxmj3|$dVR+K0Jm;$u=O?T^mSc4ek#uhY|Sr>DPuzFr&wS#GEFwZFdf zz1Oz?0M$A>Hv9gd_L^<?4qWGe8W0fWcsJ7y=GQa3R=l zG!lV8qA@5G8im5}V*dBw#qb>BJ;Z|%5Wr#u1jNO}#KaH(-vQy|0gZ-TU&tU&D4jA(PbC7)w!U5w2 zpb!oS9FBxSAuuSE0|J5a0sI_N8YE9?fit1BbeV4@4KLp=Xu`g08DX{UyuxJZ84rvb zyU%{)V_)$9y~F?cgpmGC0~ihn`&l^nfRn%h<`IEx{k!~SNlMg8Kz{YCPh0X`{n)q< z@P{*QJIIU=oE}T}T&aT1v(`YXK^oN?RlX#1wyvI_aqcK@nMPP#A6g+b3uEy}k2}t} zkHfF%9*el5f}s^9UO$77-JIy4SEz?QGyju$S)cx>3~?$mSeHY)q5pt18mbMvJ!BP2 zEUxl>+gY(p%owiuY|14W5B*5dE)XoTT!7c~K5DWVp+Ls&lHG@&7n;(;@1b^$`68xb z8@r`${sRoSl-BIMDA&BR(wj}eK#(^hMjG2KT*#ce`Vy=Q9k#FI?H-eMzMA4a$WZk5 zAHdw3q*_I#G; z&!zK8QfC2@lER(mjEBlqPx3nRa9d%^U28O=&JQPN?gJkd)tffP@^#I12^A@+3)427 z+ks&03olJ}SBhwK*D$8Eg)HYHA0?}2shgh=qr{(#&)4e@2(5u4{tzk^v*kYzq|d5S z;jv>xh3EAC;F5E3Lsy%mHrB;{Q~1V@3%|C2W-)rD`?mwOvxgl6A zT3rr{k;`&2t>`}1N`^EVWpdxS*L$XNeP*g|1sI{Wsab>}5pz+$T3KhG`-X{r9=4eN zR)74)4;Jx8E?o3hm$$x5?#000Ulr{QitkNZ6j#Y?O}Gz$s2W}>d**gq?V@G=0sG+F zL9|Txsd4YSuM)uFRA8lcgtA<}`JG0J?+@bvRSVPjYIz?fng3)dY?O&O7lI);jgaRflFCN|!9Sru0kp?-EZfXf! z=D=bX>b`t_9i%tOeKpz|RvBF48g^y&@*oz%H}jN*vf@iY4HlQiE4W4LvCNRwDh?|4 z?@QOdjnkx{X{d1PrnG$gUeG=(Am&Q8t5kvr{GCbUA8sIYw%VyY@%m{egUu=OS+jt= zBj<8vy&|J-R#TnBTxl-a1!?BAr7bW`L@rd?x81zID?PaLvo*ZYEjea+ha`}f;oZ3p zW+a~0bLi%3l`1H(eoKsxRY|N79<`2Od?4^&Tl)U^e4b03*XdRicj&oxzAzuz*~|z2 ziyK%R5R9x`8xoPUs`>|Pf#wj4N0nWwor>}|pHdJ$0hYXc=Jl6kH}dbMAmkF~(@5z4 zn6Fofi5R55L9WtgSxE9ShaY2|^k9M(aM3F`LH(G`BnY@zl<=q~=gSi(T7QC`$a=wl zfb)`ql!80QofPOpspVKSa9}zLv-!IMvAi_k?L*hxD$)V53Mb7;J$*egd973S2bYc=271amSV(Z&P`xiO)M+uunoL5@PjZ0W=xB=l zu53Zv^OH&#VNs40l(_$ERPcj}JdBPF%ZH=_~7;n?Ael|R=#95rm_jzhpf^IIUW zL#x!w}^GBW>s>I3bm zT@Z2(P{(zh9W~evSRj_P8O1}myrp?MTUb2ZGh@7kP4U_7cLUcz&|-S?iYjx~8Cucv zg%m?Y4{1r!WJm^4WIyhRpGkYDtgas}F!!5`uAXd4mfn`a&(%V2 z%cO^s9nTusGHLIO8&tRg$d^v%H1qd9Rx?#wx@M7%uKPo0l#-N(&nFgF#qWIsvr)`m zxW|)yER!y1a@w!P+GU!lWNdD{Fh?Mwpaf3y6anK{aB z8GJo}iSGH6;z{Z0Xx(e)hd>s~MnhJ~Eg3q|-s*Og`xaKzxb%^@Q?_SX_Gc_Q8~Ozv z>e^D)Z9aQ32+@#FRdf7kl_4eb+vY8a*r`PQHdry9W*j1R3(G&;&T+|(rS_^s_4__q z#o>Hoor#yDL0>* zZ(1M`n=FKsx@_0~=_Q*l64QKqHT#_of<*maT`U6l==9z;-z9!2t4;8UYqiC|ijZUtT}RZv z3>F)v?Tyq+8U@uSaq|yO-$8-8>UqbZ-rW*DQo~^`kFj2PJY>89{uB6 zpTpHk;?!Z~G53G_MUfp|ZQ~m+a3Gssf*CC{H`J8}F}xit09q+=?vw&Ay8iVx>6zV9 zqtfFwqbZa%0%PhGTDkiEdK{APgg6cOIqkerbc?Q zbIxn4*a*>$c@l}l952D4xx#c5sGyAaku$^|)lt5>k%s3CK|6+>TrYKp3x+rmK zr@J^4u;Tfyu|)i2{mcRLL6O;I8~XkhmP2?I4gT#4KG&2L8Ep;ZO&wydAK-X#hl$FuQ?5PB>JK21mi3oGg{2hSI_)@0@hHUO0Ghn=CgPg&&o2Kj|5 zvL444$Uk>IAOyXVsnr?*=S%ImxZ`@nTg&hs*%#NHM8%=CDH8&ucq8CXl11!Jm#9Se z=P4sMl<>v^f17L9 zYu{^Q4K9kNSFD;hQ(vYQ(HUaUs$qN8=V|=5DG22eeKLmiO!mCMdPaFF5Qu=fKXxNJ6;VL)n1!| zN^M1ezrVx@>a;Baii~A^GPQB)axrEy+z`7i@67^_N}k8!#JI?pBhMN>pze&@nHvX9 zF)kgqhVp0ziYJ!7c1g|`JspJL4qN@JJgD~j$s|Px(C|CoZ`TO zB|`*B(;EX-MZ#`7BB2C0Z$@eDRDwo@-vQj{uYt4_Wk8;t0NJz)?b(4UFn)8e^YmwX zMp;|J%=$c0%z@@%W7ms`qR3t)TlBj)BsD3vHT;fPB$;rBK2rb8S&g}e%H^Rtn-w5R z+vW`duqGBDni$Ctt(hPPP-^CA=Hk!i#sF74yYG~nSA=CKQ^zQZ#AcQ7Y*Onz z%hmEMggP`ey_q_ZBPtQW;lq-DT>!V!Fq%ur%_|0$H^A;lbwjaXZ-e`nQLsfr9ew@r z(NUB(M`RpDc5z6~vSIM0RF@m4D5}%&<(WSYSEBQP<(^d%@JY$Qr%t_mt1F;xp$tC6 zCuPP|X*c74fA|tN9;Tuorgc7^+qB>Z>*A`*A@;tEgbKT3MXo1W%&q1~)^%ym3w#G} z8oh+H5>&64Kn=&lzu$S%;qxGN*9sYQ!>~Kn;l~kz-ZzWE^kLh;LwR7|ZGnuf+@t13 z2@(Zwx*0m#kw#xMY;FEagKf@y2m74A%C=l{3hkVEPP2K?fLnYN%5&=hco1++nX%%sZ>`jrVh{bpV z>VsX{$cL+BC6{e-5BKlMVMKaQ5TBfIesx-Ak)+-$5Wf{GVMP4A!Oq7z9UTanEb%8utrf-QxjUfP01gp*M=lc(RAhwn8lY%7xdbf63MsKFqcL z#7@lYuGi-)9DlNpqD$*YGO3V_Wa;-tVH!@I?sEkBx1;@`pcSt{A_?|=j&x~e{r*Jf zsTQkmup5=o142K%{<=@fjbs*gG+eERpJ1qqkT+~&1=7H#Hhrm}?sCYcsBJbP^CnYF z^+4*~ahWBO8N4YKZ5#oS&0e2y=4vpRKKmf3Q@&zoA9RtFmMT<3r_{;v-#T#sok?sl zg48E_MyS|?7a0OYApxo+MsCdsHoxlr}rH;p;1qa?Bp*@|?Y zd7B<-edo<4QCzRP@@+_*dIWrDp@n|^>NOj3+sN}`bt}m~SrRzoI3EtRoCm|#f_{*% zh__$Eo$zx01nZ6mL67tC?@z$#`o2$|_@VcVFwF#|He<1{Okw|p z?_h3yY+$V~xbr;)9nekCu8H%LAO*EuE7xP}fQO9!`tf4EFd-UMiD&|kcKa*SL$>lw zb1k%J?+J)IOM@rq>OHOq3F7OMd%;Uiy1l^yL~j!n7u>l&blfM?X+7=}_R54M#n`l@ z)Ak~Awn&307NuJj1A4Z(<(sEPbDeaC0UBVWLl0uY%X;?eJ_|9)sVx2EVQGEDMAH|d zdMiFsd0YkRC7_TnxKf$*JHUzyB zblF3T^vTkC_pXtzw4t-bwFGyOTEU$yG&0^ZqjKT9hD)Om-uBgdrNmY~h!ZWr(v)~h zV;9Vktfw}yJ+OPG$9jM0uz6mWL|5TCpfSsmG)MaSMA z-IR1@1(&;YSlQao_yy@-99keb>hyBFxzXYcBZ|F9gq)uRV&Wim{lw1`A>tImCuKFX zbZuEfzyHBC7Us?E^Dp?B0yolUcC`n@k+b#54gu!XzBexIRxZw4y2|O=V4XOZl*5FJkOgo5akA z%HKpFpc6dhUl4d+j@9Sf2s;xWbbAG#e{;y3HiQ6O6e0G@ATm;4RV3nK9g zZKnt6p%HjBbJrEj7v0r`&OwIGdh-1qep-0F+?`v^NQ_uD35f&ZbVex?^V&dw>Qz5e z$7DY>j!=aN4mna=VQiLh4N!iyk3%Evk%qoGU)Hir{LCU&v?raesMNjMs0gri4WwC+ zMh@}OBizwT;q#;mX)7<0C`Ll!>X%)x&qn9z0MjWwfq3HBt#J5SiKTGBxS;mZ1iOB< za?TvBfNdwq=MVr4mtt0lGoR|NC|lM znZXO;_Vj^G#hWk|fNLykhA91qe*e=78@Fg}1G4;%O4;O+?(|3GVHDu)=T%bZBO5o+ z-aLQOf*a8VQ4;j1r$u(gHH$gsIw+?ENoeuEoo{+gFDuou&OK~NJRP-7QZs>0==;Pl z&0+bW1wkrtZx>o<&3AUdzr6*s2`PGkVBr;i+!LYVhb~nU zp;+9`lt_>aBq>RelgV&Nrd>nRoObqg@}|V38QNmDYf5pb>z08<9U)jW+Ns6TpjXkM zbzd8)m6>yB%{7>nh7Sg_J^h!N;I8{S88?bLwWh7#6<_If?t-G^0c_Sr^RBLo%s)-{9;jvk4L3vPCJ`KH-msezSM2|`m9v{jnM^C9!H9)b;!0; ztn6^m9#%~1_jOhnTtXV#^=+J>gjaAsv(kDraL!`6u z1Xef)E-T-#C<_vhCjQ|4*>_Ik3XKfy2(FL{y_T0Sv+v-`sj#ntFFYDxF7;$HPk4h` z+096q)DD(b45wbqN1@q4{nB`YHSi)YQ;m4iaS=NA4?sckoGX;7lg#=!@>ZwAvDnv_ zWmGUvpUH~d5!ojPjQ>Gio>Z|(8j{$qg(A~5dVHD-YaBg(Q}AIWIGG37h(8ytW4S0y1%E5%7#*?iE+e6)jZ-&6^& zrF!(|e*Xrd5&XgSfJ=H>OC$Oahl0Q8hmgYB;Y1b6w-rfLIlFy*yz=mu<{gJ0obr zgnm7?xS-8%?(y1LBPqyy<^#|3aG|}t96(?t;OA-=%gn*o;m`mE5yJd(yk_%mZ^VoK6Gc0dc4xXvxm^8MY*@W4to0Fz29}1 z5`7;wxt&6wJ}Ggcszo(l&r2R)dNqf1O6-aEhuju#0-ADjr|fE_XRioHagQP8B5b_; z){asL`fA1}{{d`UeZtS^v~)yMkcO)^_} zikbxpr2cm`c#H+pDk=yJM!o##q>)VQwGD3A1R)_@Z|lyMCXLzr$t2ywWjU(BO#Q`Q zK$b{x#o4`A1jZ?Od+S*K`W02LwzpPoo~l)A_mzNWy`M4?p#_kHgMF497#E3fV&Z$O zPe^LxcoT6N{pW3B;>C}WFA62WnheVdn_sm?K&jT5mmcwl^%oUyDnY;W^O;(DS~cL^ zTKz^_7#v}Uw8UydO%mrF0a9dKzgzBaDsFT1>6+vLm;0#CX}((VG{h8f(eFIE~&qgtwBsg4g$QP z4W~F^=p3CBoXg~Z*si}$J-8k~J>}bpY@-ppaGb0dyh+?BP8CAybz8Q+Q|Xi3`sl2@pH=0w2jz6`Rgh zvdiuBsGvU~5bxmmT8`_>W3mgKX|Vj!rgb7O@obu#UsW`01znWD-=c*af4Lx1RTt z{qLaiw4rD~?O{b(FW1j&WT%UVD1X11_^=(G%kLS8VI)~*FTv}zaL%!dYz2mto>h2C z(CDB8B7cLRu2*ZQ`4G}8T3TE$5kJCw^QD%TqaaC*T3KU`_82{(WW%4vOU!oa_&rA5@>rFvd8aC{KER^D) zf<&peP(EnA@DT4fKv{-6rHcJvksVhoUXFwm(yrd{P63K66Bk26FmC4~S7*vNbpn0N z0%qgd&DD##$VynLCaJ-+)=#h;$!LO*-eA6my6~t<{&9s(lG5aqgUh$i%V`loHwZ$V z=cJjmOAJ)cOf1}NWg7OS^PqGZc8hqkQjVzQxl)gD_Y;lrsJbN_qd`1$=fN=0{mao+e5wx+VSOpt*ICZT-41=P zTw1N?hu`JM2-=t-R=Sv3(K6suR(TsB((&C^Rb;!*z-Z?e(i`4rtX~+2K>DFqpA*h` zVR>DC0Ycu~97DFTh-W>>FGEouw9o8rf!ReCS3da$KXkQz3L~4T};rlP4TYl%7>!x8Qf@k&A__utcP47D+ zU+_Ad^HS#@_shxA=w|zqpBk%|PziyHGb#$#Smf{wO(^kI4iUFsD{c7K9$UhI#^_S~ z`)YXBU!WjCC?lQ+T`LGJ&KnZ8-Ly6n=wVpGkZfa0N8~k@@gW=Z`8ade34WJ2nIQefSCT>6VKJ*UE6GHX)rxurGnA40)h#Iv{uLOWGoEq2g- z1YP=HB`Y>;{N9~!qz}NLCV|O7|A`gEQk%$b@ZT!+qrqUTA8S!Y-iW&^!zgt#0@{-8 zbM84&t#{6I9YlN4MH2e17B0k(>qfF9^P3wQhyjvY904zUSnhfh)DkK#AD^RDIZxDh zRfXw~$BNtG_xP~b;Q#ui&~%L|*pF}HbQ9^gwvK`llQ6c{lib(0mF?7T7W>m0e*Q}M zOC{qBNz;zd1F{*@3}S9cDms0F?Kzo+`pb%6rMfimb18IOLODL^h&d*s(Tb#>7P(h~ zm@$4byyEEyVEKb!VE>d>_s~|h`_FgutorCP1yxbHZupeNp;*M(bgF$Pe?t2(NuW&> z)|9oPD1!uCl&?gQz>Fyp=EwO^#RN0?V-$4}tg>%dR~!n2RQTO@Mli{CT!UR#kf>uL z2;_&!m^<8Wvbta)oXaF6kCB5ps)QjClfDI(qkWQc`D5j@Gp8h)F(tl9>>CB09i(Wu zrV66-iSL^e6dHBjQ9t){!85REpDU4jZ#rn2Be%-OQxjw^-+#?;ALQ6pm#Pr|D}5~d zCkr0$X8m>OLD%R%U~wA^x`UEPYT!$&XPs_Yf#PB<6V*GkT=nlpcK#$E@4asS99>&1#{oP22+-0%(G*@(`{Wbl z>OIclz;m8CwpBx%OYBIER7Wev9vvV%StF3cqFn($@{@Z}NX0KOEU-OBRnCfF`41fzxQB%6U5svK2U z6uB>b^?pw0GPM^8Y7reU_qyfQjP-2}Vd$Ol01k11XuW<9$S+|op$zYY8B#-6MoWv4 zSk+KRG#r6a4M5^l&!pGjSt=U61=ry_+0)U|bTpihZ-=c~?x1@_C87hYbcxRbPFq_H zvmg(pl5E!+J`1h!br4{^*y3W6oUJ2C<1qz%^&qd`%oV0Oh2m9+8-#W6s*%+ZtX}@; zJu;leHLjc_IyY+9=yExnrSK2fjlMpfq>tQS1rTGOd|v)TpWn&wzKeob;h3xWB}o}C zQah-W!&V(bXK(zA|bU*1a5m1??v{3Zw?Z?~SKjSe6dIDG=JXhD5I z{-obRKx~oTn{g`Hpg8vjb)vw;8WPSJ#eY&>H4_l%CLApbP{;p$_Hn7z?q=&LM0T_I z19f)bo}HQ^ZgnT8`#w)^b&EEiBH5OcZa!3(?zcW3#j;6CbME<*ucCu%p)LJa#RD3jDnRGsnIPwd{M<=E0lNennTx!bE6}9D8+|rDmz~PoOPt$_J-Z zgG*~@3-S!k7%5a%?21pq1a)GORHzKOUil}4iBrt~7{v;^FzIsk5kx8uXUBzSGAvLb z7p#Un0db19Vei-DvG5of={G+VAtcU=5<5aQr3b-})8@wbbbnfNY74!p`Y&zTY^f+Z zmShD=5zR3V#}KF=xO)#dL+0=wDm_J-<&R+kLCZWz&@wnj*77P_OT0)3vv}YvBk|7V z%O+Sqa3 zDcl55F?0h8xMC*vlM4K~ zHvepCW%0u!pPgmg*KbtH8EJ`A%-~CnxrhaD$YRqiZ>=dp758~Zf5ygYNz`Vn4(;Nn{LL~;elKb3Jt|Cvk52wRXU--Q)t z#KPS_p5L7`2aS2R-nFYq9G5CT?GKXM0{#KIN8M6y^YugkV65sR#D%W=%xIoz%#yvh zcVUiX=}1T9I(P()5?6|od*PjP>{%>AUsE0CyIgtp4O(>r97#{$4&lYdbUMDHxh8Xk z&Gy|bky$ST&Ph8vyLRNc+)?mn97aJM%zIsz+N#u?&Av<1nIr`fif};j@(&hg5fQ^D zXsdyrd+gVYb^qr6u0zE;U9}?l8Vg~JN%;qy;Sl@)c>5cWr9&(Ij^><&avmu{sK_ol zt_TFy%jDebBuGtRK0akLPm{}Ybsay*s51*B6jm|_t+7t!hT?Qfu>g{Z#Q%6TPG911 zSJ)aA>^h|NDg_X+zYx^N2or+N^Q>@>wT>Pd^LpTXs;9>S^BUc9qP&%3EKU34tufq5 zbz!C04%hS%!%>o6)>^O10C#9>a7QmQ3rP%Zut&$e{m&74C^d_Rro%LacEOqj4AbYk zX;49f!U674V#nQ+Phe>_?RJ{eQj6a=rM=w;(a1$@Z-u&E%UD+Y`oTSj^w(DrA2%MQ z0pAQRgRy#ab=SbWbz$g(&l`5P?6IEIr`LtIyixL3{{dL&PB$atkfL5}X_^9)AQDjL z!E+U2WkFkK(oNO1_#4~v_Zyw@zkWoqj(0)gg5y>+oQi?3ku1&YCWK_iq;j9tsWOD0 zom^iVV>lI)ZpL6tLvoqWKT$}j^?1BB_K6tm;*G2hcjr`=wI)uCUN)^nX4K{$p877E1Ad6{G{RG=U! z1y)=1!p3uK&#XYT&nahkST*7dU^@DnWl?U9;&Oeky2Yz%I9diIGOx=%63q1zFxZ$X zpGJR?O7y4ljTzP7d`ggX;=~v7k1sY06)&GeafOo;_Z@edcj93)?<0Pa&+xu~$T@;? zcsS(qn}XZz1#bIUwTbeHas6VM9kV%hX5H|#FV$m>^Cl2$p;P_n;3I2g2>$e|at35c zFL;UA@h0@J5|;cJ!Ua>Wd)wu_y1V&gKZ0clpn}S|riD@68=rGgpx7U_)wO zrOrfrRZX?uMJqC9twd3u^xpR=Q{m6fdk=(zBF1G zgWwQqUhOWfZax;Fgg@}T?fxOKp5K;o_!4}|L9j^8Ciq?~;&?fOx8;FP3w&HVGb+m* zj7yIDLe6(Ml{k%HCr?dt#Egkq=#jM?-ejBp6m7QXX#uV@WNNhe(63z$IKhrABPn~2 zk8j7koMvWk?FcRxsc~?5TyGWm2lT$)6vb3WxHXYrR1v;U#3LD2JfFuI4<5YC!`1y|dXIER z{`x9E)^J(zF0SJpSI$=I0mdna!ZZr=%&aUb_o65D#Ni`?g%%Y^6&I)Jc924k&gS>A z<@5T9umbz(!6C{EMR`O+t238lSgF2!-;Lx)275shY$j!{pF8-t5z!;!@*O5a*O;>6 zoW^O(EAQe~;R|c;a=JhP4!TEy%+3}HA-kS4yASb7>_#Nn&t6_L>zPp@8Cm=f_()Tq zD$V`}cxb~oa*kDM=J)gHtqxg;OwAm=1aUJeEuHq`Lx zEp5SN7}@i-yR)Vh*TyeamAJ?%9eL3nX0e=`*Mkjxd95v52*C`l6|8WCyWR#!Pt{X3J!#zY63RhIp^geU_Uh zS(mM(Bj}3`XWx1B&OJu%v-}29O6ITz(`RwA0^cN85G+?ct+bZ5i@8rx9BIzy#=^=! zss3Eu*aCY$+DGd+xj)P~{;Xwn8%$gM2^HY-x=zhE@K?C}oN@aSBP;ppf7You>hw4I z4T^AJ5GNkxIHNJ}`Q*>91ZCr#kB`PXt-@@I>ThN7YPw)(Vfx%*1EaT_QHU>^f?548 z`FUHm`44LPT999JkNUK&K4)JxzF#BDUbjviqn)lXw+)W)*95&vw+|m{{iG0r71=sT z&Ou#qH5AMcJuJmd*E#w zw1dh-jTq{7mUl=T^9cAtgnMxJHSz;SSom3O?875u@XCLk1!`22(0BBccn6Xb>=@g( ziU5KF?TpL$D9ikEPjy*AM>?hadc|GtnrCj#knT7*ujO{6U8j_J9QxHlmZ|1)%pL4E zbmCTE-0bfW7{R%FPjY&4&=fx`dEi{EteO9i$Y%-yPAd7RkV^FV^ z%xicMyhuvS!{@I+-biEFVP4AeGlhA3olimzmikY%`V|t?tzu#vb1JLVKZU% zjs%C(KDwRpX~!zna19>e7zN&h6Wd?3MSOz>gcpy(dy&*=(}#;hL7$xH#$y#K>4OR$ z@mSoWit>T~hRqC#_Loc#0Oe#FuS?G2su6RfxSIhV_EC|EJ?fkNS?e2Up>Jm_$OJff zWeVC>N%6uF78$LFEl6{%wzUWppRknOnXDK$shgvXG#SkT^A&B?I_c9_=SVWYpimn- zW>}Jk{|u>S(2Ofm7Zt48IK6@>AV{dl3f$#w2~ETNTs4R!2bk^_LXu^Ug5wm$R6$)fY~WPCd-~%c+yU#XH`88NDP#!iD`sU{PK`kD7$L}va$OGbqpb6h zFA5dh7fJ;x0&lWeo6(BPPIF^0E1vbaED=-XLpGyBD{Z2Q@HkCC>BXuthenlQmZ*JF z<8&2gh0^J5qCnZY=MZI?;*+|50*g#f6S=S_5|iY|83e?VoV*tq>*|dd^F{4NkWs4X7sS?e%LC>lXT;hxKM@$Z)w-D$RYxU@(=i1 ztI2y=mZ%WdedDV-#$oL(G!?9evTw(|XN-byiC_IUW(6rHDjMEfP&VCKiFeuXMVq&_wCH04w_Q3dNL;Rc)*w zk8VAL?zl&|co7Fe6@~I_C)!ek6y`|^lE=tPitii@g*+>K;V0z8_oom}?uCj1+n~jD zaFET6L?%8uq0zx0Bn0}3$yHQKn@v2YDjZg4o+}&r58yt8dq+?5LRXOv`d;YG^aR0j z&!!lZA*3rxb#lP-pN~Azq&^eBo&00-2b=l5LBF$?gtOye&{?>F!(&64s&}ewKk2X; z!cTFoYPHF+E84?X@7BTrM$Ycn3&UF;Y=Miv@L;xG)uYmn}nk;8LlcwWX2^ zHS7umtAQ%)ZW?kHWWd>yKpOS!Gz#{KQaqfr@8bpGo(-|IqKCI z3lCG8?Mvd-U;xmgETWl%<1Tm8e=7QBC$JKb5Q|4f8C(N0Gjl|M$eM)6ep21Pnvlqm zTQL@LMleD+XdHaNT-_D#*08C#+fa?JJw9>`zie=%o1#VFr{?qzD#*rP2wuSmLK;10 zxdx*)r}n@>hZp=TwG0_|aRUB|Y^6_c)z3Kkt&^gt&#ED3Au(Q^=Ig4@X>lePV;?_m zlofni+Hi-Tfrmqmq*dn1I|(e2E_@lq@DNW;DUgr-9peY^b;nau?4N9EU0Zuk;pIRl zS69a~bvS!|f)4}IRfeLL5UN{RL?tLqg31J$mdTkNHd$i$^w3su0;*~MCWVmu{8y@O zo2jY}yOSghk>>RIs2erSyT=2BRqAGDO1V?;+1pb@GyaSq6$QhYqkS_J!Uc%P2f~R; zgTriBz~-E=ITK37yrh7Z#|~l&Lr%-}6tMRmz7gdN+=@4nGMYNb=>VkvCub|i5@y#D z0~gjJq2lUG+XrOC)*m^~5dXjjGHom~%f1p9!Rm{0gB-uT=);qeJUYbZ=`wl2^DR`% z&6VLHUJWw_^TZYQQnYPz!o)&dY@J8D*(&$kP5 zoN)Amg}FX=Q^tq!-vlxDAQh&wjWO?O0XApNyMnbyL+WeCeUOe~33YM-50qA7sJ-#5 zq9}6s(^=Q$02QxvndL7;qd1IxW5#R-{!p+yga0~3vvzX72Cyxjn(AoZ=Q5~(5&}u@#hy(ZZeJGk_SAOt_7W1{@6M$x>~n>ABC0@ zBjf%)SsmEs-8mN8r0eM z1>R0zjwsW?FzhKc1^AzykhGIh#O$lQgple~?hN}$n->(NAN@t;5aVV?^>!zv~TTnhKU!E z@b@Q=JakeOkK79dC+C7=qZ^YL?dHH9cNV5B##==L`80h0Dd#i|z{xpz92rU`z*-NB zV$4tvrJ3rYeNd0!V?RPbaU6G=*0ZLR>~PVwcek`flHxSE{v^0ZJ0c3+M2SLt8~Nhv zhepQw?RldU_Q{@u*Q`fIBDIcZc2gm!>~s2%Gy1a2bIoMHODRa9)QsITwBD((Ni49a z^xI+J24n@w*YAsBCTaXH$u2|5+6b-EmILm=!+AEAcS;PRXnWw9a#ZT0p)hl)V}?|) zOT$Qzk#qKz(dgxHdz>_2uU(ojqOe$dMpo*~*jsp?`{vNhbE;I(3zJy52HoUmAXxu% z*IUB!PFX08$zBOL(ims|kFYtpsGnr?xrURc^E;b)3nw1&4QWNB8w6g=Us~0|BXap)mf7;(6|WPT2EvkkBGr zZtlzIS!tTxa6k4=gsk^dTf|~*!TA1zWsI>YaecMA?R@Yiirvv9tGXIUScYhJN5{f@mvWq5BU^E89KCFD zL_}b$Fi3y@ac}SPEF0AH9CZlJ!>H~;WNEc$7L3nQ~aPo z{ymlp`VTg7sWsfKEchP!=5jcQ0+GUEmwrugq|!rajZ7n5wVy< zipjiu#`X4=;S50zABWq2dErcwr<>V6mH_J@OK1_c64FL#CC<;2pHjR|;05%P^@v_#UxFO{%2h zTZ7+~VsFTJ|B(57C{m0f=vsEF^dYq`DPG?E_bFK6=`x{g5+n`YHUjlD%jXJ-VYOtz z+EC~VQi;{fqEGkW=~MBMor)+m4GJ6Svl|V1o7Sppjqiie(!6yGO!z-BJ2nJnh)yrV zIfaf96$hQ^dDh@vn`L{r>7%Db#rB+5apX_!__Rm73N}-qg)e_fofGr}k@TEKv@Ajf zfJ+`SHvL*8<%m}0ok{30OP28uFq`^9)Kq6$WTdvCv!!_K}1Ry)E$RAFMDv6@`7rVISxbMtRt zncCBj+o_9s-P>>Co`>_URhJazz^xgSGrimtEoGIss2g=c{h}P5ehelXKC4IQKmOeB zZLMoF0CxEVn<$9I9_7~wUY;Y>Na#|B;+-XsV?Wom`OjM-j_y2;c?Gq+;YU&Tv&VeM z4jD&|-LOVTeM*k|-Qh$8xYj2=QV3cZ8uU4r2Vr zHFWWmuwu%sTSoMRey4iLd=HfbO~W0GCeWLi%(zrJW*hvcs9AhWE)hqsA16vBA3kJ& z3d?1rLq9h=S9pHAn+>BR2{$+)_=&$3j9*j%!z|?ki~DC>e^aeLqD>*j^Bv8e2)`Q*F5 zfG7Q=W`DM~IM|KzayZ^}@1k`ivl*w0G= z4P{g>V2_kKE<`@Na~`ZobB##cExUfTE6C)s=nX;wr|1$@ut`WOmAiv`hEkKvxjQ{< zzsr|ERR|H-1bc`>)JIaO5BaU1UvP%G2&L5?EL2o-8GK(@Br#m!T}p(V!c5rS23YRr z{f5%7+KN-iV3Huq27 zgwa4c=W3irTBgD)HUcA*#UWRjcHP%pIBM7$ab=i`*bbaYFj+C|rk6&jwTgXiJMd`^ zOkumw=@j*cV!lejPMWYiE^sy}B|S{BPkAiF>h4`8m6IE!sOM;;4d=~G-}nlx4y_Cb zT?8g0Fw@`gWHodAC;O+6cRh8_ex1N#)mAbe`gOWq@8X+0ktJfInDu0~s!ihk*>B*x z$?pCm*Nf0RZc$dz^0ew!O)J2Tta4iP1HNJhA1kFs4E*^<-^WREkFQ6EJl z3E8qav$_yjsZd!BrJ?cteSZIY_~-6EpZ9pao^J)S_UrB0VcuM(#IPT-P znc$3KrXS+m-FXQlf=(6L&m8wXiJW_sh>B@R$CZ6<3&;arH;YM?i2T-2e$lo2lcQ)x zkk1p27L;uPo;vO)-?pAl(#s!;;~1&5e--h=XOOsh7zmZd)j-u{|B2Qi?OVbyIW z<55xmvYx1Fh1l`g;*4GytC`O$B-H6AQZ`I@%8uw2rY)72%oV%@>G55@x;aHxW0^uc zMQ`5o0kQ_KCZaah0-b!v2R0^ot9yR}{W{0`eaMyC@8;NytiJ0n!=Q~zxSyOTQHV}j zi~)a=HXU5+ZQ@2ZA5Z5trOMLO9tNf`iv1C9bcPCzttebKS5%R16Sz3OFk*@Gfv{4p zLdfHNnUGkxp)kFDZ0eAnK)aR0@t4oN3p5m~y*$pmTHw7|d$Z;pvLl?O|Kr(H238mo zX?E>2%(U?4KE``>Do``PGDgm&$L|g4zF5N%X}`_Uxg_x0YNZ49IB|qq_n~(Q?Df=y zs*w8XdXe-JRh6U@<`W^0qmg&YnNL$QlM98qM4eBc-@rahdTxnS7JnoGFlCaDQu*s` zoKnXk$_A7J$9_{zs6{SBBq1Jw8^~?Z3&7mlhBauuc;Pz2b44o=dB1&6rXf)O?X;c2 zIkI-B!$jh^H%vAt3)OyK(&1SlZSMyCQOc)e_{2pLDY&=U;x-M@n(D^w;FcuO0_JWH zcgE@}Tv3mNHQ9mrAaBa5KJ2PT(VqZr<#(5B1fRn~cxXp!lXZBPQN0*Q-ubdLx#_7E z@=A9LFlqQ?EN**u&>iv-tXMNrTuDY%Sx+tU`u={XlK%kMnB;^);h2WRm+Z_E-W{Hci{3d`If= zDfk&MSydIt+lT(kaDI=GiM9I8@jjC%H>mjJisk7piUB1+VYNl*8zYKw$OMD4RDoG& zI}>v?!JstYPO%aTnr;aci9u1*P+Tf-ZJgAdg01>a`*LBMsQ|xpi^Hdj-72Iv(Or_3 zzU@XO8Vx}s8|J}$szsvS4t-QB@vGC{Z?}@ONLzZl+1V+v-@z2U*M{M~T{N5*^Vj4fn&fEV}G2Hcm7{DKXaH~kWb@Jkm&%o30r_+^Y%xguT%X8krnQj(nyY%^Q`R@J?8l=LdJnDn`oJLuDiW7e!}D8IOwq^hEfpP{ zcnCz)D^n%n_{sXR78^Ai11sTa)3IZKnQS>^Fd{GTKS-F6*eRHn!}Cn|v~1k>VWd1! zvZ0C$&TQur;W2ZE*TWHjcJ+uAU?bK|3hdg?Ac@Cb*ahC%0(NcpJ+V=my{kR6b?%oh zMl4)rHPjEZi6ddsB#!2>nsdrMG{uu@Dr`V1EF%*X4m_dy4k06`p3rAE0Kn^vMTZpd zR+)Tv=iese-h38w_v_k?HZQ*>I@G67ZX$U;Ov&zVuR9`>giXb-?bEYHY+1*e`M9=T zR?+}1xh1mEr((dZak7(b=g{6SZ}$eYA4q8?%a+@C(u&W5eKn?R@Sus7zQwtKeaex5 zQw6ICuiP>D_P-y9d|Z^pOhH~egRNJ7OB_;2pMgZ~uCg@eZ1sRU$aPxJ@%A+0`gcHl zUb5e*^o943J9+vkQ~30SQ=`q&Hyt?kSDs~|Mr-%iv6-}1#dotS1Bu_z>e6QOtPdaZ zWgj0Q$O{dRUpFBh#ulGBHb8&LbAJX0bcqys#a#e^(EuwR#)cu>>a-A4)%2b^(?Ms_ z>s3$yWFFb{o%&|^KeJJc7Uk-QW}@<;h3$Ew9$sJz z<#P9NlEM4>zgP6cH_9@*b>wp!nM(xXf{t*J0vp@?nFo=2c4Q{-^u~2o4@i&smz`7E z3Ig2$hdH({Cxj60_~n8|u6D5!oEU~S9#JD%`#`Z}VVcyTrD?@RTsrT4@Sn#AUEQ-Y zkyi&N#tic|9+hX`SFpPHp?GAa&Qe(Yq_PrOit zZZ2~vgz)e5Fp%%X8eQEVT$I7K%mkDC|5(W_c>=3PlsoCZU+eWR#~G+Vf`tUbK&erC zDYuhIZqvn!U~c#RSCnDenZ#p92-?Ur%mD{*4SuaCZsabDIwDVMhNNV{?bP z$WK}dO0>)}`EoKFcx(Ak;;`ke8i9K9==h*OLvpUw5039-YY`$vxjM)G>R0l^(L94A z1++g6O_vE$Hf84}*VHvfEhQ4b;j*HexuFy1Uh}n&0NN*2cQtOP{{dU3?=1nAeaI)8 z9*oC5KBCWYbJ3z&Y;yhU4`UebpAxA1!HtZ}csL#^pCwF>aWJtjh941*|vpsUC{91_ zx_omVef;cykh5AUo0b9#KZ41P-+;2%2GvVh3WalCCpqf;xmgGIo;=?5zxelqt{c_a z+vLoSH14K&B2}TxU*j`RrSF3BSqzTkl23gyZWK(Eni2DCC8HvXz?lJUdNGEayhynh zY`Y!Pc4nChxjpR%O>xFEbqB9yojN(r=lMK!Nw|alrmI8f#5ti4$gzg)1ftiUIIUatwf`1S~y9uN^0Z@K? z>I=hNa_H~g5@em4z`gxl!yTQ=2_Fbn1YyUm4Scz>JDUGkZrPA@EyS1pZ8Yo#t|Z0= zH4RSox$z+!t^MKKA7n=S|9&u>Pcs#L1Sm~*7QLwf9@kcTX4cGR7r>QxpU7;H1nkHW zr%T?18I$DOa|&S$uhi_vhrmV=V5AFohE($L2F{F#y-UX;5V9dA^&Y=*8+}*x@CX_j znM^i8@+vHeB#4pE6iIs@kb3on%(Ng=d2$=IlERF8 z254e17DcT~OIu+#?F%sH<0NYtBGC3YpDSf03tR|bhAps9Iy8fGdf$@-GgAW{*^G!n z#W39--^6cN!*iOoHw^vwj0^_oso{Oub;ZL!*^Js;u6;_)u)-A|+rf zneuJq?0as5!AqA?soS294SgPQ_H8 zgA^Zvxhy$mW*3VhZ z*ewnHcI<~8+>yQ8Fmmuap8ZvYgoF=(D5YNcZdj&F+RQl+r{a=1Ez_CH4daNOMgQO& ztNM;oSmGYFE`GBf1u30;dv?U_+Z4m8>ZrOzrck}Y8;d@ zo`E13!jbA)x*~4g2gDIb-8{0BL#O2&xFmr{pAdC*UCiV=^zooO`fwvdtZH30)*Adt z+ameLKv z(HdT^?C%1*Uj>)H*AkNT%hFLtiUCleR{(!<`$v9|9D8Fbwghc}64f?*QsJsTa=?#l zeSA%x_i;lcU;lrQb#ikfTgOG}W?kjgy&46ixA`Se9`%`@2dYk`5YJyT4TsqslD`~! zgeu!e2!13GspFpP68(XDh7@ss(Yj zVKO~;3W=?H#X=$)Egkme+Ut)T5_)Ff!h~wVx1n#d^G6K6Q-X^dc!k!QqhH&0e$qo& z_#q5-MBFas9@P(7CF!gxd0Dybxz^7j`VpZ(fI7JVHQ@NI!%BXD0P8@9)m-QJ=$D_k z(!hg!HMihbFX`Gk#GSQ7P}Dkb7^LF9o}B=8R!Et(aNKcM(iS(7D+CJK$JmbG=s)YC z0-`)|1%tywjFRmnJgPDB6YkI@DV;)`qvYkgZ|eVzW7G$=OYOIpG+OksSNzCoTQw~QGmUbS>x&1bp^N{UQ5lDG%WYM zdGup`73$X9@h%nny~5%YrtVjOWtKWx3uskT%*Jg2z*u7t!7VXorm-6| z+zuc;@FSp6cVpUt_fA7j3z9ad;?4hcDY}g$-wKj$^1{7on~VpGi%qoL+wkkSuFjcr<_k0j3Ek$IV{nuo@2f0|#$aiju>>O#r-3o(92x~M8mM1y46q7`%g zhvM*>{!f3(GoaZ!`tcO&g*yeJqoZMSPGHSIC)ev2;4Ih6Dz||<8u+n|Rb;o#?Sw;M zlikN?6K;g69xIB2j0ACVq*6&!!PUfP5m{S zk;5K$f+OglzGEa%*a{?Z*jpG^jN73@J%PIQElhOTJa zYb)>SiFq-K$TJEOjZdHHSQLnFoq8~KshCTBBL@s6@P}>^SL)++F4}!E;-SjAoIJ1D zM$oa(-p7QG+!(KDcGr~YO@tk|FOz+{r=3ohYOLgtW6Z#;4bRKs&Bx{#oGT=BY^KmH zAq``-q)(A8EWWeep?S0A`Q4W#09@)0{yEg|1%hcj7)m~Aqh+9Yf4u+hCn(8wsM$Th zPngZU<43ZQWRc=KBSbhnk5G(e$GlB0*TtGyra)g=+$#k;t1}<~f$+5Sc!$oMzPBqL zPr;$j_&O#Zojbq4!F`C&nm~pQiT_{dcNemsqoJ^`n1tQ|Xx6FDkDE5DDyzfg7%c)Q zn<|=Ny?}974T66x${qhS&`&uTZa@f5QFP+4xI?L;xF<74+G=6iu^Y>Bj8oR#KfH4D z4_iHt+h}6K5Xs01Edztqhsj6?tPm%OSA4k*OjQ^7f9pTiaL#Wq8Ik+6b(5wElzW_! zpz_v&iB3Z8wVGj4d7Rw>#;_yM+OP0idIlIhDJ*nl{Cubwp_+YKk_sWgwo2B&?VM73 z7t+g2TLr{X9jJbp;1TxIx z)IDISp`IL5)F@;9i(^|SdL#QJxNkb4+1>q32)?I5^3aYj^d?Cg<&z86{LV|bdU}ly zF9XLBYG<<;8mXe?kfX1nMdTJMu49_^Efj8vBePn&80HP;L^*=u8lT(8NtfI#)2$w= zirsO)Oo{ShkulhEd1qLyj^boUhup^sB3CD%h|&pMf*zma=@AlJ>Kk{>GE-oj+`m5Vk#W@JhQ+U_$h& zIT=Dwyz#l84qHE{suB|bIX+Bl?BnbF#E1s`WJlp^dtuLM9u@@cgUzVQg%{eaf{6nJh^iuIkp~NbIOA zC1F;BHc{`lcPavmeS{800*C05n2sVz(UN#I7)fWDn;xuSe@GXOgry-aNzO;DlDD6;Vf){gu zs;zdB_ubc8gXxvpmX$JGxy1GlqJ6EfzhU4(q*b{L!$+WOJ$=*K?GEyYUFY`5xO0m zCr!P1H!*bC=fb@HHI3R5`M;AZ3BNx;-P7Mf>{! zLUczt9cKec@iO_t*(*j!pno(Xh5j6YKj!|shKSL%Qu#M}VF<>R^MwSXSL4mfin`q` zcIfs~OgU5Oyc4*F*E{0hgGtO3yF<-ykv7dAOn#w%a(p9lYv+ah^2H7zzLS4*cwf_J z0@$s)n`Xy4t){>we%9n2f~pIqlq}U%&8DkjuR%Q&hlKoY|4girb267j&Kq0#&TiG6 zyp@d9pmPtsX&BWgV1*ttamPtWMDErL*x!plwu1n=!orYR?JD=6K!*+4_eiWQ($L{TEH?LeG5gDZkj%?eZE93)3|cqG zHTBgo22)=3*2xNoNBQyMAH|1JibJTV!W*`Ye4U`6)7f8~s93V%Ncx`hhf3VEG!6A; zN3syv2Zs?}mp)8ZI6m#v@9yNdm!-IKLmtY=S$+M*QRqiZ2uAxMsPf|su}EZNMRE0- z1WEZ3D0Z`Ptq3$!44Vk2?<|umGLgZ2Ubsp#1MpYLWZ$JgcuHUX{-?)9IU;%MN8hlV za$wIcjX=z~+SE9M8WhFE`G?U-Bw5J)ZK%lCh38h3!y=8@tSSnS<`gTdLN< zc_pvBSBs*jPK+~8`ZrC9uWsFkCB*zA7@V5Fj(Ma>LL1`D;>Uhad{`FW4$oNUx1Bwh z1&cON7akJiAXK4K)KYO$@ktG(_pGn=UB7qkxy{hy#5EU8)7M)^?t zkmXVCoGh4@6JnoUB-AGo_XMf!J$r=pZZUELMo>^bc3smpY@(8X#J-SAPk}kr0joPw zjBI&{dQ8>2F+#DvU6^T}W)v*{iEK`lqQ@xEauw`@zLK9bB#Sn+QpVL$FCBRQ=8=y} z9+l|K9DFgQAHqMF3`-qKf~1(v`6FYFP!+TZmVBY}HPZvAR<+~>Y8lW8MVk()HXAQcT@ zWu9D2q(l;^_SQmubMe6Ko&2s4pu=t4yat+dUyCa z`PRX=G~Mwi;hyKuRqx7Orm7c@VbA@|U8>Y%_IfpfMu}1Mheku5WoOkxJA$NS?<7BB z`tuowt`nVf?=J}Y{%{gO{OL+4L3{I6?vS2^TptAW_nQFmo=#GXY3WM_^vik)&w17M zA!RX4q`W#vd|eB|Ah1cQdHX-W!B}Ym~Z_&_41*yASYzA>PURmUZ_nziysXh)g0(pf|!*+}js&5<&fa6mY5&yae z*3~qQnxw<~exE|1ViP6`)&9XrW z$UkM+c76j`J@@&m*|cv!E#&GMmm2FEC5Y%wo9KFMRuRK$`f4cTH3Yj`YAjQ`+-cV= zGPGy7_m^?}HV^1~LTjm-d{6g#@a4u5J|Vs&^Cpe15e!u6H3M<=K-Lz9l5E zr-UW@BqN0P@L45WLPGr3xk-}Znx^FT-yiTJ)W`7ssZgZCB*i8-)X>2&@i3SFr!-(n z@@mmBFCjq}kCVe06)R@zvkjflHkBP;9@bT~kUwUYMQfTKte z07lo#0NUUHBZ&_hE+n!C&BzP~WWA4ipvNnEHDbkpCjoPL!Aly0(Y!y)sVK5R|M<=r;~x|!_S@mm z1i(8F5u5V>p%Nf3BPtmEMnnJS|5Kyvq|BlE`_-D=CE^HHyh9}H!~-ME(qxpA-{=%g z#MldcA+~^9oy44yjTR4nfM_+H^h&c-J_a5l86n&?B;{?2FPn^b=L?AaJp2q2i(;hkgI0FI_e zepiP_)&27rWVMxtPidNCx0eg&V?AXLeHH?JG$li6Ph=AQfw2mL13fHr4szf>$T(Hb zjqVHnDdUZLQ0xM4=9{YVCNb9`cjd<%Z%+T{<3|UrL4uF;6{5e^9ecqY*SEWuHa@${ z2Q01#VF~T*jx^U%RQW456Pd7MA+J~3c^(&5JaK!9o0(_ zPvqmLPro7Q4{K_UXq-=e0aoe#oT#WrGR-FlI=JFl2BWh>)Gl&B2LgfV$HsCT?sY~S z>M&m^pg#;nu&j$^!xyxi`JO!FiKU!wGvI2d5TL`S(ku+3B^9V-oxmdnDKWq_DFh1(|eoX z%Y?~X3i5R4)myMS_^aUEyn6DU^X% zen+{c7$m;RN^kXL#YdFomGfL`{^rJ~65M$eunNJIzcILjgt1BGqYo-mrw7b`a?bgZ z+`za2uTFswfW>n}Z^ZI1Cj zx6{ca5+LK~$UApKi@72esG5@%!$W0Lt({rVdoQr**ES=YuM9s)ScIg$G$}!|#R>{= zhJKnfyB;ASL&~=slEUvFE?s6aLR?-O7)Nw0giNOGv{v>2;a{>lP(m!yT97)<)k)q zH{X>GpUu#lua50QQKWR4rur?$;Ne%PsHQt+V)&h9x2O=(C`MwGqTcj4D>|NA|->9!&>M%m!p9| zN8Ngz*Sst-$nV%;xN3*hx=Dk_{#^J+VBDI2x}`}>y>jdzeitY$mPMmn%EwSg&HqqU zTGo*$$iOy>3}!yNp__s^PU$2T_HRK`?&4qkdQ+S!!XV5YnlFw+!FZ(v9h!Cg<2Y zI*2LSthHx=awbtU=z8s^j-uZgzcXetRsGt^aNb%nT)T4vR6?%%HeFEGCs2hd-wcjA z)ov8DJd&uEemUI^o_1Jr;vNw0NVH(}+oQ{=Y6bVMNf~-PT7Iev1vIu+;7U*=5zFaPcVuUhzLSDN-CKTzY?Dj8VHyFK)4klDq+dwdOzayPh(kd4|Qh%$QpF>)_fLw^$YOg&kW_oc*% z=YSoBL@L)NL{sz#1Z8V@kq3#a8MPXU(`)r8ioLKsos3vbf%tN;^<#It`=0J2ZdzeZ zV+b8q0xRN}?h{Ag0ZZ-g&mNT4cUhOz*+7*opU~*A0%x774}W_2O$fZ3s$L}@b$py6J{)ITSUV&-LkbR-8BvF({9NEnw3KMITU9W#v%xBc zR<2{!Bi2x-G#R2N&@vD4nh~%Hkk!Hl9qrRv0SDSc0ocnre$H+~*56|}o|Z1*!|32s zejDT`6ZH?&z2Z-3Y4#3t+4->0zU$X&LR+Gj$@D1h$~zhLV^nBY4P*}PTSiTXZ@=69 zMNygoBMrUj+1HDcs;HIRNZW(PxY{393uy^UmLz!&NqN zo$jMpI1iqW@d^KmBc&cW{FfjYR_-Xe2&PQ*H%M!}HHKzao{W>47r0_j=H5dOe+bMK zA#(l^Nzub~?ajmR8cX?JcigHNLKwdHNl=El3rx|J9bRSLEXKAifrB`&7c?=Kk})={ zeB@CKQUGOoReh=fa>T%Xif*NDr!AqPF{58B?FdV1sT0hs*)p#7ileBHa=X}@{s*xW zbhyY-raZ_aSsEXLurBu$z^~=HIW;Y)kDSXEoG0a8x<}n?C}6(lzi{>cmK_fFtDv(+Jeh%F z#s)mU%@4h_#)^xL=cv{Sl1%1$om2x8_AJ|U>A55TaWG$Nx93eRFeiz_hG&H0UCs>%=fCl?d$sfdHF8@{kr)5dI3>;cd{y4 zPh6&@;_95bmVRkYTu=$^gRX&&r|FAW99nR|-9Ks56tP?61k!Juf^wV_w3A;BEHBtxNu@}B-1 z?mjD#_?)bvuB;+>;dbX&NZhs_zBnP9IEM^jLrqk9a!xX<&OODR>Fm2HK~*4i-K}+B zacUtxK-OFGXVUlI&;wf@CsBMy$JO+S`SB_{5Zc(reE~e z9P%{wXohDd5(qGM-=v08q+pxf4gqb-V)u!dXyBiIxBEQ_@giOz-ttUUX=DWt}2KS=}1(NB8Hs^-m3r8^){XDFEajs z_^lQj(fF#S@~I8b94C$_^Y@I0(Ome#PLu1M5;7z{{mWgzAowu3ycRP5L5dilhjZ9E zgXBBeJ0GF{Qyfysl6xNBOQg2*PB&BhwnDu`NnYsrs_r9=v)$bwWUKqD8^0b zx>@K`ZuRap4wu|@?8T6{jbi<$LK0tP@xrbbTm_ZilNBASiK^*$SUc_qf?hHH+5uzd zN|Ua%>*$9n$Dll3z>$GC@rX&}*F_Rv1mmu2J0-#Xg^3{0Q81c93m!?K0V%qXQ6ELuiOM z-zCLshTvXxA7KR1F(WH!Km7^b017IEhgk$XuQat<6~Z+H!zI$B8@&ClfnymaAH4;c z;m@`44X_qDJ^mrRtJGz#fuhhoD0^$vjbT0%`dv@L=~Th1xsw&zh|k4BTsj%%YwEYp zd}urKgrF-cnPNlas*!>2ER)m%G^Ras;bKp;V`I0#Q$-yqRje1uy1#Dh09_0054(i3 zr}IzO?-YptF8FXsps50pKk^e8l1mCn?sOrtTQ_kR7D-xfd97j}P0N}Sl&ukW%5tOs z(oWQfAT0iYH!VOcye}`;Yi5Ev*Ulj|O;2@6YxmqPoB^xqDo+Wq>wAL-PHG)me!dG# z(rA&epUKO5&6d+t2`Z$+yo)t&ondGWJ@T|y9D`(AD*Xp}scvjz!F=;53nnPnfS=h* z3x4%dLjU6}BlL`)@9jzFC|1MCa=!q0xT?2wW*rte^gA4w6R33+%qhK_{)nr&1a}F@ zuGSAeadH77ebya=o5-!bF%hRv0wD5>iHK_oc030RP66cCyajyS`WD=kzRhPZ%%27JS|eRlMstUQ_WROK^>)%u<&KgAolehOkGda;H42$p zS!A2uv&E_&lSdCsF>VgrsR5GRhGC&|=R$p%!h2y#QR545{Qob(kqnXvj~I9#%IL(+{gb1Theea7M{WhFfcShYR`tjP_XhwQ7;1y)mnsI|V}B zM|euEbPrGf6bLv7*oio{TOc)jo7j&{(jgtqlGhx1a+$y_uxz=1M+G^YsdO^Cp*g@H-e!O+NRz_OH?)zkigZHTov;5K4KF3<}-nHI-#r`uS7ww`6w# z_WC)eUSj8VoYYb7>2VrGJ=)g!`OH{^qWzWX6>^6=EE#WRHHuH$N!{mo&vUy)r6D=w zKW$Ocdhq5!ZOEcZCQ;PlYePbfU>xO9&1R8wIs3@#zXa}qO36AfUNYxXj(Sc`>&NKu z3Bft>M&+fqsVV>~vbH{^c@@%c1Rmwm{W<~7IrLe3jQQr%JV{MkHa7)K(F(+ci~k`g z;<4LhsiaMbXPT?`ihod|ljJ~PARDxwm0ZR>>!CF#W1imOLuk4g7;ftcxUUdJ)?uW6DOZCuUT zdYQF4vD`|JY07v#AXUWrFsVF&H@Kd zu~s*hvFkztyn5wk{sAxCCc$18ucLmuJwQQZoM$M`7G~P45;fiaRe)?1GJQ4?dOiw~Typg4!ePVk6sk<0GA$kBVyZYCh#NzmD- z2?$}GFmI%j8M%7iQ;*r^bvFmecfOlUel0Wxfd=zWM!zVhW9sF$nml{zg4dfEW&uI? z7j8N#21g-xEj9pRJ*hE$hi}Db^roIrnB3<~?UXaN3O6@#2i`u>mqKX7nv~503-8yBaq?!X)txk*akiIsk|9z1^LQdLqw+gW3#HS|;l z?!4=j0cI=-k_VD;6EmupTr}?Uu9JHX{LC@ps@c}`xDN5=)j?Z4Y{ zP+$&T?W6^&*6K8mUoxHY^HRQm!5DjV+_*&yFc|o7L^%MSAX%=>{Y+`Ql4>3cuGNY) zvKV+p!!3h_bjT!PP?-7!Qp#6`V;HPkW1mYZ_)~|4q1FK*Kj* z$f6R}`6QEiyz8si`4y)!$PgtzAVlXL44ydJ3odp5R1%XBq&n)fVgJv~X9YIb$TSi=a}T>M{;UBq|8rTLoV*u4{+}!wK#I zGR@@6Z_43se!-$+lR7XfjQ$t!06L;+8*dGg7YQ}#{(Ass!rK3DLn6eKL3bvFsz;xthK+sck%l!fR$VI zcw^#edqYU<(-Z-B!;uy#7GR>Am>whX{iG~3PF3!cEy zvUR$Swvvgt`}Ty?v1Z|LELAt<%ci;cR@>PuR6zsR^xp7nuYPsh)pE$Q)Z~*HV1ECG zOk3cn5Z2JJgOT$R;g&hcFLmoYuIiKXnUK3SmHg7+GhSy+q*Spg@wh^6Lu^*BDk@@= zxDdf=3ou~mE&t&_ywO}I4e(?2uavGti`}qh<|6bj1)YlRBIxpM_s{Au8dF)&>?e>P z6iTG7DQ$lJp+zTbB(PZ^iRK{@gMV1}^(QZ42?+;@%a}p6EAfm2S5^{Hfl!fmZ4iw> zC*{-92gT8wjquvpU1la)G`NRKc!UGi=r@n2^5&lK$w@{zdsGM=3-cX&aKGCBa*cw% zieKhfGwzwX^;Vsr3`IAiSl)|PXc%er^X~`HtKKwQ{r`;W$?_vtzQNtcHRppW5g9Gp z(<|iQ;5ypC%*@m3vti>nPri8*#lp-u?k~z)q-(8n@!qa%Lvd-rJ>X`wEvjygd52G9 zE{Spq^_HH=dQ`Ln+77X1+N9w#9wp}dpVFagb&dY)TC(W*p@ZT)dGq90=^JVrDC9LU z@Lu3&*|d(EulWJeN1!iyNaB{f0vCz|8u}4!y1ww6$LBMlQvX5DLoGFYkEjb8CS1Jm zlLFPUNghq_Qjpktg<8P)2Gy9WKPav|e?@wqXR^Yrqm1Q(Pvz6!Iw%gmg-;oMmRF>8 z>h{*h9~`yt1e;CEE^T^sPy;aTmR_4eY7=;?*v@W7j!z_h$};^YZgX*q)SR+uD2q*H zds~4g?<}2s=}Tr-VHXBd_Id7`GR7%Z+(%RTg?KOUjj<028v`{xEPl%tBeYRpgv z{^}AJqNi6#a0q{tSKRG71TW}_jM8bU%63+Ts3K%;>zwCHgZgNtCS z*l$j*=P7^+G;xZWf`n%sA+MtI@D|y5Jx~+f`Z2`l@|AA_RWn@3^p@Gz3b3Ofkf09S zCyu+F;41-Xi{itw_?F3ur=9Uvg#^W-*;x4~n*kc;N(6f=DD4s`E?WzCqap(S-Iyk%^grcS73i?1pLQ4)Sc?lnSAoL)xUru_Dhav zm*PYP!gOqVicT=YQ7f86oDE%5Q$a7V!+lme%X#tPIA&}0J1{jOk{OYF#@jMQuwj!* z(1za=p_%*ex3yixK+np^zHIc!Dvn0r!6Fgjc^|==7d$6lWbX}#?drgbgcj@+TjM?f z?yLC`f9t(4ebUR{AX_+E#p$w+jvH|o;AhJrmC42?`<8#x+$7?}F(@d8Yk#TDv%ykN zV3yW>yo*~sBH6(bOf)bu4r6qZ)m^6ffw?w!Oz@xpM|XTkMSkQLAhd-C0u?*&_8-(L zhcx;{HxFK@89pRWo1(|7n%Dko@D5c|zkFbdE`vM+e6#Y)f{o4hFf^1T^oZCocupq8 zYqD|)@;5)U%9$ipesdq9NwH1mHGPsG3<&|}ca$XGmWWzAhoB{M3be7Ilgrd1*+hO3 z)WhZfEK9<yA9xXqgtTBXlQ?2 z#7f6k4|oz}dx_SHH&(=|ckZkRiOnnNKxfxC)-aY_(Rq8o(|MFPxAJ$J$bdFmF50nZ z@QS_a@Kt}*riAywuzfToNxBeF&2CNk|0C)!Xko!?i7KCbvc$E(rtE`Ubg9p&?$*N49>ixbJ#vyQZ6w6nw{%8@;P{~zd>KZt{!UlGj zMizr$E||}`y0&B{P+0>;mk}Z16Ui~yt=$hXb6y3a8$$Y#Z}K8@PkbQ>u|;qFJKFNN z4)^B+3cqvac1Fmzf`wKkqEZP3&fR{0UOzTc+OKM(gykF5~PI&VwKorSr1jl>?OGYZV)eyG#fLx(l1lf zq?c7n72d=(_3m032qdLuFK~+_dy7sJ?1CE7=Dc@+=jTluCo#D(0+lz#IbM}0QeWLY zP1ho+JHLR!;F7^yq_b{8xm|fD1&M~%t5Nm8LhxU59&lN-6Jurkk$&7^4u{X}0wypC zi_zh3eZL9$7_KAR`f9jL7w0@R63hE`uCvR35MOfYGHJP>5cj=CLoCSo2L%?1eVOUw zVlKW6-Uzs{WOvTMQ(p2xWjuJdT`(NkB#>yx*9o3NM{Z1nk6VA0Xz_}}Aarh=42`7n z`c7X!1NVh;fdaOsu}zMCDR{u$+sQRIy~gO`ix%pU-&ECiJ!FqHXm-5IVkd*9YR+~x zu+)HFCSa}BExI4P122xwB|~IN%~*80AzkO9Ey{Vcu9BdRQ>rc#Y~Fa-Lpz;|X48wA zGwf&j&%9^A4Psq!_i-6Jn-;rQ3y_{FLB+9fjk3pm+k#y&T)Gh$2`zhkr|wcfd)QCT zsa$Bx;T>3?gbRo?asoyryR`1b7He{{@*hqygmSTd0+Zr@PTFgQ1EZfG1ZSo@dJg?l z?jfi`);*I88jRhF4_ZS!<58sAs%|&d3_c}5-E#2!2G6hH$J@H(Th5yyI<2b;QDE|f z9*{7iZx(mk-TPuXqS%!FNzt%C%JJ#T9Uy05eX|Hr7oeg4S!zZIE1QL_?)rj=x8e-EHGXm^ha<6I7+O@x+}Dp{q|B@=ro(wo|nMaTE`tK z;m(s1azttRZ$y*b@(lBqftkXIwMYJLUArY1w-0Yi{q9vgpMH6jdp6+%E?>pu+tq^D zth`RftE(>s+lusK48Dhb0$wWDE(Vo`ob9@R5yqQT-F^l(xM$xqfB#r16!gCUJOac0 z{c~^qlWbYL^1J0hp6-hNF)bIzM}Ol%%l7A~gJDd{yZudn9$AR#Y#)?!O#ox1i)Z9w>9hX; zhZ+v1daK!Jjgz!&;X!=ecl@SD{Woksj_MA7ulYaYwWp`IZ~1)b3WT5a-)G`~566Dm z2QAhv$hm(w>F)8G3dek}<+R&vy`SOtp!2QL{{WQQXQyrd0FnH+M|B0}yQ0xC%h_hZ zwso2X?zG3_)YtLp?cY4p-9c-2NBpCkZMH;zj`{;7*RSU`i*An5_-^x{O!dU|F1!5V z{hTzWpcnNU^19Rb+kW5vu|-!uME-GV&6eA<{Jzu@*YtA!G1Ss+>FwXXXgI(8REr{8 z^87X)-Dn@!y6ih5!TDPsko|DGW|Kjd{0AfUN&AXi+X#%Dfv(@clv|zi_Y76TlP>(-57R7zvU6Memm$orQhwI z^^eB=hi}S&7ykgT-Ms$*g}q-L)EuzKOE2RcJ<~h?06p{$IsX7%;@P=&MVq^Hpsb(q zu^{Pp1iSr_`D}l}I-9o87=NoL z%#j%*Z+-B&$P+>ZaT6a$VQ+`FuR?>v8@}{aJ)49;m3PKrkE#asYpzKU)x`lAk?1 z5Q0H?5Cq)?KiYxF zA-PI%_4142Dj7KiIoVZeY8o19Y9>ZTMkdz(eZdF`2}!S#(os;*G0;-dGW_p9{{Q~t z4+f$nf`Pllg;7E{lrUUM*q=@)2!j3h1@83n3!eZF7d#yy`0@Y!=)b>V6c7#!hX96) zgNI8%2;ty@w}4BD2VEDIr^2V!wN+pj(X*o=@Zz8iuljeGQ|#qeZ&5{kuAh1D?Zqko zzZZl4%s^LhVc<@1DIriF$DVFc0ge6vbFH8ovPAG97tv?onEKZ{(e^R4P4#MNNleu}8$`EpCI}nS3Ao%h zUrPPtu?r#l2#NoJti4V{mk+Peh88{#>Qly#<7!{$&@EG4&U6)4Joj{_eqX`pQ~&6O zqCT_lpzj?fxo2I?>i^6zwAkPoq|PYBJ$UaO_ub&o(-1@SF&G-8_;bg!I|?pkKEjjszaQaSO%0BH4q_xn zq1fvBbMYe$Pv6S7Ixn}l3M*teKg5wk^83`<%N?wITS>os)>mECJ%!QZJxuj%i&x`| zs*=0^K!&f`_?bRCY=zy#6<wMIozCp4vx6SfQIgqX|2)nM=8tYAsnyAw+*cJ)m>Qc(9 zpSnlgpGi3s9}l^OH|MwKJE?M7Zhc`tUhX#LO-XQ?MHBYTGvmyUE-@E>a z{w)o^QQ^|81h#2E*9KxsSJ}!4#5XUunnGwQype4YKS|w@L+FBUI7~1kr0plZg_*^E zHRDCg<|aeYYOhfd`xl@5h&QU(_opmrI>p{e(io(I8&A$b>9&r&M=B&GdvY>~z6{ZA zTqZTAZ?A%-py_PdsS9gG#G5VmcWXDJ9c>DmC!F9d4os2Pe>p2JaQu=#+_=2jtTvP? zLFzF!G#P&Hv}9_DwBg#Y1|ox6Be4oY!EsKVB!7#wt^+p3+P98i-|60bmveCLu5F|) zK980nig5b;qSdKG54#o%4K)qIWiem3duYWg5}L{V?l8%h9uj?j{t7w?FE^zK>wpB{ zg0Cs7xaTN4>w}4>+vI1V;Cb_lg~rei6?*3u9ftE63073yWxM6O;-PP6b=PBWNVgBn z=bCbOPgLY`7fGLFjcs`m%)W40Rd6BZ*p{YvM9?LW%J%jZTtDefw{PBA`!P(&Em4ib zdP>P*(r5` z;$VxJDny+Zud0p4y0t#eLLpdKmRT zAerpeZr|{~9pT=|ZorN}iZVPUgNz@Rz1_{IYm!xe^Evd({vru-;74JG`l+0@NoU=7 z=}-*(Ncw7Td^~a5hW- z?Ib!+_L0JQ?X>ZxU_mO+iW7!8Fre?@fk(7GLTjV{Ce2ehv6F}CN358|D-BN7DXM}R zcnG>xofBaOuodE%-x|ws7X5)L3j999AG<3ou=xdyg$!p|`j6Q#Zrr)OK#S!0?uxl} z5kR&9y7z4csj? zy4I9psP3GT%+(HN72bF2cTAk?sk{G0n~=mt2`A@P^nx4bdW@ryGCFjU_{8iqdvM^LL05fumoJ30@F&>Vgv)REbOR!A)WYQWaRtXme4-5ibt6@ zyw8uRRqlM?#a_(WP)Ku}&L2p3rrS=9=2vwR4jR1KhuLeOvOZi?)5*XgVvCn2ggDe? zBIhh7hT~~V^y#N0S1`<8li9EO4`Tn>e9N`tp5$%P^%XdyT{k1D`f?n`IJ>-kf|~_ShQp z-X%DFtIW{p=La_AZL68N(D}53b2sM`ec_-?oz~XtgJT;|NzC{DQ0X{)S<|_H1=KkO z2j&q1xqHHUqtdIuek1#E+{`FZBc*8yl)z{f0Z?R{9^B$PIUyc`<`N)ONsYmPM-XixYOMBR? zkF4!jo{VOom09WDE}^)yGDBC+M8Wo$W9*IQn+p?g!+Vw#Vax5s1zjHO?&90$!67ABQE!bXgO|A$gd-$j$QPB^*hK))V(agbA( zs(#8PG=bFYYBW0zA0P6h|9x{NPUnl}>})TI8qHI4DPDQPmjK>?gYAWLbgh>U35k!n zsX&-Lv(Fq!6JyzYTA?ET_i`6+SsjoLwVoG-lTN%6^m0Mjkx(MWTm0gxaB&_VUowtuF_g zeWk%W=x5}yO*Od-9DCSfGk~gkZfB%Q?lP7~n1)4O@9bkJTN)A!%2f)6D7-JeSwI?5 z1Ih|t)}QD4yjC>R$@%aDu{x~gy2d#`D<%1r$MfV7bz6?L->`L<(dMH=lTJ8c)y6N_W#WOm}l01R}SQ4(wdv5!$ zVo>7qJFISaVem=yQ|}$C+48GTR=IZEUa3*+^=FGSbj~zmaX@16c^BT0s+jx0FlL!w zpVFQ0v0{xK0Z)TkfmDQ!+`c#lb}&7lr+sRJKwC^soibMv%pd&njZ(j8zG;M4V=+@6 z%I4z)S~iO9)Q>LjqM)`RKsP_s-y5a?5P)q`Ikph-qx@1F_~`UqDZmL;rG^X9!_I|! z&GkUP(BDK{TN=Cgl4^cYr|4I%)?BM&B1eq6>na|%u^~2Q7kyH`z(Li^_*)=5#T{VA z%Su^WB~YTP*yG&D0R?;aI(=m+nw9H3j~<%zR7CL9JUdB~Jao0{>V;=|8ByNofBlc| z830f;o*Sq4JNel>{6+M`(ZPP$ZT*ONPN7B+pNQj>NcL+Ckt1B8_>%@x)RW`EyaPge z#66FuW>YKBVayJ8)Gf@yb@4;LgVLcr2e6K!rKeMrn4gC~QZHH`yRDhQAr7EYD$YCD zm;DI2WSjHArZRn!#7~Jw+82&tLHD`WJXrQHfzoM$Tr0)+t*{#BI8uA*>R>;5V;afv z!}@K8T0LTcbU`|Xlx4ol*67wA@flG_$mS}+_6N#_(lgYhu8JVt6BNC{o3qw{86Q&b zr>RzMj&&G~OZsD|mo9mLY$vv7Iit37UB;KZxH9!38IJ$!2v<hZ)I}RDaHnu933AtmdgMZs?w7aA;q}ieRSM#FhZG@|u-e3jQl_XSG3bI}nGjr$ zGH|qSSR;s~3bwI;e(VDCq;Q)bejJz6M351ub7VOE-cFy9SkRk8I=zV`?g*51h93f5 zJ;kg#3r|xxv>!d9%M)}L=hXj(#t)VKIIi^(l5}?T8np=1*%)fD=*;YM)LUTlaaKlO z{o8kBoZZk=BFQH{4-zcml-Bk54crshjNlGP2{f6?tD%SsLgd3RVn z!P_+YF>-&ho}_<*D$LmRpR^aL4|EnX7z}c~a`ThbxGO4kn5*UY_+E zLUd3(;*ssZ*m9f???=FYsF~~PzNq=mf3&n-*XpWpLkNB)+(C*jaE}j#ba=1m#_~Q1 zJ)D6DEUWIB-KLM|>o(s$i7FoNtpZhcUCgmDibubg1G4dPx~fNg;?%3@s21youZB@QJ$nxLS z=DNIGYVu?Y?H?FW)89Mj2Xyq+c&$(O{k-d%#77ggvyg!h7h2COK!n7n)Y$zZM+1^c zq1vaGw4JQDS(V7&BE}R6YX_&Y+s~KPqaavUe$>BGjX{n2R}C9w4hO41cTnEc65bB_ znyX0oD<7#p(8n|~nmReowe}tM|$_Srbs8i-UpHvV zVKvK>TyAH!G3WgCDxW33XxtfgbK1Y#+K#)9)G|UVh+efP1e?<$flUt{P)N@lB1s5~ z;Wukkd_#Cs)$rcMLOM(c?Xb3>eo8r5&RI7H87Ppst>rqiE@4}tRYC1jbH7v`a;JUi zz1`%Z%SG@&kLcV`?9t0EfcQHP2R1(?EmOQX4%N4QJ_{2Hu?-xuXm~h2dZNo!A@C}Y zNFKm6OFQwC(Qn0HXbkp4`U|@%k@R=#-8C7pFb7L5>9ZGZ0E{wc;Ft}$q^jR|P|1!1 zX#Qdd@fnXjg8LgPG%D~8OBKgAc_+D2-us*{6U&^1GmQqRQ%fw zC$93c6yx_6MpL9qvu-H$y6qI<)ZN-XFmGak)51ju% zOfaOYVA#_r6#&7gonfG=d%O>m3t>80Y1RHl~jof^~-Vpr*$Zs@2$ zX$k6Tv~<+?p-7)af7TBWt3BLr#CuDC`VaKx9x4+MZn@QgQt`Mm?B(EP+uMcpruL71 z-Zm?~8)vaU=nIObg1S;8TdaiDE0#ad)FakwYXWcfI6J+UeZE;+dul-E85Rfnq2*n; ze*OA>M0y&AQqASNImm4+p`Cw9^y(GLb!?z+cW+b%%N$#dubIro^QrC@-zGlp?~l9S zUUsKj?wst_LgaivAa~r#|3L2k)y?3dxh)sgc+t<{78M?Pn0LdZERTjr3R*LD~d@Jv~V1gN2`uGZ*M_V5F ztyVmC#a9yVe;emX`5Wj_I+Nzpv+8iBp1HDxXBI40BEBb4rGP8@%~xwu!_fDVUlJZK z;yDIME-oMU-!BT*!kjYU?N3ND;}0ING)einfhw23_cI!-Z^%$i#&+qCSpFyN3&eTk z)Df;@vN0cf44lNVl25t&QaW_6ti)RPym^s~^hD}*pHagQD<*`zArIrNbEtxp-6PJY z*3-#?oi)OOZnpm@Og>38!#yZM`?=)ikor8v;;YYuMpuwwhT z;VWOJx{4KScr<4eeO!?54;t)<&A=w7rN5MHGG?SEGDi@9py;0%ins}-F7`hVUw(qm zx9rFh8?v_A(0s*^$&XeY63zAU)X%h}k2YYcEfc2wGA;|Cg8mq4 zBwiNWQl&*_8}WYkA|_IHJCkiT?~Y_cI}U(W@0!*<&1*NkHwHN#JHc$30l~fhd7jE@&mv9*Ff5alH_a4y^0UXAF5k$brCo2B=T$|3A@pLPzn=0jN1ty8T09NU$jXsvB zQ9vq<*Rwg00+kOu^;EcerbCuk3CD%(9>%97_68DxGs^_KufeK;xyX4%6Oq9zdSC&o zIS?G0m$e1D+{fif2?Q1UO6Fa7tNUg9YOkn5yhrjA*13B2e7poOox~RAZ`YF;DERn@ zKs)@2Gw5N%CK|@clztWhJ3PW@S({h@h_5w>x_U^OHIEeHLa;U~0e#sBDAoeHx?}!E z$>8AjRGU}QvH|Vu7JmsiHze9P>Wo1V55g75>M+*^1@mChdm=g?C9LH_DyiGDo_$xn z<8K+1y6FSYWNU4`TLUO;C;XroTW8aXwzpTqxm3%p!W;?H5|jEs@tF!YkD)T;F4&+y zp?HM*2yRL)(!Eei_%kcKd8bK%MqLC5u#P2H3 zxQ4EQy@J1Q{*S^!+3ciO^kpACBKVharnjqOJJ{NarMu;c4NprzMTh78^E8Vntuo}K zk&D!EAZy96pD?p2c2!iz{9g{jnPS358|iWN={-Zn&a~LRh_Tq=l8W*Cf%?gCVR5q$ z>{Gm+?U9yPK7-fec>gMCUK8s70~sA`6yB|H7qum}KWK$#*~yAwIiafgRQJ!{>>ftl zuW@?{eLuSb-YGF}PCS%U@QTdAsE#Fbk?1>D<}Sx?Y20J7f7=qvq0ARjC*~1h6XVT? zs0A}vj{@Cz);}w(OJF@lX>?7j-w#KteD@g3#qy+MtnQj7@lqpl1g(+K#N2=(+c+Fh z<@i^7B#gZ3tUVeg9x^c>`lVT>!UQ-HPLlPpR|3?XelR39bN_yaZM8R=tyYPbs8HUu zt}uOl%6q4I(^Z7`a_XO&JEV$!>aVZhp!5tGI@5xMjg$?Kq|o#|nS^E8Bgcc?OfaFN zSvn`I_J}vFn>)?wAHWh>qn)^ShC-|;rfYJ4D}}1|C;!95V5*~aug zyb(?Vxgoj59(ZXjML&8+ObSlZ9DPjSoQrPnq2J!YBCy%Eb4pW~$_VkW~+&3}&CZzFE* z@Rz3=byO$zO=e_f8sZ%{F-_ALRb`p_gNtcZR6SjtcZiH2#>uZ+{Hqo_b`tZAAdok# z-JqSQ5goKXBvvvA)C4R^8d4j1Ep)OLm*qn>d5gCqw!?=#vH35qEpMoOdY^JB)Tooh z*@~&{7Zxwg`?w+VmgEIQ=NL|HZYeU(vXEL6$*P_44CQERKyC4F=LO=Y{63js#>>%| z;uxmsmyiEKQR9*w^y)Lm#Em*O11t#vShU6t&k3PT$>yx^Hm-{ds<}E59gc@#TqiWF zsHnndKfWfJ)3D+(Sr*efUT3z`|4&*(+C2NsUDk|XKe~dY&Elr>7TE)>5~%~#WXqYW zXBP3M!vs~V8ScdxBj2_+qGp`Cb?zA{c`KNl5P(&1k~^z!%27WU`u_3&!|)z%`yp)) zwVzy?qqvQLZFx#FrnOgc9^CwVBvC3Apw3W}{|DN@vU$3^_KwneUdyeTCWZ<+EzeNp$^mC{0M62(yDt1B%U#$Cf z*`d|v%;wEGC$?C|5ns}9eE$j{!ynnH#5p*s2qC6lnw}hNdiKQytnvOAgl@2-)WH${ zLy1`P3LDL?>Zc0~=Ub@%?5#HAhi=2TjNY|<(!fNx)TgK#YfV+rs)wLEv&c=1JbH4G zUGQS_!_-L$hE&LqN8SJE{PFmNnsHODt}dk-|E>P-aQi-$Q_^wG=FS7Hm;qP=G!#*mP$%Q?-vs!hY3GI4mH5>uoh zmSoWXE(REpb@Pt7y=yYZ#Pk~6%IZIP`HR36zH2%}?5|gOfzx%Ts@8|`yJvp#&p}1& z#5|0a#f(Mhe3Qp$xsG%y%4&vfA6FAXOfPwbo%f0GXv1D zwC>v@?->yCkw5Z3qQhCv*>^xawGkufT#Z~KFUH_c&Ge61NZQ)8HXok+5R_ZCyL#`P za*-E+$;JC!G|biysXJLDR@~)Zihs34VYRadtJB;uqh8u}WKhh%HA#7d`v>`TJ_@l(saPFMY>R!Zg&>~UmhIOw0mUPVTDJkyNIfEEnP+Lgtcy=u7Skm*8-)-lo&fS*n z5i2g{mR`sDJQ0rb&7a>6F~lCp#>xva)4=G^IkKEq8j6nZOhrGS2n^V~l(*#bSI0DpQcAvn zB?)9MGqq1j_OxQx5j(yN80P5P-yNNbPQY&Zn1ZQMGssuXr9L@9txWy~b5f zJszIEz|pn}ZON1?Y`xolq(ooqj^Y7yfbXPyb!1~fD(}(Z08K2#+<%1N$_tb4&x;Mh z+fhHx({bb_lmuQYS~r4A%7p>7{?0(@AE=`V5_RE%BVCH`JE-TUy_}1m1ixjq&P>CSG-)=Bk55VtFr+~a^H&F_ zrg-iFDQ;WGoAPR(bn%3!SvBChWCxaS^v%m&O5X9&;$%_zZ*hDlss`Rx;;mlGZ({w0 zxgxCwm%TJnFOpqqLm zTFJ%_F|<>D$o*d|1DI=@WvvnJE3+}{Dcm*P5!Ce?#Fv?7T1q^* zJi_B7b>#baW5rF=Sm@LlD~IF#fxI5dZch{1jw@QVJ3F;D==La(m6w7t2Al*>fI>Y! zO{0fjHJP(;Lg0;J?dSd&$+_8&0!}H?qrn}0Fhu81nmuReQw!Svf+d}}@07U1b57EB zBE&L?>d46KSdpZr^ao=wR&^`fI5mkc{lri|sHol2^`BjDd~Nr0E8^-qU9>#L&KNHL z?aEnV;*z!70UhMI?a}-qZL16hr{|kADs7E3?0>BjGK?*VU1WY)Z&YagTxTWZlCA$M zVGrO2FZtev1q?!pV)f;ef1s@hWrBCl_jyK#7V(knjkbrYo3(zvUV`~^U*Dt?Z$hFzow#=GLx(%D883Pj?I055=Lrf9572sn=WSd{w* z>Vq`$w%;ylve93cW!Scyga~aNy+#Jl)zSFPlj1Ekr;)V3*?$oKk;BgUh5MGi_zyBnuM%hZDmFv-Jkc?@y_D@4*3aLn5&Ok$Q(R-+lqUMSGG0dP*SGRl9qwba z{HrW{SvODC0uL~$tqpP1UyY=ig+6ioGIK2M15|hPP+0vTQ}4xy94XuiKT4scWV#Bc zfkGh0hd$QW?I+Itc(}MlYE+Yyl%Ox+m<@4Db&o>bBvy?W{ z&iNcGsRN|Jycx`zQmUpKs1JX|#K#~J1UFfUk1)H9@1lr39@vxxUitNefLgp!?%C5v zgw$L$Y)N`I6%u?FRgY~%7H0Y;q!&yDpRC%Rv^?Tp(i3&iEu}uf7Kp-EXV(o-1PwM~ z*IR+^fR+B%uO}FerYbo%Vr=6(?vEw&njp|6)_|T+{ej9e3xuZpVg@IWRvUoX0fj1H z2!6>%X@tfOjegCRRW`z%pr_0CZrooZLawvw z?Q=7u{FEXkCRho-i45x5{`HHbtyS3FHhG>1&a(>U)bT@bZ2jTC+&#La+M^69JtMSZUK%g5Rf`9 z+QaG@3_YHpy7y(r%PhU7$wnyV4zj&+-BFM&h- zPX?zOhESkei4sA-40qxUo2{a8e?aAnwX(zxHHSY>))V)Ydz-CJIbA2s1jqK0h(>SS zAu{7~be(AvB`74uZkeg@8}4=~-kv27lVs-+yuE@o0S3v$Vye>J@WVgQi2rR!$lX)= zArRZAqdZ!34z9UM0n;E$uD`$&D?ih;dD>H}Box)78}GI{{0F?c%JgDa9)#HvPQt=1 zw_d+&M|p<-=Bbj69)-BZ--b}jUfN21GUJuBx4cg?fKBe_Fss|ntB%^T-Tfz4o9j6g z|2en@r=`FRfWj9p&QN%d&P&~wgkT@@QJ&nu(=*;bU=uzzcD-QLAPD^Gkt;r*{@u=nq7krp&plUIlLTWFIjaN~vpPE=fYjfy$ zV%n1blAlyanv`qv&tNR+I5+Ks>|s5BImH4vMu+_$E_h`2p&0 zE}q~aZdkk&2smSgh$L-@c2tW)QBJcW`lU3hD_m)i6{210~d* zXkoHG7C}KM(`MXr#qyZUYg`qAn3bjF(4tFKjtw-X8&BFNh_~%u%g$61njLQz-akzN zEL+5^OTh2oi=AxGBC*4{Xh3#H5qIo(KY#AMg=h#Y2g~!>%8j%>oA2iqL|}bo_1S;W z|E>Udka^>jE`t+!ciRG{dl2x#2_G9=z%L4S&_Kw3RJeuP^QF+18u!FIG<7U*U;KEH zc*||)e07}Pud7ou!DCtru#R>qD5=%M(Bej!b zo>;4=Of!>)Go4XETz^fw2zt2fxV|b`f8V^qPP0Eh_E<5arWjypEH!4SK9OiJivKO= z`}Q*u<`CE^IVh0muEXH=H-RH14xJ_K9_K5M)-e|klE#U?LfmGXe--~QJI z#wiY~eL#S^F?RS<(*tbaGQ#UtDk6aS%TmWsXAC>VJ%!Pa3MSw(w`w}_D%`ItKB*H1 zD&|5uZVT1s;rv;b;`TS#h z8aez&huT`4x9sWv&&9`i@HUo3ZqiHf{1~>1G{3f}?EW04CVnG3dM~RIPuo#Qlf(L; zpm(xL@Ud$_5 z$7P`|)4gU(BX^#aKpF5lnVbK>06*c<^!P_Nki*g9IX#ug zAjG6DSeD52#j;7t_?txu$m8A%3OqqYJa)?4GD*!IH);oxNwatdp>MJr`Nnew!E<}v2Co_%`mLoz29 zYu-sdw}B6OI-rNSSF+oG_E`Qc9rIaSYJ{(W%8dOg&osp;{u?K8ceH58t5w^4PyMzQBw2zmKz~IuD*{O zz)2lGY^=V2vmln9jtu`YMci@1jVA>WqRS@g-r5lR^&!s~k(d<4BPiR*n~q*Pl656x zGF~e(tBnkzM|*^MYRsn@lCS_DH?_F#RzzkqZv~KquoAxY$k8oJv$EkvxPKl%IG3>` z2{yC)MuuVxo0hlm`j}Ejq0O^wYmHZ@@Z5V-xbHUKt}h2=x5;lVqqN-!g+Lr2xbKjk$m(jZ>38$#F)!}>j zS||?%j~Khs)EFEjb?k-KnQn&Sc-xl-Q6E3T{bH&)+T&SfoMYnZ;f~64Ni<*}lnUYU?GKsh9FUterL9td#;e7W&}n2Se|A z-Fahel$*pXKe0ZzpsvEO97YtTnlCh6@%yZnJ#Cy81zH#o1uo;`n?Xb@bgKzk{_zS7 zt*wri86vs3A%W8ITrshEEvRO>7Sc=+a7o|`FgP#jV1j;3_KjI&F4TtoBF1j*dpFI1 zgdu@7TS26&{p9wzDQgzU$FZoe|Ap3`&9!P>a-==1kK{47&z&|`V5Ns;F7K>aYeFqx zZSk#H=8Us6=me)#NGf1+4}^~32Uw?C(!{#VMkdg-O%$!+ux*LW6`}S#VCVyeRC9Z`c$P6V`odUDd?;&d8^N$yB*S$!|0*>EKE5NUW1wVm zu7%nI34Bn+qosFdc)zOZFIPSBa^2g#OyfSfq7A)PB)L^&uOr`y_xo*?Eu*t*cX&dm zh<6^~pz5Jt>s!{!!%zphX_Y0C^|i&%Kr|=f$Mg0}C5YukOG9IWX|9J+93dO2hH@?K zZ73r+DYFxr$a)V(huq{bA3AnZn23y%X{bCXm|xQfxhL7FLOOQ8az6U3#ph z^uI-+-aK_Mc{$#is{P>B38;jZ#hNCSGgX9$RJUjhLt|zx|4r7gL=3+)z}S9!9l>Jm zxUSJK(L?&;543QSA-nvFRb&~XXAdAIFQ~hWOI=&)q-50n?3*!5z{rW=U>5iKa z*~rYd+{WaZjRFzB>N<~Y!ZE;9)EMIJq_Lsdyq%85`T#u>i?%li3b;P2py(Ol67Y-U zs;_@bFS55tJc@(a^tzlm$bu_M_$3ZeABX&;dsh{j@7!K%WvP#~x&-WajO6(LYS@t{ z7X!DSrg->M=@b~hd;wA&;Na0^bER^8yr-xM!ut>Im_#rkGM!vGHtc!qw|^kmFBX2F zG7nN+IX5{6Hs)|N;7^Jb95V}3S$~Scb>l4F$!xwEs7q5q}a`KemCbK`Jn$z zFt=nJ&`2Jc=2izZ5r<-y3RFC!evNNA)9hRTj!ks8M?>!8Dd+ct`e^p1kXEZ>AyzjP z%D``kZ&wGvRA|hf{kD;uTJ;m!l4ZM<+{=vbojymTh$cCk_xSzW#6MZaKWmu0C#I~D zb@T@zk1sIM`GfPc?ccLC>tm7z9hUPMvBwc1Td~9|lt3QZq04`lw`GSToJJ-?Y!Ky-vquDPYfO5(qEGzA@K$wBPni>-Q&doSyHR`1-7C3Z~b0KSl*_f84cimVa zysl!KVJxTpb^kWZ6aAyvl;QASDL+H!ruuj1rK>=Wy-dm|%BXtcy+oCTZ>8gi0)40` zaGbmos3Th=Ch-Ig4B_b@p&O35!jO66t{&1Ib>AYVGAFTlk+h?#Wj(9nNl(PoeRa#( zaBHe8OXGmVUM$-CZal>|^Qz70n{^u=TPX$#`_18mu03q6k>DWaU zynBUj44R7qg#u&KkTfM_+A*E1#3Rb=OSrd4wk24&v3l-^^x1UaDz{-Zj*$R~S1>RI zx(bos{L}96S4~qLGvg(3S+cPJ*s843ycEeRFVKM_gz3v1-oBn?tsA@$wIpA;ef6K0 z9R`~7)%4PbCE4>nl(?wk|In9wLzeG67pA@1^+3?5rAF@li|lH40PlfHgnRzjk)*Sb zN&Iyo(f_7kp3PTlM50Mmz#UIQ;x!hgpL)*XQ5pQ3OZ$X-O9_u9evH+o`EPJ;-WQZ< zv_1vHMbN~hP)F*|9Qh!2xDokD?zYDzu*b$0uC+Ug;cn-;I)JMQMX5{S^jQ;&lbgM| z7d;+A26?<6@tm#B9z-Rk86H`h@qs`t)_K+ZrHh?EGY08Y!D@BTS&>*Aij~YWDTKV- zkT-h3v`O)8-0LDH4|Gf2Gq*jlS*{}J;(gc2bJFwJ3Cwqy(gX#z&{bttZ-#U1nYljc zuS55nGh5vZI~jMc9R$t78BtyWfx4x9v2$Pa5YpjFManHaezvAn-d14*woVQa2Fj2Q;E=Gg&~eW_|^3c6uFnK z;zaLtNxM?KCD6^ z*yz?{ow5=`Sm`Ay2`e9u)7Ethoumgtln2%tgrDxF>WTE}yLK0Mu0{{#U}Z7uS@qGm zFr7`~9E$_V)PhZ6FcttJ5SO6&s$WRyab!$aS@s*Bzl?Bdks2wU#1v&0tw3}ef%##x zAZh2GKFpt!&`bcP_=p!qD_YhHWhyMB4&EjQy1_iDs<_@N({hVimq-BKrIl8#hDJJE zFI$FUu|7~vFP6wX_SezM(Tmy_Bji9Z@Xjn4#ZP5wAnbF%;;ii7#`(Spw3tce9IGn_ zg1tNL`1hj##QOn)VPIrPKNk(<~SCW!O>fJKf8w|??^~vgB8Nr z>)EOl96lb^X#b)>5(>XbNb*&gb=>D*ywO)aij_P+7fG6ITUU zpaSj#k=(LYo)84&ks{nh+|vJn+J*#6h%Lfef&BL(ktidvlDD@+Ue=n{&xZ?(K?Wcw~!nwqXg3Z$EkrGz@C~bPAC{7y?EPV zRv@p94BUkPzKXCBMSv8G49S2RaCpkl&LGsLhH zY1l9qx%$j(y6*7vT34#NWm^G}k^w;C!e6|&{api7C|fx>332vuyN$4<*;dy*499Oj0@&ov50CD)E%9JkTNQzYL&UI$Bdb;T%b@56$Z<7^Q8$Y3}ZDwD--=C ze>q`pyz!Hxdv2Qvr&fG-Z>9xn6L_G{Vl-higO5~;aIXqy+UO3RIJ>2<+5@Hb-6*7d zr0X^O2SRN`C!={@jprkR7k8Vd$@w$gFZkNTG4B<~OzVHFn zc3yYKKP$u6y0#-jfSeB8xua|<)h9!*>vvI2IpDct;r0{=u%O*G$F5V;%!v3^K9sm8Op zW!yI*wG!w;C`94eY=CPr2xdy{o=NXaknydv1@S;pXbp?n3tqtdqt$0PA+{JdbLGbmLRHuU-8a>{n{c2jB&njBgwBH-BdDKhRz_8pLru zNnK5cNd6-tvF#O=^~hlJ7Kxs5S0#0?S@p(P zDXnHNd>e&HO;7ioKH07~iRtr;PTLT~L0+$z+s&PzMuF0yGpM;RJ7>;0e4k}(1ZAbd zJ`-Y|2WI#6mTvDDKhLidv6N?t24wiD>GoSgUoj&lvc4_tcSX1_{1Qh$&!<^aGP}i_ zXNsdP4GC7>=dxzOevC^|Xrbf$M)7KQmexk&%i_WKRym-bMmncSE0PHohRS~Lry{$4 zMMsKOcycN12KWU#+dEHQb8elS^i8ONVQRwb*S6Lq&71O@ zPV;%b{9NP|deU^lc(i@e<-Ez1Gd{z&LL?jfvf>lRWlq5GAmj}{Nu!66Q;PWiRR5-W z(}L0@!*IeU5eQ}$b)MZyLHGQs&+n?v-a&WUe6z&*!zNX%%TQv6y*VIsH~cuh&hgTA zzvFV|+B3H`^LjEZChIboqX#!gW-mq{xC$h+|J|5~9JYYd-=RL%f>% zmTOshah0Q?m8Gkp4Td0wYphvESCIB7jaguQ>fj~erabrI!gXt~VU?{@RIwvfu=dQ> z>ZZhAk5zTIYQmQ<(%RRs95i)+Ud{u|cS;#h_*Lv;>=sj%x=F7yP^Xb>sm($f6UhA< zmhLXK%?z}cYeZUXb2CUJTz>3@r0o=2yd(Likp~o^-{{>FOEZ>%O{-EPG^&^yXh4Y| zaS2m?RLYXNJg!bs&8oflh)QO>?c+A8X68UQc^qlB^I1^oIfjr~5%X{pA8}7#Q_WNKk@&#G_g+#ce z`74x8EJe3;Tn$!{b!n+fSRsPEah?{q!MF+PJeeP0?oEpKO@Xl~ZC{Td)JA%W9MM8kwtv&7z7betcyneXg_CaktqGA(p4p+Lr$5{YwMP6UT)X>U zXROYdq89x8;y$^xyC%m?Nj;%pD>uM&0aWg2Ap0Jc?7R zu_NLUWd*x@681_@onQ%*Y3K4b_9y3Bh{4GsQF3u|QB!DNsqXpRKTuPRt}aL*4$GYs zxSL{On@2@eyq&S)r}2_(V6|R`f!<6!WLt&qJ|h|fALf9Z5d1eBe9nQy?kV3Y^1i<>GpKeoomE^PSKCepVPJp`91V< zt$u%o?gt7}aFpo|R>F96GeS|5UxChsOjM?T?n~PG^AmGxX02#2LO-J%1Z>uMyMH!j zDgwbMBZApV97Lso{Db}UftJj`ZKW!yTMhx(P6qlda6q!U8XK(~j0&)FgP3S`wf+_4 zMBJFl=kz`|?XMV{)~cp;9*++dWm&$j;4kEjeojg_U}Z!1;;yR)=Wn@bQ@Kf9_e=1E z{lUMLB`fD)a{mz}Y@arSeJ=uH)3rG`QgL+sD{$xvj33gGjq2>&=ob z4|iSH>)fqx4H>$}PsXl-1X+vvRG2zb%s~S(WiUw#92d}RhP^0|?4*oIdBu2?Yme}5 z{l6N{#2@O!jpO5JkO)!Cx(Ul#$+3y#2pcIIO&CY(igA@pp_*L%$WLrz39V*U!Z1h9 zL6Lqtlq*LxF*=rnX6lvsHOhqc`HuEqnD6)d%=3Ic@6RXU-seZZMiV(y8Wgd>AeSi_ z6?s+jf4CgC({TF1VHe$(XLKiS*@%!qeha8bqN)Droelc!f(_XfjQN>O#oi{)8t*|U z*8e-wxWK1(oHYheDB!Qc?j*>$)ECcHUFc|KzJ-m5t;oo;DO^I9UiZh0bv>nsq~-YX z@^R!`g6j+42{Sj$M!)4*R{C;ECCSQJs1(yyEnMFt@plPMZZL@{3Ul%p{IKi@Gd`!e zV75A{lgA;4tV{=@w&rfb5`3)kIXr}(dw;#@U_91;*bIAn`=9wi&1!0O;(#E#@qkm{ zbycD29#qv=l$*IGSw1q@QzQj~&>x+wg#QHCA8xZE(1p(f>au2J-Y0v*0|FkovasfT zd{owuyoR{~ygrc|ua9gGeX?glNpg}s^RP}nTjZnRDQ(f zBLd>c{BCiK=TJDr+`gioPIbJi z?cP7We9ER{?;cyGr_ywOWHS|mjNKpUPn`my@%wZ2OC`n@`CFocZg@+@&W2MG2hz0# zWAnA``>qxx@p6r3M*Wo4@q*-IUp9ybdBVkUMN04LyTI%bLG+ao48A6cttleTpj+|? z3D~4`_X}d)CB8r+l{R(?lX2DL=V`4|>XY8Nl5R#*&5DW{G zv&mKE6R}GOttQ2%Rj+kgSJVW`6X@8xjiF5N0v9Or$}9BUFm@e_Sk3J%0eUvACrr$I zznRc_XA-s8k&D{-YkP_0IJDY#;RbfF( zQqNtW0=i5t-GbaeD=rt;7d7tSjNJ1`rvm_Ri%IQ2Ql3^)psqzS;(QEgTc`>~&)D*v zFYC`9^h^KXkLP3>L0Ds4X7DqqOX#8JI{@JY5JIZ+$VsX0Cc{5yQu~XP+igHdD5^0<*A7NFtEbP90)CM*8X;3OSCM)t6EZ(Oa^cOs ziaaYJANo)z^BZ3_()6=Sfe@VcyYF|YKTJzjw=5+MB1?sY8PB>cyDl9M+K4P$n(JYH z&9Z&n{ThkbKj-?^(n*V6JnVcLEaRhVF-)Gh>aj3|GLXCi1+WH4ct2TgB>}?P2T#}a z6F{e~h@t)ROhhA97cK3R=eKLm7A1?tfN=dg(e!(Ssji!)a$WzYx2<(1+b7(X7hd&E zjgYZG88HpD*LQjw)yx>>QXjg`{=mocf2 z`VdhqZ!T~(ohHUzQZ6a!XKOxSuDn8r?ySnRrMB8h61CYC$DgPwpO5^>!zxtReG`ep zr@z*NQ5VERe%-=DQk{t>&M9j?5LTnA4Iwc2!Z?N_Z0mQ`wg&hume-=tI%z zk6E6@jE91X0?8;*ZzA`T@twE7X)|b_&eqzcq{5YE2HUmgMZjPVjx8^9Y-gf%DjLT9 zEDK8@m#~UM)pHF;NSh7{HFQEh&qxMpm>VuN7;XJ;`9+x%aH62>xi~U+j+xdL%el`< zjaQ$WLEo6DzBF=U0?6h zMUUS;Yy9EME7`6^T`A>uiyTfvV@lq~)xI z;&h7WzmvzgCSOqvL6iTswXlw-)YUy&<-f?b0jQi(3yL(VVo?qS zC`udk(rN4fBKQOPC;v3Nh^~es#-Wzx`|8GXy+D5_3m((%Yk^N5PUp{l{~Z-Q(QOAi mrFcP;EaKjx=pN_BEumP9Wtsv02A)%L51+huZO_)Plm7s-Y1TCW literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/grey-illo-skulls.gif b/public/images/skins/textures/tiles/grey-illo-skulls.gif new file mode 100755 index 0000000000000000000000000000000000000000..66cdc5ff79e5166de96aa7abb8ea13438dc0711d GIT binary patch literal 39172 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 G0{$Oov!4P0 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/grey-shiplap.jpg b/public/images/skins/textures/tiles/grey-shiplap.jpg new file mode 100755 index 0000000000000000000000000000000000000000..335bce2b3c938d4d0ba8e9f9012109d92fe662d9 GIT binary patch literal 57856 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

        <;Qj+%V> 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 m@kd2U`fosQ~v>XlB(MP literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/henna-leather.jpg b/public/images/skins/textures/tiles/henna-leather.jpg new file mode 100755 index 0000000000000000000000000000000000000000..615e41288b33a8633740f281c796ad8bedc6dc9c GIT binary patch literal 73213 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 PKg;_y{{Vr-9bf<1J}Q$@ literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/multi-chevrons-x.png b/public/images/skins/textures/tiles/multi-chevrons-x.png new file mode 100755 index 0000000000000000000000000000000000000000..73fb509f804b3b31beb1e879c447f5b6da6e8520 GIT binary patch literal 12528 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%0DZnHcKv4TW%c<8e$ z+y!{^^RoU+VRZC5P~{vO;(XlZCoOiPyagVz9RdUIU$(!GEO+uKR-V{^zd)uku>JXY z3Emo#HYdi=av?iTo#t@otVJEg0)uRj-H)uJTE+wV?$VEkbzr;DrY6=Gh@pHW`AL&+j zul7c~0?_w0$EM=C*81LkdQzzWF{a^3b+x_7~d-PU`vwlr-h{tzl9au!X zQaduUiPDgY3dsBJLWKW*i1Xcg0^QzL0ixRUmWx?Y%|@-G+TXnpkOsL4YNj7F-q*2G z{2WKFClJVNBYZ6a7?cUU&QHR!f}=k_`#deH4}WL&iz9)i)jdY8`hHzlADkW)<@lmD zwT6^1_e@&e)Ae&bc#PP!WF;(hu$vc1lQa#i;2VZ#e$6I+jc0=QcYRIXU%+l;nCikX zVhSB$zICnRJ=^+XE92GHa`OuBt@-(aOq;2rE6lrl}vOqi=I z9c;*_Qj<&cd(Ct8p=Z~$8b`^bPNIzYrF3Q*1CL%O`NCdv8IMn z$`(T{r5bUFy4WY>=;6AWaAstur$)T>J>7t7m(2~eLUWCqD!j2x7DYxpkiUMsOEL0W zrtGGDooe$A2?Sm|Je>Kp>|~WWrm|0uyO$fkhdNX>?BrW>;l#-T<>7CIRDM@u_5&Rv zZJe8=IK-x>Sd+N3e?c-J2X_NDK^M)U5_rVf%P`_`iY%{yJfaSfUel+&?SSWVFZa(> zA4@ZMH=G=p8Qq6jjnMnpoec3^{^u*T-7KKImCZlSbh+5aDus4UCB!?1!-s+5#O|jb zeSybUPM@r8N+es`sjJ_k=IP7Rn)q_GFk}f6Np^o2O!p)femwl??A4}kL7`0?O{INq zB-KY0U5asG{^5fUGBPRyu~aksuwtAvP=`GH; z%^mA;d3P0c$)SzdTjKW>h4u+V)4lK=n^7UCK16?MkO6L@~aeS2d^xFRsgknqdRYp zrAyaFF!iBavW@_)(98-d;S_z{RU_Mv*wHuBuv2c5>g?kRwr1lo1027Gqp9o9Rj?w_ z-g(p3>>r;Lr~D0t+Y8aMQisL*X~!&*dks9S$)WS^L5nsAfk&Ko^0$$`MCRKJ9^cK; z2tn*&R>N$)lO?Eelg5c_f+F|Fp9J3!tB%s<24|P ze3>F@le#7uRRYhl%Yz0=9c;V2tTLisB8-mQETxGCj5jFYXv!F}FEg52Xtr>C$GGrX zv*@FD^Qi+Cr`fFhwH0{X-*t_^!(X?Qtl;8;pl4@)@8VBzwR&@redtv6<3>+hcqsCN zUJp`bT)DEwHhHFp0V_Zlsr;(6Wb5&8{O~=0HS@puYR`9VC*9TODzgx^YY#yXty6Ex zGfJ(`dcHS4FM#vc#ebLTCTP-SB6gLHK8^PCIG5Esa_U#GN!*XT)EW&Xfyvit$H8F_ v7X$rWf34Gl&i4O?`T-sPFMb&reDUrLBo-ut0vG@L!T^wyQj)9{HxB(DwwI2y literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/multi-chevrons-y.png b/public/images/skins/textures/tiles/multi-chevrons-y.png new file mode 100755 index 0000000000000000000000000000000000000000..58d1f2af73d0fa4e18aba79718aa15f6c52b2ff1 GIT binary patch literal 13082 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

        @AWWTQ$5R9ay;}VUN>gT_!lA1Wu5d$v1 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 Tm{bOCHU`()$*aO(0Jr}G4cExh literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/pink-illo-panda-madness.gif b/public/images/skins/textures/tiles/pink-illo-panda-madness.gif new file mode 100755 index 0000000000000000000000000000000000000000..4bf1e47134ec2ef85dd185347884b0a6563088aa GIT binary patch literal 31915 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 Crt2{P literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/purple-wood-desktop.jpg b/public/images/skins/textures/tiles/purple-wood-desktop.jpg new file mode 100755 index 0000000000000000000000000000000000000000..fa754f8151bc30e7c1835bcd5ba2046e83f14c55 GIT binary patch literal 39917 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 z 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�~V5pjR)-rCCO%J&c1#f^xb&-47 zlhir}k&3a#w6xKUv#{D2>k=me{ZDVc8bjRQRstisxZ%LN#Sn`&Pk+wUEFp*N!Iatu zRXYL<@UOp6pv(GF2}!O}mJdD>K+U#}X}KU20&{<|HGsWeG?2SV7R?_IYqq=}W3nt& bWw-UHkP!zpHVngL9-}k6-ff{@d|$ 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 FV1m}y%DMmm literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/red-brick.jpg b/public/images/skins/textures/tiles/red-brick.jpg new file mode 100755 index 0000000000000000000000000000000000000000..028d082653d4e93a5017e93c4e39f6c4257ffc1d GIT binary patch literal 35521 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

        ^=2l|m4L-y7>8TTMs_Mlz-F_W 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/red-illo-45-caliber.gif b/public/images/skins/textures/tiles/red-illo-45-caliber.gif new file mode 100755 index 0000000000000000000000000000000000000000..0d9c93fdd21cff3399c3007c1ba5113271326dd9 GIT binary patch literal 103105 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%0A1`JTtg1ZV0 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 D?hY_1 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/red-illo-dead-revolutionaries.gif b/public/images/skins/textures/tiles/red-illo-dead-revolutionaries.gif new file mode 100755 index 0000000000000000000000000000000000000000..6d7bc0f85ae12d2238a82957aabc110b66fe4314 GIT binary patch literal 167410 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%0D+OLMc+ZKgmsa> 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/red-illo-hold-fast.gif b/public/images/skins/textures/tiles/red-illo-hold-fast.gif new file mode 100755 index 0000000000000000000000000000000000000000..c64b4dd1d32fb507b7b337f806901ffb8a9ff855 GIT binary patch literal 110082 zcmWi9c~}$I{{ERI$z){`0)zx`0s#U9468v=CjkT$AuJ*)*06|Cu|`BitLI2M zHY(bnsAz2)Ep2Iw?F3xVQX7}{Qm@w=Tw1!_#@6;rd%fkyZ~mA+&hwl(^L(DqdC%wb zzVFE^Sft6UUJ6A){|CUiX5F&P;L}Tl$FkWy8&kUH!Wl7v6_IGiJa%7WW_^BCK}yJn z%fyR9AqmdPkHQYt#dm8t9UA1lS27hCc)dFA6*W93ihaH$cxyc9+mZ?Z7+ub9Dh%nU zO=(>&wP`qS@0{DSAz@!CXy76o7}!=u?kbhOk^s7Mglr7Ex^Gd(>d5Q_VTV>E;=u1O zVVufk+p6MsmCKJ8i1eAW`U<#jE#`b=$@EqSb?~8vIH*hp4y{i)kcGW1hL6pI4pv76 z2L`0Gz*|kJucTr|2a zLZ=$yYqMpibnwTeoG-%A6d~A}j5TXS^%){U1lL3Y5ey=w!k#U3lARY>Wa8 z1=3@=_^!(2_yB0%>bOH2GSAF|A|)IZA!;g#oGSv>1Yjy82CR#>mc}zsR0@M#%i=6* zAmp*f4iw}uAlvHX8d4M=ip&dzBLX>}v@EVwB3IkzR>!le7KB>T(2co)V+YGmES02$ zva@7t@A_Gl49Jp(p#Zd{p-r>VuihwZO#^T5Ox?30zEjIt!i+1eZo+C z*{6G#99c3ua2}W$LeY!XvOQ@iieZOyd56ODYj*x`&FPch|A;gW+u!3oC)g8qx%1^|Gy^yHVw8M+Ir_o z0j9{0Y2rY}?1-4w!ig|My-4<-eOFV%RBL1%D1r~czJAW z_gn_&kfQvcp|%Gn^ico}41dv}EQuup8M2H4&GS0zApgge<(raYfD6=LbAD92=pHX~ z&sf+G*=LH5i|Rlk5=3f)GM8;&AC!;S+Bs)2m6<*X+aiKQ`OLU<+=w~PFD|irEk8rOLM?bmK>XZvTz=JTJ4K?wRju;P}|)j zSocMh6aKd3ME@qiaf(>Ch*51TZoN`MbniABSv-o?o{e6}h7Ig;=koJ16;S-C-blvbMTiPD~jJQZZkbB`TDnZE>N4 z4jtNFmyf_DnI;!gu93Gei@NVVLIVc|54>Ldq!gQLa@MdT98;!NRLFDWC!}@j>LSy4 zgeSCl_pewgD<(NFGf;E8K&c^a=O|0^yK*{~j&-e!-HcK>$@%4%=rys}!Rt{0Q&AP+ zWqRV4Y<3PKKV-F{HfSX^*cdh|b+U1om(qkE<1Kr7kxHml;iQ}+Eo;zoZ~zhu_>9+9dv@6?-}= z(TSEc5sOmlo;PX((1w#=h$3xz9(v5?Th4g(T(vIf#=yi)`JplDT4rri%lBJDy61AZ z(n9OrjPAnPVfLOO{l3s&Rue@b)RRjdZmPu3F5BU~=z-#gOxJm_P6G&U`<-Zo*PTIA0Co`_R*bzm~&zAuk3y6;T$k zyxVHqAlKiyvluxPr4xVmg*PWemQxDgG;yd|B^phkVi@`A_JGqo?_QME;9Ud{D$F*f zlQ(Vq94&d!RJ&nNUQ!fzNGuw)=q38|Nh+0pH1f3zQP-H4F}Mxcla+T(@@kcVD&O%I<#N^e8XOLLv;4JX?X21Uh5YzLAW8F zn?k+UD&26Q+9xcA&(B09~EgwajXWrK9gL(_?1 zaSb$Ic_pgc$C0ZdnO!Do;SUZ5j(MP1qgYHM3^`2l8UY#5Njq!8dL>Jys^K&MnDS?D z4Ll>oJAD{82WAwGKZ?Fz4VAgb$bnI>BJ4I}r-TxvHfzHaZhj;Iq?iFj5eGstNTzaJfuBEejdN3uE1HH)nQ>T0AH@xru8Km{ zM?v@o7a#5+`u=Vv6_0+iBZGjkVw{$6o-x<3(uy}bth^*IjQN{*xE|TQ0<;8-`UHpiHz&vYJ~xnBGmd z$4Qahfb++a#ihShB=_mtr4kn&Fr2cloi0_$ zac#&CE{x-f;*_}1MXZvt&WAPPJ%dz6q5lK}A46|yuAH{{!GY!pp;Jc3J}5!bAGlfR zdH_8?2+~}=X{(a>oB9CYD+qL}9}E;OqPm{-PA6vB(YPvK1zt%D3*9#Es|qNqTmc`Q zvXz@i7RyMYCs43-Wlk|)Y!z|(p`; zTqWBZjh-Ud^0Lf_-`!{=J;-2Jm-K|m7SLc}oE!(l-0rpzr3WsYVlsX(bvE=Ewgs3D za)SNEe~7>*8;n}n6`z^&+=V>bmd#!%pWJljAG|$|?8G|Pz6_NQ(f4!3g{Gf%ipSKA z{6*X`V6I8KfF?S$umw~sxaYDJYh0c|5pO{=QI?Lc{`6m73s*dh`j63~U~g+M*&DWG z(3)_-^DuVG!@Dqz5dw$BS~BE;{!VDi*nPQusZkZOca&uF=-P;X4g`FzLO%I0)!Bnj@#igsW^hOai)=^V1`qFh3W`AllgXNZt`uD^~U2lQm;q zqLYJEV9_)Cil1r#!)xQK4Yq+lNpMhO1*N_1Ifaq1MGr}`ylnV_bdh}0BIQ~3#o&L? ztcWrU?)tH&isYwHld~540-{M6V)?YfGw-&Do;<=ocBh~#O%`3hi}|WBd-|3AZnm=F zQDd~X@%O#Lh$UBif!ii^(YF$KnLR#!3`R%gY_S+GPl$j03Jy-)n(Ae7^~gy8;RNTA z9)9G5PUv}$ugqPB1Fjz}_A(`tAk1n0vmT_I1RHSlpbgbH_*@68vrK@h5v~`0fI_DX zOo129o`dzf*%~#b@_`ud?DHuCXE_Tm0WW5`jwF7#6PD!3SG{`1vQ#1d( z!-)0@I^B!_H}q;xXr!*Ee^!7 zW9syDJ!6)h_s8$B=c#-pfcw;Ya^0<){7WC!!yyC*qC~GwaF~8*1CcZSE7M?z05I^l zp_P8_+kWt?gSXkm-J^dkh2X{bICUltP_B7$X)V*Wwl!JWY?R!SE6WJZ?2`~qy%O*} zTS_HL9cUySiMpV2g7K7KbUQ$!n+}qbOV&?m z`={0X5MRK09LaE@GC%V!$=>DTOp?sIYOGw-)a?cyy&%ZYy+;pqj=-Q4+N6gs`UM!Z zK90<|1Xv#t==Ge1Eqdg}*3iYa#J?^UNlDqld+jfKnVqfi^NAEdu%gw;O4>e;mhZ#h z>}+hkffwQhkA285By-G%M!LZvy&%s8l@hQZ9onqN61L<8(1^}mUQ)t3xJ~gk!4<0E zb!wQQpCfRqyjxtc$+j+w6J-+GUohzFGEnJaO2mk;hE zIbAfmEs7aK#_xLu|K27_0noYviM^MZM}o}+x__DwEPew0NMdsgGa1r2sUxBl!&axnh(LVs4rr}#jMp8KPZqcXwEyzntc z{Hi}@mFpStz5p)4NFf4V!;#Zq|9UF6O^v*?j(OIRTnspQkmKnnyuk!*@-t76pikt| zdyy~C^LLnn_M4y-9R0SA_+lzDlIn=m7s&}E(Xr!(Bd;kZ?-;Q)U1}rGeNhwK1|CaO7XB z(zb$JAJ%vcojZaS`rtJ_Cf&tf#t;|`aHC7GjFc<`oG;#!u<;U3eyU8*K>hG~|B7=o zXrIY$1#g3cf9F}#d_S59B=;DM>(hNqHV$T+pcsPDs(q_)gJkxlE&6W(WP%UAk;wL{ z{yYh#sF`WMVL#{QN!1*wi(hdp@hJ`0c$pA+BLv)%eaG%+Dhxn@(`q;;mIhdhTLzNr4W&$g( zqmP%tcqJy&N4!IbwM38L>#o3+g86=Un+x7dAqC*GynL>RfGlpzrUpC%doLdFh*teF zz147Bk2AfWtaya3xYO;SxC@eZ7hQ=gLW93t3C%J=@m{dyX+@`3u$>7fxsf0A$dgNG z5RUFPd{pm(A?o60AB(!Zbc4ERJ^|PG0{*713G^^&LL?OQwh!4$1VnpTzqJ?MNMk(m zFKr_i0u1`2Mg7iW*(|lB@P~~)9qW`eBGIviC5K~u+>&zE7|Bu@H1}z^pSXTG-S)8` zX1bX79iOWF(5&+ZZ>TwtO*^*&+DQsl(ER0qC*6%)_A>JDT$u}W``slJH>RPC>Ea$E z;5}}rUd?}*U}aa&mzwf|YS`LG$lAw<{NlMp*XgrlICt8R5}C>>B~t2+0*?WpYSva4 zWOhN{kjzJZVlAU$`HGKI{8t z<{UM+MS$CCu*w_jV+m4CShyZ)Q!|RG)vs2=8}#q$Nx<Ez){GsTiXWM0|J4|h*8LqRFu0Kq z+}_w%7(9~c76r)&co1hGz1pCA=z|aj?!VngA>Px_I}hqNm`==4iEm^?e&QD##QCqe z;PmcfoMxSzI$piu{eKsLK%B>=V+8ke=Ii0X1jZ5r++c~9f}1)wquH^%(}x|#`Q}E> zm=_+bW`0?Mm3xuta&|Pz2{CQvAk2CP{~I3&c|0UEF~ds00{xsH)y(Rpnzw}21UFNt#I{RG(anDx&L;&6-+_`6K9EE8bN{@J>%H4 zw{x=zR(aLef8Lb*QatWsKhm@GA3*UAjOXQ4_;_6uGzaJNeF04WYpFiy?@H(f!0HWI z;Vvc)7^$lzT#|Xiz#L0G`3Qv~NC~IEE5-%buY6UnhyHa5{j6Rhr8uaI|Jw!r$P@6X z|5}Wjef_^1eUXTG4(ETh+P@C)CcPko45*-h8}NQ{t$$?&t8xcaX^Ga59|scYOat8S zhwAZevI6TR;La^=n+&|y)7W8Ma2&qx<;Tby8n0uxp10FdRFo_R7EhtXK!Dbhj zov+)hXB;}S;urt*8w~6a=(r$R{Jy?`=>`dIe2{?Oe14pD+hSfNS>B6X z^uhfw&ZdM3SQ0!5$-h+4p4a-+VFri9m)DQq~hT{Nvj85<`%r^XT1E3|Cs?z zrunOU3?2>U&}cC|(YggI{&0UZ4zB(TU8zl)DCdP6K)jNrHM~1EGWptV*%Ei6*1P>K z`7tAFVMXZIk+iDB#l7Lj9&7k$NW8DK_?V9)@Nr(8Ybn8MoV_oA_t+iao*_SP z3toPPWx3!z>R*1#f)3_Xt|pM|>1H_I1E4)FhXE#@qY%QvVHqUM$mzTTNQPR4phqL*}%aXYSiS{HWe>%bpB1|9*8 z?Hc2(wKv^pM~+4b`;orAepV);;wg|^u8b9tHZ2Ru4q3`+`Y8lOmPQJh^0 zN#MH`jP%`L*<=Y%x8K9wMVjGOxFv7fkY)tmM7_6g1*&$pOx$IvmlZjka^$8{bmL(U zb@JPL)9qy+9MU>|vrWo^>rZF>F|fWpLy4y~)Rc6Rj-@yu34nWt)A%!_?&Qgh(u7U8 z#aMg0_HNATM=v>V*VhC#uYLK&3Irarzs(GI)$^#n#d?_kWG4{FGuB62Bf|;?*ov{TGkx70THwO|cw35cgG0Ek>s z62;WwNsM2=<&^UnMgR`DGEVkHizc};*j`n;ckZqgYXOgvU!Ar5FPza4WzW}f6lnxu zLml2+W~ibx>ZTeQBn7GWn^6ejct3wr*B{@;iFG(ZwmhRBeM5hkGp*fU1HO;s#HNut zTVu><40XDPAongU#D)*?&j2}NiOO}lBRs{(vZdr-q(zz+D&&iG zdpeRDawqN4_r{-Gi{drsI6%M@1A!J_?4@Q4Ms4QOlX6Dt!iN<74^Gj}c*?X?(+daA z)jzfcRyMmj`7hK~5PX<$wOzO5Q!Sh`r)(`mA-NnC#(Ni`t4}o7S>tuyMY6?<;_`+$ z3&s^x$P3e#XmF*b8fttAGDjFtcZ(y7GGCQNMJlOoeq-FD7Ou31w62eFDdMg_Xs$ij zSTs)a=9|8+#ltGRK0E4ioP}f$pH+voZN5*2Dk2tJ=#cJ@zDe+IXKZ0wnztiJe zfals@Q&A|CRRtj1_N3%1aGulT5zo6%MRug`g$(S#-DZlCKDqtWHu{NL%dd&uC~^~G zd!8dL!!!{>pr%FOWkZqY2(+>w2SlrWf`5?yJB~9!#o6K2;SSHHLcck>p$78bCsUq~ z)O%?~h(}JxbgHLczvSX_?mL-id{@V3&(@2z&PCi)>b;!q+>lMCYE>@{!uM*Py_uT@ncY;&!poaO>VT%Bc zD22quUFSCkJbWfV2Q17q2NmZh%n;>c$Rr4NF5zy|+z8p>B_E8N(KtYa*7;{}L*G$L z%Grm&2$KT=rI3Ka3#m{Wv45e$0=-7<4Sfjgu@Z8t%b#6vz9uNx=EF++kHdm$CTnzr z@z$VSgQ?BuT}f!^IrBnL!V7cVVwYxKk4iEfDoXRPH6$vost$Z-I;?Q+clfZ_Nq{Wp zFrMTFFiBaq`yjMajRs~At(hu0uQrO}i5(wuyIn|XKc)N>nC)q=11uTJ@V;+GD1(q; z*Cy2Xy=xx$0>t22_G2&S?>`em(kJOnMHgGSjtO?7+Kd#J+zFi2F;;6xc4IZD&RVzT znEFo4E-@L@P>8`>0f5}i~tu?_<2NTIP; zsga=a`Zuu$XCV=u6TXXV|M!F;J0YKv62Lx(+7!4`f(Vq=txJ6bI<+!8AlQ%L2G@p| z#X0E1m)f-SxJEb>IK|nDPgDbDa=zN}3hKuq3B+2z^q0;jPUV-H5@|!{|wkeX$ z+mek5`nrSCv;`dFuv1{;RvBri(dZD1`d%m0HeRRUcBs+7d9oB{{5$~Sswiq%KP6ay zun>0{n3)|WPMt<;i=Sxagw;lNtgzIrdqSz2P$UB<6Y91gG7tqvPuYYu?nqgc8TzCW zolBd{b9`^XZIyHgPtQ=gTi^V7L-uU7cQ5i>7jc}c+rXYVVHRI6Ou^f-78_oNBomBH z)3`@C*KZEKq6_@xS1Dd=bd-2c($tm?b#$@43m4!dDYmTzNh4@SnA@lUlxkKxRF6%x!oh zYN(&5&D5kP2Uq#dcKIQAH)$1n0TgFs1*#mD)s+g@uZmH_V93afwM+Bx5904lfDi0u6w@+yN?ZZQaLBv2tAYP~g8jp2Hi83Q!sJ!nU92-B%hXw? zqIo9{+~S?MWKR2uUaM5+CPaEUFArqT5N^Z#4wF@8LcVxFG1Q;V&@?&bcsUt!r$TK< zB`)Ot_!ZUx$gZ?m82s$v^T`56N*W=E(^&8Qu!)^tX$elFM>L7OE%T*B)r%AnIN<|J zbq8jTYg)r>-kHPEAh>S-r|`;jZ)dDJF%PJ@&;hzFNpC{l@fL7lb=3FdHN%~AMYGQ9 zp=!Dw`P&!hxvA|-W&FV3IZi=Ni%stvW_v2HJ9;QgK~zi4^ary0)ZE3%v7B4Ma3F_7 zR=RCsHCjf^4pAbw9mPkfZAany(ZOi1Dh{_s;1H&SwrI}PXri%v@ME(A0j#)w$}B~K zOsK)mgk0_llX9JjS*kaO_|1nlGD6hM7{D~pfbBDj`mG@*#(fH`ZMJepB>|PM2R1`; zb&CY2Bs8*-_$;Fz4gk_X49uCyw|wQSQ8lWBQVhK%-j+HeqIW=|zoNNPI?%1mb7I9Q`ORrSC&otaPR2*B4P{ZpCPpfyhNsaa$O{btnOyR_dn*GNf- zOmcww61yTZQhYtilK_+kWs|U0(vt%$6<&+V9;$CfI;+jugMg(5nG^-4+PKX(atvKL zMrt;BjXOx`&ISM9Tx-SPCn|m0R%P29ye$bIE|Ih>#ap?4*3NwE7FWv-uWg6-;A}Ve z@RYfNIL;b`2qF_QnI$x(`UsA8urPcGry0o-YY{2sw_D=;KsegE)Wm2asN-xZdax^6 z!z?D@H6|c-P`k3h5(l-qxeZgE9iDrcH44vjo)=J5=Q#i{ON0rj&j*ndJgu`>t~D#6aqE3mHS#(=UXEVP&;T4wy7<5>R2ppU1&i2$?G$R4Dxf`(j*j{?}QRR5a;$>ZLZkx7VP# zmghr$=bBG{WY4IC=X=3o^0OG1EyfR6&G32OXt1``!O=7o^}ZQ0f?T%^GMy6AvqGAw*@?%4`zxI2 zgP`>c0<`2S!6&e-|C3o~nSY=ySPfa$cb-W&7(+wJ{m2eK zQf$EgoPUks1YaKklfzJz&zfgo@{PFV8O)V-l&6}lenZMK~rl}9#l2#;A z!Yya{Mx$FZFdxzY0bRrA_kk-1K1)D%?(7!OO4(5b|U=O`d8!AdjcXsM7;t8c=& zj@Dvhn^^rXo`z~)jA$jSc{9a(@_qt?{t*cO`Uo8|zaQ;H8Z@_jvWmD$7?~%RtZ-tNaLXfAC&g|!3$Dvo3^yw>eY zj-MV}zQ*6iRkFfNY|PmjfU_DYt0<&hk%KQ`E0(6b|L2iv?td+j;4$3X_7-HD??%d;C5vYI zcA8h}hCXd*`8o`oNP-gyRMX6;8@NALZ^>W|ruu5cF7qcnD4WuWh2S#Twu53)0R3_dsT^D4n;o6q|c_Kg!J@YblzG8m00GxR& z4(&(d9aq=U5LS`5B?x2mnZDh)Bx}JBsOO;Nt8-NCb4$+! z=?bq+*t|5_NU26GOeK8jcZlnrF)!M(OxCKO%(yF8=!60Rh4)iCv!H)CNkn}xt>9o_ z5i{8(-)_xVd>|j9S(9elxmL1Kft)C>WZTmQW&Pv8>dRva^ zlea>_Lc%QfTO?}BbV2_dwxKdNl@a5DW}DhL5>#QgBv*ne60I6te#~fL%*4y&B`p2y;dEYBE2W3R#}7nEV;htlkbJc9=#Djf$HX)HIui#^-|2h{mOPx$`(t5>0t=* z?zWfLZSl9oR$79{@P;4JcvpBzvuz&T(&uE_Gi_BytFs6V?F7cqRZILeiAL(y-&TaA zL=)z@>SHl0It$L(e(AL=mPoIV7{dq+-M*Z6;OC8meenAo5#IO}b|~c-!*l+h(-oRK zDx>YyN_2&T%4u$^P*N%vh}LY$_oC--%n4+rs;VtQisZYfyd zGOu=9lSV1Hd0+z`dpGeT%x%V$R%G0oW? zY0rf&pD{%2KCkhi)_Wx%&Y#ViUL(m1AknL>5@9818ihlq z+W$(Th76Xk`WP|ZvMe1HsR1+lDtFwx`t#N^1qY-2w!3YhSn_wCmvN<^`g9B9=XUbj zmu9pZYnHut*UqD#uF5o+%p!6n+8j0al5IA?L}J0{t`K<_Kwrs!z9bFow_$jm*KUZ? znJYxQM;GVRzQI`XMU}6&#dmx^#6Y`;)hEflSQPKZ(Wd%Zs8ht`k#u(6LiC`%kG5(Z z$9I?cd$hQxl!@j>Jfp3{-FFx2(tNc1B- zv~+Lysspi~f4ETGu|*y|p@y@Q+|&Pw{EBLiMh_ds?(S=A_60}}+cAqmM#$4$L;+w7 zpQ(9zSfziKFBb8yVnkfUsavhV15j9j8-@2p1Xa4no6yDkm(Hg)-|?QR#4@QThn&KA z{6OQ=&h~HIS}hiPS4Rkw`ET^Z${vh)%yla>7dM7AX!OKapTKFVAdTY;7sCib%URIp zfCJCuko#)iZE)~*7L9J7u~TxCKrW^=PdsVOXm<0QOgkVWnEw z9v3GOO`8MW26y)g88bH2dB|ua0Uyor3;5ga7?8l1CP^6kC0~7`I<&CY8vZzkf+C7e z6Z=GUl!47rUU_7Ns6vvRbjY#A7N{XoAkiQ(VGDy)y{+sZtd^2p3ff^~=Gjag7_bqy zm}OxGZ9?5*sxA6(B?V)`LG{(hud{+YU@OOegIU)hzq%UFzt{@NhA1X`dtlfW^Sr^J#?R5f!c*i2JF!Nq>e4`CYXBq1OClzUoL<5dZ3~U5BYYFti0pzH z9bBU5)nd}oid(#R)Uo06(*c^*a&@W#0zlzw)tm^sXhXJx5ujeKrs)u|U*oDvs?>RO zdkt2@PcluauV~W91NH#rp(-+G{yS`4VN#t}0LN+G4^&GG-o=LwmakZxBjJI5 zkT#IgdE$Q;L@Oeh)m{c$F+k7Z2j^I5jMw+<=AKJ~iJpX)b4qR{ay4Fd^wOrt^IrMT zZHx4*(_l%02Fq>;kNFZ{F__Vyu(?!vg1Ho4BHKUb67h|$Nn_EQ7l%sD+<`eV`2W^ce zCy@Ed>*y|=`hC6!Ew7w`U$Q-Y$Pk{c%oE)dS{g}%w0kf+BE!+Tu)zRr9;Bcj^sH?f zSNI&e=bz0pHrqa6I_S?YR6&-4KEPvhEsP8ON}r;xw;?Z`U>dFOt&4LsayI z2`ta|`rovVis-q|j|PY*%OXOAc3QF9fWo-lDH# zeP9|17#|7P)dfq9@Y;hW574{K#XNEgLsQ1)c@H&eXujQfjiZpW7ptI_Ae<%s8bIky zH1BVW6zy^h5e;xoK|UF9rUFJ4H6g2SQqeWl*h(iXilflL{NDDcAe#A$;YMhKusx(7 z%-K{)f)B>2+xY9Q{%r-#C;4vcfZ^w1`umfOXBb(_b@RN4w&L z?aorv=zyc=4l9&@u8ZS1-n0*#ixGKkXhmad@lWzu|8rCSthvoe@2bHn^RLIQlvBdd z$R+J_Y36o=t%B#fbZIh|Z*sLoHIQKmMoYx-K5JCJ8+NJJSItu+b2L7&UMYZF#GR(O zZ_n$Jfd4BsaI*0qUumbU7V7y2r2{8}GF%Y6-9)K&SD)M8tc_^AXkIu}E0pz*%+xXe zesVe=O0J?~4!9P=XrbU`N82>s84Q~@!7w=1iapU=B~ntL`)5w3D(!W{kV|l5Qj0B; zr^R+ZM!EKC>B_^camIbDG{0F`Lz%blehl6;YLV@0kryjxtio>c@X0NyvkcL}#3)FN z@a;eTeKb^h?DOJ(oVMs(i`V%68rkZuzE=C(V9B2>;^)vXQfQ8FyIT?`AztZJEeA7s z1bcm!nq^Pe3a@8Y|L23Hg*re?vV#Bcw_P~-gm+Ni{y%j_s&tdM8}%?vo3^5qRYXt}hWG9#bR z+<>W(Spt%SN}P~{q@l%b^Gkgb(3|<$*|QDsrpYBcZ|xk8vibHs96OYu!dswwavS4; z`HE_i3agrE^WxV_l{EC98Ly>UX<162g}G$g!jIjY74}m242}jwsJWWm zI{a~dPFxM>z?2h#+trJZYi79q$S~t^GYxH@uwMP?|Kj(n>HqD8pxC-R^fK2hi?|J~ z4)dT%tu%}|Kp^yW$CvBP3nS#nrhC31-XN@++`<_7^dxHQXU5%!;Awh(A9irl70n`F zMz`T>(f_7A5%tyPvQJOZ>y*?Z^}LNM)es|CbEB)&cXlF}5RL?aVnyV)Nxn<7=7o~E zg(YVa9n__jh8|P}EGbij=p}5`!dlm!s7j9@-HQlpq+pHDg6(pkNzV;tZ_n3elAf0|Q1}xaUpeA8IQHGFd@MeAi%wS)+o(=0_miuqurT_mgktzxki_!$%+73GmZN4JbdKj=xI9^+d1> zwTcc(J1{)JC*7OA>CMSO(^}*PMxx&qV`LZSw=WtP77Xd4IwAvk~q-JKnrMk<lxbwLi99K zjm$##OM56*xej3F43Vz-&_QgMZr=ok4R>g*Ycm+1}v?`4RKlbw)mA7*9u=o-6` zXN6v2&+zK@yY0Tc$rp}5L$KO}gncs%#^FFc8KsNMyhw(u2%~wV|a0gRa8kX(uZ(}H4nvi7l{Lz4=CV;1HynZi^g%C z@QN*9_wcNt;RHQBtHE40U?KW}bo4vl`g_7b9cBm7RoUTB4Ck*rW{rL>x=@b(FG?1! zO`h^F!}cK(FxLx^=8-;lB<%8Vgr9o*{Vyt3!hb2v;Rfvt#jhQ_aaa!c7vTP<*@)QA zSHR5tc2%K_DbYrTG3STs=4p=SJP@9j+7DkSTwp&R?0e&2q3*)_!w`uC>*;tG$*g;- za9Cz&v$!z8?lW_h$KFT*svamb%RGI^!@NhmQUsEG!>GcH>iruoQ4)K zDRKEIJPKVd;ETmbI0glDh!PvjX-eI(6Kf;w2ZBw|@M$QZ!5od2^Na-v58C5`!wO~0s3Mk-3l>!E zfo90lG>Y3zvU`X@OdmVm6K|uW?k~efX?DXfn|EE5@7Sz3xmiIche4t$>q3IBvym4dxZ49wQ3vnc4d+wewQmUabw!iIN0K3|l8k(w{lTyK z@nD2s7X$Z$WoNX(4P+2cC)#~8G0lUbaFPNFQkY{Wb&GF5mOqCGhn7XJ;{Q;~a4eGU z(cUSgzo{qFjAp|BOYCkPqSU5$$p0F(2s^58jGp96Jg=7*E$bSN9nz(^Hhmd9-o2$a zJ&Y3d#HCv3czbbhod;>w1}@94%OT&W`g#59RLWlzcTM8vhew~}fA{tov_do-(m+Ox z=@D#rPUXx6rFFc)g5*CzP9gj7f2Jv7x9(m#9Zw%*?1r^LI!r-gfLe!Ip(mA?H&1>g zp~FqHRo8{Q^PxwCo0ai1oZdnuBp;&xYB2v;8IO!pi5G?=e)7aVzmO79`JQiW=_DDV z+Pm;iS}{-nWr6;5I0U0Zi8lvsz;iHw+{;P05DZh)w;utR$BoeHZVr_83-2n%17la+ z2p!TbctIuHr*3w8-uQ`R<^y@!a6}l0U{ha1**vv*VLzFKSwvG-X#+C#4$Z-#kBcbr zl~!>xxUBQYu@RZr@`*AJR#7nFS;0sWO$}d3rv*+p5F3Wl=xNUIJ4bcxoSw#lpt$hT zga^~~TOU}74o|ES4l6br7t{R=;P7zb@T}e1h@LL7f)=J}C199sBys!5T$EDxkgNxZs1s~P&B#~RKKp|Sh&J9m z&jK~Iwonowv2l0ztNN&L2Oa6u#RgF~D|H73;1Ed&BaK{Qys#*BUm_o3XHogL&d2o^ zv7n17u&bI(sQ{YJ!oI%z-`*$s^@2!>S_ z!INP#lnSs%>vM5O6vzd#5a#z!B84%~SA zNbsw1qn5$4m^G!}97>;YKq@K|INX+Bwe2xROC07~T3PU(fu1wTIr}GF@pt4RiA^3x zB~xeq^X&cNdg2!3`%*?x&%a}E^S0>skJsBDlXM%t)+Gw zsBNkBZKJg!8_LS=Wpp` z@$7pz*0DbH4qk-HG`&dYv$%3d`y7}C4MACbytIHz5-tfI=mQ5|@?UTwmSg#8cF$pIw^P(Tn^EUy z2$HFA&8^7P*mrT%k08)x< z3qRf0Azb$DmyTylpKTmj`|#~~GC300S$-VLL-S8X=Vx%?w|9jpivQQ5CyT{F z-AvZ#(};17jk3GR1H>i4JM$WX7yz$CVq!p(-^<--@b1X`j7a>9{c>~Y+i?RU`tSRt zNU$e;1AC2sbbV`+6{rz5Dh4qY;%Lgw*#tp&28IhhPI z=ZO9Svf{Wwl!~J?MgDQ%$gDzNk^ABIhR#i=RrxBeJEh^cGU+DVT&DV;>QJSI@Wxqj zGSIU_6*`Uj04IzPBnq$22491U4ChRpapkVrf4Vc3B44!-Li2hLAHxIAMp~C19R$p@ zWIW2AR<-W%4%x#GIgOeew2uKi&Iwzi|L z=!ad&Io?u5qMq=ywp{6V`H6^u!-rl9qFpoh=QRTxUe;c!3ex*tV?Hci6{Xbt)5!-i zLXv0oyZfIGNoNaXHCW@|~?cBD0WVupY?P6u9-0L8M z7<~pa^Qkc$h11_T*;bkE0}WF`Uxvk>wx(Jcaa^jQR=q4@W#H83drO;8moA!3-_q=< zBlcFsVz?S|Yf>MNWM2wvyjJ$sQq(6yUc#J5S~lmFGS^i(MSS9R!2U^_g|W}D)sOO+Y(H} zEEbwdW)&9Tsk724{c`^^;l46khEw;WgQ{?5hXx-Sxr9z32c__9Bmo(<$>jOAGR5(q z+9R4$7dhes+?NH=8V5c8V(8#8KXOrQd-GPE8wv`vpOa%KY`~z>1Dz~zw9U=D)kvp z-^zBEHjFn8QpAKZ0*(BnIFK$UD^5=lg*f?WZ`6I?l*Wkrro*l%tFd(qQx@r2EO1Ne zER8V5x6+pWt0mk%EhDzVw$4(%dhPhoiQIuJn0J_+6%-Itv)^1}x($7s|Fb~F8Frp` zLfd2KmMBxHL{!OMpT$9p8%-ct;q6!*-0I2~7jU-4E%fWB+w8IzCSfSB&5g(iEbMl( zVJ1qXtZq>}ysI1UB_}9$&syK}z9csh&(@dOIpf=N0Hgv;RBCNw?nrO>fKM0;T?$^_!79I<)TA|W;3LAG>~_{7 zc*lf$&9l&)Feul^0eM?rnxl`w--l=YF}6kG6MGv92KrV!`6{46%mf#k`x5*^SjASt z1wH&(>cnsOZ#mtdB!MEPpj1}}r0Cu!NM!(RIkT=aEc;VBv9C4u=%{h+fCrz710e0H$ihUL- z^Xrd;SDI@SIi|XW1AVHMMmDVK_tsa|=w!KINxc$fnUxkl{~S(=6K9OpVy=iIP|GxoVtC4B&6*?l>-$n|==7CcBYF&K`yEo7EVVQE7^u>5ORk*{C$&(iQEo4C z5kg6@tKh6XH(78Wk>S7Kp*=VMzb8Ls5w-Im{p+(PQ{#`_+^WU0e7~c88(>HZ|nYF(bzU2B{4DZL_3o7Z`8Ye|C~a#KGw8qjNU2pl&X%J z1~(OOq;Q1?JN=T!zt%EXQ057Wa(T3x7OUuPp83cdKd=m;MD^yM z`xzTM*S}+vcLi9fqhenUE08AJ){63LWXa0*ZF4;EefK5*#&-MC=e--(n1Pt_9vaDt z2s-7sg5M&LpmYjU?^RFc-pz4oibrON zhT7&0)Ekv~z6rcXNeC?4^KFeYYeBfraBg2}QE{ceA$+Qb7K2TAG zUuW$R)qV9Z;dViaQo1g$6f)`-sWXXMJ`=L$9Gw;NG1NG9%m2iSJxua8ufnh&!UMR1 zAdZ%0Kb(B*w<6J0W`4s`?-;l#4JiD$V*a}7)x#Z~ez^yW+069F^A&67)Xditbv<56 zt@15SE~D+5li>>$bRXD13A~zI_8)wd2d@a3)NHlv)+Pw(Z*9C&WKOBmAo<$eNE0M# z#sGT!tDuVIr-h%^z>=zi9~WM@BHJ|5AGCmvC$Q$T=jUXFZ%kz_@0`%SE%Ab4V<{rl z4f$29wG%DAo~y;y2`|d~{QqfpEJaU#m%~rhuiQyMrTb!K0fq%6+l3urQH=roa|-Nd zMYRlikqa)MQ_3Jr%4(-CmxPex+?4P!DQlo$X?t8eqiv%;u00+Y&`*@Oq^nO}x$X+` zF~nF3CGGQo=Z0}&1KNU(iaYjZP~z735kQIWHGrcrzyroT^2`>qpn;v!WDqxK`^(w6?*>rszRN-DDd7SR3#BEhpT;$CAc#}905se+bqxdc^ctpHp_AOYN`Q9^ zzu=A?tBMPXZy%QzmY;E5C?@3%ea{Nm`6Q$q`t%h6og3tWE|5s0N1SYsXxk;BtmMeh z2P2)&Dj7jXY5D%l36bE(1_+D-F%Ezg+Ir<@Y-?EK{((tNT)>4De>J@(x(9Z+fOsx| zi+QA*3{2;yTmT>c*xxa@a&5(sba^cPl|>s_QTM}50!rz9jaPuRHeJUm8)QZ+)U{q7ZkfJcA5=EdFF+$CS7=EI^{%(VKa!GX-_V{vyeGO>_~QGIJK7^u@iRj@pK(?}Lm4Rfv??6z z?dXN&9O(8)LVEFS?O^Nz6?B)B$VpW#C;XERDf7JlZInE~X(?#mgHjU`X(Zis{?>6} z4(Xr5NLyU~_YKfKz9rrnkTO&pG@N|oC!7Ru9;ZoXuy1K3bV%~Z^9H3;ZZsrvC(<@% zl;|1li%fW3>0t)(*f&W?adbkJEG3aAvZG0~l-y3zog&p;* z2$HsjyP#T^ve;D+uo6&=biHeQD0i%D7~1P0ZuKb(W(nO4`tBN)`BIgSactz1cZ?`J zOlxdUkNYY3s7t=Ug$8lK%RCU?K^|Q};;xVkTK%p-^lr4s$&u50r7131o6B#ko8o`p zcnwK3QDXOU)qi$6|s zG1t?>pe7PZ=~c%uposK)Pb>}Xm4tGV6qo!cBdU6|{^)xeUnIPKc#&it*f@0iBpYJ% zz`xT<;urNc?mOmh0}kCFQ6tCO;Da3!VWGJhW362CtgKw@ka|kNx%{zG*quj@<<+l zUGZT-p<)IB>#6@#fzB26D5uBj3JruU0KswMcrHR6p^=d1I!~txj z>ZJPZ5x|62mWo|rV0?^nMy+VsBes3hj{kN|@|5CitHtYx;+a z4u4-;!G0GG){fNgzF-rzaO!T*Cih5uWY9yW=;ETFa}feQw2}Io!pNWpLG?Z)w1kS- z2tvQT+|6)Z7fJuIJ^&gY%l$L1(*UE*FwQ`>EQ8?^UQ~-^{;70rT>CM_uFHuJL%7l4mM?YLx%k#K5}85>0Pf z9;=NXQmHg(Nc*_eCvl2Y#WSL<;Saw>6kB?svxdd3k9S;eSM6qgZeX|WGziGeLKG?#IOBFI>VV8Vcc{0ah4} zLFZg@DJ6D+x0_tWP5s82;gdU|f#q_GA?Q5;G1*_Z9Wv+2PUXJjC z;@}@jf(&|re7=#x{&^jr(HqkwMsvK%b6*f+CN8*Rfyhki%)LZGqUt)$JqS}>gtlG% zBki}_7_ka@NG?WU(SDccCIwv&E8k@hUooP!SJczP0^(q8P8cQz=s-IGyTq+0PpX*u zF#;-GF)a-NeMb@>B>G6R;yt_A5z^t#)B0VB+sDA>x?O`=h;M{s?i@F~E! zpEtCfzlU-OVp1@hOj|9H@+k`WF#ZoEdaiX}Dg3^tzJYZ?40fM1 zT06y$II#YU6=PJ>zir{|b60wLZd(fM4dWS!v3>5%K8xvL+k^jt$DY*l9?heyn14DY z>*<8Yx3|iMum_ZXB8SGm{@xVU5bnZ%?URF5C3+G$hY~%$IeG24iTR;%ApHUBNU!ie z`(-%xZr8JpHw;|xT%ykh`trh%TeKLI{LYHMWMmxzUr+0+0aD^7?{~`lsT`Fv+cjB2PRPPNdH~%3lhId!@*h zWC=%y9A^c6Qo;V-y!o`ySn7uksquEGno|c+m5U9cl!<-?Z18?I*uW4RDH-b=QiPTw zM@cMiVo+PzJ0GS7HPRtEPI#9TWL)2I0QtONXkr3OEaM9@hClXXKYEb+uFc|7sknFi zBKC(OId+s(1eJ?cPr@TRggp74MF|d4GWz!UI9HLKlgQ7;hlgbqRT{LNFAp9wBn_y% z^Ah79byOdX#jmQwj3mXA`q(AysR`VWDX9!0HgZdCFod_uwUqxOj}-RU#ax|nj=K6k zsMOU$U)3Z%1$IyB0uJQ$zMbI0%OHc~{<#Uau;Mpw{V-Kaxo}vEmc1Dg5~j*%a*(}} zM=r4rDp%7Vt!o!hy&^aaoxK3r%?%z77A-3e8AG{Sm5erp1anKJMTZCXd%!XVE~Z4^ z8Z_sD=37=-#f1L)Rqz^ZKou=HcLq5huPgB^&hK2Ac?EjWE_qxaI@z8*o>Qkj4~~aa z(d@HEPjhtXp=H*C8p>Kc|PFb~s5WLe;0wWq|%`0Ja z+?v<5*ZqE_5v@y{!brxd9u*~&@=lIP$2`g^7<%AeUl28ED);_;j@ruwCwYESw}{St z5PKYg+Q=W^ZpX$IssZ<&=V&UQzY{QJ4ZXT0evU;-?V6GiXXr9jir9AgagUq6R)eBSGs&F)rSY9jIC^1+FR}T^ zraaDe_LG=}3o7fK z!{0;(A?7c8yMJPuCnx4j>&x76O`|Hx(IvG&S)FTj5ByG3;#r-mKQAcirXANlmTF6~ zR678=nn(;;ZaKT$2Imy)Cq;KwS%W938)}%)jO%|yJjif-Nz7rGMcrkz^NlroCQSKa z4>{-0p9FfSb|MkCJh%QtackwI^JO>u8Xs3F^vM@&EQ%DBiQ$(!p}H_(rAa!b$;i7S z*4smTSEnu-q_d#kOUmYm&mGZ=R(@XLgkp=&! z+aNhOTA`YkyTIMA0`VL*Df{`}pOj@MzpshHv&!%U^Oq~;gvWZ_H(2CCdCr87XlHBG z=?cb^_}hTP6L=~f#Tn_pzE~WK6)(jD4#`L5UVd`{bfW!s|4?) z4dTR>-e7EVQC*hmL6q{QJ zPlU*~MsU+litoOH{N;Jtq*CZkOCrvJ?{_Ao-25qH%BeP$h|d$a2jW^=JXgh`mCo8I zUi{ZM<(AaxP#|8XX#(70twUQ=3+#$>SHhuC+~`39@QUUP?UMmtqcAFq8aOYL@`;>% z`ecd^rf4q7?i6_`t-Xcy$So$HNPMcFIH~BoZpqgFiF&Px<@o9A;AuG17dd0=X*LKA zfta?dZNwFoU*e>1<{Wtsx;z#XoZj4*c+}gSi`GB3dNv;|QoW=2ZNLgXTXdKf7h%;k zy}zBxvdWWZ4wm*F4~Xp3%2ex1|2tmk;*0(M*wX>itGe6<(NUw*8k^j2u*s}a_OgGc z*-C{kFQTtMKJ@rWI;P$FJsz#^CBCb|V640FV;?+t3DJ&9K))fPYQ({64TPPP1K#i?*rUQw3z zb3nGY5W8_v4%{EOg^(Y{mL;BFu~gUa&CcuNi1^p4YvVe1E~& z;q=khd#6&AM7lr*Ra2~r2f7e5^X|>j{=g(!lum`iZ~z7I-8<-cpUP^ckaJEr_AOAi zq3cqF&Vv|z4E%_1jZ4X&ycJ;w^1wbOf8OyI0j{aIDpFgRD+UCm_X5^-O@xxP?Gpn-pS zB~eADj=+&cpO($Pidy*yX4mY%fHroxf)?sbBTB%2Qtm5ex8RGyX*p|{6)|3BDUHfru6s?u2=M6 zJ%gO(^Jfka8Zv8#CLmm!M;U?vXZIU`YCR4Lt+b>s@jhMJ9|t^Qq${km*~6eh#TT;&0P&B^uc~x_W17P;v2#2pKXywb_=#-?t>xkR zsMcfmejS$#4B~L-C!4on$cfRu&}D8UnE7GcuF6>xzMT)hI)#4Yz@uo{y`(VY83{7n zv;Rxbel@(%wmG0rK^u|cqd@f(hQ#LpzB!rH&H{$O#v9SY-Y3?;DYK>!xsrmGc5B>5 zH1DnnZq-JJ!i&PlgUk*lsy!rZaGf}YL32uIB*&Q=S}`P(>Pp398%C_cxKc1P9>^Y3 za7;TX80-cn?nONWPuC^URXq~My^orM{AY=4$%IL#p)ybTZ5CC#zy?bA zQq9CHqGHxm89}W0oI+sU7^(+uS~A-QqBsym3e^BB^Pv@-s)H<+*kZdtomR7Hc==vUWs zW00B=CDhX;Tvw@DlTnVVZh}lnrSxpI~oc!3DP{#-}D71 zy60c83D2HJcwuYNiB5$*zGf*M}!Nh^LNG+(%(_dNJCN^wdr zU&(7Z%8C_Uklce$Verdb!3KVkGhZCx+x@P6(#A6f*KZeA0aPj(H|z1>kXHYzrxBVd4pI&L87RM)%uC6ReO5f8&`ACWv6DVQ@1+IF8QBJ`JXSB7o zWNSI3HnL9^i%Uw)KqqO{i;lV+M`&bTAwcxtou~43J~_e(Reys3ZVkf49!g4RUJggQ z1aG?KG7{AOIF|pLW$r!zkD|gyBk{`)+mII1{JZlj?>2wDZvINh@6KKMe+d!klO<9C zO->U|iC=P5TsFyrICR(ri+QGRf&74JeO3%6a*K?<4253w`$OcXI_O(cvXm5Drj`bC z;3ojZlki24bd&qFJJ@TyceOYG$T`SpS(aHN|(kP}^jA*I(d@PrTWSu?+eH zh5A$SbO!S1i)_=t9=(VO%-@-`c|xnTxJ<0`pxb@8z=@)aY_1oJqJ>L*BD)K-0^vK0 z&}0r50^uq>w#zN}$_+a>l(&jLa0=hFA`|ow?h5{oS8ngoF=JJ)#9MCSO=Vi&rp*@g*ZKOn zdfr9?=1^~c0cCvAE4ul!VW}HBVG*b(N#+Bwl12l3ykQf{c2&H8A0{lCBsUOS&RCnd7*9^>8Jb=J9Hi@cR_QU=w%YMa99b4t(bu4dBv0md4*VU`6yiFmKpzp z`UA}1m1HtY;Aj(+z{qKz0Py@82TgQNhFa#U?Xb{?FD3GBr{ul5 z^36{_&)wyQsyOwa5cp97;>oGsyy9w;SluHz1+qVx99lOje|#?Pw{wmI8`k_YCG-*I zzu^kH#Dz)EONwo9W)3pL2S=HpXn?P_hy`xwb3F@NVrS4znOoKzb+vr@H1XHFfqCAs zt$Bb-xZB*SH;kJj{*GDn!4UintlnI^-O>Sgk8a-8QQ@z|Yy6hw0?8-=q?T?Q! zeP=BL&G0t0a>!@F(7ShUDDT|pE%Or!1OHm3`{koov~FmdMZB7nujOaXJ!05G{uCI0 zR4-ClW{hM?P;i((KB|Emcdy6)!P`x9^}e zF1dg~4)DNmseYQ$ZuEt0B^8Av>$GfdrE&R9WT_iHa|50;Uq10Hv=BhIH^SRYND}kr zz3GkfENG1zyzT@C0odgRF6KXf^0rkbJlQ1sE=X4FhBgs+fk}SQD_BZ_c_!gJ_vEzK zL7H=Z{4loqCbsTAXduUy7h1%x0RcfSRnv;ZW@6p%7Xy9R3n1Uk8_m5cksit-#1LuX(o^V^^74jRb_kl2^Nc3~$` z{`EO5cAUNd-`n6OD?zljW~h6Y#`)6?-VZD63ZK#1c$naz6mQ z&0HIwfFAGvI);V`FTBPr;Qk}qZ^B=2yjc{fVbHhZ1vCxcG-0eqm_Z5tmu>6jkpH@& zDb5W3dY51l5(GT@M%~d3AkznS_=L8?2wvfRh?Z@8j=sb}8^BwocSRCH@oTI2jS@im z;0l1{TZA7IXoU+HzCg`h_^=7zzzC89VZU&BPb6&eL1%tcO!L3yXM#|-=p{GLo5${M zrL@aMJDid!p6Q>*AfK$yqpO6u1U$}_V{(F-cM2e<zq{O~nbg~ex_lYa0t6q~qZ1DnZMaq6N;1 z3F!22LhSFug}$AwK=gr4c&wsQ(}sq~;*geStidTf64{L@Y<(Ft2zaDprM^S{oP8@tNp6x@87DT)!)JSDcZ9~P-06p?%0iCUwXM@}aL-!Y@9UKx&g}536i0rU zkVlE%ik=ud*xdeH{`e&bAQ`-6XC48oNnw?9$E%(%R?5Gd5IOE#-b}G>-o<}hNp2Ca zz%RK)*?Qq7PM%Jq>JAX^MJ5Bt?3BJmzqyqs(tNyVzc2Ic9MOKqW@v2ITp3^=zhjH& z&9+0oEqh1eC$3j(AHn9&OtY5ND)WrvidwET9awxtj+gE3dLY11M|^evRZ&_jc-mR- zSK6O0625ryrB+uYl*zZAB6oB3F^eXGd|Vkmpj;Ok-Ka7wzgdgSTDYJJ2G$t(a?!{? zWnowXp)06xGt@P~RJ3XDiN%$3c12yS2!VV@2{2E-;DRCihXG~eyD2ACRHjw{{r2sb z<{vT_O$bUZ78#StW+gOZtJJ*QHkr5Bi5s1k*?k|x#(kX*n#GxX`c)-c>7_I4GW;7B zR?#aih3{$3i`tUVZaBE%Q8CqR_h?|W^Z4G3(gA19SZ>qt_s;<9oV3ETZKUJ7UteAp zeU$1yhOx1BU3B-feMXOLdz?AkKFQhUK@`*HgtI6-KVm}cQwzTkC9*A&DvYnEBvki1 zKpZ&tXBNat2R%Vjy(xUxBvsMjHt|EEZdb(p)bO{b7gHUIb@3$~_Mk3ZWN_q<#7`0; zyzSuus3n57M(!tpbX^8v2u{-RUSTw`9OQQRn$#x%r`?uW(3rTm07W@6W=;mb^vqguI$Oj z83w>#oBD)AK@W=k{p^h_$Jn{1Ytg|V`sEH)G9XY)Uoy784cHHhcgt?)B8& zEsh1qlG&*daPaD25?+E*lvY$V!Go`gFrrh&ub&(x*|5OEF`G~iU^h~ZibKMbt{3E& z^vq22>D$&hdCiP)`$J1d8=9PIwt)_^qd~uq>ZplyP~r7d9G8h^#dRH)WIj$h68MA) z7-B1Mx^z#d%SiD_k9W!?=!%fKMyz{Ucw^5^$)X(meCzGaiVh3@n4pa4#!`w%XIaDElMS+J^DG{vc4Re1 z!x*1+!&4)?0qvS&P<|{*LedMFTE97$fq+6*eMprBJFcojeIPa21qnIpq~}jCp>LkJ z+>||TBh61lBLuU3ef=pWzD>tT3ac+q(5_>U#t0S9b-~gxR+!#NYFC8cPAu@C#A6Q; zsOxjw-vdA6ZJ<$R1aewpBcD;&4X+1{YiFX-1W+7wSncK5oz*n5#G}9o)6Rd}tb$j} z5VXa_iYZ!unHB`byCnjg(yp2eKC7VRiV`3;re^TWrT{i&KwH~9%BKX#8DK&7NWc2A zx4|;UgYD{K)vy7`&eBM@&mOb>bki4;!mvB3HZ1(KExgjO-dZFapB@HJ8I33AIIZfE zA%!Lj1g&%kFe%X>iln9Lo=XDvB*^j%ij(&Mkx$3OfvtLy3%UfY`)JO7O{}Ugd7C zHk)rmAx=+P8M$Lqs(x}x4{1i3Q+H^9dkCP{^L|NZnV+m0U`J`8@Oft0Q?A{A4Z*8A zzZVz#vd3B5*$6uTv);@Idf^3$$((W`m?hdhzYb}$icXC7$23mb5u3-t8CyNMO=cX` zE1{TIg>Xk5JnE>^wx%K>DdYzSqI%Z_n~FBML}p(Or+caPYsA9K>9U*|X(C2KifBii%Rp{F-%_9A8VkZ1wZ-Jf)?~K6u0u8OBo_aeOIn=U8yV6b8Dplz zB@rO;gb$16hGu;3LAI6n-pg>1(CQ*4s5n{Z7sxHn<#h{NysRv}bOR{LfFHV90ji&R z>`PL>cjh;luLz`Gdc{_!bt66u6#Cjp=e@g=`!`7P2%vamf%JS`_QE}T@flxTY$cFh z9_&~3EOy8`OC`}aF9|?cLt@FL?PFI+Gz@Kqh?`Qya<5e-_cHMTnaWlFKQHLDEp+x_ z(Ql)0o0Hub(6{4riV~#IAm(PTsP+#mKbb-o``Xp{T^a4WO|Hn0QfRIdR*Ku-(Om4f>n=-5&H<7bA3;*oeq-@li)sT5;Hpb*u{wc9|TisBCX@U}Sf2j(|1-g3%slVLdf03xyICXH74~{+SwvDTB`7fo%tHkq#Q*I6w z{KKsic!Gr!2W$qTu?2nsK_LsEkO?G{HloMP)=b&u2zXpoyA@&h|GN`hCEGuZbhtta z=rM@fdZ2FY|9`rtsZ9|S?nj8kSIw*t5Q4h0OQ0+@gY@!Tj)Mf>$on5%(KX5FC0hM~ zRZub10X0&f)qFMXBy?|9{IEh{_Gov%Y2f+B_vS9@7d$jMmWOo6g2_uU!~1I2)G@;v5!cx)ikTb$pyf$a*FA61;07V2Y*aaX`;1MZOHSq3brvSbVa0kFahv8{y724 zH>wMDOya02l7N672nSK6uJ+$BEXX|#Eeb4j^M(sJqss;c?V44{RHyXw&9FG&kko=o zbnHYCHY7flQ^Za!fDA1V zfKa%|_SYSdTv#JuGhNOVK-7xb}C~N3E~2z&z0=KR9J5l_>TtU zmq)-BtfbnSt_ywB6!UMH{x2&r1>8#Zoc)8b3w_qbW`GXXEM(4!xR+vaSV^-4sYe}* znPMj!JF@iGCVv#F9>`iThtag#ROaT09z;O`br;t4#-Ue!hS#^j#f*8iDoA)+=$lF$a8lnsqvV{5y9^z3?7h1M@xNv%|Qt`S2v%&89) z=8`o@MK$9n2C>wQJ6@xbAK8l&%#YS7Kgr_EGq(-D$ z5;$0jxnGe|*r5?hotuohDev_iw@>T_J#;vaV$iZCb zv5z^>Xa`y_65mxaBT=OY0#L#r97@jGe8zSr?Lrwp+Bt?BUfnWTfKXS;i{LPvDLZACRrA}9tVZYAb$|_b zwq*}8mCg{%1nF=r))FEfNt96R3R9CL)=uf{B?E%&Rj|$kO=HC0N?80;WbUa6MkAEz zwI+A%<+VYp(=QCqnXUB-)IPh|DGc>N8V^I9L9;1#9^G~CfqlWtt%dte<_us89iiy5 zMs+5_Urnmw4(8A)LX?AsD5urssfGHY{B-Qd427 zsiIje19CXTkEm1dz$`U+9zQn!aR*AUXoV}W(mu$pE&+mY=Y zJNYz|MAnQODM_;+YO=G?gnR}EPwl$(#eQqD$==32oSRaETiC_!_qJQD6W0SoSGy!m zFx6s|@?36Wz6?4QNo&JD(mY2_{Zvcsh|G#5{pVqT!SqwS>|7JAww$;c*%4M0_TH z{>4?J>M_PTYYl?qz|WGb(b>{1SZqasT+RXuJJ+Tyy-mBnp|KbjRh$P`^0f@h4JIH z#FFq-UIkjGwbXphyM^7(9KyP5Kc*ZxqqCs0>cNJEpV(c)@h zAz>E~apZM4R0rRFb5=oW$FET}QnO&pxvRMeTeK)qYH)yb zr#2#h5t<+j#}*sl70zpA3ANcK5bJz*PN}t?VzTOxup;ZH@wNWujk-}-pITF>X9Pv> z3iKd0m5sFknb8{Oy+?I0MwYotB3D2CXBf4MFDGf*8codb+U3rhRZZV(@NM4^zUx zt4^TMLL|__2=W2kg-#kPJ}`E-HGtXqpvPb8My1uRU)-{PgMopuEgrEh8MS9R>^LVF zUyZ&(Vb`wlJA`khd%jl;qEn5`!a0I}FTYYYAu{nSKW*WrciBn?!G^*1CBCoM1=RiR z9!MIg5wzLSv&n@<$ls+1we)QvY|CS7Kbnjzeb*XS6cbZz%_hN#e~v|Zu<~?1{AZn( z3JXWz^nsE)&96nffH0LE*@IZ$0pvSOiEi5MtENmZ8a4%60&3Sl%}Fi(n3uWw!C`E) z54;Iqt+FH4NWH{LTj8_i!$NFbf&SLqvh2xV*B9jOtI0 z{6C8BKA@?3{{#5TEm< z;XqO{wF9DIQB9+wF4-BNqNz=zQuEdU$;_X2m)E-1^~Ueqzx*HMobB`ZykGAht2b}x zdG~6BYSC0?#q;A?9kG^l-OY0NQiFOaU*gPo$0VDU?~4lhs_ERRxLvmhTz^8K+8(kh zs7FUp@gbS7KDy_m4*H1{5l0lnq&YO;-u>xIzr8T3vb3Dk5IvKlC(D3ku=tw|Uv-uT zwo@;fg#g0MaYbprRUn#OmaznrFJk|`SfTpYCnxK>)Wm{_(0h*rsJ|p%nPu^eH8HPX z-U-^7ISTLk-($QWa;Y3FL;&0Af zm_JSzw)q7`C2IajK69nx5Z2oENy%dl><@*@G!8!A-yD@QRyCAyQ3UO(g&Vk)Z#hn> zTJp`0aUN9tJ6Er1r3(_UY+x1?U`{wD|-#-)EvZHqYrj8k}pz8P~y>M z*H}nEJ#z_;GAV?xK7v2%ls#FwG|Ae(JvU*$R{<*vD{M|o?D~NAUrH8a2*TZ7Cy_uZ za44a_lwOP%m(~>^M^^7Ms;nH0&72ums`j2vw~odCH9ZLokdb4tsB{aq=B=(sL4Nfx zXuzk4QW{E5A8EowMHDN{8+1Ds^SQHp-8v&74O-c@0gBCXJzAzHDYs(yL*tp|*pr-t z&Q?D-lOfvL%r~y-^10T@*OGQD$MI}b#PG;5{3!Z?BamnB zEkQHjES$ZiOaB2Cw{nH0vC|y?88uLTopa{LR8Imk(kUeiNsMT0V}HV zdd^FaRbBUBx%t=I1hGdZEkXPGKcHYy-*@Ifi=LulbjAzLv^bQ`R4$xgEuYS)lO6a% zqctaF)&qW~Ai!;?Nu&9-DPExRUINJQsNtWfi7A9zdV=%vEQ0dd_s1c5hek2V$y2;{Z46qS0FZ zI?c|)q^W7ox#NyMd{)~itzF?65ur_y=2?$g=TvZHE zHH`#qvO?>OjL}M41S6pN6>GMrgCG3tcH<_4Z*K_eo%7ylFn3}rl9&q=aXn4}35hS* zL8zspUf_Ztp2E>*b8udM54zAblH{J0JU4DzxUgn*@OrZ_mX9cgxE!#W6#Sc?n9%ZALMg{l#M{!mpg!OS`f-&CEU^%?mV7^lZn z<1UZBIZOP^6Hd4n5=x(ta0-bE&N8^L|Bft^@5-7_N*_c~;x{xhi8h88_Imth<1~)j z;DT62qXj1S4AKN**y@ih-hz#6w*xRL! zEe=kZ-<+kJ%^#V4+N-(cf@@Ebbu0Uw@(ndBV`_VxNe@oJ!IaZ~jB%>@7CfeqPA2PPr>1-)&@}uB*NTp%o=gkQ(m)4d!Q*Lm}$^O zJ4H1W!mtS1Sz#zc&f(A&7gfJ#xb$R#!J{XC1siH7{eNIQ$b^DE-EG78pNm++YMy7z+95t3?PX95 zH_wCZ(40&&D)B9mRNSf0Z59*O94aZ@%-6wkvUA<5L8=w0zr=#-d!FDMhm3(ViFDXT zHk>u@+msbCJ6Yc#kt!U|)b_}u?#uz_K2F;R2}*lQf2JAQ5a(a5O+ZuE!_5?BD5->hz)oXP2%jwmlh z%3T?fVSz0v zzTPNZbQ_I9+3*H0ja#@MbD#dI3Ej(Q5br{}nt5d79t%%1jp9KNDlD$nz0To*nPtKS z24~=3tLrtrABB=Wi|D?$)gLvZduld^EV9Gj9zD4=Z0Mq{tH2SJ<5*NqUlGl>!v#l1 zkiQIODQ)MhtT~Ho!9O09}4&&ol@*0YIjTDU@Xb}U49P9 z;5eIs5qzD_0*jcR&S)&iG*3o+v$Po~R2E?c9W!K}rE>fa^6N9tGFp%a>ryEyL95kmNUGRiJ&o0{a4jqBeqB7D4fUQE8C=K%=f!20fa`!!<%dbBSSstp zZD7=x!ibu_$L`5 zh7pw}gU_u(21lT=b!Nv#N?~$H2m;apzqNiOZ*!s)@8yL~IO2~uMW`7JJ23Zo9=-~| zM`MqSC?%w+f~&n<#=Tk8xQ8x5&vt)Gdu&4a-Bv&n;wuyHew zi3(I1#9B7eN85`=vmN|19ftcuHg-EB%W2-k6y)Dth(QW`6sdB~#1%mascgKJp5ub? zw2|;CT2nEq={5_;%?bG)tl96&)2s;3$bm-`dWU~s>3WKKb^B%iB6HF%hq#MPyG<)> zz}cb2Ol;aUI<^SWX(_eQ5}eM)v)P$d&Y+6AUGwM=K;zmRhbjYp%qsd&P~+50K*4%8 zxH>>}nF?@0WU*yIZCzlkW%7zM=`t)R_dvLltgVwUK*qP&*N#SVuM(7^@alBrW6!Z7 zv&jk-JUpnmOhuu+qIx=>lLd8qbi?L=Hjl9R()J|JOgYe%LqRUjR~IRXy>wmgn&(88 z4<68KPO0x@!T6CrGjE6y&Y8uJJ?_)Afp(-(W?3())IzCVX-<_TtdBQ7zv9FFbUJwb zG@lwc8eGK_-#~S{;hh{uwcfFUHS?85wW|SJQOBz)6!|jf<6bFpwO&cA)e;7G{)pv+BuS@U2UxOY}PvB4Xm;s+HW@hYoSB@fGX=8;rFt$ z{;FIceJiT`iyzw92&T?dbzJqBl4z*=?>hXMHBHRx%PZ*k2}kG+=%Cp0k*_!R8w%Gt zgae)u3(IWRy|GRH^juw11q7$mb&WuR8;&H~3Ki)=`BAMKgY2-PhLudPA8d1CbiZ_b zRHbr65jWFR1#4c4fr}}gQxj<5uuNy;Jdf3Z&Y<;FI0~Q#W0=NSoBYMxr+33mJ%(mT zyq-$D?CiTzpu0>bH^V0}AO|cj*GYX#-%n=)ik-)Hc~p;`;%f7p0a%yLzV??VoOb|C zj#w4l03kvXEWF`N7;v^9bH2FBf7>okB*i|t3_Y9rLsGq204Uw`8~iVG{cS5C3npWo zDa}ie6gp5JEjC1l*^UNkDTEiq(nlh1IBI$*bP)FMqQbg?#9HE~sS3#HK*l{G6Bb8&RnHU6Ro>};CDAX~W}6 z#l{OuomAPSNWXN7{S1KNH%Bkh{7V6P43w8C{&HbP@p{K*k9?R$x;-$jGHYnU;DN^L zAU>|u?2zJh+Tn>W(;TTaz<`gQYw1_4b@Udq(B<-38aABuqz%@gHvn;)o((d-_$*_= zfRog+i0#)js_Q>h&eZ%1ng^?N_JCH=x=%*3k~Cnpk&>absE7?QvNKqJMu=vqzRHZS zX0>6&*4Y<&@7*~*N_x}-GDo*0CzN8*T4q#pTpN!<>DlYe)cL9Py@ddL=i_UV7Ti;DHr$z2?yZuH>Vc)ZbVn< z6vK}6VLGs{63Mx#p*%v`5_;rNWSOquGc**qq!XyIC3rtP@29qk_hvhi;(JKMkrqf%hTCbR!t~en;mK& zUwE}d4YUGHT~gbU1ScDmNyiRYkbzN2z6%{L_ZgC9V`gPvl)=p__EXo1uyB(L~yH#N+8D*P<{x#pLeQd;_H>SQQNXy21 zKNzx@Zzh7n>wx%~5y=3YrIa2h$VaNEj^jV0=5UKb*9@fJmv}326Sv_adxBfvf6Z6#R1Kwep@1p>${YFkAGQ>$zLz$y9pc(dIeb&Zs^rn{}j5dn83r$(IiA z*2%!etM8KLUGJD@4SJRx`^i6j#P!-#s0 z%}%T;MWI4wmwTe5L9t`rx#hHO*f}%b{dXk>cy8^8@>P#$ z$eAYHC)Qr(AI=dx{GAST15Wh=3o4}|Os9!#>X8j#_PQwVve30aiJJWkbQ*3B)v!aZ zw~p@6ft(A$x8E*@z^)1NmmkHT_^9e>hV~KlZ|vhw3ydCgZe^*IOO6(+JP>b-H|Gjz zXZVe)i!YBLwiE4V&4ERZ;}(@D~5vN2h*N zx;%kZo;15BqSg~Q4D(X=k?`!mK1f>y?Sy{Wv;2QX=}nO%e1b9=Xt@51hkv7ztd1Sw z4%Iz)hSad1)R-%}3Wcqf+W(^Ar5<&C&LGR7Pju5YU$cKLbqFCSgljQFNtNE9xm-+9{T# zC#}DCq2-H5Gh)5t+#Gp ztY6K83~$_d5Sdz1TJhtk3KspH$bSS$56U9*QOA?Po>zl&3lAGlo%VP_Viq#Sd1pSl zetOOlpf@x&R-Morm!CFd-u*(Zs-cR3r+#T;F_~OpR9Wn!ByTCwPFQ4LT@k`v0v+>z0xo_RWCt23_pqaIFPw3BWt*VeEH z3u%_cpzk*eyqU($_mA$;<89d6RSHJ6?LFIAW9*I>GwO--6o>Q`RStV33KT~;YATD5 zYX)&*LtU&I&wh1T33Z`e6=BjVRXIuZE$pq*h|bVU26+AjJcAZ}5e<2i1h`3$EK#rd zu`{$gjgh^QYhql1w;gxrl8iOGDSMwo_5`2Aw=0W#1@q$g>M6gy z#AtZhs+(o4&kXbLkHFnr&xJL?8sXgg54s~>UGWjnbs%T0kV`#=-<8d~XJrowju{-r zB%GvVa2&}rZB~PxuHZ@5XMEaRtzb>e`*$2n<Gf5ghsb zX|r1Ty@#Rk!W@rF)fRO^nyxu5K*BYozh>_}C|dU7+MCnOag}y(G+0T)03PXgbj7mF zog#H{&2g74ZeCC8{6>~ZMt6M3`CHJ|K51Yo@37tDOA#7wyzTgh3lFL7VQNK=_gQLoW zraH@TL{N3wh;lCr zq`xB)n|l4DDKz#mDXlDqQ6*QuAf**n96y4hwtbx+NM8H_rA5^U1cj@U<{qM=pf30ujxUv_MPJ=?sE1AM2woPDRUza%Zk+WAWm^~U$G%q3ylaqA zO6(bdV+C~pWw1anlO=m%M_1;WvD+(eMlUx5zcdatcbma__831_mA){JG!!f8mFOh; znF;zbjzD9F9dc{hMx3-asRxokL-+p)j``}h449u;*WENb+b0V{uRYt>FBOxeqKwP$ z1_k+EBd@>K7^v4l!6c3K*&2b>BYMwAW6OViKbb%8E72@L`Z}aUFO;}_XxaBWOr`%g7d^89 zI$BJU3UyAVxYpPHUp0*-#<3kmps7EHL@NJY(0-MsRpCIs#(gb5%nSA~Qn93;Dmg~h z&7tNY$sc#rWgUwEp1voI`$ud@YO{l`eOS_>yZhq|E$<5;%zIDNdd+i!1p z!c#UkGEJG@7BFxeDt~w`@QfEkm9s*sLJ&5PG=m~F|0lg_$bvpP2}hRtMY|wrjHYKG&(^dX zr(o(1xlVv1PAf9;<+@dyd+r-Z)VHP|y8Qlk1znZAAPR3ixicl!5j@q$=4g^l!Q3jZV< zJLmmhKrRbPveIFG^a{C5{F!*Wb36Y?e2%D(=mO3qLuC^=hI`S81RdQqif*vON}#I` zf3Z|J*qs>{!BYo?OsT@24PiV-J4T1p)X-{_hG-9tG5r5H-j2@L&O%gVwl2hbzp*C3X)mk;5nG7Q_a5wZ@O$+3wnRKpfZ~M$r*>*O5W9zpZ^sBqqdxb zE8x6s$|-91AhmqG1C|4ykAk~wNI41hqT;=j4D^U=R>;nn<$0VRcE?{m$=i3bfl}e+ zDy?#K)ow0ikPGRiiqAUWB6{J|$%Q%3BlUn#Ggvu*-!nk(HG{jP=uvj!lM@e$X;7rw zNK)6An`LqIVurnw`~^>CEJ|U9QosvGZ2wZ)Cc2_U6O332h+JA*L|eW&zVLxfwvJRL zmImrsrO^|c^LDV$rp)nZc6);DsDNLl0qB!Ukci}v?-^M;qaE~Yh^DanG+_mTh*HTS zousy2i1&o{n$_cd;QwZ1NLvIZ2FR@~Gvnptv$|l6#xPDAVFPO;Pn0=Ci5_K@P8j@) z_&rise#HnNT1UbZgFe;CP;W?ynfLJ& zKc2X2sPn=;SXBlWWgQ{846E+}Xg&3yY`IM~ChkL28RXw3+d!%Peg=i1Ds0UwV z77a27j7(^KgJ^z4(kipyJ}m{MYIUjNR$ClA!Q%j}CF8996xPw-EYLJre2s=_#do(ruPqqiJ?yseX+pPZs0aMF1Pgoz^M z$>r&h6g)@^4W!?}p7oav6YUhPW|4B6Xo7rn+oo0}DZvT}?g@ViH70|1?lwlEn*!{} zz#<1ZKTavO1?D&so|{xW^@JM6ATRT~mlLH5wQV>^b%0DhSIY=H9fIYwVC}U#tFj;S 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 I0Uyl#KbmO#1poj5 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/red-illo-vintage-scarlet.gif b/public/images/skins/textures/tiles/red-illo-vintage-scarlet.gif new file mode 100755 index 0000000000000000000000000000000000000000..b02b168d7b1d38f311ee3ca32e7f31ec3b63fee7 GIT binary patch literal 93867 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

        ``)wqK6v%oOl=%ZVUtiy*Z-BAJSjoLfo(|rc_ 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 =uqyeq~u z=;>UNHlp_0iD&(!j zr+qfxjMrprwX_R%rqy$2#hbdzRl^!2apN7$iI@&5DJgl>-V^dQWcQhfo~Y3fgJZVF zo{)+TY3DdU?$7-;D?H}7VXKH>+%Z^aYO#D|5YrYqWs!PyXJ@nTFN12j4XO86IyWY3 zo_=HZ`pxE^uF{}>Kvf=}c&62*=dMb@!rlYmMb=sy03>y#8z4MzjVjB;Za%0TCy`5?)DKgLhA~HE> zli_=s)FM*d%%WlWu+^LRLca_a)?-~S_ol7!ewj$Vr9JXZErVBY zeR-24e+#?$P(ukjwW&R^v{xa+?Jy{$Nr|4O444#Ae*XEDnmV{2tQ5?3$FgSvqR1Y&jcfe&$QX z9Syh2V+?d*k1SBE$&-i<+F;{DHz1kq%GAxzSXDx&eAy4QF_A2Jg)PJr8eADU z@XYGt>CQui$7BnsX`4-sk~YkgwQQad994w#9xR&3FXMbzu2d^{xY?(S7;QVGjDhwP z`|XbHk&RwOezb*7Wz(AkrwlD%77}RE6BM>%DM+XDJ7;WK65ltSIhU9etU}TD_!7cZ zA*ATV^&^`p;K_myj#)>13l z|CI}*EVzM~Z9y0I)ARq6wsJDGFq$6ia?0i-Nj>vXlhz9i literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/transp-dot.gif b/public/images/skins/textures/tiles/transp-dot.gif new file mode 100755 index 0000000000000000000000000000000000000000..1edaec5fa88a1984a5857c7cd793ec48ae4b7026 GIT binary patch literal 70 zcmZ?wbhEHbWMyDwSj5J_#>U3Y&6Aapm!6va@y$;L28J*1{{TtFpDc_F3~UTKKsHb% WD+2>Fcg8NEq$M6nY!cb34AuZp<`3}z literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/transp-notebook-spiral-x.png b/public/images/skins/textures/tiles/transp-notebook-spiral-x.png new file mode 100755 index 0000000000000000000000000000000000000000..3b955182214332eef37f728d24e7140260b28664 GIT binary patch literal 50183 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%0AQcEu6SE9d)K>^e#263O=HOzG=U}Qr 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

        $^6hRTqb*e+xs5NZgsxQV0USlhe7mY(nAn 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/white-graph-paper.jpg b/public/images/skins/textures/tiles/white-graph-paper.jpg new file mode 100755 index 0000000000000000000000000000000000000000..ad0874d474360b59049c42ab676c9ac7aabfabf8 GIT binary patch literal 62301 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℞0qorBYZe2alx1)QLO*pJ}uj9#0zhqyM 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 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/white-lined.jpg b/public/images/skins/textures/tiles/white-lined.jpg new file mode 100755 index 0000000000000000000000000000000000000000..95f2b2fc4dfd8d5b750dd5dfa84a698e3b09ac13 GIT binary patch literal 3014 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 LF!zHzeQM}G2SA$% literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/yellow-leaves.jpg b/public/images/skins/textures/tiles/yellow-leaves.jpg new file mode 100755 index 0000000000000000000000000000000000000000..3e979e257c03a9c7d0af400a5f4df6dfcd982331 GIT binary patch literal 76306 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

        I)!S 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

        gjGK?3{YP)~ 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 Qs&y3|PlsJK8VFhc*-rifssI20 literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/yellow-postit.jpg b/public/images/skins/textures/tiles/yellow-postit.jpg new file mode 100755 index 0000000000000000000000000000000000000000..15d8720002c41b522adb14db288dc79c624e487f GIT binary patch literal 3699 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 XG+{{VZWennM=dt&7>rFEg+KBS^YFI& literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/yellow-thick-card.jpg b/public/images/skins/textures/tiles/yellow-thick-card.jpg new file mode 100755 index 0000000000000000000000000000000000000000..7e5e4dfdab44b00137e366d7f330f1cd5effbd5e GIT binary patch literal 31086 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 dgo&&28FiZn6vqdefgjqe!G2M|Jj~OB_{v? literal 0 HcmV?d00001 diff --git a/public/images/skins/textures/tiles/yellow-watercolour-paper.jpg b/public/images/skins/textures/tiles/yellow-watercolour-paper.jpg new file mode 100755 index 0000000000000000000000000000000000000000..f3ade5344304f056a59808208574d1437022d418 GIT binary patch literal 31186 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 ISy7Y!*}doS_y7O^ literal 0 HcmV?d00001 diff --git a/public/images/unused/bluesymbol.png b/public/images/unused/bluesymbol.png new file mode 100755 index 0000000000000000000000000000000000000000..73fa0d922b18eef3daa17e482738e243f7ef04fb GIT binary patch literal 508 zcmV&%ghj-*tX7$57gKdvEva``hnt-`~Ek_w~MguNJuH-Z^*9Z_b&SHr~FaaXLR| zr?qQNGcyx{J9EzOIKMMLGjr;lIiGfF&d!;3W)3rRnw^Gl%`v|-zxn;lRKqy-jA6`} zF$@4O?#wXF%$zyLz6{e$Gsc)PV|Ks*a7ih)ts?D+P$?Qv5OUkhYWFi|RBuz8(oz&# zN-*T^zB2m9`oHLmHFYJ~NsIVyHzmg`pva3p!^U1X6(31D)_np0000g^he#9vuH!9{p6{_3pUx zL9}Ceqlu2HbP0l+XkKr0Qzm literal 0 HcmV?d00001 diff --git a/public/images/unused/indicator.gif b/public/images/unused/indicator.gif new file mode 100755 index 0000000000000000000000000000000000000000..915c1984cb8541c40f28762a09970b6578632aa3 GIT binary patch literal 3897 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 literal 0 HcmV?d00001 diff --git a/public/images/unused/rails.png b/public/images/unused/rails.png new file mode 100755 index 0000000000000000000000000000000000000000..43651b1b47bcab48fb1a2c63acf8be0406dd59b5 GIT binary patch literal 6447 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 JPDHLkV1n8CNSOct literal 0 HcmV?d00001 diff --git a/public/images/unused/skin_preview_none.png b/public/images/unused/skin_preview_none.png new file mode 100755 index 0000000000000000000000000000000000000000..7df36f3a3f2d3b2539a80b6d9c94beeb379084b0 GIT binary patch literal 7515 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 literal 0 HcmV?d00001 diff --git a/public/images/unused/spinner.gif b/public/images/unused/spinner.gif new file mode 100755 index 0000000000000000000000000000000000000000..878eb61f7c3faf99763f45b1fd5ff49c39046821 GIT binary patch literal 1456 zcmb`GZA?>F7=VvZ#5+)^j@mLN)ZIENj@F_Mr{ef3C{WQlL8M5xvMEfA1OkDmpXbkWp69%8 z*fFvHLAfh%1xo;|uC9v3;#aR;)z{ZoS69Dy@nU#*czSxerKN?sudAyY8X8JYPR`BE zeg6Ep$z*D1Xn6VZWmQ#GTwGjFPfuH0+rx(smzI`RR#w{E+sDSnGBYzJ5{Xu;ot>S1 z_Uzffz<@%bxOC}KR#w*JwY4=SCMGE<3CHp9@bK%`uaAz7rlzJ6 z1Q8n>ySTVGH8s`T+&n)&|Mcn8^z?MI*_@b|D3i&$y1GhBOLKB^Qc_Zii;E{FCahMg zTrSt^^%)r%5W=XasECM&?(XgJ4z5fWNH{i9xSI1KHLr196fa0 zyzPC@n{0B+yAC%=yG<^}oAyO+CV;9d5msk6aCpacd#Ckrjj2(?##pibi&G0 z4_b5Iyk~?8hO2aVg|fWsopSNMPw9`zzSIsp&uf+!F6^nzaotdB8v*APYjO~d9e$;rM)aH@-E z8SH(_x3lH1$x|AbS_AA6#0~Ja?$$6NL&y3w5ZM)qF*)otC;tGQSbbNsBPe)Z7)i;8 zG&a)73Q;5A>b%>{&N{vsqaxj~7=I)OVZ{(+b8e}}0s8Z>g=ey^%iG(+zoO-FLJ4_1 z6~@F+6ofcQPT>@ja5;vYB<>L5$4^MLgs0Hq9zjO}yh1Hqso{Z2(Byv~Qdw&6i=$oi zO4kS^QkYjtaGQ|*xAP0#B9YS~tp-M&oM>0R6=&G8*Tikvc?88(vN<~Zmg+lgxgJtg z)P>r=quf(5YFHI(B`T;{BFZqIGqGpd;Eh{!h0g+N#P}UC^1vJ(WG^DX2k0(Od&Y(jW+ZvjqQ{)GFL37XJ+L79JRJ}uTnFhzEcFkX<4td^kG cqaLsP9!k$kLvEMC-wSm8v$^09z29r+FAfI&8UO$Q literal 0 HcmV?d00001 diff --git a/public/images/unused/wig.png b/public/images/unused/wig.png new file mode 100755 index 0000000000000000000000000000000000000000..913bee63eb8ec6a6b45eb30c88dcce9b31a66114 GIT binary patch literal 5873 zcmVdf&cvid2ewlbev?=B>JG?G17eE}hz*D>HXt@2wi0YWY_S2c0kOpf#0CTz7Z+D+nc#FfE(i;A zG~lNlauaeF(ie&I)2+_c^Vmkgxi4B{gbYgtN9U8_C3ff1%MWSJcqQm0jd3`AV39c3XF3AiH?re zA|fJuwf`G(QKJKbqGFKN%@B|rUy2V23DII>W3|xGQ0=0yFf9p@<53|Yr+Kp01^{lq z;Rda6@nY@87hlwN?cS}u^Ugb3NlA&;r%xa2{hsjWz8VaW@o{nGQ=HC|)1A(J)11!r z{Cmtqr?YdA19A&;+6qQ;aq-u3g&U!-uu|@4w#)%GgE)1m*Xi<#JUl@OTa`^mw%SZnu_$WVl>^ z0icXYPG`3u10){#$d`4rZQEAs)Txu!y?b}MvozL-R|%_kEd6G$CJIp~MF)6qvP<$P~;)*M@E?v5qk9}^>CRQ5YY;abRePj{VFdn*V?sfS9=$RRgD@oO53?} zr*`AbH~VTcJ1FxIg8$&<@$tKh8N7hAR0rk=z+~gfJShza$h9GgE%{SwPEL+Ce*E~e z-~HqlUKu`oxYr`g$E1B(MTK_YzyWQ@C6{P%Rj=7$roeSb6Ru{`ZiFO_toOt)+vSSM z_jqPvDMw2Z61>1H(OuaG#F!EHqxcj*fFzv@h#bgAmLn0>xvP+B{C=A@ZM5f}drot~ zmgIZKjvck@uDi}JAjQSS+PZb?&N<$d`#d>dfc8XEk~ShH#+vb89ta?O+8F;v4}AdQ zKOsdLY*ym%=myEuXSiGv{JR0f(_$@a0A>|`7wN(OX()3ys~Z!bE)72?&l+bM^hQ5m z#9G}|xJ8j;$BxzV^YhPs&&(;G*P^|1*#gz6SPa$&)3JTuYyLazvlumk!m7;jZiiCtw zrD_c2$m1`vQc|D48g~r)*QKCM6_j9n!MVi;H3b zlXPndBVWlDiY%ar2qWXzG0b)*))F?6wxeQW9Uf++`V6%IBC|fkTC)l<19VPW4*=Q#X|A#xW@?{bb>HgF`%DR8UA0$ zZsp1@^x^(w(Q32Yt6#r5H#b+i@4ox0Tr2cin9-k! zBbSATTkrcQ;v5ha)fIRB_5;-ZWNf(OUx;g01?75(#0mm$C;$|!RG^3yD~e3aSq(*Y zUZ~IVbu}e!qM&KaLSZfL(9knj%zFVQePVI@ZcRIgi92(^%Z44lX>y{Z3vSSZ%GWZ0G6jtAd}h~|{URe*DmUdihTb$>@EVp~v zIu-LORNQkZ>e~r0iqxdoL?4Kk=2FhgpkGs`w)F;<@da@t5-agiW9V-?T+ds@rnqA8 z{(Bf;grCy6hvTw%Cay%a-w%im71)paQSx?`hnPRTkPj^}=2hg@LDA6;>U8^s5z3?y zE6C=V(ykqGXSo7HEJG$*WMyB4ltczQAWm4yH{>8Yse5@#EyBPgL4;)`u->x0NP$wO z+{2@4pz&496<&#D@PnbC8xYFy1>*GV_5LI$z{P#jZLrfvj#6d#M_ zY&C;Yrd$EXwe}V!B(qW6mdxJuMt+l!@IKFoy|A)iDF8TYQ$m&ts5=QGjE2JQljUn6 z9AzqCQ+xB4X{2BBTnXeCSM6JBv)Bg2isBt)?y{gY4_D*OO{@$IWkyhR+qlXCip)as z-N`=6=dd#G%q>$jr=^r90M~IvM1&)zYK_dBc(ws7DQI5KdGZPG_h{O=5dyS>#LwF| z`ctANkoUggmayhiV{xPMymIBjt|kvM_2-@QbybZ92!oj?{ulGVlQ`myAAV?Y2!O3! zX#vHE6@9BJ;B0WOFfp}<-0p{@$SEb6n^3U0pCSCE79|tIn-du#Zu1`6-HXWgiTbeu ztiv0l4C25fIYs|Yl$$K~4@?GAUxb8Q(`+`%5zwE(Crc7|HEzH$(FY*PlKg^Fp@6v= zKW+wPkR_JLb>upm$o`Y2D85m8)^HjDi_Y^>=OP!MM<;r3OtmvwQ zBd0m-T#O;3{({(X96&CBSvjg(;!V*j#v!>rKrv|U?@WtDvf&L^=XD`vrm_sjzQEtl z3}6$6oKK_O=QH)SinCzIJ?X1PU%WA6of1p=WKCT&@}>eL8CG?M`0*)#M5il;H7+nv zHdsL^H@OU>$jG{iwuL&=I#Z%4RC=*q#QYv6_X_u0F-6~7Hg%HzSH8c@aXByTyzPq> z7!oV)j*UGvmgg82D93(Z)m0TXyS=^4zI!B~lUct6DBki(AbCrQ?!Llt51Uu{0p*X( z-Y}({I{>BJlu;W+%p!d)Ld#Pd|3vY#)nEB8#|zb-fYQomoE{hzwWn7^#IXu>Pq7dv zyX@VPYV-?gsi667w#I)K<>*DXQY+;RfSm~_Q7G;yD=5Z{<^Ec@?$7rRi;0;=0r1^5 zrXz;ry9QeL2AU%7wwa zq`y)!F~=);jxaGvZfP%X0DOr{djmk11LPgtJE=JU(q7_6o<6w65-3ya5I=m0#33y2 zp2DhB)e6doDEuIbJDs7FF3Of-r6^pMj%B%Zg<6AIRSokpSlTMpewkW&&eONfYV_qB z0ImR>-vlin%*^2`e#k)Y79T#jo&XuAHczmIorZGG_yeU-DQ=lkx}oe+i^6LwYb{iI zg?bJ#=@+b5tR^<-0KtsQa&+1#b)a8WSHr4<#Nmd9;Q}AW5>BsHOvsng)}E*G1C>(K zBw+IW*L2ehO~C+24721D$%N_TA!cZdRA9%SKM?W`$~-LX;0)!43QWPbz6BuPN6~wb zy~uv#Ao4B8PgiF>tMu)&8-oTA+*Q9B`uc|`Yim6O^!@;`i5PTD;=x=Mc*RxtqQC*j zPh9gJ%H2l)W;1El@b`=*Zv2(wk+@t*HVuhjENwZ~l}R=T%YP7e{4&>`w8k8XM30<;F& z975@@`m-K6Mt?p4DTNGy&7$v-EZ+dBqPAMXXt_UJC~?U5vqDn(bRy1q0qM# zyAnm_O%jds#+CWF^SjSCPE#xRhHbh5w%2-Y&CNdci#Lq(~1y7?bxkeAJ=zMyy$ zX8(E}fcTn0KZ0^^2ZTf^`bk|XTNM_Wsfi?j`-=U5Qmn5iPC(&3W~j{!=B%H7Up1$8 zh0u0PsE@PNE*166V~pjJrUWDc%B@CueUZC;qu6l9oN!d~Ufc$DgV6N#G&b>sN zu?#e6i7F8CJTC~Tm75fdLSz>J{%W-!P4Z)$O0Q&A(zzQJs-P${2~b`Y z>v>RR)q095$B*BZnnsSRwkPAa8-#yzr@`F~~=fu>*SkES!0nUWLD zQR7&l>SOA@KhyVe#^!F);-bU@l=bsG#Z>6j3!+Q{Y$6s>$V@w#rQ*a&^~$sltN4LI ztzmGz#4X7T&8np}RJU0oRe!Z^&5D}yn6K%3qQCgT#LCT9FXfb;TM;gA^71>K45yQC z%~Cv`PX5H~PDc5INwyA}-IJdP#PPhs5)agT;&3T{&#H7)RaVw~0CAe{vdbe`Vnl8u1L0!{ z_+}=}3Cj}jF=lwzKFmlXs+Sm`i*il%SvQDR)4>SJB@jhXd><%e_6r;OOi zMBLV3fbj6{bogkFrQBeVBXlGalZ{)X@`!2m%$n*e$WK&j9BGvlTPn_R=L3ic_v>ve zEh7hTU19YO2oH8MfIUKS%_U}wRY;t;R08%KmC&7U9?@9fsK2r^{s6J9V{ImoRaab_ zoUPs|ktGORduY7^B4u@4&1Q)kdA{SuevaKL3E_MduqQVIAbiAwtJJFr@AJ3w#9EZ! z&BA>aX6YLQMOVf3?y^wq4XLKryiBg@IF^!2@N(v>eX&!6C{EOc76Zh{JblmAVZ6cU zNdZhOi>?Mq!7*1~F+GX&tam`@=-rv;uByrUbRYFQzh3t=u^C#0pW4?QFs|A%DB z2Kj{Sd~A_Y4Iun&$@wg)WUJRN#5(3S2<-)smYCq%%XC1#!zv!YKSmhmr~E$v!uktF zBz~6z$P-H{f2UY>Cq9b@SO{qM5*vRvQ3q-UR`jU6wr7-z6c|PFYD0tNA6XUzQpWfM8ezY7#NqVxyV&#>pHGSLFHJr(!;AL%mn~4oC&!S3;1v3LrBaatl%TO#hU=J2Dy{(PW%6$vi}b%TWmmVKy0xAvBd_& z2E-N{5E~F%Y(Q*4Y_S2c0kOpf#1', {'id': 'modal-bg'}).addClass('modal-closer'), + _loadingDiv = $('

        ').addClass('loading'), + _wrapDiv = $('
        ', {'id': 'modal-wrap'}).addClass('modal-closer'), + _modalDiv = $('
        ', {'id': 'modal'}), + _contentDiv = $('
        ').addClass('content userstuff'), + _closeButton = $('').addClass('action modal-closer') + .click(function(event) { event.preventDefault(); }) + .attr('href', '#') + .text('Close'), + _title = $('').addClass('title'), + _tallHeight, + _mobile = (function(uastring) { // detectmobilebrowsers.com (added ipad to regex) + return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(ad|hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(uastring) || + /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(uastring.substr(0,4)); + })(navigator.userAgent||navigator.vendor||window.opera), + _mobileScrollTop = -1, // for returning to previous page scroll position after closing modal + _scrollbarWidth = _mobile ? 0 : (function() { // used as a margin when scrollbar is hidden + var inner = $('

        ').css({'width': '100%', 'height': 200}), + outer = $('

        ').css({ + 'height': 150, + 'left': 0, + 'overflow': 'hidden', + 'top': 0, + 'visibility': 'hidden', + 'width': 200 + }).append(inner).appendTo($('body')), + w1 = inner[0].offsetWidth, + w2; + + outer.css('overflow', 'scroll'); + w2 = inner[0].offsetWidth; + if (w1 == w2) w2 = outer[0].clientWidth; + + outer.remove(); + return (w1 - w2); + })(), + _keyboard; + + function _toggleScroll(on) { + if (_mobile) { return; } + $('body').css({ + 'margin-right': on ? '' : _scrollbarWidth, + 'overflow': on ? '' : 'hidden', + 'height': on ? '' : _bgDiv.height() + }); + } + + function _calcSize() { + var img, scaledHeight, maxHeight, + hidden = !_modalDiv.is(':visible'); + + if (_mobile && _mobileScrollTop < 0) { + _mobileScrollTop = $(window).scrollTop(); + } + + if (hidden) { _modalDiv.css('opacity', 0).show(); } + + _modalDiv.removeClass('tall'); + + if (_modalDiv.hasClass('img')) { + img = _contentDiv.children('img').first(); + + _modalDiv.toggleClass('tall', _modalDiv.height() >= 0.95*_bgDiv.height()); + } else if (!_mobile) { + scaledHeight = _bgDiv.height()*_tallHeight.scale; + maxHeight = Math.min(scaledHeight, _tallHeight.max); + + _modalDiv.toggleClass('tall', (!maxHeight || _modalDiv[0].scrollHeight > maxHeight)); + } + + if (hidden) { _modalDiv.hide().css('opacity', ''); } + + if (_mobile) { + _wrapDiv.css('top', _mobileScrollTop); + } else { + _wrapDiv.css('top', $(window).scrollTop()); + } + } + + function _setContent(content, title) { + _loading = false; + + _contentDiv.empty(); + if (content instanceof $) { _contentDiv.append(content); } + else { _contentDiv.html(content); } + + title = (title instanceof $) ? title : $('').addClass('title').text(title || ''); + _title.replaceWith(title); + _title = title; + + if (!_contentDiv.is(':empty')) { + _calcSize(); + + if (!_contentDiv.is(':visible')) { + _keyboard.toggleHandlers(true); + _loadingDiv.hide(); + _modalDiv.fadeIn(function() { + _contentDiv.focus(); + }); + } + } + } + + function _show(href, title) { + _modalDiv.hide(); + _wrapDiv.show(); + if ($.support.opacity) { _bgDiv.add(_loadingDiv).fadeIn(); } + else { _bgDiv.add(_loadingDiv).show(); } + + _toggleScroll(false); + + _loading = true; + + if (href.indexOf('#') === 0) { + _setContent($(href).html(), title || ''); + } else if (href.indexOf('.jpg') == href.length-'.jpg'.length || + href.indexOf('.gif') == href.length-'.gif'.length || + href.indexOf('.bmp') == href.length-'.bmp'.length || + href.indexOf('.png') == href.length-'.png'.length) { + + _modalDiv.addClass('img'); + + var img = $('').appendTo($('body')).attr('src', href), + imgLoad = function() { + + var srcLink = $('').addClass('title') + .attr({'href': href, 'title': 'View original', 'target': '_blank'}) + .text(title || + (href.indexOf('/') != -1 ? href.substring(href.lastIndexOf('/')+1) : href) + ).css('text-decoration', 'underline'); + + img.remove(); + if (!_loading) { return; } + + if (title) { img.attr('alt', title); } + + _setContent(img[0], srcLink); + }; + + if (img[0].complete) { imgLoad(); } + else { img.load(imgLoad); } + } else { + $.ajax({ + url: href, + success: function(data) { + if (!_loading) { return; } + _setContent(data, title); + } + }); + } + } + + function _hide() { + _loading = false; + _title.text(''); + + _keyboard.toggleHandlers(false); + + _wrapDiv.fadeOut(function() { + _setContent(''); + _toggleScroll(true); + _modalDiv.css('width', '').removeClass('tall img'); + if (_mobile && _mobileScrollTop >= 0) { + $('html, body').animate({'scrollTop': _mobileScrollTop}, 'fast'); + _mobileScrollTop = -1; + } + }); + + if ($.support.opacity) { _bgDiv.fadeOut(); } + else { _bgDiv.hide(); } + } + + function _addLink(elements) { + elements.each(function() { + var img = $(this).is('img') ? $(this).removeClass('modal') : false, + a = !img ? $(this) : $('') + .css('border', 'none') + .attr({ + 'title': (img.attr('title') || img.attr('alt')), + 'href': img.attr('src') + }).replaceAll(img) + .append(img); + + a.addClass('modal modal-attached') + .attr('aria-controls', 'modal') + .filter(function() { + return $(this).closest('.userstuff').length === 0; + }).click(function(event){ + _show($(this).attr('href'), $(this).attr('title')); + event.preventDefault(); + }); + + // if link refers to in-page modal content, find it and hide it + if (a.attr('href').indexOf('#') === 0) { + $(a.attr('href')).hide(); + } + }); + } + + // add modal elements to page + $('body').append( + _bgDiv.append(_loadingDiv), + _wrapDiv.append( + _modalDiv.append( + _contentDiv, + $('
        ').addClass('footer') + .append( + _title, + _closeButton + ) + ).trap() + ) + ); + + // find the height scale and max-height of modal windows whose content is taller than the viewport + // values should come from the css ruleset for #modal.tall + _tallHeight = _mobile ? null : (function() { + var heights = {}, modalDiv = _modalDiv.clone(); + + modalDiv.css('margin-top', 9001).addClass('tall').appendTo(_bgDiv); + heights.scale = !modalDiv.height() ? 0.8 : parseInt(modalDiv.css('height'))/100; + heights.max = parseInt(modalDiv.css('max-height')); + + modalDiv.remove(); + return heights; + })(); + + // enable exit controls + $('body').click(function(event) { + if ($(event.target).hasClass('modal-closer') || + (_modalDiv.hasClass('img') && $(event.target).hasClass('content'))) { + _hide(); + } + }); + + // recalculate modal size on viewport resize + $(window).resize(function() { + if (_modalDiv.is(':visible')) { _calcSize(); } + }); + + // set up keyboard handling + _keyboard = (function() { + var scrollValues = { + 38: -20, // up arrow + 40: 20, // down arrow + 33: -200, // page up + 34: 200 // page down + }, + tabbed = false, + handlers = { + 'keydown': function(event) { + if (scrollValues[event.which]) { + _contentDiv[0].scrollTop += scrollValues[event.which]; + event.preventDefault(); + } else if (_modalDiv.is(':visible')) { + var target = event.target, + tag = target.tagName.toLowerCase(), + escKey = event.which == 27, + enterKey = event.which == 13, + targetIsInput = /^(input|textarea|a|button)$/.test(tag), + // ignore enter keypresses on links & inputs + targetInModal = !!$(target).closest('#modal')[0]; + + if (escKey || enterKey && (!targetInModal || !targetIsInput)) { + _hide(); + } + + // key events triggered from outside the modal should also die, + // except for ctrl combinations like ctrl+c (or cmd+c on macOS) + var keyShortcut = event.ctrlKey || event.metaKey; + if (escKey || (!targetInModal && !keyShortcut) || enterKey && !targetIsInput) { + event.preventDefault(); + event.stopPropagation(); + } + } + }, + 'keypress': function(event) { + if (scrollValues[event.which]) { event.preventDefault(); } + }, + 'keyup': function(event) { + if (scrollValues[event.which]) { event.preventDefault(); } + else if (event.which == 9 && !tabbed) { + _closeButton.focus(); + tabbed = true; + event.preventDefault(); + } + } + }; + + return { + toggleHandlers: function(on) { + tabbed = false; + for (var eventType in handlers) { + if (handlers.hasOwnProperty(eventType)) { + if (on) { + $('body').on(eventType, handlers[eventType]); + } else { + $('body').off(eventType, handlers[eventType]); + } + } + } + } + }; + })(); + + // set modal-classed links to open modal boxes + _addLink($('a.modal, img.modal')); + + // ensure handlers are attached to dynamically added modal invokers + $('body').on('click', 'a.modal, img.modal', function(event) { + var $this = $(this); + if ($this.is('.modal-attached')) { return; } + _addLink($this); + event.preventDefault(); + if ($this.is('img')) { + $this.parent().click(); + } else { + $this.click(); + } + }); + + return { + show: _show, + setContent: _setContent, + hide: _hide, + addLink: _addLink + }; + + })(jQuery); + +}); diff --git a/public/javascripts/ao3modal.min.js b/public/javascripts/ao3modal.min.js new file mode 100755 index 0000000..612e712 --- /dev/null +++ b/public/javascripts/ao3modal.min.js @@ -0,0 +1 @@ +jQuery(document).ready(function(){window.ao3modal=function(t){var e,a,i,o,s,l,n,d,c,r,p,h,m=!1,$=t("
        ",{id:"modal-bg"}).addClass("modal-closer"),f=t("
        ").addClass("loading"),g=t("
        ",{id:"modal-wrap"}).addClass("modal-closer"),u=t("
        ",{id:"modal"}),v=t("
        ").addClass("content userstuff"),w=t("").addClass("action modal-closer").click(function(t){t.preventDefault()}).attr("href","#").text("Close"),b=t("").addClass("title"),_=(l=navigator.userAgent||navigator.vendor||window.opera,/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(ad|hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(l)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(l.substr(0,4))),k=-1,y=_?0:(d=t("

        ").css({width:"100%",height:200}),c=t("

        ").css({height:150,left:0,overflow:"hidden",top:0,visibility:"hidden",width:200}).append(d).appendTo(t("body")),r=d[0].offsetWidth,c.css("overflow","scroll"),r==(n=d[0].offsetWidth)&&(n=c[0].clientWidth),c.remove(),r-n);function x(e){!_&&t("body").css({"margin-right":e?"":y,overflow:e?"":"hidden",height:e?"":$.height()})}function C(){var e,a,i,o=!u.is(":visible");_&&k<0&&(k=t(window).scrollTop()),o&&u.css("opacity",0).show(),u.removeClass("tall"),u.hasClass("img")?(e=v.children("img").first(),u.toggleClass("tall",u.height()>=.95*$.height())):_||(i=Math.min(a=$.height()*p.scale,p.max),u.toggleClass("tall",!i||u[0].scrollHeight>i)),o&&u.hide().css("opacity",""),_?g.css("top",k):g.css("top",t(window).scrollTop())}function z(e,a){m=!1,v.empty(),e instanceof t?v.append(e):v.html(e),a=a instanceof t?a:t("").addClass("title").text(a||""),b.replaceWith(a),b=a,v.is(":empty")||(C(),v.is(":visible")||(h.toggleHandlers(!0),f.hide(),u.fadeIn(function(){v.focus()})))}function O(e,a){if(u.hide(),g.show(),t.support.opacity?$.add(f).fadeIn():$.add(f).show(),x(!1),m=!0,0===e.indexOf("#"))z(t(e).html(),a||"");else if(e.indexOf(".jpg")==e.length-4||e.indexOf(".gif")==e.length-4||e.indexOf(".bmp")==e.length-4||e.indexOf(".png")==e.length-4){u.addClass("img");var i=t("").appendTo(t("body")).attr("src",e),o=function(){var o=t("").addClass("title").attr({href:e,title:"View original",target:"_blank"}).text(a||(-1!=e.indexOf("/")?e.substring(e.lastIndexOf("/")+1):e)).css("text-decoration","underline");i.remove(),m&&(a&&i.attr("alt",a),z(i[0],o))};i[0].complete?o():i.load(o)}else t.ajax({url:e,success:function(t){m&&z(t,a)}})}function D(){m=!1,b.text(""),h.toggleHandlers(!1),g.fadeOut(function(){z(""),x(!0),u.css("width","").removeClass("tall img"),_&&k>=0&&(t("html, body").animate({scrollTop:k},"fast"),k=-1)}),t.support.opacity?$.fadeOut():$.hide()}function j(e){e.each(function(){var e=!!t(this).is("img")&&t(this).removeClass("modal"),a=e?t("").css("border","none").attr({title:e.attr("title")||e.attr("alt"),href:e.attr("src")}).replaceAll(e).append(e):t(this);a.addClass("modal modal-attached").attr("aria-controls","modal").filter(function(){return 0===t(this).closest(".userstuff").length}).click(function(e){O(t(this).attr("href"),t(this).attr("title")),e.preventDefault()}),0===a.attr("href").indexOf("#")&&t(a.attr("href")).hide()})}return t("body").append($.append(f),g.append(u.append(v,t("
        ").addClass("footer").append(b,w)).trap())),p=_?null:(e={},(a=u.clone()).css("margin-top",9001).addClass("tall").appendTo($),e.scale=a.height()?parseInt(a.css("height"))/100:.8,e.max=parseInt(a.css("max-height")),a.remove(),e),t("body").click(function(e){(t(e.target).hasClass("modal-closer")||u.hasClass("img")&&t(e.target).hasClass("content"))&&D()}),t(window).resize(function(){u.is(":visible")&&C()}),h=(i={38:-20,40:20,33:-200,34:200},o=!1,s={keydown:function(e){if(i[e.which])v[0].scrollTop+=i[e.which],e.preventDefault();else if(u.is(":visible")){var a=e.target,o=a.tagName.toLowerCase(),s=27==e.which,l=13==e.which,n=/^(input|textarea|a|button)$/.test(o),d=!!t(a).closest("#modal")[0];(s||l&&(!d||!n))&&D();var c=e.ctrlKey||e.metaKey;!s&&(d||c)&&(!l||n)||(e.preventDefault(),e.stopPropagation())}},keypress:function(t){i[t.which]&&t.preventDefault()},keyup:function(t){i[t.which]?t.preventDefault():9!=t.which||o||(w.focus(),o=!0,t.preventDefault())}},{toggleHandlers:function(e){for(var a in o=!1,s)s.hasOwnProperty(a)&&(e?t("body").on(a,s[a]):t("body").off(a,s[a]))}}),j(t("a.modal, img.modal")),t("body").on("click","a.modal, img.modal",function(e){var a=t(this);!a.is(".modal-attached")&&(j(a),e.preventDefault(),a.is("img")?a.parent().click():a.click())}),{show:O,setContent:z,hide:D,addLink:j}}(jQuery)}); diff --git a/public/javascripts/application.js b/public/javascripts/application.js new file mode 100755 index 0000000..fe43d74 --- /dev/null +++ b/public/javascripts/application.js @@ -0,0 +1,641 @@ +// Place your application-specific JavaScript functions and classes here +// This file is automatically included by javascript_include_tag :defaults + +//things to do when the page loads +$j(document).ready(function() { + setupToggled(); + if ($j('form#work-form')) { hideFormFields(); } + hideHideMe(); + showShowMe(); + handlePopUps(); + attachCharacterCounters(); + setupAccordion(); + setupDropdown(); + updateCachedTokens(); + + // add clear to items on the splash page in older browsers + $j('.splash').children('div:nth-of-type(odd)').addClass('odd'); + + // make Share buttons on works and own bookmarks visible + $j('.actions').children('.share').removeClass('hidden'); + + // make Approve buttons on inbox items visible + $j('#inbox-form, .messages').find('.unreviewed').find('.review').find('a').removeClass('hidden'); + + prepareDeleteLinks(); + thermometer(); + $j('body').addClass('javascript'); +}); + +/////////////////////////////////////////////////////////////////// +// Autocomplete +/////////////////////////////////////////////////////////////////// + +function get_token_input_options(self) { + return { + searchingText: self.data('autocomplete-searching-text'), + hintText: self.data('autocomplete-hint-text'), + noResultsText: self.data('autocomplete-no-results-text'), + minChars: self.data('autocomplete-min-chars'), + queryParam: "term", + preventDuplicates: true, + tokenLimit: self.data('autocomplete-token-limit'), + liveParams: self.data('autocomplete-live-params'), + makeSortable: self.data('autocomplete-sortable') + }; +} + +// Look for autocomplete_options in application helper and throughout the views to +// see how to use this! +var input = $j('input.autocomplete'); +if (input.livequery) { + jQuery(function($) { + $('input.autocomplete').livequery(function(){ + var self = $(this); + var token_input_options = get_token_input_options(self); + var method; + try { + method = $.parseJSON(self.data('autocomplete-method')); + } catch (err) { + method = self.data('autocomplete-method'); + } + self.tokenInput(method, token_input_options); + }); + }); +} + +/////////////////////////////////////////////////////////////////// + +// expand, contract, shuffle +jQuery(function($){ + $(".expand").each(function(){ + // start by hiding the list in the page + list = $($(this).data("action-target")); + if (!list.data("force-expand") || list.children().size() > 25 || list.data("force-contract")) { + list.hide(); + $(this).show(); + } else { + // show the shuffle and contract button only + $(this).nextAll(".shuffle").show(); + $(this).next(".contract").show(); + } + + // set up click event to expand the list + $(this).click(function(event){ + list = $($(this).data("action-target")); + list.show(); + + // show the contract & shuffle buttons and hide us + $(this).next(".contract").show(); + $(this).nextAll(".shuffle").show(); + $(this).hide(); + }); + }); + + $(".contract").each(function(){ + $(this).click(function(event){ + // hide the list when clicked + list = $($(this).data("action-target")); + list.hide(); + + // show the expand and shuffle buttons and hide us + $(this).prev(".expand").show(); + $(this).nextAll(".shuffle").hide(); + $(this).hide(); + }); + }); + + $(".shuffle").each(function(){ + // shuffle the list's children when clicked + $(this).click(function(event){ + list = $($(this).data("action-target")); + list.children().shuffle(); + }); + }); + + $(".expand_all").each(function(){ + target = "." + $(this).data("target-class"); + $(this).click(function(event) { + $(this).closest(target).find(".expand").click(); + }); + }); + + $(".contract_all").each(function(){ + target = "." + $(this).data("target-class"); + $(this).click(function(event) { + $(this).closest(target).find(".contract").click(); + }); + }); +}); + +// check all or none within the parent fieldset, optionally with a string to match on the id attribute of the checkboxes +// stored in the "data-checkbox-id-filter" attribute on the all/none links. +// allow for some flexibility by checking the next and previous fieldset if the checkboxes aren't in this one +jQuery(function($){ + $('.check_all').each(function(){ + $(this).click(function(event){ + var filter = $(this).data('checkbox-id-filter'); + var checkboxes; + if (filter) { + checkboxes = $(this).closest('fieldset').find('input[id*="' + filter + '"][type="checkbox"]'); + } else { + checkboxes = $(this).closest("fieldset").find(':checkbox'); + if (checkboxes.length == 0) { + checkboxes = $(this).closest("fieldset").next().find(':checkbox'); + if (checkboxes.length == 0) { + checkboxes = $(this).closest("fieldset").prev().find(':checkbox'); + } + } + } + checkboxes.prop('checked', true); + event.preventDefault(); + }); + }); + + $('.check_none').each(function(){ + $(this).click(function(event){ + var filter = $(this).data('checkbox-id-filter'); + var checkboxes; + if (filter) { + checkboxes = $(this).closest('fieldset').find('input[id*="' + filter + '"][type="checkbox"]'); + } else { + checkboxes = $(this).closest("fieldset").find(':checkbox'); + if (checkboxes.length == 0) { + checkboxes = $(this).closest("fieldset").next().find(':checkbox'); + if (checkboxes.length == 0) { + checkboxes = $(this).closest("fieldset").prev().find(':checkbox'); + } + } + } + checkboxes.prop('checked', false); + event.preventDefault(); + }); + }); +}); + +// Set up open and close toggles for a given object +// Typical setup (this will leave the toggled item open for users without javascript but hide the controls from them): +// +//
        +// foo! +// +//
        +// +// Notes: +// - The open button CANNOT be inside the toggled div, the close button can be (but doesn't have to be) +// - You can have multiple open and close buttons for the same div since those are labeled with classes +// - You don't have to use div and a, those are just examples. Anything you put the toggled and _open/_close classes on will work. +// - If you want the toggled item not to be visible to users without JavaScript by default, add the class "hidden" to the toggled item as well. +// (and you can then add an alternative link for them using
        ";$tp=$(i);if(b.timeOnly===true){$tp.prepend('
        '+'
        '+b.timeOnlyTitle+"
        "+"
        ");a.find(".ui-datepicker-header, .ui-datepicker-calendar").hide()}this.hour_slider=$tp.find("#ui_tpicker_hour_"+g).slider({orientation:"horizontal",value:this.hour,min:b.hourMin,max:d,step:b.stepHour,slide:function(a,b){c.hour_slider.slider("option","value",b.value);c._onTimeChange()}});this.minute_slider=$tp.find("#ui_tpicker_minute_"+g).slider({orientation:"horizontal",value:this.minute,min:b.minuteMin,max:e,step:b.stepMinute,slide:function(a,b){c.minute_slider.slider("option","value",b.value);c._onTimeChange()}});this.second_slider=$tp.find("#ui_tpicker_second_"+g).slider({orientation:"horizontal",value:this.second,min:b.secondMin,max:f,step:b.stepSecond,slide:function(a,b){c.second_slider.slider("option","value",b.value);c._onTimeChange()}});this.timezone_select=$tp.find("#ui_tpicker_timezone_"+g).append("").find("select");$.fn.append.apply(this.timezone_select,$.map(b.timezoneList,function(a,b){return $("